// 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 = '
';
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;
}