// ==UserScript==
// @name LearnedLeague Utility
// @namespace Violentmonkey Scripts
// @match https://*.learnedleague.com/viewtopic.php*
// @match https://*.learnedleague.com/question.php*
// @match https://*.learnedleague.com/match.php*
// @match https://*.learnedleague.com/mini/match.php*
// @match https://*.learnedleague.com/oneday.php*
// @grant none
// @version 1.5.2
// @author BlumE
// @license MIT
// @description Utility for learnedleague.com: load your answers inline with questions, link to questions from forum threads, copy OP forum post template, see your placement in One Days if you had different correct or moneyed
// ==/UserScript==
let processFunction;
if (window.location.pathname === "/question.php") {
processFunction = handleQuestionPage;
} else if (window.location.pathname === "/viewtopic.php") {
processFunction = handleMessageBoardTopicPage;
} else if (window.location.pathname === "/match.php") {
processFunction = handleMatchPage;
} else if (window.location.pathname === "/mini/match.php") {
processFunction = handleMiniMatchPage;
} else if (window.location.pathname === "/oneday.php") {
processFunction = handleOneDayPage;
} else {
return;
}
// If page is still loading, queue function for when it is done
if (document.readyState !== "loading") {
processFunction();
} else {
document.addEventListener('DOMContentLoaded', processFunction);
}
function handleQuestionPage() {
let answerDiv = document.querySelector('#xyz > span');
if (!answerDiv) return;
const statsDiv = document.querySelector('#main > div > div.indivqContent > div > div:nth-child(5) > div');
if (!statsDiv) return;
const [leagueNumber, matchDayNumber, questionNumber] = window.location.search.slice(1).split('&');
if (!(leagueNumber && matchDayNumber && questionNumber)) return;
if (document.getElementsByClassName('res_table').length > 0) {
// Only add "Your Answer" section if page has the results box that indicates you participated
appendYourAnswerDiv(statsDiv, leagueNumber, matchDayNumber, questionNumber);
}
appendCopyTemplateDiv(statsDiv, leagueNumber, matchDayNumber, questionNumber, answerDiv)
}
function handleMessageBoardTopicPage() {
addLinkToQuestionPage();
}
/**
* Adds a button to load your answers and includes them next to the correct answer
* Handles the different kind of match pages
*/
function handleMatchPage() {
const queryTerm = window.location.search.substring(1);
if (queryTerm.startsWith('id=')){
addLinkToLoadMatchAnswersSpecificMatch();
} else if (queryTerm.indexOf('_Div_') !== -1) {
addLinkToLoadMatchAnswersSpecificDivision();
} else {
addLinkToLoadMatchAnswers();
}
}
/**
* Adds a button to load your answers and includes them next to the correct answer
* Handles the different kind of mini match pages
*/
function handleMiniMatchPage() {
const queryTerm = window.location.search.substring(1);
if (queryTerm.startsWith('id=')){
addLinkToLoadMiniMatchAnswersSpecificMatch();
} else {
let [mini_league_name, match_day_number, group_number] = queryTerm.split('&');
if (group_number) {
addLinkToLoadMiniMatchAnswersSpecificGroup();
} else {
addLinkToLoadMiniMatchAnswers();
}
}
}
/**
* Adds a link on forum topics that include the proper LL question header.
* e.g. LL83 MD9Q6 (KINGSTON) to the question page.
*/
function addLinkToQuestionPage() {
const reLeagueNumber = /[Ll][Ll](\d+)/;
const reMatchDayNumber = /[Mm][Dd](\d+)/;
const reQuestionNumber = /[Qq](\d+)/;
let postHeader = document.querySelector("#pageheader a");
if (postHeader) {
let postName = postHeader.innerHTML;
let leagueNumber = reLeagueNumber.exec(postName);
let matchDayNumber = reMatchDayNumber.exec(postName);
let questionNumber = reQuestionNumber.exec(postName);
if (leagueNumber && matchDayNumber && questionNumber) {
let linkURL = `/question.php?${leagueNumber[1]}&${matchDayNumber[1]}&${questionNumber[1]}`
let newLink = document.createElement('a');
newLink.href = linkURL;
newLink.title = "Link";
newLink.text = " Link >>";
newLink.style = "border-bottom: dotted 1px;color: #336666;"
postHeader.parentElement.appendChild(newLink);
}
}
}
/**
* Adds a button to load your answer for the given question
*/
function appendYourAnswerDiv(statsDiv, leagueNumber, matchDayNumber, questionNumber) {
let answerHeader = document.createElement('h3');
answerHeader.innerHTML = "<i>Your</i> Answer";
let answerLinkDiv = document.createElement('div');
answerLinkDiv.style = "margin-bottom:1.5em;margin-left:0.5em;";
let answerToggle = document.createElement('a');
answerToggle.id = "answerToggle";
answerToggle.innerHTML = 'Click here to reveal';
answerToggle.href = `javascript:RemoveContent('answerToggle');javascript:InsertContent('answerValue')`;
answerToggle.onclick = function () {fillInMyAnswer(leagueNumber, matchDayNumber, questionNumber);};
let answerValue = document.createElement('p');
answerValue.id = "answerValue";
answerValue.style = "display:none";
answerValue.innerHTML = `<i>Loading...</i>`;
answerLinkDiv.appendChild(answerToggle);
answerLinkDiv.appendChild(answerValue);
statsDiv.appendChild(answerHeader);
statsDiv.appendChild(answerLinkDiv);
}
/**
* Adds a button to copy a template for a question to your clipboard for use in a new
* forum post including the post subject and a nicely formatted body with the question text
* included.
*/
function appendCopyTemplateDiv(statsDiv, leagueNumber, matchDayNumber, questionNumber, answerDiv) {
let answer = answerDiv.textContent.trim();
let postSubject = `LL${leagueNumber} MD${matchDayNumber}Q${questionNumber} (${answer})`;
let postBody = templateBody();
let postContent = postSubject + "\\n" + postBody;
let templateHeader = document.createElement('h3');
templateHeader.innerHTML = "Forum Post Template";
let templateCopyDiv = document.createElement('div');
templateCopyDiv.style = "margin-bottom:1.5em;margin-left:0.5em;";
let templateCopy = document.createElement('a');
templateCopy.id = "subjectToggle";
templateCopy.innerHTML = "Click here to copy template to clipboard";
templateCopy.href = `javascript:navigator.clipboard.writeText("${postContent}")`;
templateCopyDiv.appendChild(templateCopy);
statsDiv.appendChild(templateHeader);
statsDiv.appendChild(templateCopyDiv);
}
/**
* Processes the body of the question to transform any special symbols or formatting to something the message board
* system recognizes
*/
function templateBody() {
let questionDiv = document.querySelector('.indivqQuestion');
let answerDiv = document.querySelector('#xyz > span');
let answer = answerDiv.textContent.trim();
let postBody = `[quote="Question"]${questionDiv.innerHTML.trim()}[/quote] Answer: [spoiler]${answer}[/spoiler]`;
let template = document.createElement('template');
template.innerHTML = postBody;
let content = [...template.content.childNodes].map(node => processNode(node)).join("");
content = content.replace(/"/g, '\\\"');
return content;
}
function processNode(node) {
let val;
if (node.hasChildNodes()) {
val = [...node.childNodes].map(node => processNode(node)).join("");
} else {
val = node.textContent;
}
if (node.nodeType === node.TEXT_NODE) {
return val
} else {
const equivalentElements = ['b', 'i', 'u'];
if (equivalentElements.indexOf(node.localName) !== -1) {
return `[${node.localName}]${val}[/${node.localName}]`;
} else if (node.localName === 'em') {
return `[i]${val}[/i]`;
} else if (node.localName === 'a') {
return `[url=${node.href}]${val}[/url]`;
} else if (node.localName === 'br') {
return '\\n'
} else if (node.localName === 'sup') {
const superscriptMap = new Map([['0', '⁰'], ['1', '¹'], ['2', '²'], ['3', '³'], ['4', '⁴'], ['5', '⁵'], ['6', '⁶'], ['7', '⁷'], ['8', '⁸'],
['9', '⁹'], ['+', '⁺'], ['-', '⁻'], ['=', '⁼'], ['(', '⁽'], [')', '⁾'], ['n', 'ⁿ'], ['i', 'ⁱ']]);
if ([...val].every(char => superscriptMap.has(char))) {
return [...val].map(char => superscriptMap.get(char)).join('');
} else if (
node.children.length === 1
&& equivalentElements.indexOf(node.firstChild.localName) !== -1
&& node.firstChild.children.length === 0
&& [...node.firstChild.textContent].every(char => superscriptMap.has(char))
) {
// Handle edge case of <sup><i>123</i></sup>
return `[${node.firstChild.localName}]${[...node.firstChild.textContent].map(char => superscriptMap.get(char)).join('')}[/${node.firstChild.localName}]`;
} else {
return "^" + val;
}
} else if (node.localName === 'sub') {
const subscriptMap = new Map([['0', '₀'], ['1', '₁'], ['2', '₂'], ['3', '₃'], ['4', '₄'], ['5', '₅'], ['6', '₆'], ['7', '₇'], ['8', '₈'],
['9', '₉'], ['+', '₊'], ['-', '₋'], ['=', '₌'], ['(', '₍'], [')', '₎'], ['a', 'ₐ'], ['e', 'ₑ'], ['o', 'ₒ'],
['x', 'ₓ'], ['h', 'ₕ'], ['k', 'ₖ'], ['l', 'ₗ'], ['m', 'ₘ'], ['n', 'ₙ'], ['p', 'ₚ'], ['s', 'ₛ'], ['t', 'ₜ'], ['ə', 'ₔ']]);
if ([...val].every(char => subscriptMap.has(char))) {
return [...val].map(char => subscriptMap.get(char)).join('');
} else if (
node.children.length === 1
&& equivalentElements.indexOf(node.firstChild.localName) !== -1
&& node.firstChild.children.length === 0
&& [...node.firstChild.textContent].every(char => superscriptMap.has(char))
) {
// Handle edge case of <sub><i>123</i></sub>
return `[${node.firstChild.localName}]${[...node.firstChild.textContent].map(char => subscriptMap.get(char)).join('')}[/${node.firstChild.localName}]`;
} else {
return "_" + val + "_";
}
} else {
console.log('unknown node ', node);
return val;
}
}
}
function fillInMyAnswer(seasonNumber, matchDayNumber, questionNumber) {
queryPastAnswers(seasonNumber, matchDayNumber).then(function (response) {
const parser = new DOMParser();
const doc = parser.parseFromString(response, "text/html");
// Hopefully this remains consistent
const answerQuery = `table.qtable > tbody > tr:nth-child(${parseInt(questionNumber) + 1}) > td:nth-child(3)`;
const answerNode = doc.querySelector(answerQuery);
let answerValue = document.getElementById('answerValue');
if (!answerNode) {
answerValue.innerHTML = 'Failed to retrieve';
} else {
answerValue.innerHTML = answerNode.innerHTML;
}
}).catch(function (err) {
let answerValue = document.getElementById('answerValue');
answerValue.innerHTML = 'Failed to retrieve ' + err;
})
}
function queryPastAnswers(leagueNumber, matchDayNumber) {
return new Promise(function (resolve, reject) {
const req = new XMLHttpRequest();
req.addEventListener("load", onload);
req.open("POST", "/thorsten/pastanswers.php");
req.onload = function () {
if (req.status >= 200 && req.status < 300) {
resolve(req.response);
} else {
reject({
status: req.status,
statusText: req.statusText
});
}
};
req.onerror = function () {
reject({
status: req.status,
statusText: req.statusText
});
};
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
req.send(`season=${leagueNumber}&matchday=${matchDayNumber}`);
})
}
function addLinkToLoadMatchAnswersSpecificMatch() {
let parentDiv = document.querySelector('.QTable').parentElement
let answerLinkDiv = document.createElement('div');
answerLinkDiv.style = "margin-bottom:1.0em";
let answerToggle = document.createElement('a');
answerToggle.id = "answerToggle";
answerToggle.innerHTML = 'Click here to reveal your answers';
answerToggle.href = `javascript:RemoveContent('answerToggle')`;
const questionLink = new URL(document.querySelector('.ind-Numb2 a').href);
const [leagueNumber, matchDayNumber, questionNumber] = questionLink.search.slice(1).split('&');
answerToggle.onclick = function () {fillInMyMatchAnswersSpecificMatch(leagueNumber, matchDayNumber);};
let answerLoadingProgress = document.createElement('p');
answerLoadingProgress.id = "answerLoadingProgress";
answerLoadingProgress.hidden = true;
answerLoadingProgress.innerHTML = `<i>Loading...</i>`;
answerLinkDiv.appendChild(answerToggle);
answerLinkDiv.appendChild(answerLoadingProgress);
parentDiv.prepend(answerLinkDiv);
}
function fillInMyMatchAnswersSpecificMatch(leagueNumber, matchDayNumber) {
const answerLoadingProgress = document.querySelector('#answerLoadingProgress')
answerLoadingProgress.hidden = false;
queryPastAnswers(leagueNumber, matchDayNumber).then(function (response) {
const parser = new DOMParser();
const doc = parser.parseFromString(response, "text/html");
const answerTable = doc.querySelector(`table.qtable`);
if (!answerTable) {
answerLoadingProgress.innerHTML = '<i>Failed to retrieve</i>';
} else {
let matchTable = document.querySelector(`table.QTable`);
// Fill in your answers next to actual answers
for (let i = 1; i <= 6; i++) {
let yourAnswer = answerTable.rows[i].cells[2].innerHTML;
let resultImgSrc = answerTable.rows[i].cells[3].firstChild.src;
matchTable.rows[i].cells[1].innerHTML += `<div><i>${yourAnswer}</i> <img src="${resultImgSrc}" style="height: 12px"></img></div>`;
}
answerLoadingProgress.hidden = true;
}
}).catch(function (err) {
console.log(err);
})
}
function addLinkToLoadMatchAnswersSpecificDivision() {
let parentDiv = document.querySelector('.qacontainer').parentElement
let answerLinkDiv = document.createElement('div');
answerLinkDiv.style = "margin-bottom:1.0em";
let answerToggle = document.createElement('a');
answerToggle.id = "answerToggle";
answerToggle.innerHTML = 'Click here to reveal your answers';
answerToggle.href = `javascript:RemoveContent('answerToggle')`;
const questionLink = new URL(document.querySelector('.qaqnumber a').href);
const [leagueNumber, matchDayNumber, questionNumber] = questionLink.search.slice(1).split('&');
answerToggle.onclick = function () {fillInMyMatchAnswersSpecificDivision(leagueNumber, matchDayNumber);};
let answerLoadingProgress = document.createElement('p');
answerLoadingProgress.id = "answerLoadingProgress";
answerLoadingProgress.hidden = true;
answerLoadingProgress.innerHTML = `<i>Loading...</i>`;
answerLinkDiv.appendChild(answerToggle);
answerLinkDiv.appendChild(answerLoadingProgress);
parentDiv.insertBefore(answerLinkDiv, document.querySelector('#lft > div:nth-child(3)'));
}
function fillInMyMatchAnswersSpecificDivision(leagueNumber, matchDayNumber) {
const answerLoadingProgress = document.querySelector('#answerLoadingProgress')
answerLoadingProgress.hidden = false;
queryPastAnswers(leagueNumber, matchDayNumber).then(function (response) {
const parser = new DOMParser();
const doc = parser.parseFromString(response, "text/html");
const answerTable = doc.querySelector(`table.qtable`);
const answerDivs = document.querySelector(`#lft > div:nth-child(5)`);
if (!answerTable) {
answerLoadingProgress.innerHTML = '<i>Failed to retrieve</i>';
} else {
// Fill in your answers next to actual answers
for (let i = 1; i <= 6; i++) {
let yourAnswer = answerTable.rows[i].cells[2].innerHTML;
let resultImgSrc = answerTable.rows[i].cells[3].firstChild.src;
answerDivs.children[i-1].innerHTML += `<div><i>${yourAnswer}</i> <img src="${resultImgSrc}" style="height: 12px"></img></div>`;
}
answerLoadingProgress.hidden = true;
}
}).catch(function (err) {
console.log(err);
})
}
function addLinkToLoadMatchAnswers() {
let parentDiv = document.querySelector('#lft > div.yellolbl').parentElement
let answerLinkDiv = document.createElement('div');
answerLinkDiv.style = "margin-bottom:1.0em";
let answerToggle = document.createElement('a');
answerToggle.id = "answerToggle";
answerToggle.innerHTML = 'Click here to include your answers';
answerToggle.href = `javascript:RemoveContent('answerToggle')`;
const questionLink = new URL(document.querySelector('#lft > div.ind-boxATbl > div:nth-child(1) > span > a').href);
const [leagueNumber, matchDayNumber, questionNumber] = questionLink.search.slice(1).split('&');
answerToggle.onclick = function () {fillInMyMatchAnswers(leagueNumber, matchDayNumber);};
let answerLoadingProgress = document.createElement('p');
answerLoadingProgress.id = "answerLoadingProgress";
answerLoadingProgress.hidden = true;
answerLoadingProgress.innerHTML = `<i>Loading...</i>`;
answerLinkDiv.appendChild(answerToggle);
answerLinkDiv.appendChild(answerLoadingProgress);
parentDiv.insertBefore(answerLinkDiv, document.querySelector('#lft > div.yellolbl'));
}
function fillInMyMatchAnswers(leagueNumber, matchDayNumber) {
const answerLoadingProgress = document.querySelector('#answerLoadingProgress')
answerLoadingProgress.hidden = false;
queryPastAnswers(leagueNumber, matchDayNumber).then(function (response) {
const parser = new DOMParser();
const doc = parser.parseFromString(response, "text/html");
const answerTable = doc.querySelector(`table.qtable`);
const answerDivs = document.querySelectorAll('.indivqAnswerwrapper');
if (!answerTable) {
answerLoadingProgress.innerHTML = '<i>Failed to retrieve</i>';
} else {
let matchTable = document.querySelector(`table.QTable`);
// Fill in your answers next to actual answers
for (let i = 1; i <= 6; i++) {
let yourAnswer = answerTable.rows[i].cells[2].innerHTML;
let resultImgSrc = answerTable.rows[i].cells[3].firstChild.src;
answerDivs[i-1].children[1].innerHTML += `<div style="color: #293A55; font-weight: 400"><i>${yourAnswer}</i> <img src="${resultImgSrc}" style="height: 12px"></img></div>`;
}
answerLoadingProgress.hidden = true;
}
}).catch(function (err) {
console.log(err);
})
}
function addLinkToLoadMiniMatchAnswersSpecificMatch() {
addLinkToLoadMatchAnswersSpecificMatch();
}
function addLinkToLoadMiniMatchAnswersSpecificGroup() {
addLinkToLoadMatchAnswersSpecificDivision();
}
function addLinkToLoadMiniMatchAnswers() {
addLinkToLoadMatchAnswers();
}
function queryOneDay(oneDayId) {
return new Promise(function (resolve, reject) {
const req = new XMLHttpRequest();
req.addEventListener("load", onload);
req.open("POST", `/oneday/results.php?${oneDayId}&12`);
req.onload = function () {
if (req.status >= 200 && req.status < 300) {
resolve(req.response);
} else {
reject({
status: req.status,
statusText: req.statusText
});
}
};
req.onerror = function () {
reject({
status: req.status,
statusText: req.statusText
});
};
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
req.send();
})
}
function bisect(arr, value) {
let lo = 0;
let hi = arr.length;
while (lo < hi) {
const mid = (lo + hi) >> 1;
if (typeof(arr[mid]) == 'undefined' || arr[mid] <= value) {
lo = mid + 1;
} else {
hi = mid;
}
}
return lo;
}
function makeElement(elementType, className, innerHTML, colspan) {
element = document.createElement(elementType);
if (className) {
element.className = className;
}
if (innerHTML) {
element.innerHTML = innerHTML;
}
if (colspan) {
element.setAttribute("colspan", colspan);
}
return element
}
function createTheorycraftForm(oneDayId) {
let existingDiv = document.getElementById('theorycraftDiv');
if (existingDiv) {
// Toggle display of theorycraft div
existingDiv.style.display = existingDiv.style.display === 'none' ? '' : 'none';
return
}
queryOneDay(oneDayId).then(function (response) {
const questionCount = 12;
const parser = new DOMParser();
const doc = parser.parseFromString(response, "text/html");
const table = doc.querySelector('.tbl_q > tbody')
const correctPct = Array(questionCount);
const incorrectPct = Array(questionCount);
const moneyPct = Array(questionCount);
let row;
for (let i = 0; i < questionCount; i++) {
row = table.children[i+1].children;
correctPct[i] = Number(row[1].textContent);
incorrectPct[i] = 100 - correctPct[i];
moneyPct[i] = Number(row[2].textContent);
}
const maxScore = incorrectPct.toSorted().slice(questionCount - 5, questionCount).reduce((a,b) => a+b) + 15*questionCount;
const percentiles = doc.querySelectorAll('.pctile > tbody > tr');
const percentileValues = Array(99);
let percentile, points;
for (let i = 0; i < percentiles.length; i++) {
if (!percentiles[i].children.length) continue;
percentile = Number(percentiles[i].children[0].textContent);
if (!percentile) continue;
points = Number(percentiles[i].children[1].textContent);
percentileValues[percentile-1] = points;
}
const cleanPercentileValues = percentileValues.filter(x => typeof x !== 'undefined');
function updateTheoryCraftForm(e) {
let questionCorrect, questionMoneyed, questionValue, score;
let totalScore = 0;
let numberCorrect = 0;
for (let i = 0; i < questionCount; i++) {
questionCorrect = document.getElementById(`q${i+1}c`).checked;
questionMoneyed = document.getElementById(`q${i+1}m`).checked;
questionValue = document.getElementById(`q${i+1}v`);
score = questionCorrect * (15 + questionMoneyed * incorrectPct[i]);
questionValue.innerHTML = questionCorrect * (15 + questionMoneyed * incorrectPct[i]);
if (questionCorrect && questionMoneyed) questionValue.className = 'omg u bb';
else if (questionCorrect) questionValue.className = 'omg bb';
else if (questionMoneyed) questionValue.className = 'omr bb';
else questionValue.className = 'om bb';
totalScore += score;
numberCorrect += questionCorrect;
}
document.getElementById(`tcPoints`).innerHTML = totalScore;
document.getElementById(`tcNumberCorrect`).innerHTML = numberCorrect;
let calculatedPercentile = percentileValues.indexOf(cleanPercentileValues[bisect(cleanPercentileValues, totalScore)-1]) + 1;
document.getElementById(`tcPercentile`).innerHTML = calculatedPercentile;
}
let theorycraftDiv = document.createElement('div');
theorycraftDiv.id = 'theorycraftDiv';
theorycraftDiv.classList.add('pctile_container');
theorycraftDiv.innerHTML = `<h2>Theorycrafting</h2>`
let innerDiv = document.createElement('div');
innerDiv.style = "overflow-x:auto;";
theorycraftDiv.appendChild(innerDiv);
theorycraftDiv.appendChild(document.createElement('br'));
let theorycraftTable = document.createElement('table');
theorycraftTable.id = "theorycraft";
theorycraftTable.className = 'std';
theorycraftTable.style = "width:98%";
let thead = document.createElement('thead');
let tr1 = document.createElement('tr');
tr1.bgcolor = "#f6f7f2";
tr1.innerHTML = `\
<td class="std-head-mid"> </td>
<td class="std-head-mid"> </td>
<td class="std-head-mid">1</td>
<td class="std-head-mid">2</td>
<td class="std-head-mid">3</td>
<td class="std-head-mid">4</td>
<td class="std-head-mid">5</td>
<td class="std-head-mid">6</td>
<td class="std-head-mid">7</td>
<td class="std-head-mid">8</td>
<td class="std-head-mid">9</td>
<td class="std-head-mid">10</td>
<td class="std-head-mid">11</td>
<td class="std-head-mid">12</td>
<td class="std-head-mid" style="border-left:1px solid lavender;">#c</td>
<td class="std-head-mid">Points</td>
<td class="std-head-mid">%ile</td>`
thead.appendChild(tr1);
let tr2 = document.createElement('tr');
tr2.bgcolor = "#ffffff";
tr2.innerHTML = `\
<td class="std-head-mid" colspan="2">% incorrect:</td>
<td class="std-head-mid">${incorrectPct[0]}</td>
<td class="std-head-mid">${incorrectPct[1]}</td>
<td class="std-head-mid">${incorrectPct[2]}</td>
<td class="std-head-mid">${incorrectPct[3]}</td>
<td class="std-head-mid">${incorrectPct[4]}</td>
<td class="std-head-mid">${incorrectPct[5]}</td>
<td class="std-head-mid">${incorrectPct[6]}</td>
<td class="std-head-mid">${incorrectPct[7]}</td>
<td class="std-head-mid">${incorrectPct[8]}</td>
<td class="std-head-mid">${incorrectPct[9]}</td>
<td class="std-head-mid">${incorrectPct[10]}</td>
<td class="std-head-mid">${incorrectPct[11]}</td>
<td class="std-head-mid"> </td>
<td colspan="2" class="std-head-mid" style="font-size:0.85em;font-family:" lato',="" sans-serif;="" '=""><i>${maxScore} (max)</i></td>
<td class="std-head-mid"> </td>`
thead.appendChild(tr2);
let tr3 = document.createElement('tr');
tr3.bgcolor = "#ffffff";
let correctHeader = makeElement('td', 'std-head-mid omg', 'correct', '2');
correctHeader.addEventListener('click', e => {[...document.getElementsByClassName('correctCheckbox')].forEach(x => x.checked = !x.checked); updateTheoryCraftForm(e)});
tr3.appendChild(correctHeader);
let correctCheckbox, correctCheckboxContainer;
for (let i = 0; i < questionCount; i++) {
correctCheckboxContainer = document.createElement('td');
correctCheckboxContainer.className = "std-head-mid";
correctCheckbox = document.createElement('input');
correctCheckbox.id = `q${i+1}c`;
correctCheckbox.classList.add('correctCheckbox');
correctCheckbox.type = 'checkbox';
correctCheckbox.style = 'appearance:auto;opacity:1;height:17px;width:17px;'
correctCheckbox.addEventListener('input', updateTheoryCraftForm);
correctCheckboxContainer.appendChild(correctCheckbox);
tr3.appendChild(correctCheckboxContainer);
}
tr3.appendChild(makeElement('td', 'std-head-mid omg', ' '));
tr3.appendChild(makeElement('td', 'std-head-mid omg', undefined, "2"));
tr3.appendChild(makeElement('td', 'std-head-mid omg', ' '));
thead.appendChild(tr3);
let tr4 = document.createElement('tr');
tr4.bgcolor = "#ffffff";
let moneyedHeader = makeElement('td', 'std-head-mid u', 'moneyed', '2');
moneyedHeader.addEventListener('click', e => {[...document.getElementsByClassName('moneyCheckbox')].forEach(x => x.checked = !x.checked); updateTheoryCraftForm(e)});
tr4.appendChild(moneyedHeader);
let moneyCheckbox, moneyCheckboxContainer;
for (let i = 0; i < questionCount; i++) {
moneyCheckboxContainer = document.createElement('td');
moneyCheckboxContainer.className = "std-head-mid";
moneyCheckbox = document.createElement('input');
moneyCheckbox.id = `q${i+1}m`;
moneyCheckbox.classList.add('moneyCheckbox');
moneyCheckbox.type = 'checkbox';
moneyCheckbox.style = 'appearance:auto;opacity:1;height:17px;width:17px;';
moneyCheckbox.addEventListener('input', updateTheoryCraftForm);
moneyCheckboxContainer.appendChild(moneyCheckbox);
tr4.appendChild(moneyCheckboxContainer);
}
tr4.appendChild(makeElement('td', 'std-head-mid omg', ' '));
tr4.appendChild(makeElement('td', 'std-head-mid omg', undefined, "2"));
tr4.appendChild(makeElement('td', 'std-head-mid omg', ' '));
thead.appendChild(tr4);
let tbody = document.createElement('tbody');
tbody.innerHTML = `
<tr style="" class="">
<td class="std-midleft" style="width:40px;padding-top:6px;border-bottom:1px solid lavender "></td>
<td class="std-midleft" style="width:100px;padding-top:6px;border-bottom:1px solid lavender "></td>
<td id="q1v" class="om bb">0</td>
<td id="q2v" class="om bb">0</td>
<td id="q3v" class="om bb">0</td>
<td id="q4v" class="om bb">0</td>
<td id="q5v" class="om bb">0</td>
<td id="q6v" class="om bb">0</td>
<td id="q7v" class="om bb">0</td>
<td id="q8v" class="om bb">0</td>
<td id="q9v" class="om bb">0</td>
<td id="q10v" class="om bb">0</td>
<td id="q11v" class="om bb">0</td>
<td id="q12v" class="om bb">0</td>
<td id="tcNumberCorrect" class="oc">0</td>
<td id="tcPoints" class="ot">0</td>
<td id="tcPercentile" class="ot">1</td>
</tr>`;
theorycraftTable.appendChild(thead);
theorycraftTable.appendChild(tbody);
innerDiv.appendChild(theorycraftTable);
const container = document.getElementById('profilesdivcontainer');
container.insertBefore(theorycraftDiv, container.firstChild);
// If we have our results here, prefill the theorycraft form with our results
let resultsH2 = document.evaluate("//h2[contains(., ' Results')]", document, null, XPathResult.ANY_TYPE, null).iterateNext()
if (resultsH2) {
// there's probably a better way to accomplish this
let yourAnswers = [...resultsH2.parentElement.children[1].children[0].children[1].children[0].children].slice(2, questionCount+2)
for (let i = 0; i < questionCount; i++) {
if (yourAnswers[i].classList.contains('omg')) {
document.getElementById(`q${i+1}c`).checked = true;
}
if (yourAnswers[i].classList.contains('omr') || yourAnswers[i].classList.contains('u')) {
document.getElementById(`q${i+1}m`).checked = true;
}
}
updateTheoryCraftForm();
}
}).catch(function (err) {
console.log(err);
})
}
function handleOneDayPage() {
let profilesTabs = document.getElementById('profilestabs');
let theoryButtonContainer = document.createElement('li');
let theoryButton = document.createElement('a');
theoryButton.textContent = 'tc';
theoryButton.id = 'theorycraftButton';
const oneDayId = document.location.search.slice(1);
theoryButton.onclick = function () {createTheorycraftForm(oneDayId);};
theoryButtonContainer.appendChild(theoryButton);
profilesTabs.appendChild(theoryButtonContainer);
}