// ==UserScript==
// @name Duolingo Pro BETA
// @namespace Violentmonkey Scripts
// @match https://*.duolingo.com/*
// @grant GM_log
// @version 2.0B1
// @author anonymoushackerIV
// @description Duolingo Auto-Solver Tool - WORKING AUGUST 2023
// @license MIT
// @downloadURL none
// ==/UserScript==
//localStorage.getItem("someVarKey");
let solvingIntervalId;
let isAutoMode = false;
isAutoMode = Boolean(sessionStorage.getItem('isAutoMode'));
const debug = false;
let numberOfTimes = 0;
numberOfTimes = Number(sessionStorage.getItem('numberOfTimes'));
let isStartButtonPressed = false;
isStartButtonPressed = Boolean(sessionStorage.getItem('isStartButtonPressed'));
let onboardingDone;
if (Boolean(localStorage.getItem("onboardingDone")) === false) {
console.log('onboardingDone False');
} else if (Boolean(localStorage.getItem("onboardingDone")) === true) {
console.log('onboardingDone True');
} else {
console.log('onboardingDone Set to false');
onboardingDone = false;
Boolean(localStorage.setItem("onboardingDone", onboardingDone));
}
//...all your existing c
const onBoardingHTML = `
Solve, a better Skip button
Stuck somewhere and want to see the answer? Press Solve to only solve that question.
Solve All, skip the whole hustle
A steak saver and a leaderboard champion. Solve All let’s you finish the whole lesson without the hard work.
AutoSolver Box, full automation (BETA)
AutoSolver Box enables you to set a certain amount of lessons you want completed, then mutes your tab, both sounds and visuals until it’s done.
More coming soon
Many bug fixes, support for more languages and lessons are coming, as well as a dedicated app that will put your steak and leaderboard position at safe hold, without you needing to sign in everyday.
`;
function injectOnBoardingHTML() {
// Creating a container for the overlay
if (Boolean(localStorage.getItem("onboardingDone")) === false) {
const containerOnBoarding = document.createElement('div');
containerOnBoarding.innerHTML = onBoardingHTML;
document.body.appendChild(containerOnBoarding);
} else {
console.log('idk check');
}
}
//setTimeout(injectOnBoardingHTML, 1000);
injectOnBoardingHTML();
function onBoardingButton() {
if (Boolean(localStorage.getItem("onboardingDone")) === false) {
const onBoardingContinueButton = document.querySelector('.BoxOneTwoButtonOne');
console.log('continue pressed');
onBoardingContinueButton.addEventListener('click', () => {
console.log('continue registered');
onboardingDone = true;
localStorage.setItem("onboardingDone", onboardingDone);
window.location.reload();
});
} else {
console.log('idk check again');
}
}
onBoardingButton();
if (window.location.href.includes('duolingo.com/learn')) {
// HTML content
const htmlContent = `
SEND FEEDBACK
Stories are not supported yet
Chests can’t open automatically
How many lessons would you like to AutoSolve?
START
`;
// CSS content
const cssContent = `
.boxFirst {
display: inline-flex;
flex-direction: column;
align-items: flex-end;
gap: 16px;
position: fixed; /* Fix the position to the bottom-right corner */
bottom: 24px;
right: 24px;
z-index:2;
}
.ContactButton {
position: relative;
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border: 2px solid rgb(var(--color-swan));
border-bottom: 4px solid rgb(var(--color-swan));
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: rgb(var(--color-snow));
color: rgb(var(--color-eel));
text-align: center;
cursor: pointer;
height: 50px;
}
.ContactButton:hover {
position: relative;
min-width: 50px;
font-size: 17px;
border: none;
border: 2px solid rgb(var(--color-swan));
border-bottom: 4px solid rgb(var(--color-swan));
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: rgb(var(--color-snow));
color: rgb(var(--color-eel));
text-align: center;
cursor: pointer;
height: 50px;
filter: brightness(0.9);
}
.ContactButton:active {
position: relative;
min-width: 50px;
font-size: 17px;
border: none;
border: 2px solid rgb(var(--color-swan));
border-bottom: 2px solid rgb(var(--color-swan));
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: rgb(var(--color-snow));
color: rgb(var(--color-eel));
text-align: center;
cursor: pointer;
height: 48px;
filter: brightness(0.9);
}
.boxOne {
padding: 16px;
background-color: rgb(var(--color-snow));
border-radius: 16px;
width: 300px;
border: 2px solid rgb(var(--color-swan));
}
.BoxOutside {
height: 100%;
width: 100%;
margin-right: 20px;
}
.BetaTagAlert {
display: flex;
justify-content: space-between;
align-items: center;
align-self: stretch;
padding-bottom: 10px;
}
.BETATagSpaceText {
color: rgb(var(--color-eel));
font-size: 25px;
font-style: normal;
font-weight: 700;
line-height: 100%; /* 50px */
margin-top: 0px;
margin-bottom: 0px;
}
.BETATag {
display: flex;
padding: 10px;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 12.5px;
background: #FF4B4B;
}
.BETATagText {color: #FFF;
font-style: normal;
font-weight: 700;
line-height: normal;
margin-top: 0px;
margin-bottom: 0px;
}
.BoxInsideAlert {
display: inline-flex;
align-items: center;
gap: 5px;
height: 18px;
padding-bottom: 16px;
}
.AutoBoxAlertIcon {
width: 20px;
height: 18px;
}
.AutoBoxAlertText {
color: #FF4B4B;
font-weight: 700;
height: 18px;
margin-top: 16px;
}
.AutoBoxAlertTwo {
display: inline-flex;
align-items: center;
gap: 5px;
height: 18px;
padding-bottom: 24px;
padding-top: 16px;
}
.AutoBoxAlertTwoIcon {
width: 20px;
height: 20px;
}
.AutoBoxAlertTwoText {
color: #FFC800;
font-weight: 700;
height: 18px;
margin-top: 16px;
}
.AutoBoxExplanation {
color: rgb(var(--color-eel));
margin-top: -0px;
}
.AutoBoxExplanation {
color: rgb(var(--color-eel));
margin-top: -0px;
height: 30px;
font-weight: 700;
}
.BoxInside {
height: 100%;
width: 100%;
display: flex;
margin-right: 20px;
}
.button-down {
position: relative;
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border-bottom: 4px solid #168DC5;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
text-align: center;
cursor: pointer;
}
.button-down:hover {
position: relative;
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border-bottom: 4px solid #168DC5;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
text-align: center;
cursor: pointer;
filter: brightness(1.1);
}
.button-down:active {
position: relative;
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border-bottom: 0px solid #168DC5;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
text-align: center;
cursor: pointer;
margin-top: 4px;
filter: brightness(1.1);
}
.ticker {
position: relative;
min-width: 100px;
width: 100%;
font-size: 17px;
border: none;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: rgb(var(--color-swan));
color: rgb(var(--color-eel));
margin-left: 10px;
text-align: center;
}
.button-up {
position: relative;
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border-bottom: 4px solid #168DC5;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
margin-left: 10px;
text-align: center;
cursor: pointer;
}
.button-up:hover {
position: relative;
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border-bottom: 4px solid #168DC5;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
margin-left: 10px;
text-align: center;
cursor: pointer;
filter: brightness(1.1);
}
.button-up:active {
position: relative;
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border-bottom: 0px solid #168DC5;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
margin-left: 10px;
text-align: center;
cursor: pointer;
margin-top: 4px;
filter: brightness(1.1);
}
.StartToolWithValue {
position: relative;
min-width: 150px;
width: calc(100% - 0px);
font-size: 17px;
border: none;
border-bottom: 4px solid #168DC5;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
margin-top: 10px;
text-align: center;
cursor: pointer;
}
.StartToolWithValue:hover {
position: relative;
min-width: 150px;
width: calc(100% - 0px);
font-size: 17px;
border: none;
border-bottom: 4px solid #168DC5;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
margin-top: 10px;
text-align: center;
cursor: pointer;
filter: brightness(1.1);
}
.StartToolWithValue:active {
position: relative;
min-width: 150px;
width: calc(100% - 0px);
font-size: 17px;
border: none;
border-bottom: 0px solid #168DC5;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
text-align: center;
cursor: pointer;
margin-top: 14px;
filter: brightness(1.1);
}
`;
// Function to inject HTML and CSS into the document
let injectedContainer = null;
let injectedStyleElement = null;
function injectContent() {
// Check if the current URL matches the target URL
if (window.location.href === 'https://preview.duolingo.com/learn' || window.location.href === 'https://duolingo.com/learn') {
//console.log('tageturlmatches')
// Inject the content if it's not already injected
if (!injectedContainer) {
// Creating a container for the overlay
injectedContainer = document.createElement('div');
injectedContainer.innerHTML = htmlContent;
document.body.appendChild(injectedContainer);
// Creating a style tag for CSS
injectedStyleElement = document.createElement('style');
injectedStyleElement.type = 'text/css';
injectedStyleElement.innerHTML = cssContent;
document.head.appendChild(injectedStyleElement);
}
} else {
//console.log('tageturlnotmatches')
// Remove the content if it was previously injected
if (injectedContainer) {
document.body.removeChild(injectedContainer);
document.head.removeChild(injectedStyleElement);
injectedContainer = null;
injectedStyleElement = null;
}
}
}
// Check the URL and inject/remove content every 1 second
setInterval(injectContent, 1000);
// Function to initialize JavaScript functionality
function initialize() {
const ticker = document.querySelector('.ticker');
const buttonUp = document.querySelector('.button-up');
const buttonDown = document.querySelector('.button-down');
const solveFastButton = document.querySelector('.StartToolWithValue');
solveFastButton.addEventListener('click', () => {
sessionStorage.setItem('isAutoMode', true);
sessionStorage.setItem('numberOfTimes', numberOfTimes);
isStartButtonPressed = true;
sessionStorage.setItem('isStartButtonPressed', true);
isAutoMode = true;
});
buttonUp.addEventListener('click', () => {
numberOfTimes++;
ticker.textContent = numberOfTimes;
sessionStorage.setItem('numberOfTimes', numberOfTimes);
});
buttonDown.addEventListener('click', () => {
numberOfTimes--;
if (numberOfTimes < 0) {
numberOfTimes = 0;
}
ticker.textContent = numberOfTimes;
sessionStorage.setItem('numberOfTimes', numberOfTimes);
});
console.log(isAutoMode)
}
// Calling the functions to inject content and initialize functionality
injectContent();
initialize();
}
const muteButtonHTML = `
SETTINGS
MUTE SOUND
`;
const muteButtonCSS = `
.TopBoxPart {
display: inline-flex;
gap: 16px;
flex-direction: column;
position: fixed;
align-items: flex-end;
top: 100px;
right: 16px;
z-index: 2;
}
.SettingsButtonOne {
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border: 2px solid rgb(var(--color-swan));
border-bottom: 4px solid rgb(var(--color-swan));
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: rgb(var(--color-snow));
color: rgb(var(--color-eel));
text-align: center;
cursor: pointer;
height: 50px;
}
.SettingsButtonOne:hover {
position: relative;
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border: 2px solid rgb(var(--color-swan));
border-bottom: 4px solid rgb(var(--color-swan));
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: rgb(var(--color-snow));
color: rgb(var(--color-eel));
text-align: center;
cursor: pointer;
height: 50px;
filter: brightness(0.9);
}
.SettingsButtonOne:active {
position: relative;
min-width: 50px;
font-size: 17px;
border: none;
border: 2px solid rgb(var(--color-swan));
border-bottom: 2px solid rgb(var(--color-swan));
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: rgb(var(--color-snow));
color: rgb(var(--color-eel));
text-align: center;
cursor: pointer;
height: 48px;
margin-top: 2px;
filter: brightness(0.9);
}
.MuteAllDuolingoSounds {
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border: 2px solid rgb(var(--color-swan));
border-bottom: 4px solid rgb(var(--color-swan));
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: rgb(var(--color-snow));
color: rgb(var(--color-eel));
text-align: center;
cursor: pointer;
height: 50px;
}
.MuteAllDuolingoSounds:hover {
position: relative;
min-width: 50px;
width: height;
font-size: 17px;
border: none;
border: 2px solid rgb(var(--color-swan));
border-bottom: 4px solid rgb(var(--color-swan));
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: rgb(var(--color-snow));
color: rgb(var(--color-eel));
text-align: center;
cursor: pointer;
height: 50px;
filter: brightness(0.9);
}
.MuteAllDuolingoSounds:active {
position: relative;
min-width: 50px;
font-size: 17px;
border: none;
border: 2px solid rgb(var(--color-swan));
border-bottom: 2px solid rgb(var(--color-swan));
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: rgb(var(--color-snow));
color: rgb(var(--color-eel));
text-align: center;
cursor: pointer;
height: 48px;
margin-top: 2px;
filter: brightness(0.9);
}
`;
function injectMuteButton() {
const injectedMuteButtonContainer = document.createElement('div');
injectedMuteButtonContainer.innerHTML = muteButtonHTML;
document.body.appendChild(injectedMuteButtonContainer);
// Creating a style tag for CSS
const injectedMuteButtonStyle = document.createElement('style');
injectedMuteButtonStyle.type = 'text/css';
injectedMuteButtonStyle.innerHTML = muteButtonCSS;
document.head.appendChild(injectedMuteButtonStyle);
console.log('injected mute button');
}
injectMuteButton();
window.document.querySelector('.MuteAllDuolingoSounds').onclick = function() {
function muteAudioElements(doc) {
var audioElements = doc.getElementsByTagName('audio');
for (var i = 0; i < audioElements.length; i++) {
audioElements[i].muted = !audioElements[i].muted;
}
}
// Mute audio elements in the main document.
muteAudioElements(window.document);
// Mute audio elements inside iframes.
var iframes = window.document.getElementsByTagName('iframe');
for (var i = 0; i < iframes.length; i++) {
try {
muteAudioElements(iframes[i].contentDocument);
} catch (e) {
console.error('Unable to access iframe content:', e);
}
}
// Update the button text.
this.textContent = this.textContent === 'UNDER CONSTRUCTION' ? 'MUTE SOUND' : 'UNDER CONSTRUCTION';
};
function checkDomainAndCallSolving() {
console.log('checking domain');
// Get the current URL.
const currentUrl = window.location.href;
// Check if the domain of the current URL includes "duolingo.com/lesson" or "duolingo.com/unit".
const domain = currentUrl;
const isDuolingoLessonOrUnit = domain.includes("duolingo.com/lesson") || domain.includes("duolingo.com/unit") || domain.includes("duolingo.com/practice");
console.log(isDuolingoLessonOrUnit);
// If the domain is a Duolingo lesson or unit, and the let value is true, call the solving function.
if(Boolean(isDuolingoLessonOrUnit) && Boolean(isAutoMode)) {
console.log('checked domain true');
setTimeout(solving, 6000);
} else {
console.log('shouldnt happen ' + domain);
}
}
// Add the checkDomainAndCallSolving function to the window.onload event listener.
window.onload = setTimeout(checkDomainAndCallSolving, 2000);
function checkAutoMode() {
if(isAutoMode === true) {
console.log('smth');
console.log(numberOfTimes);
} else {
console.log('wdf');
}
}
setInterval(checkAutoMode, 1000);
//testing
function checkUrl() {
const currentUrl = window.location.href;
const mainUrls = [
'http://duolingo.com',
'https://duolingo.com',
'duolingo.com',
'duolingo.com/learn',
'http://duolingo.com/learn',
'https://duolingo.com/learn',
'http://preview.duolingo.com',
'https://preview.duolingo.com',
'preview.duolingo.com',
'preview.duolingo.com/learn',
'http://preview.duolingo.com/learn',
'https://preview.duolingo.com/learn',
];
const currentOrigin = window.location.origin;
try {
if(mainUrls.includes(currentUrl) && isAutoMode && numberOfTimes > 0 && isStartButtonPressed === true) {
window.location.href = currentOrigin + '/lesson';
numberOfTimes = numberOfTimes - 1;
sessionStorage.setItem('numberOfTimes', numberOfTimes);
console.log('hey1');
} if(isStartButtonPressed === true && numberOfTimes === 0) {
isStartButtonPressed = false;
sessionStorage.setItem('isStartButtonPressed', false);
}
} catch (error) {
console.log('error number 7');
}
console.log(currentUrl);
console.log('isAutoMode ' + isAutoMode)
}
setInterval(checkUrl, 1000);
//testing
function addButtons() {
if (window.location.pathname === '/learn') {
let button = document.querySelector('a[data-test="global-practice"]');
if (button) {
return; //button.click();
}
}
const solveAllButton = document.getElementById("solveAllButton");
if (solveAllButton !== null) {
//solving();
return;
}
const original = document.querySelectorAll('[data-test="player-next"]')[0];
if (original === undefined) {
const startButton = document.querySelector('[data-test="start-button"]');
console.log(`Wrapper line: ${startButton}`);
if (startButton === null) {
return;
}
const wrapper = startButton.parentNode;
const solveAllButton = document.createElement('a');
solveAllButton.className = startButton.className;
solveAllButton.id = "solveAllButton";
solveAllButton.innerText = "COMPLETE SKILL";
solveAllButton.removeAttribute('href');
solveAllButton.addEventListener('click', () => {
solving();
setInterval(() => {
const startButton = document.querySelector('[data-test="start-button"]');
if (startButton && startButton.innerText.startsWith("START")) {
startButton.click();
}
}, 3000);
startButton.click();
});
wrapper.appendChild(solveAllButton);
} else {
const wrapper = document.getElementsByClassName('_10vOG')[0];
wrapper.style.display = "flex";
const solveCopy = document.createElement('button');
//
const presssolveCopy1 = () => {
solveCopy.style.borderBottom = '0px';
solveCopy.style.marginBottom = '4px';
solveCopy.style.top = '4px';
};
// Function to revert the border-bottom when the button is released
const releasesolveCopy1 = () => {
solveCopy.style.borderBottom = '4px solid #2b70c9';
solveCopy.style.marginBottom = '0px';
solveCopy.style.top = '0px';
};
// Add event listeners for mousedown, mouseup, and mouseleave
solveCopy.addEventListener('mousedown', presssolveCopy1);
solveCopy.addEventListener('mouseup', releasesolveCopy1);
solveCopy.addEventListener('mouseleave', releasesolveCopy1);
//
const pauseCopy = document.createElement('button');
//
const presspauseCopy2 = () => {
pauseCopy.style.borderBottom = '0px';
pauseCopy.style.marginBottom = '4px';
pauseCopy.style.top = '4px';
};
// Function to revert the border-bottom when the button is released
const releasepauseCopy2 = () => {
pauseCopy.style.borderBottom = '4px solid #ff9600';
pauseCopy.style.marginBottom = '0px';
pauseCopy.style.top = '0px';
};
// Add event listeners for mousedown, mouseup, and mouseleave
pauseCopy.addEventListener('mousedown', presspauseCopy2);
pauseCopy.addEventListener('mouseup', releasepauseCopy2);
pauseCopy.addEventListener('mouseleave', releasepauseCopy2);
//
solveCopy.id = 'solveAllButton';
solveCopy.innerHTML = solvingIntervalId ? 'PAUSE SOLVE' : 'SOLVE ALL';
solveCopy.disabled = false;
pauseCopy.innerHTML = 'SOLVE';
const defaultButtonStyle = `
position: relative;
min-width: 150px;
font-size: 17px;
border: none;
border-bottom: 4px solid #2b70c9;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
margin-left: 20px;
cursor: pointer;
`;
const solveCopyStyle = `
position: relative;
min-width: 150px;
font-size: 17px;
border: none;
border-bottom: 4px solid #2b70c9;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #1cb0f6;
color: rgb(var(--color-snow));
margin-left: 20px;
cursor: pointer;
`;
const pauseCopyStyle = `
position: relative;
min-width: 100px;
font-size: 17px;
border: none;
border-bottom: 4px solid #ff9600;
border-radius: 16px;
padding: 13px 16px;
transform: translateZ(0);
transition: filter .0s;
font-weight: 700;
letter-spacing: .8px;
background: #ffc800;
color: rgb(var(--color-snow));
margin-left: 20px;
cursor: pointer;
`;
solveCopy.style.cssText = solveCopyStyle;
pauseCopy.style.cssText = pauseCopyStyle;
[solveCopy, pauseCopy].forEach(button => {
button.addEventListener("mousemove", () => {
button.style.filter = "brightness(1.1)";
});
});
[solveCopy, pauseCopy].forEach(button => {
button.addEventListener("mouseleave", () => {
button.style.filter = "none";
});
});
original.parentElement.appendChild(pauseCopy);
original.parentElement.appendChild(solveCopy);
solveCopy.addEventListener('click', solving);
pauseCopy.addEventListener('click', solve);
//solving();
}
}
setInterval(addButtons, 1000);
function solving() {
if (solvingIntervalId) {
clearInterval(solvingIntervalId);
solvingIntervalId = undefined;
document.getElementById("solveAllButton").innerText = "SOLVE ALL";
isAutoMode = false;
} else {
document.getElementById("solveAllButton").innerText = "PAUSE SOLVE";
isAutoMode = true;
solvingIntervalId = setInterval(solve, 500);
}
}
function solve() {
const selAgain = document.querySelectorAll('[data-test="player-practice-again"]');
const practiceAgain = document.querySelector('[data-test="player-practice-again"]');
if (selAgain.length === 1 && isAutoMode) {
// Make sure it's the `practice again` button
//if (selAgain[0].innerHTML.toLowerCase() === 'practice again') {
// Click the `practice again` button
selAgain[0].click();
// Terminate
return;
//}
}
if (practiceAgain !== null && isAutoMode) {
practiceAgain.click();
return;
}
try {
window.sol = findReact(document.getElementsByClassName('_3FiYg')[0]).props.currentChallenge;
} catch {
let next = document.querySelector('[data-test="player-next"]');
if (next) {
next.click();
}
return;
}
if (!window.sol) {
return;
}
let nextButton = document.querySelector('[data-test="player-next"]');
if (!nextButton) {
return;
}
if (document.querySelectorAll('[data-test*="challenge-speak"]').length > 0) {
if (debug)
document.getElementById("solveAllButton").innerText = 'Challenge Speak';
const buttonSkip = document.querySelector('button[data-test="player-skip"]');
if (buttonSkip) {
buttonSkip.click();
}
} else if (window.sol.type === 'listenMatch') {
if (debug)
document.getElementById("solveAllButton").innerText = 'Listen Match';
console.log('hello');
const nl = document.querySelectorAll('[data-test$="challenge-tap-token"]');
window.sol.pairs?.forEach((pair) => {
for (let i = 0; i < nl.length; i++) {
let nlInnerText;
if (nl[i].querySelectorAll('[data-test="challenge-tap-token-text"]').length > 1) {
nlInnerText = nl[i].querySelector('[data-test="challenge-tap-token-text"]').innerText.toLowerCase().trim();
} else {
//nlInnerText = findSubReact(nl[i]).textContent.toLowerCase().trim();
nlInnerText = nl[i].getAttribute('data-test').split('-')[0].toLowerCase().trim();
console.log(nlInnerText);
}
if (
(
nlInnerText === pair.learningWord.toLowerCase().trim() ||
nlInnerText === pair.translation.toLowerCase().trim()
) &&
!nl[i].disabled
) {
nl[i].click();
}
}
});
} else if (document.querySelectorAll('[data-test="challenge-choice"]').length > 0) {
// choice challenge
if (debug)
document.getElementById("solveAllButton").innerText = 'Challenge Choice';
if (window.sol.correctTokens !== undefined) {
correctTokensRun();
nextButton.click()
} else if (window.sol.correctIndex !== undefined) {
document.querySelectorAll('[data-test="challenge-choice"]')[window.sol.correctIndex].click();
nextButton.click();
}
} else if (document.querySelectorAll('[data-test$="challenge-tap-token"]').length > 0) {
// match correct pairs challenge
if (window.sol.pairs !== undefined) {
if (debug)
document.getElementById("solveAllButton").innerText = 'Pairs';
let nl = document.querySelectorAll('[data-test$="challenge-tap-token"]');
if (document.querySelectorAll('[data-test="challenge-tap-token-text"]').length
=== nl.length) {
window.sol.pairs?.forEach((pair) => {
for (let i = 0; i < nl.length; i++) {
const nlInnerText = nl[i].querySelector('[data-test="challenge-tap-token-text"]').innerText.toLowerCase().trim();
try {
if (
(
nlInnerText === pair.transliteration.toLowerCase().trim() ||
nlInnerText === pair.character.toLowerCase().trim()
)
&& !nl[i].disabled
) {
nl[i].click()
}
} catch (TypeError) {
if (
(
nlInnerText === pair.learningToken.toLowerCase().trim() ||
nlInnerText === pair.fromToken.toLowerCase().trim()
)
&& !nl[i].disabled
) {
nl[i].click()
}
}
}
})
}
} else if (window.sol.correctTokens !== undefined) {
if (debug)
document.getElementById("solveAllButton").innerText = 'Token Run';
correctTokensRun();
nextButton.click()
} else if (window.sol.correctIndices !== undefined) {
if (debug)
document.getElementById("solveAllButton").innerText = 'Indices Run';
correctIndicesRun();
}
} else if (document.querySelectorAll('[data-test="challenge-tap-token-text"]').length > 0) {
if (debug)
document.getElementById("solveAllButton").innerText = 'Challenge Tap Token Text';
// fill the gap challenge
correctIndicesRun();
} else if (document.querySelectorAll('[data-test="challenge-text-input"]').length > 0) {
if (debug)
document.getElementById("solveAllButton").innerText = 'Challenge Text Input';
let elm = document.querySelectorAll('[data-test="challenge-text-input"]')[0];
let nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
nativeInputValueSetter.call(elm, window.sol.correctSolutions ? window.sol.correctSolutions[0] : (window.sol.displayTokens ? window.sol.displayTokens.find(t => t.isBlank).text : window.sol.prompt));
let inputEvent = new Event('input', {
bubbles: true
});
elm.dispatchEvent(inputEvent);
} else if (document.querySelectorAll('[data-test*="challenge-partialReverseTranslate"]').length > 0) {
if (debug)
document.getElementById("solveAllButton").innerText = 'Partial Reverse';
let elm = document.querySelector('[data-test*="challenge-partialReverseTranslate"]')?.querySelector("span[contenteditable]");
let nativeInputNodeTextSetter = Object.getOwnPropertyDescriptor(Node.prototype, "textContent").set
nativeInputNodeTextSetter.call(elm, '"' + window.sol?.displayTokens?.filter(t => t.isBlank)?.map(t => t.text)?.join()?.replaceAll(',', '') + '"');
let inputEvent = new Event('input', {
bubbles: true
});
elm.dispatchEvent(inputEvent);
} else if (document.querySelectorAll('textarea[data-test="challenge-translate-input"]').length > 0) {
if (debug)
document.getElementById("solveAllButton").innerText = 'Challenge Translate Input';
const elm = document.querySelector('textarea[data-test="challenge-translate-input"]');
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, "value").set;
nativeInputValueSetter.call(elm, window.sol.correctSolutions ? window.sol.correctSolutions[0] : window.sol.prompt);
let inputEvent = new Event('input', {
bubbles: true
});
elm.dispatchEvent(inputEvent);
}
nextButton.click()
}
function correctTokensRun() {
const all_tokens = document.querySelectorAll('[data-test$="challenge-tap-token"]');
const correct_tokens = window.sol.correctTokens;
const clicked_tokens = [];
correct_tokens.forEach(correct_token => {
const matching_elements = Array.from(all_tokens).filter(element => element.textContent.trim() === correct_token.trim());
if (matching_elements.length > 0) {
const match_index = clicked_tokens.filter(token => token.textContent.trim() === correct_token.trim()).length;
if (match_index < matching_elements.length) {
matching_elements[match_index].click();
clicked_tokens.push(matching_elements[match_index]);
} else {
clicked_tokens.push(matching_elements[0]);
}
}
});
}
function correctIndicesRun() {
if (window.sol.correctIndices) {
window.sol.correctIndices?.forEach(index => {
document.querySelectorAll('div[data-test="word-bank"] [data-test="challenge-tap-token-text"]')[index].click();
});
// nextButton.click();
}
}
function findSubReact(dom, traverseUp = 0) {
const key = Object.keys(dom).find(key => key.startsWith("__reactProps$"));
return dom.parentElement[key].children.props;
}
function findReact(dom, traverseUp = 0) {
let reactProps = Object.keys(dom.parentElement).find((key) => key.startsWith("__reactProps$"));
while (traverseUp-- > 0 && dom.parentElement) {
dom = dom.parentElement;
reactProps = Object.keys(dom.parentElement).find((key) => key.startsWith("__reactProps$"));
}
if(dom?.parentElement?.[reactProps]?.children[0] == null){
return dom?.parentElement?.[reactProps]?.children[1]?._owner?.stateNode;
}
else{
return dom?.parentElement?.[reactProps]?.children[0]?._owner?.stateNode;
}
//return dom?.parentElement?.[reactProps]?.children[0]?._owner?.stateNode;
}
window.findReact = findReact;
window.ss = solving;