// TODO: Sidestep race condition in a less patchwork manner setTimeout(function(){ renderBypass(); /* TODO: Check if it actually went through */ }, 1250); function renderBypass() { // Setup page elements //Get Katex CSS var katex_css = document.createElement('link'); katex_css.setAttribute('rel','stylesheet'); katex_css.setAttribute('href','https://cdn.jsdelivr.net/npm/katex@0.13.11/dist/katex.min.css '); document.head.appendChild(katex_css); // Clear the "hidden explanation" out and replace it with a blank explanation area. // The innermost item is ".s1i7awl8" document.querySelector('main .mwhvwas').innerHTML = '

Explanation

'; var expArea = document.querySelector('.sladerBypass .s1i7awl8') // Render new stuff // Get the webpage data, devoid of any headers or cookies. Acts as if the user is not logged in at all. var data = httpGet(window.location); // Is this an abomination? Yes. // Does it work? Also yes. // // ... // // I don't want to talk about it. // var b = data.match(/(?<=window.Quizlet\["questionDetailsPageData"] = ).+?(?=; QLoad\("Quizlet.questionDetailsPageData")/gm); if (!b) { if (window.location.toString().includes('quizlet.com/explanations/textbook-solutions')) { var oldlink = getOldTextbookLink(); expArea.innerHTML = `

Textbooks currently only supported by Slader Bypass on the old website.


Click here to be redirected to the working version of this question. If that doesn't work, try finding it manually on the old site.
`; } else { // Display ratelimit message expArea.innerHTML = `

You have been ratelimited by Quizlet


Try clearing your cookies for Quizlet and reloading this page, this usually fixes it.
— Slader Bypass.
`; } } // TODO: Handle textbookExercisePageData. // Parse JSON data var qDetails = JSON.parse(b[0]); // Display JSON data as answer qDetails.question.solutions.forEach(solution => { const numSteps = solution.steps.length; solution.steps.forEach(step => { const stepNum = step.stepNumber; // Create card element var div = document.createElement('div'); // Insert boilerplate card data div.innerHTML = '

'; // Step X: .s39tzu2 div.querySelector('.s39tzu2').innerHTML = (numSteps === stepNum) ? "Result" : "Step " + stepNum; // x of x: .sb9ch1t div.querySelector('.sb9ch1t').innerHTML = stepNum + ' of ' + numSteps; // I'm not 100% on the structure of these, but I'll take a stab at it. // It seems that only one column is ever used. I'll iterate anyways, because I can't trust that. step.columns.forEach(column => { // Insert inner text if (column.text) div.querySelector('.sladerBypassKatex').textContent = column.text.replaceAll('\n\n\n', '\n\n'); // The replace call is a bit funky but it works. // Insert image, if applicable if (column.images.additional) { var image = document.createElement('img'); image.setAttribute('src', column.images.additional.regular.srcUrl); div.querySelector('.sladerBypassKatex').appendChild(image); } }); // Append card to explanation area. expArea.appendChild(div); }); }); // Render Katex for each card expArea.querySelectorAll('.sladerBypassKatex').forEach(textArea => { renderMathInElement(textArea, { delimiters: [ {left: "$$", right: "$$", display: true}, {left: "$", right: "$", display: false}, {left: "\\(", right: "\\)", display: false}, {left: "\\begin{equation}", right: "\\end{equation}", display: true}, {left: "\\begin{align}", right: "\\end{align}", display: true}, {left: "\\begin{alignat}", right: "\\end{alignat}", display: true}, {left: "\\begin{gather}", right: "\\end{gather}", display: true}, {left: "\\begin{CD}", right: "\\end{CD}", display: true}, {left: "\\[", right: "\\]", display: true} ], throwOnError : false }); }); }; // Handle GET request function httpGet(url) { var req = new XMLHttpRequest(); req.open( "GET", url, false ); // false -> synchronous request req.send( null ); return req.responseText; } function getOldTextbookLink(url) { // This is mostly approximate. const bookTitle = window.location.toString().match(/(?<=quizlet\.com\/explanations\/textbook-solutions\/).+?(?=-\d\d\d\d\d\d\d)/)[0]; const bookISBN = window.location.toString().split(bookTitle)[1].split('/')[0].replaceAll('-', ''); const page = document.getElementsByClassName('tsqwngb')[0].children[1].innerHTML.slice(5); const problem = document.getElementsByClassName('t1aekklg')[0].innerHTML.slice(9); return "https://www.slader.com/textbook/" + bookISBN + '-' + bookTitle + '/' + page + '/problems/' + problem; }