-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnaurok-solver.user.js
12 lines (11 loc) · 26.3 KB
/
naurok-solver.user.js
1
2
3
4
5
6
7
8
9
10
11
12
// ==UserScript==
// @name Naurok Solver
// @namespace http://tampermonkey.net/
// @version 1.0.0
// @description Solves Naurok questions
// @author Микола Шрам
// @match https://naurok.com.ua/*
// @icon https://naurok.com.ua/favicon.ico
// @grant none
// ==/UserScript==
var EntryPoint;(()=>{"use strict";class e{constructor(){this.storageKey="naurok_solver_config",this.defaultConfig={delay:1e3,useRandomDelay:!1,minDelay:500,maxDelay:2e3,autoClick:!0,highlight:!0,highlightColor:"#90EE90",highlightDuration:2e3,locale:"en_US",provider:"gpt24",openaiApiKey:""},this.initConfig()}initConfig(){const e=localStorage.getItem(this.storageKey);if(e)try{const t=JSON.parse(e);window.solveConfig={...this.defaultConfig,...t},this.saveConfig()}catch(e){console.error("Error parsing saved config:",e),window.solveConfig={...this.defaultConfig},this.saveConfig()}else localStorage.setItem(this.storageKey,JSON.stringify(this.defaultConfig)),window.solveConfig={...this.defaultConfig}}getValue(e){return window.solveConfig[e]}setValue(e,t){return e in this.defaultConfig&&(window.solveConfig[e]=t,this.saveConfig(),!0)}saveConfig(){localStorage.setItem(this.storageKey,JSON.stringify(window.solveConfig))}resetToDefault(){window.solveConfig={...this.defaultConfig},this.saveConfig()}}class t{constructor(t,n=new e){this.isVisible=!1,this.elements=new Map,this.title=t,this.configManager=n,this.container=this.createContainer(),this.styleElement=this.createStyles(),this.setupDragging()}createContainer(){const e=document.createElement("div");return e.className="solver-ui",e.innerHTML=`\n <button class="close-btn">×</button>\n <h2>${this.title}</h2>\n <div class="content"></div>\n <div class="footer"></div>\n `,e.querySelector(".close-btn").addEventListener("click",(()=>this.hide())),e}createStyles(){const e=document.createElement("style");return e.textContent='\n.solver-ui {\n position: fixed;\n top: 50%;\n left: 50%;\n margin-left: -150px;\n margin-top: -150px;\n background: #1a1a1a;\n color: #fff;\n padding: 20px;\n border-radius: 8px;\n font-family: Arial, sans-serif;\n z-index: 10000;\n min-width: 300px;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n display: none;\n user-select: none;\n}\n\n.solver-ui.visible {\n display: block;\n}\n\n.solver-ui h2 {\n margin: 0 0 15px 0;\n font-size: 18px;\n color: #fff;\n border-bottom: 2px solid #333;\n padding-bottom: 8px;\n cursor: move;\n}\n\n.solver-ui .setting-row {\n margin: 10px 0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.solver-ui label {\n margin-right: 10px;\n font-size: 14px;\n}\n\n.solver-ui input[type="number"] {\n width: 80px;\n padding: 4px;\n border: 1px solid #333;\n background: #2a2a2a;\n color: #fff;\n border-radius: 4px;\n}\n\n.solver-ui input[type="checkbox"] {\n width: 16px;\n height: 16px;\n accent-color: #4CAF50;\n}\n\n.solver-ui input[type="color"] {\n width: 40px;\n height: 25px;\n padding: 0 2px;\n border: none;\n border-radius: 4px;\n background: #2a2a2a;\n}\n\n.solver-ui .close-btn {\n position: absolute;\n top: 10px;\n right: 10px;\n background: none;\n border: none;\n color: #fff;\n cursor: pointer;\n font-size: 18px;\n opacity: 0.7;\n}\n\n.solver-ui .close-btn:hover {\n opacity: 1;\n}\n\n.solver-ui .keybind-info {\n margin: 0;\n padding: 0;\n border: none;\n font-size: 12px;\n color: #888;\n}\n\n.solver-ui .reveal-row {\n justify-content: space-between;\n margin-top: 20px;\n gap: 10px;\n}\n\n.solver-ui .reveal-btn {\n flex: 1;\n background: #4CAF50;\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n transition: background 0.2s;\n}\n\n.solver-ui .reveal-btn:hover {\n background: #45a049;\n}\n\n.solver-ui .author {\n display: block;\n margin-top: 5px;\n font-style: italic;\n color: #666;\n text-align: center;\n}\n\n.solver-ui .setting-group {\n border: 1px solid #333;\n border-radius: 4px;\n padding: 10px;\n margin: 15px 0;\n}\n\n.solver-ui .delay-row {\n opacity: 1;\n transition: opacity 0.3s;\n}\n\n.solver-ui .delay-row.disabled {\n opacity: 0.5;\n}\n\n.solver-ui .delay-row input[disabled] {\n cursor: not-allowed;\n background: #222;\n}\n\n.solver-ui select {\n padding: 4px;\n border: 1px solid #333;\n background: #2a2a2a;\n color: #fff;\n border-radius: 4px;\n cursor: pointer;\n}\n\n.solver-ui select:focus {\n outline: none;\n border-color: #4CAF50;\n}\n\n.solver-ui .buttons-container {\n margin-top: 20px;\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.solver-ui .button-row {\n display: flex;\n gap: 10px;\n justify-content: space-between;\n width: 100%;\n}\n\n.solver-ui .button-row:last-child {\n margin-top: 5px;\n}\n\n.solver-ui .reveal-btn {\n flex: 1;\n width: 100%;\n background: #4CAF50;\n color: white;\n border: none;\n padding: 8px 16px;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n transition: background 0.2s;\n}\n\n.solver-ui .reveal-btn:hover {\n background: #45a049;\n}\n\n.solver-ui .search-btn {\n background: #2196F3;\n}\n\n.solver-ui .search-btn:hover {\n background: #1976D2;\n}\n\n.solver-ui .api-key-row.hidden {\n display: none;\n}\n\n.solver-ui input[type="password"] {\n width: 200px;\n padding: 4px;\n border: 1px solid #333;\n background: #2a2a2a;\n color: #fff;\n border-radius: 4px;\n}\n\n.solver-ui .footer-divider {\n border: none;\n border-top: 1px solid #333;\n margin: 15px 0 10px 0;\n}\n\n.solver-ui .footer-content {\n text-align: center;\n font-size: 12px;\n color: #888;\n}\n',e}addToggle(e,t,n,i){const o=this.configManager.getValue(e)??n,s=document.createElement("div");s.className="setting-row",s.innerHTML=`\n <label>${t}</label>\n <input type="checkbox" id="${e}" ${o?"checked":""}>\n `;const r=s.querySelector("input");return r.addEventListener("change",(t=>{this.configManager.setValue(e,t.target.checked),i?.(t.target.checked)})),this.container.querySelector(".content").appendChild(s),this.elements.set(e,r),this}addSelect(e,t,n,i,o){const s=this.configManager.getValue(e)??i,r=document.createElement("div");r.className="setting-row",r.innerHTML=`\n <label>${t}</label>\n <select id="${e}">\n ${Object.entries(n).map((([e,t])=>`\n <option value="${e}" ${e===s?"selected":""}>\n ${t}\n </option>\n `)).join("")}\n </select>\n `;const a=r.querySelector("select");return a.addEventListener("change",(t=>{this.configManager.setValue(e,t.target.value),o?.(t.target.value)})),this.container.querySelector(".content").appendChild(r),this.elements.set(e,a),this}addNumberInput(e,t,n,i,o,s,r){const a=this.configManager.getValue(e)??n,l=document.createElement("div");l.className="setting-row",l.innerHTML=`\n <label>${t}</label>\n <input type="number" id="${e}" \n value="${a}"\n min="${i||0}"\n max="${o||""}"\n step="${s||1}">\n `;const c=l.querySelector("input");return c.addEventListener("change",(t=>{const n=parseInt(t.target.value);this.configManager.setValue(e,n),r?.(n)})),this.container.querySelector(".content").appendChild(l),this.elements.set(e,c),this}addColorPicker(e,t,n,i){const o=this.configManager.getValue(e)??n,s=document.createElement("div");s.className="setting-row",s.innerHTML=`\n <label>${t}</label>\n <input type="color" id="${e}" value="${o}">\n `;const r=s.querySelector("input");return r.addEventListener("change",(t=>{this.configManager.setValue(e,t.target.value),i?.(t.target.value)})),this.container.querySelector(".content").appendChild(s),this.elements.set(e,r),this}addButton(e,t,n,i=""){const o=document.createElement("button");return o.id=e,o.className=`reveal-btn ${i}`,o.textContent=t,o.addEventListener("click",n),this.container.querySelector(".content").appendChild(o),this.elements.set(e,o),this}addButtonRow(e){const t=document.createElement("div");return t.className="button-row",e.forEach((({id:e,text:n,onClick:i,className:o=""})=>{const s=document.createElement("button");s.id=e,s.className=`reveal-btn ${o}`,s.textContent=n,s.addEventListener("click",i),t.appendChild(s),this.elements.set(e,s)})),this.container.querySelector(".content").appendChild(t),this}addGroup(e){const t=document.createElement("div");return t.className="setting-group",t.id=e,this.container.querySelector(".content").appendChild(t),{addToggle:(e,n,i,o)=>{const s=this.configManager.getValue(e)??i,r=document.createElement("div");r.className="setting-row",r.innerHTML=`\n <label>${n}</label>\n <input type="checkbox" id="${e}" ${s?"checked":""}>\n `;const a=r.querySelector("input");return a.addEventListener("change",(t=>{this.configManager.setValue(e,t.target.checked),o?.(t.target.checked)})),t.appendChild(r),this.elements.set(e,a),this},addNumberInput:(e,n,i,o,s,r,a)=>{const l=this.configManager.getValue(e)??i,c=document.createElement("div");c.className="setting-row delay-row",c.innerHTML=`\n <label>${n}</label>\n <input type="number" id="${e}" \n value="${l}"\n min="${o||0}"\n max="${s||""}"\n step="${r||1}">\n `;const d=c.querySelector("input");return d.addEventListener("change",(t=>{const n=parseInt(t.target.value);this.configManager.setValue(e,n),a?.(n)})),t.appendChild(c),this.elements.set(e,d),this}}}addPasswordInput(e,t,n,i,o){const s=this.configManager.getValue(e)??n,r=document.createElement("div");r.className="setting-row",r.innerHTML=`\n <label>${t}</label>\n <input type="password" id="${e}" \n value="${s}"\n placeholder="${i}">\n `;const a=r.querySelector("input");return a.addEventListener("change",(t=>{this.configManager.setValue(e,t.target.value),o?.(t.target.value)})),this.container.querySelector(".content").appendChild(r),this.elements.set(e,a),r}addFooter(e){return this.container.querySelector(".footer").innerHTML=`\n <hr class="footer-divider">\n <div class="footer-content">\n ${e}\n </div>\n `,this}getElement(e){return this.elements.get(e)}show(){this.container.classList.add("visible"),this.isVisible=!0}hide(){this.container.classList.remove("visible"),this.isVisible=!1}toggle(){this.isVisible?this.hide():this.show()}mount(){return document.head.querySelector("#solver-styles")||(this.styleElement.id="solver-styles",document.head.appendChild(this.styleElement)),document.body.appendChild(this.container),this}setupDragging(){let e,t,n,i,o=!1;const s=this.container.querySelector("h2");s.style.cursor="move",s.addEventListener("mousedown",(e=>{if("input"===e.target.tagName.toLowerCase()||"select"===e.target.tagName.toLowerCase()||"close-btn"===e.target.className)return;const t=this.container.getBoundingClientRect();n=e.clientX-t.left,i=e.clientY-t.top,e.target===this.container.querySelector("h2")&&(o=!0)})),document.addEventListener("mousemove",(s=>{o&&(s.preventDefault(),e=s.clientX-n,t=s.clientY-i,this.container.style.left=`${e}px`,this.container.style.top=`${t}px`,this.container.style.margin="0")})),document.addEventListener("mouseup",(()=>{o=!1}))}}const n={settings:{title:"Solver Settings",autoClick:"Auto Click",randomDelay:"Random Delay",fixedDelay:"Fixed Delay (ms)",minDelay:"Min Delay (ms)",maxDelay:"Max Delay (ms)",highlight:"Highlight Answer",highlightColor:"Highlight Color",highlightDuration:"Highlight Duration (ms)",revealAnswer:"Reveal Answer",language:"Language",keybindInfo:"Press 'X' to toggle settings",author:"by Mykola Scar",copyPrompt:"Copy Prompt",promptCopied:"Prompt copied to clipboard!",searchGoogle:"Search in Google",provider:"AI Service Provider",providers:{gpt24:"GPT-24",openai:"OpenAI GPT-4"},openaiApiKey:"OpenAI API Key"}},i={settings:{title:"Налаштування",autoClick:"Авто Клік",randomDelay:"Випадкова Затримка",fixedDelay:"Фіксована Затримка (мс)",minDelay:"Мін. Затримка (мс)",maxDelay:"Макс. Затримка (мс)",highlight:"Підсвічування Відповіді",highlightColor:"Колір Підсвічування",highlightDuration:"Тривалість Підсвічування (мс)",revealAnswer:"Показати Відповідь",language:"Мова",keybindInfo:"Натисніть 'X' щоб відкрити налаштування",author:"Розробник: Микола Шрам",copyPrompt:"Скопіювати Запитання",promptCopied:"Запитання скопійовано!",searchGoogle:"Шукати в Google",provider:"Провайдер AI",providers:{gpt24:"GPT-24",openai:"OpenAI GPT-4"},openaiApiKey:"OpenAI API Ключ"}};class o{constructor(){this.locales={en_US:n,uk_UA:i},this.defaultLocale="en_US"}setLocale(e){this.locales[e]?this.currentLocale=e:this.currentLocale=this.defaultLocale}t(e){const t=e.split(".");let n=this.locales[this.currentLocale];for(const e of t){if(!n||!n[e]){n=this.locales[this.defaultLocale];for(const e of t)n=n&&n[e];break}n=n[e]}return n||e}}class s{constructor(){this.configManager=new e,this.i18n=new o,this.i18n.setLocale(this.configManager.getValue("locale")),this.lastAnswer=null,this.lastPrompt=null,this.window=new t(this.i18n.t("settings.title"),this.configManager),this.init(),this.setupKeyboardShortcut()}setupKeyboardShortcut(){document.removeEventListener("keydown",this.handleKeyPress),this.handleKeyPress=e=>{"x"===e.key.toLowerCase()&&this.window.toggle()},document.addEventListener("keydown",this.handleKeyPress)}init(){this.window.addSelect("provider",this.i18n.t("settings.provider"),{gpt24:this.i18n.t("settings.providers.gpt24"),openai:this.i18n.t("settings.providers.openai")},"gpt24",(()=>{this.updateApiKeyVisibility(),document.dispatchEvent(new Event("providerChanged"))})),this.window.addPasswordInput("openaiApiKey",this.i18n.t("settings.openaiApiKey"),"","sk-...").classList.toggle("hidden","openai"!==this.configManager.getValue("provider")),this.window.addSelect("locale",this.i18n.t("settings.language"),{en_US:"English",uk_UA:"Українська"},"en_US",(()=>this.updateUI())),this.window.addToggle("autoClick",this.i18n.t("settings.autoClick"),!0);const e=this.window.addGroup("delay-settings");e.addToggle("useRandomDelay",this.i18n.t("settings.randomDelay"),!1,(e=>this.updateDelayInputs(e))),e.addNumberInput("delay",this.i18n.t("settings.fixedDelay"),1e3,0,null,100),e.addNumberInput("minDelay",this.i18n.t("settings.minDelay"),500,0,null,100,(()=>this.validateDelayRange())),e.addNumberInput("maxDelay",this.i18n.t("settings.maxDelay"),2e3,0,null,100,(()=>this.validateDelayRange())),this.window.addToggle("highlight",this.i18n.t("settings.highlight"),!0),this.window.addColorPicker("highlightColor",this.i18n.t("settings.highlightColor"),"#90EE90"),this.window.addNumberInput("highlightDuration",this.i18n.t("settings.highlightDuration"),2e3,0,null,100),this.window.addButtonRow([{id:"copy-prompt",text:this.i18n.t("settings.copyPrompt"),onClick:async()=>{if(this.lastPrompt)try{await navigator.clipboard.writeText(this.lastPrompt);const e=this.window.getElement("copy-prompt"),t=e.textContent;e.textContent=this.i18n.t("settings.promptCopied"),setTimeout((()=>{e.textContent=t}),2e3)}catch(e){console.error("Failed to copy prompt:",e)}}},{id:"search-google",text:this.i18n.t("settings.searchGoogle"),onClick:()=>{if(this.lastPrompt){const e=this.lastPrompt.split("\n")[0],t=`https://www.google.com/search?q=${encodeURIComponent(e)}`;window.open(t,"_blank")}},className:"search-btn"}]),this.window.addButtonRow([{id:"reveal-answer",text:this.i18n.t("settings.revealAnswer"),onClick:()=>{this.lastAnswer&&window.highlightAnswer(this.lastAnswer)}}]),this.window.addFooter(`\n <div class="keybind-info">${this.i18n.t("settings.keybindInfo")}</div>\n <span class="author">${this.i18n.t("settings.author")}</span>\n `),this.window.mount(),this.updateDelayInputs(this.configManager.getValue("useRandomDelay"))}updateDelayInputs(e){const t=this.window.getElement("delay"),n=this.window.getElement("minDelay"),i=this.window.getElement("maxDelay");t.parentElement.classList.toggle("disabled",e),n.parentElement.classList.toggle("disabled",!e),i.parentElement.classList.toggle("disabled",!e),n.disabled=!e,i.disabled=!e,this.window.container.querySelectorAll(".delay-row").forEach((t=>{(t.contains(n)||t.contains(i))&&t.classList.toggle("disabled",!e)}))}validateDelayRange(){const e=this.configManager.getValue("minDelay");e>this.configManager.getValue("maxDelay")&&(this.configManager.setValue("maxDelay",e),this.window.getElement("maxDelay").value=e)}updateUI(){this.i18n.setLocale(this.configManager.getValue("locale"));const e=this.window,n=e.isVisible;this.window=new t(this.i18n.t("settings.title"),this.configManager),this.init(),n&&this.window.show(),e.container.remove()}setLastAnswer(e){this.lastAnswer=e}setLastPrompt(e){this.lastPrompt=e}updateApiKeyVisibility(){const e=this.window.getElement("openaiApiKey")?.parentElement;e&&e.classList.toggle("hidden","openai"!==this.configManager.getValue("provider"))}}class r{constructor(e){this.letters=e}async getAnswer(e){throw new Error("getAnswer must be implemented by provider")}}class a extends r{constructor(e){super(e),this.userId=`#/chat/${Date.now()}`,this.systemMessage=`You are ChatGPT, a large language model trained by OpenAI.\nKnowledge cutoff: 2023-10\nCurrent model: gpt-4o-mini\nCurrent time: ${(new Date).toString()}\n\nInstructions:\n1. You will receive test questions with multiple choice answers\n2. The question type will be specified (single choice or multiple choice)\n3. For single answer questions, respond in this format:\n **[Letter]) Answer text**\n \n For multiple answer questions, list each correct answer on a new line:\n **[Letter1]) Answer text**\n **[Letter2]) Answer text**\n \n4. Use only one letter per answer\n5. Be concise and confident in your response\n6. Make sure to provide the correct number of answers based on the question type`}async getAnswer(e){const t=`${e}\n\nRemember:\n- For single choice questions, provide exactly one answer like: **A) Answer text**\n- For multiple choice questions, list each answer like:\n **A) First answer**\n **B) Second answer**\n- Always use ** around the letter and )\n- Don't add any explanations before the answer, start with **`,n=await fetch("https://gpt24-ecru.vercel.app/api/openai/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"},body:JSON.stringify({messages:[{role:"system",content:this.systemMessage},{role:"user",content:t}],stream:!0,model:"gpt-4o-mini",temperature:.5,presence_penalty:0,frequency_penalty:0,top_p:1,max_tokens:4e3})});if(!n.ok)throw new Error(`API request failed: ${n.statusText}`);const i=n.body.getReader();let o="",s="";for(;;){const{value:e,done:t}=await i.read();if(t)break;s+=(new TextDecoder).decode(e);const n=s.split("\n");s=n.pop()||"";for(const e of n)if(e.startsWith("data: ")){const t=e.slice(6);if("[DONE]"===t)continue;try{const e=JSON.parse(t);e.choices[0].delta.content&&(o+=e.choices[0].delta.content)}catch(e){continue}}}console.log("Bot full response:",o);const r={A:"А",B:"Б",C:"С",D:"Д",E:"Е",F:"Ф",G:"Г",H:"Г",I:"І",J:"Й",K:"К",L:"Л",M:"М",N:"Н",O:"О",P:"П",Q:"К",R:"Р",S:"С",T:"Т",U:"У",V:"В",W:"В",X:"Х",Y:"У",Z:"З"},a=[/\*\*([АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ])\)/g,/відповідь:\s*([АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ])/gi,/^([АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ])\)/gm,/([АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ])\)\s+[\wІіЇїЄєҐґ]/g];for(const e of a){const t=Array.from(o.matchAll(e)).map((e=>{const t=e[1];return r[t]||t})).filter((e=>this.letters.includes(e)));if(t.length>0)return console.log("Extracted answer letter(s) using pattern:",e,":",t),1===t.length?t[0]:t}return console.log("No letters found using any pattern"),o}}class l extends r{constructor(e){super(e),this.systemMessage="You are an AI assistant helping with test questions.\n\nInstructions:\n1. You will receive test questions with multiple choice answers\n2. The question type will be specified (single choice or multiple choice)\n3. For single answer questions, respond in this format:\n **[Letter]) Answer text**\n \n For multiple answer questions, list each correct answer on a new line:\n **[Letter1]) Answer text**\n **[Letter2]) Answer text**\n \n4. Use only one letter per answer\n5. Be concise and confident in your response\n6. Make sure to provide the correct number of answers based on the question type"}async getAnswer(e){const t=`${e}\n\nRemember:\n- For single choice questions, provide exactly one answer like: **A) Answer text**\n- For multiple choice questions, list each answer like:\n **A) First answer**\n **B) Second answer**\n- Always use ** around the letter and )\n- Don't add any explanations before the answer, start with **`,n=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${window.solveConfig.openaiApiKey||""}`},body:JSON.stringify({model:"gpt-4",messages:[{role:"system",content:this.systemMessage},{role:"user",content:t}],temperature:.7,max_tokens:150,stream:!0})});if(!n.ok){if(401===n.status)throw new Error("Invalid OpenAI API key");throw new Error(`API request failed: ${n.statusText}`)}const i=n.body.getReader();let o="",s="";for(;;){const{value:e,done:t}=await i.read();if(t)break;s+=(new TextDecoder).decode(e);const n=s.split("\n");s=n.pop()||"";for(const e of n)if(e.startsWith("data: ")){const t=e.slice(6);if("[DONE]"===t)continue;try{const e=JSON.parse(t);e.choices[0].delta.content&&(o+=e.choices[0].delta.content)}catch(e){continue}}}console.log("OpenAI response:",o);const r={A:"А",B:"Б",C:"С",D:"Д",E:"Е",F:"Ф",G:"Г",H:"Г",I:"І",J:"Й",K:"К",L:"Л",M:"М",N:"Н",O:"О",P:"П",Q:"К",R:"Р",S:"С",T:"Т",U:"У",V:"В",W:"В",X:"Х",Y:"У",Z:"З"},a=[/\*\*([АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ])\)/g,/відповідь:\s*([АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ])/gi,/^([АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ])\)/gm,/([АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯABCDEFGHIJKLMNOPQRSTUVWXYZ])\)\s+[\wІіЇїЄєҐґ]/g];for(const e of a){const t=Array.from(o.matchAll(e)).map((e=>{const t=e[1];return r[t]||t})).filter((e=>this.letters.includes(e)));if(t.length>0)return console.log("Extracted answer letter(s):",t),1===t.length?t[0]:t}return console.log("No letters found using any pattern"),o}}!function(){const t="абвгґдеєжзиіїйклмнопрстуфхцчшщьюя".toUpperCase().split(""),n=new e,i=new s;function o(){return"openai"===n.getValue("provider")?new l(t):new a(t)}let r=o(),c="",d=!1,u=null,h=null;async function g(e){const i=document.querySelector(".test-options-grid");if(!i)return;const o=null!==document.querySelector(".question-option-inner-multiple"),s=o?".question-option-inner-multiple":".question-option-inner.ng-scope",r=i.querySelectorAll(s),a=Array.isArray(e)?e:[e];n.getValue("highlight")&&r.forEach((e=>{e.style.backgroundColor=""}));const l=[];for(const e of a){const i=t.indexOf(e);if(-1!==i&&r[i]){const t=r[i];n.getValue("highlight")&&(t.style.backgroundColor=n.getValue("highlightColor"),l.push(t)),console.log("Highlighted answer:",e,"at index:",i)}}if(n.getValue("highlight")&&setTimeout((()=>{l.forEach((e=>{e.style.backgroundColor=""}))}),n.getValue("highlightDuration")),n.getValue("autoClick")){await new Promise((e=>setTimeout(e,300)));for(const e of a){const i=t.indexOf(e);if(-1!==i&&r[i]){const t=r[i],o=n.getValue("useRandomDelay")?Math.random()*(n.getValue("maxDelay")-n.getValue("minDelay"))+n.getValue("minDelay"):n.getValue("delay");await new Promise((e=>setTimeout(e,o))),t.click(),console.log("Clicked answer:",e,"at index:",i)}}o&&(await new Promise((e=>setTimeout(e,500))),await async function(){const e=document.querySelector(".test-multiquiz-save-button");e&&(e.click(),console.log("Clicked save button"))}())}}document.addEventListener("providerChanged",(()=>{r=o()})),window.highlightAnswer=g,setTimeout((function(){setInterval((()=>{if(d)return;const e=function(){const e=document.getElementsByClassName("test-content-text")[0]?.childNodes[1]?.childNodes[0];if(!e)return null;const n=e.innerText,i=null!==document.querySelector(".question-option-inner-multiple"),o=i?".question-option-inner-multiple":".question-option-inner.ng-scope",s=Array.from(document.querySelectorAll(o)),r={};return s.forEach(((e,n)=>{if(n<t.length){const i=e.querySelector(".question-option-inner-content");r[t[n]]=i?i.innerText:e.innerText}})),{question:n,answers:r,isMultipleChoice:i}}();e&&e.question!==c&&(u&&(u.style.backgroundColor="",u=null),h&&(clearTimeout(h),h=null),d=!0,c=e.question,async function(e){if(!e)return;let n=`${e.question}\n\n`;for(const[t,i]of Object.entries(e.answers))n+=`${t}) ${i.replace(/^[АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ]\)\s*/,"")}\n`;i.setLastPrompt(n);let o=`${e.question}\n\n`;o+=`Тип запитання: ${e.isMultipleChoice?"множинний вибір (декілька правильних відповідей)":"одиночний вибір (одна правильна відповідь)"}\n\n`,o+="Варіанти відповідей:\n";for(const[t,n]of Object.entries(e.answers))o+=`${t}) ${n.replace(/^[АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ]\)\s*/,"")}\n`;try{const e=await r.getAnswer(o);if(Array.isArray(e))i.setLastAnswer(e),await g(e);else{const n=e.replace(/[^АБВГҐДЕЄЖЗИІЇЙ��ЛМНОПРСТУФХЦЧШЩЬЮЯ]/g,"").trim();t.includes(n)&&(i.setLastAnswer(n),await g(n))}}catch(e){console.error("Error getting answer:",e)}}(e).finally((()=>{d=!1})))}),1e3)}),1e3)}(),EntryPoint={}})();