The more questions you answer the smarter it will get. Features: spelling-assistance & auto - complete, definitions and examples, actively learning bot.
// ==UserScript== // @name Vocabulary.com Answer Bot // @namespace http://tampermonkey.net/ // @version 3.01 // @description The more questions you answer the smarter it will get. Features: spelling-assistance & auto - complete, definitions and examples, actively learning bot. // @author longkidkoolstar // @match https://www.vocabulary.com/* // @icon https://cdn1.iconfinder.com/data/icons/network-and-comminications-flat-square-rounded-sha/120/content__blog__media__articles__news__management__edit-512.png // @license MIT // @grant none // ==/UserScript== let url = window.location.href,list=url.split("/")[4],words_defs,lists,learned=[],incorrect=[],inProgress=false; if(localStorage.getItem("lists")!==null){lists = JSON.parse(localStorage.getItem("lists"))} else{lists = []}if(localStorage.getItem("words&defs")!==null){words_defs = JSON.parse(localStorage.getItem("words&defs"))} else{words_defs = []}if(localStorage.getItem("learned")!==null){learned = JSON.parse(localStorage.getItem("learned"))} if(localStorage.getItem("wrong")!==null){incorrect = JSON.parse(localStorage.getItem("wrong"))} let dictionary = "https://api.dictionaryapi.dev/api/v2/entries/en/"; //console.log(list,lists,partsOfList(list,"words"),partsOfList(list,"defs")) if(!url.includes("/practice")){ setInterval(function(){ if(document.getElementsByClassName("activity practice")[0]!==undefined){ let practice = document.getElementsByClassName("activity practice")[0]; if(!lists.includes(list)){ practice.addEventListener("click",function(){ let enteries = document.getElementsByClassName("entry"); for(let i=0;i<enteries.length;i++){ let word = enteries[i].children[0].innerText.trim(); let def = enteries[i].children[1].innerText.trim(); words_defs.push({"word":word,"def":def,"list":list}); if(enteries.length-1==i){ localStorage.setItem("words&defs",JSON.stringify(words_defs)); lists.push(list); localStorage.setItem("lists",JSON.stringify(lists)); } } }) } if(list.trim().length>0){ practice.click(); } } },1000) } else if(url.includes("/practice")){ setTimeout(function(){ if(!lists.includes(list)){ location.href=url.split("/practice")[0]; } else{ bot() } },250) } if(url.includes("/play/")){ bot(); } function bot(){ let bot = setInterval(function(){ if(document.getElementsByClassName("challenge-history")[0].children[1].children!==undefined&&inProgress!==true){ let arr = document.getElementsByClassName("challenge-history")[0].children[1].children; let currQuest = getQuest(arr); if(currQuest!==false){ let questIndx = Number(currQuest.innerText-1) let questBox = document.getElementsByClassName("question")[questIndx]; let quest_Type = questType(questBox); let nxt = document.getElementsByClassName("next")[0]; if(quest_Type!==false){ inProgress = true; if(quest_Type=="spell"){ answerSpelling(questBox,questIndx); } if(quest_Type=="choice1"){ answerMultChoice(questBox); } if(quest_Type=="choice2"){ answerMultChoice(questBox,2); } } else{ console.log("Question type doesn't exist 🤨"); inProgress=false; } nxt.addEventListener("click",function(){ inProgress=false; //console.log("inProgress = false!") }) } } },500) } setInterval(()=>{ makeRoom(); if(document.getElementsByClassName("next active")[0]!==undefined){ document.getElementsByClassName("next active")[0].click(); } },250) function makeRoom(){ if(document.getElementsByClassName("vcom-challenge resizable large started")[0]!==undefined){ document.getElementsByClassName("vcom-challenge resizable large started")[0].style.minHeight="2500px"; } } function questType(quest){ let type=false; let children = quest.children; for(let i=0;i<children.length;i++){ if(children[i].className=="spelltheword"){ type = "spell" } if(children[i].className=="choices"){ if(children[1].childElementCount>0){ type= "choice1"; } else if(children[1].childElementCount==0){ type="choice2"; } } } console.log(type) return type; } function getQuest(arr){ let r###lt=false; for(let i=0;i<arr.length;i++){ if(arr[i].classList[0]=="enabled"&&arr[i].classList[1]=="selected"&&arr[i].classList.value=="enabled selected"){ r###lt = arr[i]; } } return r###lt; } function partsOfList(listId,part){ let words = []; let defs = []; let examples = []; for(let i=0;i<words_defs.length;i++){ if(words_defs[i].list==listId){ if(!words.includes(words_defs[i].word)){ words.push(words_defs[i].word) } defs.push(words_defs[i].def); if(!examples.includes(words_defs[i].example)){ examples.push(words_defs[i].example) } } if(words_defs.length-1==i){ if(part=="words"){ return words; } if(part=="defs"){ return defs; } if(part=="examples"){ return examples; } } } } function getChoices(arr){ let temp=[]; for(let i=0;i<arr.length;i++){ temp.push(arr[i].innerText); } return temp; } function learn(word,choice,def){ let present=false; for(let i=0;i<learned.length;i++){ if(learned[i].word==word&&learned[i].choice==choice){ present=true; console.log(`${word} is known 💡`) } } if(!present){ learned.push({"word":word,"choice":choice}); if(choice.split(" ").length==1){ learned.push({"word":choice,"choice":def}); } localStorage.setItem("learned",JSON.stringify(learned)) console.log(`Learned ${word} 🧠`) } inProgress=false; } function getDef(word){ let def = false; let words = partsOfList(list,"words"); let defs = partsOfList(list,"defs"); for(let i=0;i<words.length;i++){ if(words[i].includes(word)||word.includes(words[i])){ def = defs[i]; } } return def; } function defineChoices(word,arr){ for(let i=0;i<arr.length;i++){ if(arr[i].innerText.split(" ").length==1){ let def = getDef(arr[i].innerText); if(def!==false){ arr[i].innerText += `: ${getDef(arr[i].innerText)} - (answer?)`; arr[i].style.color = "orange"; arr[i].innerText+=" 🧠" clean(word,arr) } } } } function answerMultChoice(questBox,clause){ let word,choiceBox,choices; if(clause==2){ let chil = questBox.children[2].children; if(chil.length>1){ for(let i=0;i<chil.length;i++){ if(chil[i].tagName=="STRONG"){ word = chil[i].innerText } } } else{ word = questBox.children[2].children[0].innerText; } } else if(clause==undefined){ word = questBox.children[1].children[0].children[0].innerText; } choiceBox = questBox.children[3].children; choices = getChoices(choiceBox); defineChoices(word,choiceBox) let instruct = questBox.children[2]; let words = partsOfList(list,"words"); let defs = partsOfList(list,"defs"); let def=false; deepSearch(word,questBox); //deepDef(word,choices,choiceBox); def = getDef(word); defAllChoices(choices,choiceBox,def) maybe(choices,choiceBox) if(def!==false){ let answr = false; for(let i=0;i<choices.length;i++){ if(choices[i].includes(def)||def.includes(choices[i])){ answr = i; } } if(answr!==false){ choiceBox[answr].style.color="springgreen"; choiceBox[answr].innerText+=" 🧠" clean(word,choiceBox) } else{ answr=false; if(learned.length>0){ for(let i=0;i<learned.length;i++){ for(let j=0;j<choiceBox.length;j++){ if(learned[i].word.includes(word)||choiceBox[j].innerText.includes(learned[i].choice)||learned[i].choice.includes(choiceBox[j].innerText)||word.includes(learned[i].word)){ answr = learned[i].choice; } } } } if(answr!==false){ for(let i=0;i<choices.length;i++){ if(choices[i].includes(answr)||answr.includes(choices[i])){ choiceBox[i].style.color="springgreen"; choiceBox[i].innerText+=" 🧠" clean(word,choiceBox) } } } else{ //console.log("No answer found - normal way"); } } } for(let i=0;i<choiceBox.length;i++){ choiceBox[i].addEventListener("click",function(){ setTimeout(function(){ grabChoice(word,choiceBox,def); },250) }) } } function grabChoice(word,choices,def){ let correct = false; for(let i=0;i<choices.length;i++){ if(choices[i].className=="correct"){ learn(word,choices[i].innerText,def); correct = true; } if(correct){ if(choices[i].className!=="correct"){ wrong(word,choices[i].innerText) } } else{ if(choices[i].className=="incorrect"){ wrong(word,choices[i].innerText); } } } } function clean(word,choices){ for(let j=0;j<choices.length;j++){ for(let i=0;i<incorrect.length;i++){ if(incorrect[i].word==word&&incorrect[i].choice==choices[j].innerText){ choices[j].style.color="red"; } } } } function wrong(word,choice){ let present=false; for(let i=0;i<incorrect.length;i++){ if(incorrect[i].word==word&&incorrect[i].choice==choice){ present=true; console.log(`${word}'s choice is known as incorrect ❌`); } } if(!present){ incorrect.push({"word":word,"choice":choice}); localStorage.setItem("wrong",JSON.stringify(incorrect)) console.log(`Learned ${word}'s incorrect choice 🧠`) } inProgress=false; } async function deepSearch(word,questBox){ try{ let api=`https://vocabulary.now.sh/words/${word}`; let api2=`https://vocabulary.now.sh/word/${word}`; let r###lt=await fetch(api).then(data => data.json()).then(data => data.data[0]); let example=await fetch(api2).then(data => data.json()).then(data => data.data); let def = await r###lt.description; let choiceBox = questBox.children[3].children; let choices = getChoices(questBox.children[3].children); let instruct = questBox.children[2]; let content = questBox.children[1]; let answr=false; for(let i=0;i<choices.length;i++){ if(choices[i].includes(example)||choices[i].includes(def)||def.includes(choices[i])||example.includes(choices[i])){ answr=i; } } if(answr!==false){ choiceBox[answr].style.color="springgreen"; choiceBox[answr].innerText+=" 🧠" } else{ //console.log("DeepSearch failed. Will add correct answer to dataSet when answered. 🤔"); } if(getDef(word)!==false){ let set = false; let rep = false; if(content.children.length>0){ rep = content; } if(instruct.children.length>0){ rep = instruct; } if(rep!==false){ if(!set){ set = true; rep.style.overflowY="auto"; rep.style.height="fit-content"; rep.innerHTML+=`<hr><div style="margin-top:50px;"><b style="color:black;">${word}</b> means: ${getDef(word)} 🧠 <br><br> <span style="font-size:18px; margin-bottom:10px;"><b style="color:black;">Example:</b> ${example}</span></div><br>`; questBox.style.marginTop="-45px"; } } } for(let i=0;i<choices.length;i++){ if(similarity(choices[i],def)||similarity(choices[i],example)/*||similar(def,choices[i])||similar(example,choices[i])*/){ choiceBox[i].style.color="springgreen"; choiceBox[i].innerText+=" 🧠" } } } catch(e){ return false; } } function maybe(choices,choiceBox){ for(let i=0;i<choices.length;i++){ for(let j=0;j<learned.length;j++){ if(choices[i].toLowerCase().includes(learned[j].word.toLowerCase())||learned[j].word.toLowerCase().includes(choices[i].toLowerCase())){ if(!choiceBox[i].innerText.includes(" - maybe this...")){ choiceBox[i].innerText+=" - maybe this..."; choiceBox[i].style.color="orange"; } } } } } function cleanUp(choices){ for(let i=0;i<choices.length;i++){ choices[i].style.color="#36588e"; } } function answerSpelling(questBox,indx){ let inp = questBox.children[1].children[1].children[1]; let submit = questBox.children[1].children[2].children[0]; let surrender = questBox.children[1].children[2].children[1]; let status = document.getElementsByClassName("status")[indx]; let speak = questBox.children[1].children[1].children[0]; let label = questBox.children[1].children[0]; let words = partsOfList(list,"words"); speak.click(); function auto(matches){ inp.value=matches[0]; inp.blur(); setTimeout(function(){ submit.click(); inProgress = false; },350) } inp.addEventListener("keyup",function(evt){ if(inp.value.trim().length>0){ label.innerText = "Spell the word:"; let input = inp.value; let matches=[]; for(let i=0;i<words.length;i++){ if(words[i].toLowerCase().includes(input.toLowerCase())||input.toLowerCase().includes(words[i].toLowerCase())){ matches.push(words[i]); } } if(matches.length>0){ label.innerText = "Matches 😉:" let newLabel = document.createElement("div"); label.append(newLabel); let max = 5; if(matches.length<5){ max = matches.length; } for(let i=0;i<max;i++){ newLabel.style="width:100%;height:fit-content;display:flex;align-items:center;justify-content:center;flex-direction:row;overflow:hidden;" newLabel.innerHTML+=` <p style="cursor:pointer;margin:5px;" class = "spellGuess">${matches[i]}</p>`; let guesses = document.getElementsByClassName("spellGuess"); for(let i=0;i<guesses.length;i++){ guesses[i].addEventListener("click",()=>{ inp.value = guesses[i].innerText; setTimeout(()=>{ submit.click(); inProgress = false; },350) }) } } if(matches.length==1){ let auto_do = true; if(status.children.length>0){ if(status.children[0].innerText.includes("again")){ auto_do = false; } } if(auto_do){ auto(matches); } } } else{ label.innerText = "No matches 😟"; } } else{ label.innerText = "Spell the word:"; } }) inp.addEventListener("keydown",function(evt){ if(evt.keyCode==13){ if(inp.value.trim().length>0){ inProgress=false; } } }) submit.addEventListener("click",function(){ inProgress=false; }) } function similarity(s1, s2) { var longer = s1; var shorter = s2; if (s1.length < s2.length) { longer = s2; shorter = s1; } var longerLength = longer.length; if (longerLength == 0) { return 1.0; } if((longerLength - editDistance(longer, shorter)) / parseFloat(longerLength)>0.5){ return true; } } function editDistance(s1, s2) { s1 = s1.toLowerCase(); s2 = s2.toLowerCase(); var costs = new Array(); for (var i = 0; i <= s1.length; i++) { var lastValue = i; for (var j = 0; j <= s2.length; j++) { if (i == 0) costs[j] = j; else { if (j > 0) { var newValue = costs[j - 1]; if (s1.charAt(i - 1) != s2.charAt(j - 1)) newValue = Math.min(Math.min(newValue, lastValue), costs[j]) + 1; costs[j - 1] = lastValue; lastValue = newValue; } } } if (i > 0) costs[s2.length] = lastValue; } return costs[s2.length]; } function similar(phrase,choice){ let simScore1 = 0; let simScore2 = 0; phrase = cleanPunc(phrase).split(" "); choice = cleanPunc(choice).split(" "); for(let i=0;i<phrase.length;i++){ for(let j=0;j<choice.length;j++){ if(phrase[i].includes(choice[j])||choice[j].includes(phrase[i])){ return true; } } } return false; } function cleanPunc(string){ return string.replace(/[^A-Za-z0-9\s]/g,"").replace(/\s{2,}/g, " "); } /* async function deepDef(word,choices,choiceBox){ try{ let api = dictionary+word; let dets = await fetch(api).then(data => data.json()).then(data=>data[0].meanings[0].definitions[0]); let synms = dets.synonyms; let antms = dets.antonyms; let def = dets.definition; for(let i=0;i<choices.length;i++){ for(let j=0;j<synms.length;j++){ if(choices[i].includes(synms[j])||synms[j].includes(choices[i])){ choiceBox[i].style.color="springgreen"; choiceBox[i].innerText+=" 🧠" } } } } catch(error){ console.log("Can't find synonyms for this one. Not a big problem, I have other ways of dealing with this 😊") } } */ async function defAllChoices(choices,choiceBox,def){ for(let i=0;i<choices.length;i++){ if(choices[i].split(" ").length==1){ let api = dictionary+choices[i]; let defs = await fetch(api).then(data => data.json()).then(data=>data[0].meanings[0].definitions); let temp=[]; for(let j=0;j<defs.length;j++){ if(defs[j]!==undefined){ temp.push(defs[j].definition); } } for(let x=0;x<temp.length;x++){ choiceBox[i].innerText+=` - ${temp[x]}`; } } } }