// ==UserScript== // @name 优学院答题助手 V14.9 // @namespace https://thewinds.me/ // @version 14.9.8 // @description 全自动刷课 | 智能避让 | 自动进入讨论 | 自动回复 | 自动净化AI答案 | 支持暂停/继续 | 自动关闭标签 | 修复UI显示 // @author Winds (Modified) // @license CC-BY-NC-4.0 // @match *://*.ulearning.cn/* // @connect homeworkapi.ulearning.cn // @connect workers.dev // @connect * // @grant GM_xmlhttpRequest // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant unsafeWindow // @downloadURL https://update.greasyfork.icu/scripts/556996/%E4%BC%98%E5%AD%A6%E9%99%A2%E7%AD%94%E9%A2%98%E5%8A%A9%E6%89%8B%20V149.user.js // @updateURL https://update.greasyfork.icu/scripts/556996/%E4%BC%98%E5%AD%A6%E9%99%A2%E7%AD%94%E9%A2%98%E5%8A%A9%E6%89%8B%20V149.meta.js // ==/UserScript== (function() { 'use strict'; // ================= 配置区域 ================= const USER_API_URL = GM_getValue('UL_AI_URL', ''); const CONFIG = { get aiBaseUrl() { return USER_API_URL; }, interval: 2000, selectors: { listContainer: ".table-homework", writeBtn: ".item-operation .button-red-solid", nextPageBtn: ".pagination-wrap .next", questionContainer: ".question-choice, .question-gap-filling, .question-short-answer", titleContext: ".title", question: ".question-title", textInput: ".ul-textarea__inner", choiceItem: ".choice-item", choiceIndex: ".index", choiceClickArea: ".ul-radio, .ul-checkbox", judgeTrueIcon: ".icon-zhengque", judgeFalseIcon: ".icon-cuowu1", checkedSelector: ".is-checked, .is-active, input:checked", startQuizBtn: ".ul-button--primary", bottomBarNum: ".number .answered", submitBtn: ".ul-button--primary", modalConfirmBtn: ".ul-message-box .ul-button--primary", headerBackBtn: ".header-back, .goback, .icon-fanhui", resultPageMarker: ".homework-result-report, .score-panel", itemName: ".item-name", checkboxClass: ".ul-checkbox", // 👇👇👇 讨论区相关选择器 👇👇👇 discussionPageMarker: ".course-discussion-page", // 讨论列表页标志 discussionRow: ".discussion-list .table-body", // 讨论列表行 myPostCount: ".item-post-my span", // 我的帖子计数 viewDiscussionBtn: ".item-operation .button-red-hollow", // 查看按钮 // 👇👇👇 讨论详情页自动回复相关 👇👇👇 discussionDetailTitle: ".contentTopText", // 题目容器 discussionSubmitBtn: ".el-button.submit.el-button--primary" // 提交按钮 } }; let API_ANSWERS = {}; let HAS_FETCHED_API = false; let hasAutoReplied = false; // 防止单页重复回复 // ================= 状态管理 ================= const isListPage = () => document.querySelector(CONFIG.selectors.listContainer) !== null; const isResultPage = () => location.href.includes("stuReport") || document.querySelector(CONFIG.selectors.resultPageMarker) !== null; const isDiscussionListPage = () => document.querySelector(CONFIG.selectors.discussionPageMarker) !== null; // 判断是否为讨论详情页 const isDiscussionDetailPage = () => { return document.querySelector(CONFIG.selectors.discussionDetailTitle) !== null && document.getElementById('cke_editorContainer') !== null; }; const isPotentialQuizPage = () => !isListPage() && !isResultPage() && !isDiscussionListPage() && !isDiscussionDetailPage() && ( document.querySelectorAll(CONFIG.selectors.questionContainer).length > 0 || document.querySelector(CONFIG.selectors.startQuizBtn) !== null ); let isRunning = false; let isPaused = false; let questionsList = []; let currentIndex = 0; // ================= 首次运行检查 ================= function checkFirstRun() { if (!GM_getValue('UL_HAS_INIT', false)) { const tips = "🎉 欢迎使用优学院助手!\n\n请输入AI API地址(留空则只做客观题):\n注意:配置API后,进入讨论题将自动生成回复!"; const input = prompt(tips, ""); if (input !== null) { GM_setValue('UL_AI_URL', input.trim()); GM_setValue('UL_HAS_INIT', true); location.reload(); } } } // ================= API 获取 (客观题) ================= function getIdsFromUrl() { const url = location.href; const ocIdMatch = url.match(/ocId=(\d+)/); const homeworkIdMatch = url.match(/homeworkId=(\d+)/); if (ocIdMatch && homeworkIdMatch) return { ocId: ocIdMatch[1], homeworkId: homeworkIdMatch[1] }; return null; } function getToken() { const match = document.cookie.match(/token=([^;]+)/); return match ? match[1] : localStorage.getItem("token"); } function fetchStandardAnswers(callback) { const ids = getIdsFromUrl(); if (!ids) { if(callback) callback(false); return; } const token = getToken(); if (!token) { if(callback) callback(false); return; } const apiUrl = `https://homeworkapi.ulearning.cn/quiz/homework/stu/questions?homeworkId=${ids.homeworkId}&ocId=${ids.ocId}&showAnswer=true`; const statusEl = document.querySelector('#status-text'); if(statusEl) statusEl.innerHTML = "📡 正在抓取标准答案..."; GM_xmlhttpRequest({ method: "GET", url: apiUrl, headers: { "Authorization": token, "User-Agent": navigator.userAgent }, onload: function(response) { try { const json = JSON.parse(response.responseText); if (json.result) { API_ANSWERS = {}; json.result.forEach((q, index) => { if(q.id) API_ANSWERS[q.id] = q.correctAnswer; API_ANSWERS[`INDEX_${index}`] = q.correctAnswer; }); HAS_FETCHED_API = true; if(statusEl) statusEl.innerHTML = `✅ 成功获取 ${json.result.length} 题答案`; if(callback) callback(true); } else { if(callback) callback(false); } } catch (e) { if(callback) callback(false); } }, onerror: () => { if(callback) callback(false); } }); } // ================= UI 创建 (已修复宽度) ================= GM_addStyle(` #ai-panel { position: fixed; top: 20px; right: 20px; width: 360px; /* 🟢 宽度增加到360px */ height: 420px; background: #fff; box-shadow: 0 4px 20px rgba(0,0,0,0.15); border-radius: 12px; z-index: 99999; font-family: sans-serif; border: 1px solid #ebeef5; display: flex; flex-direction: column; transition: all 0.3s; overflow: hidden; } #ai-header { padding: 12px 15px; background: #2c3e50; color: white; height: 44px; box-sizing: border-box; font-weight: 600; display: flex; justify-content: space-between; align-items: center; cursor: move; } #ai-content { padding: 15px; overflow-y: auto; flex-grow: 1; display: flex; flex-direction: column; } .ai-btn { background: rgba(255,255,255,0.2); border: 1px solid rgba(255,255,255,0.6); color: white; padding: 3px 8px; /* 🟢 减小内边距 */ border-radius: 4px; cursor: pointer; font-size: 12px; margin-left: 3px; /* 🟢 减小间距 */ } .ai-btn:hover { background: rgba(255,255,255,0.3); } .reasoning { color: #666; font-style: italic; background: #f8f9fa; padding: 8px; margin-bottom: 10px; font-size: 12px; border-left: 3px solid #ddd; } .answer { color: #333; font-weight: 600; white-space: pre-wrap; } .current-q { border: 2px solid #2c3e50 !important; box-shadow: 0 0 10px rgba(44,62,80,0.2); } #ai-panel.minimized { width: 50px !important; height: 50px !important; border-radius: 50%; background-color: #2c3e50; } #ai-panel.minimized #ai-content, #ai-panel.minimized #ai-header { opacity: 0; pointer-events: none; } #ai-panel.minimized::after { content: "⚙️"; font-size: 24px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white; pointer-events: none; } `); function createUI() { if (document.getElementById('ai-panel')) return; const panel = document.createElement('div'); panel.id = 'ai-panel'; panel.innerHTML = `
🤖 优学院助手
等待操作...
`; document.body.appendChild(panel); const actionBtn = panel.querySelector('#btn-action'); const stopBtn = panel.querySelector('#btn-stop'); const pauseBtn = panel.querySelector('#btn-pause'); const minimizeBtn = panel.querySelector('#btn-minimize'); minimizeBtn.onclick = (e) => { e.stopPropagation(); panel.classList.add('minimized'); }; panel.onclick = () => { if (panel.classList.contains('minimized')) panel.classList.remove('minimized'); }; const header = panel.querySelector('#ai-header'); let isDragging = false, startX, startY, initLeft, initTop; header.onmousedown = (e) => { isDragging = true; startX = e.clientX; startY = e.clientY; const rect = panel.getBoundingClientRect(); initLeft = rect.left; initTop = rect.top; }; document.onmousemove = (e) => { if(isDragging) { panel.style.left = (initLeft + e.clientX - startX) + 'px'; panel.style.top = (initTop + e.clientY - startY) + 'px'; } }; document.onmouseup = () => isDragging = false; panel.querySelector('#btn-settings').onclick = () => { const current = GM_getValue('UL_AI_URL', ''); const newUrl = prompt("配置 AI API 地址:", current); if (newUrl !== null) { GM_setValue('UL_AI_URL', newUrl.trim()); location.reload(); } }; stopBtn.onclick = () => { isRunning = false; GM_setValue('UL_QUEUE_MODE', false); location.reload(); }; pauseBtn.onclick = togglePause; // 页面类型判断与初始化 if (isDiscussionDetailPage()) { // 讨论详情页 document.querySelector('#status-text').innerText = "📝 讨论详情页"; actionBtn.innerText = "▶ 自动回复"; actionBtn.onclick = () => { processDiscussionReply(); showPauseBtn(); }; // 队列模式自动开始 if (GM_getValue('UL_QUEUE_MODE', false)) { showPauseBtn(); setTimeout(processDiscussionReply, 2000); } } else if (isDiscussionListPage()) { // 讨论列表页 document.querySelector('#status-text').innerText = "💬 讨论列表"; actionBtn.innerText = "▶ 扫描未做"; actionBtn.onclick = () => { processDiscussionListPage(); showPauseBtn(); }; // 自动模式 if(GM_getValue('UL_QUEUE_MODE', false)) showPauseBtn(); setTimeout(processDiscussionListPage, 1500); } else if (isListPage()) { GM_setValue('UL_LIST_URL', window.location.href); actionBtn.innerText = "▶ 队列"; actionBtn.onclick = () => { startListQueue(); showPauseBtn(); }; if (GM_getValue('UL_QUEUE_MODE', false)) { actionBtn.style.display = 'none'; stopBtn.style.display = 'inline-block'; showPauseBtn(); setTimeout(processListPage, 2000); } } else if (isResultPage()) { document.querySelector('#status-text').innerText = "✅ 作业已完成"; actionBtn.innerText = "↩️ 返回"; actionBtn.onclick = goBackToList; if (GM_getValue('UL_QUEUE_MODE', false)) setTimeout(goBackToList, 3000); } else if (isPotentialQuizPage()) { actionBtn.innerText = "▶ 答题"; actionBtn.onclick = () => { startQuiz(false); showPauseBtn(); }; setTimeout(() => { startQuiz(true); showPauseBtn(); }, 1500); } } // ================= 暂停逻辑 ================= function showPauseBtn() { document.querySelector('#btn-pause').style.display = 'inline-block'; } function togglePause() { isPaused = !isPaused; const btn = document.querySelector('#btn-pause'); const status = document.querySelector('#status-text'); if (isPaused) { btn.innerText = "▶"; btn.style.background = "#27ae60"; status.innerHTML = `⏸ 已暂停`; } else { btn.innerText = "⏸"; btn.style.background = ""; status.innerHTML = "⚡ 继续运行..."; // 根据当前页面类型恢复执行 if (isDiscussionDetailPage()) processDiscussionReply(); else if (isDiscussionListPage()) processDiscussionListPage(); else if (isListPage()) processListPage(); else if (isPotentialQuizPage()) processNextQuizItem(); } } // ================= 核心功能1:讨论详情页自动回复 ================= function processDiscussionReply() { if (!isDiscussionDetailPage() || hasAutoReplied) return; if (isPaused) return; // 暂停检查 const logDiv = document.querySelector('#ai-log'); const statusText = document.querySelector('#status-text'); if (!CONFIG.aiBaseUrl) { if(logDiv) logDiv.innerHTML += `
⚠️ 未配置AI,无法自动回复。请在设置中配置API。
`; return; } hasAutoReplied = true; // 锁定防止重复 statusText.innerText = "🧠 AI 生成观点中..."; if(logDiv) logDiv.innerHTML = '
正在提取题目...
'; // 提取题目 const titleEl = document.querySelector(CONFIG.selectors.discussionDetailTitle); let promptText = "请就以下话题发表一段深刻的、正能量的、符合大学生身份的观点(150字左右):\n"; if (titleEl) { promptText += titleEl.innerText.trim(); } else { promptText += "未知话题"; } const payload = { prompt: promptText }; GM_xmlhttpRequest({ method: "POST", url: CONFIG.aiBaseUrl, headers: { "Content-Type": "application/json" }, data: JSON.stringify(payload), responseType: 'text', onload: function(response) { // 处理流式或非流式响应 let answer = ""; if (response.responseText.includes("data: ")) { const chunks = response.responseText.split('data: '); chunks.forEach(c => { if(!c.trim() || c.includes('[DONE]')) return; try { answer += JSON.parse(c).choices[0].delta.content || ""; } catch(e){} }); } else { try { const json = JSON.parse(response.responseText); answer = json.choices[0].message.content || json.response; } catch(e) { answer = response.responseText; } } if (!answer) { if(logDiv) logDiv.innerHTML += `
AI 响应为空
`; return; } // 👇👇👇 净化 AI 答案:删除 "XXX字" 相关的描述 👇👇👇 answer = answer.replace(/[((\[]?\s*\d+\s*字(左右)?\s*[))\]]?[::]?/g, "").trim(); if(logDiv) logDiv.innerHTML += `
${answer}
`; statusText.innerText = "✍️ 正在写入编辑器..."; // 写入 CKEditor (需要 unsafeWindow) try { if (unsafeWindow.CKEDITOR && unsafeWindow.CKEDITOR.instances && unsafeWindow.CKEDITOR.instances.editorContainer) { unsafeWindow.CKEDITOR.instances.editorContainer.setData(answer); if(logDiv) logDiv.innerHTML += `
写入成功,2秒后提交...
`; setTimeout(() => { if (isPaused) return; // 提交前检查暂停 const submitBtn = document.querySelector(CONFIG.selectors.discussionSubmitBtn); if (submitBtn) { submitBtn.click(); statusText.innerText = "✅ 已提交"; if(logDiv) logDiv.innerHTML += `
已点击提交。2秒后自动关闭...
`; setTimeout(() => { if (isPaused) return; // 关闭前检查暂停 // 【核心逻辑】完成任务:设置标志位 + 关闭窗口 GM_setValue('UL_DISCUSSION_STATE', 'finished'); window.close(); // 兜底:如果无法关闭(比如同一个标签页打开的),尝试返回 setTimeout(() => { statusText.innerText = "⚠️ 窗口未关闭,尝试返回..."; goBackToList(); }, 500); }, 2000); } else { if(logDiv) logDiv.innerHTML += `
未找到提交按钮
`; } }, 2000); } else { if(logDiv) logDiv.innerHTML += `
CKEditor 对象未找到,无法自动写入。
`; } } catch (e) { console.error(e); if(logDiv) logDiv.innerHTML += `
写入出错: ${e.message}
`; } }, onerror: () => { if(logDiv) logDiv.innerHTML += `
AI 请求失败
`; } }); } // ================= 核心功能2:讨论列表自动化 ================= function processDiscussionListPage() { if (!isDiscussionListPage()) return; if (isPaused) return; // 暂停检查 // 【关键】保存当前列表页地址 GM_setValue('UL_LIST_URL', window.location.href); const logDiv = document.querySelector('#ai-log'); const statusText = document.querySelector('#status-text'); statusText.innerText = "🔍 扫描未做讨论..."; if(logDiv) logDiv.innerHTML = '
正在分析列表...
'; const rows = Array.from(document.querySelectorAll(CONFIG.selectors.discussionRow)); let targetBtn = null; let targetTitle = ""; for (let row of rows) { const myCountEl = row.querySelector(CONFIG.selectors.myPostCount); if (myCountEl) { const count = parseInt(myCountEl.innerText.trim()); // 只有当帖子数为 0 时才进入 if (!isNaN(count) && count === 0) { const btn = row.querySelector(CONFIG.selectors.viewDiscussionBtn); const titleEl = row.querySelector('.discussion-name .text span'); if (btn && btn.innerText.includes("查看")) { targetBtn = btn; targetTitle = titleEl ? titleEl.innerText : "未知主题"; break; } } } } if (targetBtn) { GM_setValue('UL_QUEUE_MODE', true); // 确保进入详情页后知道是自动模式 GM_setValue('UL_DISCUSSION_STATE', 'processing'); // 标记为正在处理 statusText.innerText = "⚡ 进入讨论 (完成后自动刷新)..."; if(logDiv) logDiv.innerHTML += `
发现未做讨论:${targetTitle}
`; // 【核心逻辑】开启轮询,等待子标签页完成任务 const checkTimer = setInterval(() => { if (isPaused) return; // 轮询中检查暂停,但不清除定时器,等待恢复 const state = GM_getValue('UL_DISCUSSION_STATE'); if (state === 'finished') { clearInterval(checkTimer); GM_setValue('UL_DISCUSSION_STATE', 'idle'); // 重置状态 statusText.innerText = "✅ 检测到任务完成,正在刷新..."; if(logDiv) logDiv.innerHTML += `
任务完成,刷新列表...
`; setTimeout(() => location.reload(), 1000); // 刷新页面 } }, 1000); setTimeout(() => { if(!isPaused) targetBtn.click(); }, 2000); } else { statusText.innerText = "✅ 本页已完成"; const nextBtn = document.querySelector(CONFIG.selectors.nextPageBtn); if (nextBtn && !nextBtn.classList.contains('disabled') && nextBtn.style.display !== 'none') { if(logDiv) logDiv.innerHTML += `
自动翻页中...
`; setTimeout(() => { if(!isPaused) { nextBtn.click(); setTimeout(processDiscussionListPage, 3000); } }, 2000); } else { if(logDiv) logDiv.innerHTML += `
🎉 所有讨论均已完成!
`; GM_setValue('UL_QUEUE_MODE', false); } } } // ================= 列表页逻辑 ================= function startListQueue() { GM_setValue('UL_LIST_URL', window.location.href); GM_setValue('UL_QUEUE_MODE', true); location.reload(); } function processListPage() { if (!isListPage() || !GM_getValue('UL_QUEUE_MODE', false)) return; if (isPaused) return; // 暂停检查 const btns = Array.from(document.querySelectorAll(CONFIG.selectors.writeBtn)); const todoBtns = btns.filter(btn => { const txt = btn.innerText; if (!txt.includes("写作业") && !txt.includes("继续")) return false; if (!CONFIG.aiBaseUrl) { const row = btn.closest('.tr') || btn.closest('li'); const titleEl = row ? row.querySelector(CONFIG.selectors.itemName) : null; if (titleEl && titleEl.innerText.includes("主观题")) return false; } return true; }); if (todoBtns.length > 0) { document.querySelector('#status-text').innerText = `发现 ${todoBtns.length} 个作业`; setTimeout(() => { if (!isPaused) todoBtns[0].click(); }, 3000); } else { const nextBtn = document.querySelector(CONFIG.selectors.nextPageBtn); if (nextBtn && !nextBtn.classList.contains('disabled')) { setTimeout(() => { if(!isPaused) nextBtn.click(); setTimeout(processListPage, 3000); }, 2000); } else { GM_setValue('UL_QUEUE_MODE', false); document.querySelector('#status-text').innerText = "全部完成"; } } } // ================= 答题页提交逻辑 ================= function checkAndSubmit() { const progressEl = document.querySelector(CONFIG.selectors.bottomBarNum); let isFinished = false; if (progressEl) { const match = progressEl.innerText.match(/(\d+)\s*\/\s*(\d+)/); if (match && parseInt(match[1]) >= parseInt(match[2])) isFinished = true; } if (isFinished) { const submitBtn = Array.from(document.querySelectorAll(CONFIG.selectors.submitBtn)).find(b => b.innerText.includes("提交")); if (submitBtn) { submitBtn.click(); setTimeout(() => { if (isPaused) return; // 暂停检查 const confirmBtn = Array.from(document.querySelectorAll(CONFIG.selectors.modalConfirmBtn)).find(b => b.innerText.includes("确定")); if (confirmBtn) { confirmBtn.click(); document.querySelector('#ai-log').innerHTML += `
提交成功,准备返回...
`; setTimeout(goBackToList, 3000); } }, 1000); return true; } } return false; } function goBackToList() { const savedUrl = GM_getValue('UL_LIST_URL'); if (savedUrl && savedUrl.includes('ulearning')) { window.location.href = savedUrl; return; } const backBtn = document.querySelector(CONFIG.selectors.headerBackBtn); if (backBtn) { backBtn.click(); return; } window.history.back(); } function startQuiz(isAuto) { const startBtns = Array.from(document.querySelectorAll(CONFIG.selectors.startQuizBtn)); const realStartBtn = startBtns.find(b => b.innerText.includes("开始答题")); if (realStartBtn) { realStartBtn.click(); setTimeout(() => startQuiz(isAuto), 2000); return; } questionsList = Array.from(document.querySelectorAll(CONFIG.selectors.questionContainer)); if (questionsList.length === 0) return; isRunning = true; document.querySelector('#btn-action').style.display = 'none'; document.querySelector('#btn-stop').style.display = 'inline-block'; fetchStandardAnswers(() => processNextQuizItem()); } function processNextQuizItem() { if (!isRunning || isPaused) return; // 暂停检查 if (currentIndex >= questionsList.length) { if(!checkAndSubmit()) setTimeout(goBackToList, 2000); return; } const container = questionsList[currentIndex]; container.scrollIntoView({ behavior: "smooth", block: "center" }); if (isQuestionAnswered(container)) { currentIndex++; setTimeout(processNextQuizItem, 500); return; } const apiResult = getApiAnswerForQuestion(currentIndex); if (apiResult) { if (apiResult[0] === 'true' || apiResult[0] === 'false') autoSelectJudge(apiResult[0], container); else autoSelectChoices(apiResult.join(" "), container); currentIndex++; setTimeout(processNextQuizItem, 1000); } else if (CONFIG.aiBaseUrl) { callAI(container, (ans) => { autoFillText(cleanMarkdown(ans), container); currentIndex++; setTimeout(processNextQuizItem, 3000); }); } else { currentIndex++; setTimeout(processNextQuizItem, 1000); } } function getApiAnswerForQuestion(index) { if (!HAS_FETCHED_API) return null; return API_ANSWERS[`INDEX_${index}`] || null; } function isQuestionAnswered(container) { const input = container.querySelector(CONFIG.selectors.textInput); if (input && input.value.trim()) return true; return container.querySelectorAll(CONFIG.selectors.checkedSelector).length > 0; } function autoSelectJudge(ans, container) { const sel = ans === 'true' || ans.includes('正确') ? CONFIG.selectors.judgeTrueIcon : CONFIG.selectors.judgeFalseIcon; container.querySelector(sel)?.closest('.ul-radio')?.click(); } async function autoSelectChoices(ansStr, container) { const choices = container.querySelectorAll(CONFIG.selectors.choiceItem); for (let c of choices) { const idx = c.querySelector(CONFIG.selectors.choiceIndex)?.innerText.trim().replace('.',''); if (idx && ansStr.toUpperCase().includes(idx)) c.querySelector(CONFIG.selectors.choiceClickArea)?.click(); } } function callAI(container, callback) { const qElem = container.querySelector(CONFIG.selectors.question); if (!qElem) return; const prompt = `题目:${qElem.innerText.trim()}\n请直接给出答案,不要解释。`; GM_xmlhttpRequest({ method: "POST", url: CONFIG.aiBaseUrl, headers: { "Content-Type": "application/json" }, data: JSON.stringify({ prompt: prompt }), onload: function(response) { let fullText = ""; if (response.responseText.includes("data: ")) { const chunks = response.responseText.split('data: '); chunks.forEach(c => { if(!c.trim() || c.includes('[DONE]')) return; try { fullText += JSON.parse(c).choices[0].delta.content || ""; } catch(e){} }); } else { try { fullText = JSON.parse(response.responseText).choices[0].message.content; } catch(e){ fullText = response.responseText; } } callback(fullText); } }); } function cleanMarkdown(text) { return text.replace(/\*\*/g, "").replace(/#/g, "").trim(); } function autoFillText(text, container) { const input = container.querySelector(CONFIG.selectors.textInput); if (input) { input.value = text; input.dispatchEvent(new Event('input')); input.dispatchEvent(new Event('blur')); } } window.addEventListener('load', () => setTimeout(() => { createUI(); checkFirstRun(); }, 2000)); })();