// ==UserScript== // @name AI TRANSLATION OF Auto F2 CleanCookie — AI FREE! Claude Opus 4.6 | Beginner Friendly | 2-Min Setup // @namespace https://greasyfork.org/ // @version 7.7.8 // @license ALL RIGHT RESERVED TO Mei In. // @description AI TRANSLATION OF Auto F2 CleanCookie all credit to Mei In ( https://greasyfork.org/en/users/1389070-mei-in ) Add super convenient F2 one-click reset to Arena.ai (LMArena), auto-accept cookies. Designed for beginners! Get started with top-tier AI in just 2 minutes. Super easy, loved by beginners globally! Supports: Claude Opus 4.6, Gemini, Grok, GPT, etc. // @match https://lmarena.ai/* // @match https://arena.ai/* // @match https://www.lmarena.ai/* // @match https://gemini.google.com/* // @match https://chatgpt.com/* // @match https://z.ai/* // @match https://chat.qwen.ai/* // @match https://aistudio.google.com/* // @match https://claude.ai/* // @match http://x.ai/* // @match https://poe.com/* // @match https://cursor.com/* // @match https://www.kimi.com/* // @match https://grok.com/* // @match https://copilot.microsoft.com/* // @match https://ernie.baidu.com/* // @match https://ai.baidu.com/ // @match https://manus.im/* // @match https://hunyuan.tencent.com/* // @match https://www.doubao.com/* // @match https://www.intercom.com/* // @match https://www.drift.com/* // @match https://www.zendesk.com/* // @match https://www.ada.cx/* // @match https://www.forethought.ai/* // @match https://www.tidio.com/* // @match https://openrouter.ai/* // @match https://www.together.ai/* // @match https://together.ai/* // @match https://fireworks.ai/* // @match https://www.fireworks.ai/* // @match https://sambanova.ai/* // @match https://cloud.sambanova.ai/* // @match https://build.nvidia.com/* // @match https://yupp.ai/* // @match https://gigachat.ru/* // @match https://www.sberbank.ru/gigachat/* // @match https://developers.sber.ru/gigachat/* // @match https://ya.ru/* // @match https://yandex.ru/alice/* // @match https://alice.yandex.ru/* // @match https://shedevrum.ai/* // @match https://yiyan.baidu.com/* // @match https://wenxin.baidu.com/* // @match https://chat.baidu.com/* // @match https://tongyi.aliyun.com/* // @match https://qianwen.aliyun.com/* // @match https://modelscope.cn/* // @match https://www.modelscope.cn/* // @match https://www.coze.com/* // @match https://coze.com/* // @match https://www.coze.cn/* // @match https://xinghuo.xfyun.cn/* // @match https://passport.xfyun.cn/* // @match https://chatglm.cn/* // @match https://www.chatglm.cn/* // @match https://open.bigmodel.cn/* // @match https://zhipuai.cn/* // @match https://kimi.moonshot.cn/* // @match https://moonshot.cn/* // @match https://www.minimaxi.com/* // @match https://hailuoai.com/* // @match https://www.hailuoai.com/* // @match https://tiangong.cn/* // @match https://www.tiangong.cn/* // @match https://neice.tiangong.cn/* // @match https://mureka.ai/* // @match https://www.baichuan-ai.com/* // @match https://baichuan-ai.com/* // @match https://www.01.ai/* // @match https://www.lingyiwanwu.com/* // @match https://chat.wanzhi.com/* // @match https://chat.deepseek.com/* // @match https://www.deepseek.com/* // @match https://chat.sensetime.com/* // @match https://www.sensechat.cn/* // @match https://youdao.com/ai/* // @match https://zi.youdao.com/* // @match https://ai.360.com/* // @match https://www.so.com/ai/* // @match https://ai.sogou.com/* // @match https://yuewen.cn/* // @match https://www.yuewen.cn/* // @match https://www.wisemodel.cn/* // @match https://wisemodel.cn/* // @match https://www.modao.cc/* // @match https://step.fun/* // @match https://stepchat.cn/* // @match https://www.stepfun.com/* // @match https://yuanbao.tencent.com/* // @match https://ima.qq.com/* // @match https://metaso.cn/* // @match https://www.metaso.cn/* // @match https://www.tizi.ai/* // @match https://tizi.ai/* // @match https://ollama.com/* // @match https://www.ollama.com/* // @match https://lmstudio.ai/* // @match https://jan.ai/* // @match https://www.jan.ai/* // @match https://localai.io/* // @match https://oobabooga.github.io/* // @match https://github.com/oobabooga/* // @match https://koboldai.org/* // @match https://sillytavern.app/* // @match https://clova.ai/* // @match https://www.ncloud.com/product/aiService/* // @match https://wrtn.ai/* // @match https://www.wrtn.ai/* // @match https://www.browserling.com/* // @match https://line.me/ja/service/* // @match https://elyza.ai/* // @match https://www.elyza.ai/* // @match https://www.sakana.ai/* // @match https://www.meta.ai/* // @match https://meta.ai/* // @match https://ai.meta.com/* // @match https://chat.mistral.ai/* // @match https://mistral.ai/* // @match https://www.mistral.ai/* // @match https://lechat.mistral.ai/* // @match https://aleph-alpha.com/* // @match https://www.aleph-alpha.com/* // @match https://www.deepl.com/* // @match https://deepl.com/* // @match https://huggingface.co/* // @match https://www.huggingface.co/* // @match https://you.com/* // @match https://www.you.com/* // @match https://perplexity.ai/* // @match https://www.perplexity.ai/* // @match https://replika.ai/* // @match https://replika.com/* // @match https://character.ai/* // @match https://www.character.ai/* // @match https://beta.character.ai/* // @match https://pi.ai/* // @match https://www.pi.ai/* // @match https://inflection.ai/* // @match https://jasper.ai/* // @match https://www.jasper.ai/* // @match https://anthropic.com/* // @match https://www.anthropic.com/* // @match https://bard.google.com/* // @match https://talkie-ai.com/* // @match https://www.talkie-ai.com/* // @match https://glow.app/* // @match https://www.minimax.com/* // @match https://minimax.com/* // @match https://hailuoai.video/* // @match https://baixiaoying.com/* // @match https://www.baixiaoying.com/* // @match https://dearmate.ai/* // @match https://www.dearmate.ai/* // @match https://eggbun.net/* // @match https://www.eggbun.net/* // @match https://langotalk.org/* // @match https://www.langotalk.org/* // @match https://mirinae.io/* // @match https://www.mirinae.io/* // @match https://talkpal.ai/* // @match https://www.talkpal.ai/* // @match https://langbuddy.ai/* // @match https://www.langbuddy.ai/* // @match https://bebot.io/* // @match https://www.bebot.io/* // @match https://be-spoke.io/* // @match https://www.be-spoke.io/* // @match https://mondly.com/* // @match https://www.mondly.com/* // @match https://memrise.com/* // @match https://www.memrise.com/* // @match https://airfriend.chat/* // @match https://kyotogram.com/* // @match https://tabiko.ai/* // @match https://nikkei.com/* // @match https://www.nikkei.com/* // @match https://asknikei.com/* // @match https://accio.alibaba.com/* // @match https://www.accio.alibaba.com/* // @match https://qwen.alibaba.com/* // @match https://tongyi.aliyun.com/qwen/* // @match https://wenku.baidu.com/* // @match https://yiyan.baidu.com/welcome/* // @match https://iflytek.com/* // @match https://www.iflytek.com/* // @match https://xinghuo.xfyun.cn/desk/* // @match https://spark.iflytek.com/* // @match https://www.spark.iflytek.com/* // @match https://ying.zhipu.ai/* // @match https://www.ying.zhipu.ai/* // @match https://kimi.ai/* // @match https://chat.kimi.ai/* // @match https://kimi.moonshot.ai/* // @match https://sensetime.com/* // @match https://www.sensetime.com/* // @match https://sensechat.sensetime.com/* // @match https://viva.sensetime.com/* // @match https://step.ai/* // @match https://www.step.ai/* // @match https://stepchat.com/* // @match https://www.stepchat.com/* // @match https://stepfun.ai/* // @match https://ai.01.ai/* // @match https://zuoyebang.com/* // @match https://www.zuoyebang.com/* // @match https://manus.app/* // @match https://app.manus.im/* // @match https://butterflymx.com/* // @match https://www.butterflymx.com/* // @match https://infomaniak.com/* // @match https://www.infomaniak.com/* // @match https://freshchat.com/* // @match https://www.freshchat.com/* // @match https://freshworks.com/* // @match https://acquire.io/* // @match https://www.acquire.io/* // @match https://botsify.com/* // @match https://www.botsify.com/* // @match https://octane.ai/* // @match https://www.octane.ai/* // @match https://chatfuel.com/* // @match https://www.chatfuel.com/* // @match https://manychat.com/* // @match https://www.manychat.com/* // @match https://wotnot.io/* // @match https://www.wotnot.io/* // @match https://landbot.io/* // @match https://www.landbot.io/* // @match https://kore.ai/* // @match https://bots.kore.ai/* // @match https://yourgpt.ai/* // @match https://www.yourgpt.ai/* // @match https://botpress.com/* // @match https://www.botpress.com/* // @match https://rasa.com/* // @match https://www.rasa.com/* // @match https://instadesk.com/* // @match https://www.instadesk.com/* // @match https://genspark.ai/* // @match https://www.genspark.ai/* // @match https://snapchat.com/* // @match https://www.snapchat.com/* // @match https://myai.snapchat.com/* // @match https://telegram.org/* // @match https://www.telegram.org/* // @match https://web.telegram.org/* // @match https://discord.com/* // @match https://www.discord.com/* // @match https://slack.com/* // @match https://www.slack.com/* // @match https://teams.microsoft.com/* // @match https://www.teams.microsoft.com/* // @match https://skype.com/* // @match https://www.skype.com/* // @match https://voiceflow.com/* // @match https://www.voiceflow.com/* // @match https://dialogflow.cloud.google.com/* // @match https://dialogflow.com/* // @match https://amazon.com/alexa/* // @match https://developer.amazon.com/alexa/* // @match https://alexa.amazon.com/* // @match https://www.amazon.com/alexa/* // @match https://siri.apple.com/* // @match https://www.apple.com/siri/* // @match https://bixby.samsung.com/* // @match https://www.samsung.com/bixby/* // @match https://assistant.google.com/* // @match https://www.assistant.google.com/* // @match https://hunyuan.tencent.com/bot/* // @match https://openai.com/* // @match https://www.openai.com/* // @match https://platform.openai.com/* // @match https://api.openai.com/* // @match https://playground.openai.com/* // @match https://beta.openai.com/* // @match https://labs.openai.com/* // @match https://chat.openai.com/* // @match https://runwayml.com/* // @match https://www.runwayml.com/* // @match https://midjourney.com/* // @match https://www.midjourney.com/* // @match https://stability.ai/* // @match https://www.stability.ai/* // @match https://stablediffusionweb.com/* // @match https://dreamstudio.ai/* // @match https://www.dreamstudio.ai/* // @match https://elevenlabs.io/* // @match https://www.elevenlabs.io/* // @match https://synthesia.io/* // @match https://www.synthesia.io/* // @match https://heygen.com/* // @match https://www.heygen.com/* // @match https://app.heygen.com/* // @match https://d-id.com/* // @match https://www.d-id.com/* // @match https://studio.d-id.com/* // @match https://playground.ai/* // @match https://www.playground.ai/* // @match https://lexica.art/* // @match https://www.lexica.art/* // @match https://craiyon.com/* // @match https://www.craiyon.com/* // @match https://deepai.org/* // @match https://www.deepai.org/* // @match https://writesonic.com/* // @match https://www.writesonic.com/* // @match https://copy.ai/* // @match https://www.copy.ai/* // @match https://rytr.me/* // @match https://www.rytr.me/* // @match https://notion.so/product/ai/* // @match https://www.notion.so/product/ai/* // @match https://notion.ai/* // @match https://quillbot.com/* // @match https://www.quillbot.com/* // @match https://grammarly.com/* // @match https://www.grammarly.com/* // @match https://app.grammarly.com/* // @match https://wordtune.com/* // @match https://www.wordtune.com/* // @match https://app.wordtune.com/* // @match https://otter.ai/* // @match https://www.otter.ai/* // @match https://fireflies.ai/* // @match https://www.fireflies.ai/* // @match https://gamma.app/* // @match https://www.gamma.app/* // @match https://beautiful.ai/* // @match https://www.beautiful.ai/* // @match https://tome.app/* // @match https://www.tome.app/* // @match https://magicstudio.com/* // @match https://www.magicstudio.com/* // @match https://remove.bg/* // @match https://www.remove.bg/* // @match https://cleanup.pictures/* // @match https://www.cleanup.pictures/* // @match https://lensa-ai.com/* // @match https://www.lensa-ai.com/* // @match https://prisma-ai.com/* // @match https://www.prisma-ai.com/* // @match https://hotpot.ai/* // @match https://www.hotpot.ai/* // @match https://artbreeder.com/* // @match https://www.artbreeder.com/* // @match https://deepdream.com/* // @match https://www.deepdream.com/* // @match https://nvidia.com/ai/* // @match https://www.nvidia.com/ai/* // @match https://ai.nvidia.com/* // @match https://ngc.nvidia.com/* // @match https://developer.nvidia.com/* // @match https://picsi.ai/* // @match https://www.picsi.ai/* // @match https://leonardo.ai/* // @match https://www.leonardo.ai/* // @match https://app.leonardo.ai/* // @match https://getimg.ai/* // @match https://www.getimg.ai/* // @match https://bluewillow.ai/* // @match https://www.bluewillow.ai/* // @match https://canva.com/* // @match https://www.canva.com/* // @match https://adobe.com/sensei/* // @match https://www.adobe.com/sensei/* // @match https://firefly.adobe.com/* // @match https://beta.dreamstudio.ai/* // @match https://app.runwayml.com/* // @match https://app.midjourney.com/* // @match https://www.bing.com/chat/* // @match https://bing.com/chat/* // @match https://bing.com/create/* // @match https://www.bing.com/create/* // @match https://microsoft.com/ai/* // @match https://www.microsoft.com/ai/* // @match https://azure.microsoft.com/ai/* // @match https://azure.com/* // @match https://www.azure.com/* // @match https://github.com/features/copilot/* // @match https://copilot.github.com/* // @match https://github.com/copilot/* // @match https://codeium.com/* // @match https://www.codeium.com/* // @match https://tabnine.com/* // @match https://www.tabnine.com/* // @match https://replit.com/* // @match https://www.replit.com/* // @match https://replit.com/ai/* // @match https://aws.amazon.com/bedrock/* // @match https://aws.amazon.com/codewhisperer/* // @match https://codewhisperer.aws/* // @match https://aws.amazon.com/ai/* // @match https://console.aws.amazon.com/* // @match https://aimlapi.com/* // @match https://www.aimlapi.com/* // @match https://writecream.com/* // @match https://www.writecream.com/* // @match https://simplified.com/* // @match https://www.simplified.com/* // @match https://app.simplified.com/* // @match https://fliki.ai/* // @match https://www.fliki.ai/* // @match https://murf.ai/* // @match https://www.murf.ai/* // @match https://play.ht/* // @match https://www.play.ht/* // @match https://resemble.ai/* // @match https://www.resemble.ai/* // @match https://descript.com/* // @match https://www.descript.com/* // @match https://soundraw.io/* // @match https://www.soundraw.io/* // @match https://aiva.ai/* // @match https://www.aiva.ai/* // @match https://boomy.com/* // @match https://www.boomy.com/* // @match https://beatoven.ai/* // @match https://www.beatoven.ai/* // @match https://soundful.com/* // @match https://www.soundful.com/* // @match https://suno.ai/* // @match https://www.suno.ai/* // @match https://app.suno.ai/* // @match https://udio.com/* // @match https://www.udio.com/* // @run-at document-start // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_registerMenuCommand // @grant GM_addStyle // @updateURL // @downloadURL https://update.greasyfork.icu/scripts/572148/AI%20TRANSLATION%20OF%20Auto%20F2%20CleanCookie%20%E2%80%94%20AI%20FREE%21%20Claude%20Opus%2046%20%7C%20Beginner%20Friendly%20%7C%202-Min%20Setup.user.js // @updateURL https://update.greasyfork.icu/scripts/572148/AI%20TRANSLATION%20OF%20Auto%20F2%20CleanCookie%20%E2%80%94%20AI%20FREE%21%20Claude%20Opus%2046%20%7C%20Beginner%20Friendly%20%7C%202-Min%20Setup.meta.js // ==/UserScript== (function () { 'use strict'; // ═══════════════════════════════════════════════════════════════ // §0 Module Toggle System // ═══════════════════════════════════════════════════════════════ const MODULE_KEYS = { reset: 'module_session_reset', splitter:'module_text_splitter', preset: 'module_model_preset', }; const MODULE_LABELS = { reset: '🗑️ Session Reset (F2 Clean)', splitter:'✂️ Auto Splitter Lite', preset: '⚡ Model Preset Pro', }; function isModuleEnabled(key) { return GM_getValue(MODULE_KEYS[key], true); } function toggleModule(key) { const current = isModuleEnabled(key); GM_setValue(MODULE_KEYS[key], !current); const state = !current ? '✅ Enabled' : '❌ Disabled'; if (typeof alert !== 'undefined') { alert(`${MODULE_LABELS[key]}\n${state}\n\nPlease refresh the page to apply changes.`); } } // Register toggles in Tampermonkey / Greasemonkey menu for (const key of Object.keys(MODULE_KEYS)) { const enabled = isModuleEnabled(key); const prefix = enabled ? '✅' : '❌'; GM_registerMenuCommand( `${prefix} ${MODULE_LABELS[key]}`, () => toggleModule(key), key.charAt(0) ); } // ═══════════════════════════════════════════════════════════════ // §1 Session Reset Module // ═══════════════════════════════════════════════════════════════ if (isModuleEnabled('reset')) { (function initSessionReset() { const CONFIG = { BTN_ID: 'lm-rst', REDIRECT_URL: 'https://arena.ai/text/side-by-side', WHITELIST: ['lmarena.ai', 'arena.ai'], RECAPTCHA_SITEKEY: '6Led_uYrAAAAAKjxDIF58fgFtX3t8loNAK85bW9I', TURNSTILE_SITEKEY: '0x4AAAAAAA65vWDmG-O_lPtT', CF_PATTERNS: [ 'challenges.cloudflare.com', 'static.cloudflareinsights.com', 'cdn-cgi/challenge-platform', 'turnstile/v0/api.js', ], RECAPTCHA_PATTERNS: [ 'google.com/recaptcha', 'gstatic.com/recaptcha', 'recaptcha/enterprise', ], SECURITY_COOKIE_PATTERNS: [ 'cf_clearance', '__cf_bm', '_cf_', 'cf-', '__cflb', '__cfuid', 'cf_ob_info', 'cf_use_ob', '_ga', '_gid', '_gat', 'ph_', 'arena-auth', ], POPUP_CHECK_INTERVAL: 500, POPUP_TIMEOUT: 30000, DEBUG: true, }; const host = location.hostname.replace(/^www\./, ''); const isHome = CONFIG.WHITELIST.some(d => host === d || host.endsWith('.' + d)); const log = { _prefix: '[ArenaReset]', _styles: { info: 'color: #2196F3; font-weight: bold;', success: 'color: #4CAF50; font-weight: bold;', warn: 'color: #FF9800; font-weight: bold;', error: 'color: #F44336; font-weight: bold;', security: 'color: #E91E63; font-weight: bold;', }, info: (...a) => CONFIG.DEBUG && console.log(`%c${log._prefix} ℹ️`, log._styles.info, ...a), success: (...a) => CONFIG.DEBUG && console.log(`%c${log._prefix} ✅`, log._styles.success, ...a), warn: (...a) => CONFIG.DEBUG && console.warn(`%c${log._prefix} ⚠️`, log._styles.warn, ...a), error: (...a) => console.error(`%c${log._prefix} ❌`, log._styles.error, ...a), security: (...a) => CONFIG.DEBUG && console.log(`%c${log._prefix} 🛡️`, log._styles.security, ...a), }; const S = Object.freeze({ IDLE: { t: '🗑️ (F2) <<<<<<<🐥💙', d: false, c: '#E48900' }, SCANNING: { t: '🔍 Scanning...', d: true, c: '#2196F3' }, WORKING: { t: '⏳ Clearing...', d: true, c: '#FF9800' }, BYPASSING: { t: '🛡️ Bypassing...', d: true, c: '#9C27B0' }, SUCCESS: { t: '✅ Cleared! Redirecting...', d: true, c: '#4CAF50' }, FAILURE: { t: '❌ Failed, press F2 again', d: false, c: '#F44336' }, }); // Anti-fingerprinting try { Object.defineProperty(navigator, 'webdriver', { get: () => false, configurable: true, }); log.info('navigator.webdriver overridden to false'); } catch (e) { log.warn('Failed to override navigator.webdriver:', e.message); } // Network request monitor const securityRequestLog = []; const originalFetch = window.fetch; window.fetch = async function (...args) { const url = typeof args[0] === 'string' ? args[0] : args[0]?.url || ''; const isSecurityReq = CONFIG.CF_PATTERNS.some(p => url.includes(p)) || CONFIG.RECAPTCHA_PATTERNS.some(p => url.includes(p)) || url.includes('siteverify') || url.includes('challenge'); if (isSecurityReq) { const entry = { time: new Date().toISOString(), type: 'fetch', url: url.substring(0, 200), method: args[1]?.method || 'GET', }; securityRequestLog.push(entry); log.security('Intercepted FETCH:', entry.method, url.substring(0, 120)); } try { const response = await originalFetch.apply(this, args); if (isSecurityReq) { const clone = response.clone(); try { const text = await clone.text(); log.security('FETCH response:', response.status, text.substring(0, 200)); } catch (_) {} } return response; } catch (err) { if (isSecurityReq) log.error('FETCH failed:', url.substring(0, 80), err.message); throw err; } }; // Styles function injectResetStyles() { const sheet = new CSSStyleSheet(); sheet.replaceSync(` #${CONFIG.BTN_ID} { position: fixed; top: 10px; right: 10px; z-index: 2147483647; padding: 10px 18px; background: linear-gradient(135deg, #E48900, #ff6b00); color: #fff; border: none; border-radius: 10px; cursor: pointer; font: bold 13px/1.2 system-ui, -apple-system, sans-serif; box-shadow: 0 4px 15px rgba(228,137,0,.4); transition: all .2s ease; user-select: none; backdrop-filter: blur(10px); } #${CONFIG.BTN_ID}:hover:not(:disabled) { transform: scale(1.05) translateY(-1px); box-shadow: 0 6px 25px rgba(228,137,0,.6); } #${CONFIG.BTN_ID}:active:not(:disabled) { transform: scale(.97); } #${CONFIG.BTN_ID}:disabled { opacity: .55; cursor: wait; } .lm-rst-status { position: fixed; top: 50px; right: 10px; z-index: 2147483646; padding: 8px 14px; background: rgba(0,0,0,.85); color: #fff; border-radius: 8px; font: 11px/1.4 monospace; max-width: 350px; max-height: 300px; overflow-y: auto; pointer-events: none; opacity: 0; transition: opacity .3s; backdrop-filter: blur(10px); } .lm-rst-status.visible { opacity: 1; pointer-events: auto; } .lm-rst-status .entry { margin: 2px 0; } .lm-rst-status .entry.ok { color: #4CAF50; } .lm-rst-status .entry.warn { color: #FF9800; } .lm-rst-status .entry.err { color: #F44336; } .lm-rst-status .entry.sec { color: #E91E63; } `); document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]; } let statusPanel = null; function createStatusPanel() { statusPanel = document.createElement('div'); statusPanel.className = 'lm-rst-status'; document.body.appendChild(statusPanel); return statusPanel; } function addStatus(text, type = 'ok') { if (!statusPanel) createStatusPanel(); const div = document.createElement('div'); div.className = `entry ${type}`; div.textContent = `${new Date().toLocaleTimeString()} ${text}`; statusPanel.appendChild(div); statusPanel.scrollTop = statusPanel.scrollHeight; statusPanel.classList.add('visible'); } function hideStatusPanel(delay = 3000) { setTimeout(() => { if (statusPanel) statusPanel.classList.remove('visible'); }, delay); } // Cookie cleanup function clearAllCookies() { const hostname = location.hostname; const expiry = '=;expires=Thu, 01 Jan 1970 00:00:00 GMT'; const paths = ['/', '/text', '/search', '/image', '/video', '/code']; const domains = ['', hostname, '.' + hostname]; const parts = hostname.split('.'); for (let i = 1; i < parts.length; i++) { const parent = parts.slice(i).join('.'); domains.push(parent, '.' + parent); } let cleared = 0; const cookieList = document.cookie.split(';'); for (const pair of cookieList) { const name = pair.split('=', 1)[0].trim(); if (!name) continue; for (const path of paths) { for (const domain of domains) { const domainStr = domain ? `;domain=${domain}` : ''; const base = `${name}${expiry};path=${path}${domainStr}`; document.cookie = base; document.cookie = `${base};Secure`; document.cookie = `${base};SameSite=None;Secure`; document.cookie = `${base};SameSite=Lax`; document.cookie = `${base};SameSite=Strict`; } } cleared++; } const securityCookies = [ 'cf_clearance', '__cf_bm', '_cfuvid', '__cflb', 'arena-auth-prod-v1', '_ga', '_ga_L5C4D55WJJ', '_ga_DB32ZN1WHB', '_gid', 'ph_phc_LG7IJbVJqBsk584rbcKca0D5lV2vHguiijDrVji7yDM_posthog', 'user_country_code', 'sidebar_state', ]; for (const name of securityCookies) { for (const path of paths) { for (const domain of domains) { const domainStr = domain ? `;domain=${domain}` : ''; document.cookie = `${name}${expiry};path=${path}${domainStr}`; document.cookie = `${name}${expiry};path=${path}${domainStr};Secure`; document.cookie = `${name}${expiry};path=${path}${domainStr};SameSite=None;Secure`; } } } log.info(`Attempted to clear ${cleared} Cookies + ${securityCookies.length} known security Cookies`); addStatus(`Cleared ${cleared} Cookies + ${securityCookies.length} Security Cookies`, 'ok'); return cleared; } function clearStorage() { let lsCount = 0, ssCount = 0; try { lsCount = localStorage.length; localStorage.clear(); } catch (e) { log.warn('localStorage clear failed:', e.message); } try { ssCount = sessionStorage.length; sessionStorage.clear(); } catch (e) { log.warn('sessionStorage clear failed:', e.message); } addStatus(`Cleared localStorage(${lsCount}) + sessionStorage(${ssCount})`, 'ok'); return lsCount + ssCount; } async function clearIDB() { if (typeof indexedDB?.databases !== 'function') { addStatus('IndexedDB.databases() unavailable', 'warn'); return 0; } try { const dbs = await indexedDB.databases(); await Promise.allSettled(dbs.map(db => new Promise((resolve, reject) => { const req = indexedDB.deleteDatabase(db.name); req.onsuccess = resolve; req.onerror = () => reject(req.error); req.onblocked = resolve; }))); addStatus(`Cleared ${dbs.length} IndexedDB databases`, 'ok'); return dbs.length; } catch (e) { log.error('IndexedDB clear exception:', e); addStatus('IndexedDB clear failed', 'err'); return 0; } } async function clearCaches() { if (!('caches' in self)) { addStatus('Cache API unavailable', 'warn'); return 0; } try { const keys = await caches.keys(); await Promise.all(keys.map(k => caches.delete(k))); addStatus(`Cleared ${keys.length} Cache Storage items`, 'ok'); return keys.length; } catch (e) { addStatus('Cache Storage clear failed', 'err'); return 0; } } async function unregisterServiceWorkers() { if (!('serviceWorker' in navigator)) { addStatus('Service Worker API unavailable', 'warn'); return 0; } try { const registrations = await navigator.serviceWorker.getRegistrations(); await Promise.all(registrations.map(r => r.unregister())); addStatus(`Unregistered ${registrations.length} Service Workers`, 'ok'); return registrations.length; } catch (e) { addStatus('Service Worker unregistration failed', 'warn'); return 0; } } function resetTurnstile() { try { if (window.turnstile) { document.querySelectorAll('[class*="turnstile"], [id*="turnstile"], [data-sitekey*="0x"]') .forEach(el => { try { window.turnstile.remove(el); } catch (_) {} }); try { window.turnstile.reset(); } catch (_) {} addStatus('Turnstile state reset', 'sec'); return true; } } catch (e) { log.warn('Turnstile reset exception:', e.message); } addStatus('Turnstile not loaded or reset failed', 'warn'); return false; } function resetRecaptcha() { try { if (window.grecaptcha?.enterprise) { try { window.grecaptcha.enterprise.reset(); } catch (_) {} try { if (window.___grecaptcha_cfg?.clients) { Object.keys(window.___grecaptcha_cfg.clients).forEach(key => { delete window.___grecaptcha_cfg.clients[key]; }); window.___grecaptcha_cfg.count = 0; } } catch (_) {} addStatus('reCAPTCHA Enterprise reset', 'sec'); return true; } } catch (e) { log.warn('reCAPTCHA reset exception:', e.message); } addStatus('reCAPTCHA not loaded or reset failed', 'warn'); return false; } function cleanSecurityIframes() { let removed = 0; document.querySelectorAll('iframe').forEach(iframe => { const src = iframe.src || ''; if (src.includes('cloudflare') || src.includes('turnstile') || src.includes('challenges') || src.includes('recaptcha') || src.includes('cdn-cgi')) { iframe.remove(); removed++; } }); if (removed > 0) addStatus(`Removed ${removed} security iframes`, 'sec'); return removed; } function clearCFBeaconData() { ['__cfBeacon', '__cfRay', '__cf_', '_cf_'].forEach(key => { if (window[key] !== undefined) { try { delete window[key]; } catch (_) { try { window[key] = undefined; } catch (__) {} } } }); Object.keys(window).forEach(key => { const lk = key.toLowerCase(); if ((lk.startsWith('cf') || lk.startsWith('__cf') || lk.startsWith('_cf')) && !['chrome','confirm','close','cleartimeout','clearinterval','constructor','console','customelements'] .some(safe => lk.startsWith(safe))) { try { delete window[key]; } catch (_) {} } }); addStatus('CF Beacon tracking data cleared', 'sec'); } function clearPostHog() { Object.keys(window).filter(k => k.includes('posthog') || k.includes('ph_')).forEach(key => { try { if (window[key]?.reset) window[key].reset(); delete window[key]; } catch (_) {} }); try { const keysToRemove = []; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if (key && (key.includes('posthog') || key.includes('ph_'))) keysToRemove.push(key); } keysToRemove.forEach(k => localStorage.removeItem(k)); if (keysToRemove.length > 0) addStatus(`Cleared ${keysToRemove.length} PostHog items`, 'ok'); } catch (_) {} } function autoHandleSecurityPopups() { const handleAttempt = () => { let handled = 0; const cookieSelectors = [ '//div[@role="dialog"]//button[contains(.,"Accept")]', '//div[@role="dialog"]//button[contains(.,"Agree")]', '//div[@role="dialog"]//button[contains(.,"OK")]', ]; for (const xpath of cookieSelectors) { try { const node = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; if (node && node.offsetParent !== null) { node.click(); handled++; break; } } catch (_) {} } const bannerBtn = document.querySelector('button[aria-label="Dismiss banner"]'); if (bannerBtn && bannerBtn.offsetParent !== null) { bannerBtn.click(); handled++; } document.querySelectorAll('[role="dialog"], [class*="modal"], [class*="overlay"], [class*="popup"]').forEach(dialog => { const text = dialog.textContent || ''; if (text.includes('Security Verification') || text.includes('security check') || text.includes('Protected by reCAPTCHA')) { log.security('Detected security verification popup'); addStatus('Detected security verification popup', 'sec'); const recapInDialog = dialog.querySelector('.grecaptcha-badge, [data-sitekey]'); if (recapInDialog && window.grecaptcha?.enterprise?.execute) { try { window.grecaptcha.enterprise.execute(CONFIG.RECAPTCHA_SITEKEY, { action: 'submit' }) .then(token => { addStatus('reCAPTCHA token acquired', 'sec'); }) .catch(() => { addStatus('reCAPTCHA execute failed', 'err'); }); } catch (e) {} } const turnstileInDialog = dialog.querySelector('[class*="turnstile"]'); if (turnstileInDialog && window.turnstile?.execute) { try { window.turnstile.execute(turnstileInDialog); } catch (e) {} } handled++; } }); return handled; }; handleAttempt(); let attempts = 0; const maxAttempts = CONFIG.POPUP_TIMEOUT / CONFIG.POPUP_CHECK_INTERVAL; const interval = setInterval(() => { attempts++; if (handleAttempt() > 0 || attempts >= maxAttempts) clearInterval(interval); }, CONFIG.POPUP_CHECK_INTERVAL); const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (node.nodeType !== 1) continue; const html = node.outerHTML || ''; if (html.includes('Security Verification') || html.includes('captcha') || (node.tagName === 'IFRAME' && ((node.src || '').includes('turnstile') || (node.src || '').includes('recaptcha') || (node.src || '').includes('cloudflare')))) { setTimeout(handleAttempt, 200); } } } }); const startObserver = () => { if (document.body) observer.observe(document.body, { childList: true, subtree: true }); }; if (document.body) startObserver(); else document.addEventListener('DOMContentLoaded', startObserver, { once: true }); setTimeout(() => { observer.disconnect(); clearInterval(interval); }, CONFIG.POPUP_TIMEOUT); } function interceptTurnstileCallback() { const originalCallback = window.onloadTurnstileCallback; window.onloadTurnstileCallback = function (...args) { log.security('Turnstile onload callback triggered!'); addStatus('Turnstile API loaded', 'sec'); if (typeof originalCallback === 'function') return originalCallback.apply(this, args); }; } interceptTurnstileCallback(); function scanProtectionStatus() { return { turnstile: { loaded: !!window.turnstile, widgetCount: document.querySelectorAll('[class*="turnstile"]').length, }, recaptcha: { loaded: !!window.grecaptcha, isEnterprise: !!window.grecaptcha?.enterprise, }, cloudflare: { cfClearance: document.cookie.includes('cf_clearance'), cfBm: document.cookie.includes('__cf_bm'), }, networkLog: securityRequestLog.slice(-10), }; } let resetting = false; let btn = null; function applyState(state) { if (!btn) return; btn.textContent = state.t; btn.disabled = state.d; btn.style.background = `linear-gradient(135deg, ${state.c}, ${state.c}dd)`; } function sleepReset(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function resetSession() { if (resetting) return; resetting = true; if (statusPanel) statusPanel.innerHTML = ''; log.info('═══ Session Reset Started ═══'); addStatus('Session reset started...', 'ok'); applyState(S.SCANNING); const protectionStatus = scanProtectionStatus(); addStatus(`Found: Turnstile=${protectionStatus.turnstile.loaded}, reCAPTCHA=${protectionStatus.recaptcha.loaded}`, 'sec'); await sleepReset(300); applyState(S.WORKING); try { addStatus('── Clearing Security States ──', 'sec'); resetTurnstile(); resetRecaptcha(); cleanSecurityIframes(); clearCFBeaconData(); clearPostHog(); await sleepReset(200); addStatus('── Clearing Storage ──', 'ok'); clearStorage(); addStatus('── Clearing Cookies ──', 'ok'); clearAllCookies(); addStatus('── Clearing IndexedDB and Caches ──', 'ok'); await Promise.allSettled([clearIDB(), clearCaches(), unregisterServiceWorkers()]); await sleepReset(200); applyState(S.BYPASSING); const remainingCookies = document.cookie.split(';').filter(c => c.trim()).length; addStatus(`${remainingCookies} Cookies remaining after first clear`, remainingCookies > 0 ? 'warn' : 'ok'); if (remainingCookies > 0) { clearAllCookies(); const finalCookies = document.cookie.split(';').filter(c => c.trim()).length; addStatus(`${finalCookies} Cookies remaining after second clear`, finalCookies > 0 ? 'warn' : 'ok'); } applyState(S.SUCCESS); addStatus('Session reset complete!', 'ok'); log.success('═══ Session Reset Complete ═══'); if (isHome) { addStatus(`Redirecting to: ${CONFIG.REDIRECT_URL}`, 'ok'); setTimeout(() => { location.href = CONFIG.REDIRECT_URL; }, 800); } else { addStatus('Refreshing page...', 'ok'); setTimeout(() => { location.reload(); }, 1000); } hideStatusPanel(5000); } catch (e) { log.error('Session reset exception:', e); applyState(S.FAILURE); addStatus(`Error: ${e.message}`, 'err'); resetting = false; } } // Hotkeys document.addEventListener('keydown', (e) => { if ((e.key === 'F2' || e.keyCode === 113) && !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) { e.preventDefault(); e.stopPropagation(); resetSession(); } if ((e.key === 'F4' || e.keyCode === 115) && !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) { e.preventDefault(); if (statusPanel) statusPanel.classList.toggle('visible'); } if ((e.key === 'F6' || e.keyCode === 117) && !e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey) { e.preventDefault(); console.log('%c📊 Current Protection Status', 'color: #673AB7; font-size: 14px; font-weight: bold;'); console.log(JSON.stringify(scanProtectionStatus(), null, 2)); } }, { capture: true }); function initReset() { if (document.getElementById(CONFIG.BTN_ID)) return; injectResetStyles(); btn = document.createElement('button'); btn.id = CONFIG.BTN_ID; applyState(S.IDLE); btn.addEventListener('click', resetSession); document.body.appendChild(btn); createStatusPanel(); autoHandleSecurityPopups(); scanProtectionStatus(); log.success('Arena Reset Initialized'); } if (document.body) initReset(); else document.addEventListener('DOMContentLoaded', initReset, { once: true }); window.__arenaReset = { scan: scanProtectionStatus, reset: resetSession, clearCookies: clearAllCookies, clearStorage, clearIDB, clearCaches, resetTurnstile, resetRecaptcha, cleanIframes: cleanSecurityIframes, getSecurityLog: () => securityRequestLog, config: CONFIG, }; })(); } // end reset module // ═══════════════════════════════════════════════════════════════ // §2 Auto Splitter Lite Module // ═══════════════════════════════════════════════════════════════ if (isModuleEnabled('splitter')) { // Needs to execute at document-idle equivalent timing const initSplitter = () => { const CHUNK_SIZE = 120000; const POLL_MS = 500; const AUTO_SPLIT_DEBOUNCE = 350; const FINAL_OK_TEXT = 'OK'; const WAIT_PREFIX = `Below is the content I am providing (Part {{CURRENT}} of {{TOTAL}}). Please read it completely and hold it in memory. Do not reply or analyze it yet. Wait until I say 'OK', and then follow my instructions for the full content. --- `; const WAIT_SUFFIX = ` --- Above is Part {{CURRENT}} of the data (Total: {{TOTAL}} parts). Please remember this. Do not output anything yet. Wait for my 'OK' before replying.`; const state = { chunks: [], finals: [], sent: [], sending: false, abort: false, }; let autoSplitTimer = 0; const $s = (sel, root = document) => root.querySelector(sel); const $$s = (sel, root = document) => [...root.querySelectorAll(sel)]; const sleepS = ms => new Promise(r => setTimeout(r, ms)); const tpl = (s, current, total) => s.replace(/\{\{CURRENT\}\}/g, current).replace(/\{\{TOTAL\}\}/g, total); const escapeHtml = s => { const d = document.createElement('div'); d.textContent = s; return d.innerHTML; }; const visible = el => { if (!el || !el.isConnected) return false; const st = getComputedStyle(el); const rect = el.getBoundingClientRect(); return st.display !== 'none' && st.visibility !== 'hidden' && rect.width > 0 && rect.height > 0; }; const insidePanel = el => !!el?.closest('#aa-lite-panel'); const textOf = el => [el?.textContent || '', el?.getAttribute?.('aria-label') || '', el?.getAttribute?.('title') || '', el?.id || '', el?.className || ''] .join(' ').toLowerCase(); const hasWord = (text, words) => words.some(w => text.includes(w)); const SEND_WORDS = ['send', 'submit', '發送', '发送', '送出', '傳送']; const STOP_WORDS = ['stop', '停止', '中止', 'stop generating']; GM_addStyle(` #aa-lite-toggle{ position:fixed;right:20px;bottom:20px;z-index:999999; width:52px;height:52px;border:none;border-radius:50%; background:#5b6cff;color:#fff;font-size:22px;cursor:pointer; box-shadow:0 6px 18px rgba(0,0,0,.25); } #aa-lite-panel{ position:fixed;right:20px;bottom:84px;z-index:999998; width:420px;max-height:80vh;display:flex;flex-direction:column; background:#111827;color:#e5e7eb;border:1px solid #374151;border-radius:14px; overflow:hidden;box-shadow:0 12px 30px rgba(0,0,0,.35); font:13px/1.5 system-ui,-apple-system,Segoe UI,Microsoft JhengHei,sans-serif; } #aa-lite-panel.hide{display:none} #aa-lite-head{ display:flex;align-items:center;justify-content:space-between; padding:12px 14px;background:#1f2937;font-weight:700; } #aa-lite-head button{background:none;border:none;color:#9ca3af;cursor:pointer;font-size:18px} #aa-lite-body{padding:12px;display:flex;flex-direction:column;gap:10px;overflow:auto} #aa-lite-text{ width:100%;min-height:120px;max-height:260px;resize:vertical; background:#0b1220;color:#e5e7eb;border:1px solid #374151;border-radius:10px; padding:10px;box-sizing:border-box;outline:none; } .aa-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap} .aa-row input[type="number"],.aa-row select{ background:#0b1220;color:#e5e7eb;border:1px solid #374151;border-radius:8px;padding:6px 8px; } .aa-row label{display:flex;align-items:center;gap:6px;color:#d1d5db} .aa-btns{display:flex;gap:8px;flex-wrap:wrap} .aa-btns button{flex:1;padding:8px 10px;border:none;border-radius:8px;cursor:pointer;font-weight:600} .aa-warn{background:#f59e0b;color:#111827} .aa-good{background:#10b981;color:#fff} .aa-bad{background:#ef4444;color:#fff} #aa-lite-status{padding:8px 10px;border-radius:8px;background:#0b1220;color:#93c5fd;white-space:pre-wrap} #aa-lite-stats{font-size:12px;color:#9ca3af} #aa-lite-list{display:flex;flex-direction:column;gap:8px} .aa-item{border:1px solid #374151;border-radius:10px;background:#0b1220;overflow:hidden} .aa-item.sent{border-color:#10b981} .aa-item-head{display:flex;justify-content:space-between;gap:8px;padding:8px 10px;background:#111827;align-items:center} .aa-item-meta{font-size:12px;color:#9ca3af} .aa-item-actions{display:flex;gap:6px} .aa-item-actions button{border:1px solid #374151;background:#1f2937;color:#e5e7eb;border-radius:6px;padding:4px 8px;cursor:pointer;font-size:12px} .aa-item pre{margin:0;padding:10px;max-height:140px;overflow:auto;white-space:pre-wrap;word-break:break-all;color:#d1d5db;font-size:12px} .aa-empty{text-align:center;color:#6b7280;padding:18px 8px;border:1px dashed #374151;border-radius:10px} `); document.body.insertAdjacentHTML('beforeend', `
📋 Splitter Lite
Standby
`); const ui = { toggle: $s('#aa-lite-toggle'), panel: $s('#aa-lite-panel'), close: $s('#aa-lite-close'), text: $s('#aa-lite-text'), wait: $s('#aa-wait'), mode: $s('#aa-mode'), finalOk:$s('#aa-final-ok'), gap: $s('#aa-gap'), send: $s('#aa-send'), copy: $s('#aa-copy'), clear: $s('#aa-clear'), status: $s('#aa-lite-status'), stats: $s('#aa-lite-stats'), list: $s('#aa-lite-list'), }; function setStatus(msg) { ui.status.textContent = msg; } function setBusyControls(busy) { [ui.text, ui.wait, ui.mode, ui.finalOk, ui.gap].forEach(el => { if (el) el.disabled = busy; }); } function normalizeText(text) { return (text || '').replace(/\r\n?/g, '\n').trim(); } function needWrap(i) { if (!ui.wait.checked) return false; return ui.mode.value === 'all' || i === 0; } function prefix(i, total) { return tpl(WAIT_PREFIX, i + 1, total); } function suffix(i, total) { return tpl(WAIT_SUFFIX, i + 1, total); } function maxContentSize(i, total) { if (!needWrap(i)) return CHUNK_SIZE; return Math.max(1000, CHUNK_SIZE - prefix(i, total).length - suffix(i, total).length); } function resetSegments() { state.chunks = []; state.finals = []; state.sent = []; } function buildChunksByLines(text, total) { const pieces = text.split('\n').map((line, idx) => idx === 0 ? line : '\n' + line); const chunks = []; let current = ''; for (const originalPiece of pieces) { let piece = originalPiece; while (piece.length) { const chunkIndex = chunks.length; const limit = maxContentSize(chunkIndex, total); if (!current) { if (piece.length <= limit) { current = piece; piece = ''; } else { chunks.push(piece.slice(0, limit)); piece = piece.slice(limit); } continue; } if (current.length + piece.length <= limit) { current += piece; piece = ''; } else { chunks.push(current); current = ''; } } } if (current) chunks.push(current); return chunks; } function splitText(raw) { const text = normalizeText(raw); if (!text) { resetSegments(); render(); return; } let total = 1, chunks = []; while (true) { chunks = buildChunksByLines(text, total); if (chunks.length === total) break; total = chunks.length; } state.chunks = chunks; state.finals = chunks.map((chunk, i) => needWrap(i) ? prefix(i, total) + chunk + suffix(i, total) : chunk ); state.sent = Array(state.finals.length).fill(false); render(); } function autoSplitNow(showStatus = true) { clearTimeout(autoSplitTimer); if (state.sending) return; if (!ui.text.value.trim()) { resetSegments(); render(); if (showStatus) setStatus('Standby'); return; } splitText(ui.text.value); if (showStatus) setStatus(`✂️ Auto-split into ${state.finals.length} parts`); } function scheduleAutoSplit() { clearTimeout(autoSplitTimer); autoSplitTimer = setTimeout(() => autoSplitNow(true), AUTO_SPLIT_DEBOUNCE); } function render() { const rawText = normalizeText(ui.text.value); const maxLen = state.finals.reduce((m, s) => Math.max(m, s.length), 0); ui.stats.textContent = state.finals.length ? `Original: ${rawText.length.toLocaleString()} chars | ${state.finals.length} Parts | Max Part: ${maxLen.toLocaleString()} / ${CHUNK_SIZE.toLocaleString()}` : ''; if (!state.finals.length) { ui.list.innerHTML = `
Not split yet
`; return; } ui.list.innerHTML = state.finals.map((chunk, i) => { const raw = state.chunks[i]; const wrapLen = chunk.length - raw.length; const preview = chunk.slice(0, 300) + (chunk.length > 300 ? '\n\n...' : ''); return `
📦 Part ${i + 1} ${needWrap(i) ? '⏳' : ''} ${state.sent[i] ? '✅' : ''}
${chunk.length.toLocaleString()} chars ${needWrap(i) ? `|Content ${raw.length.toLocaleString()} + Prompt ${wrapLen.toLocaleString()}` : ''}
${escapeHtml(preview)}
`; }).join(''); } function copyText(text) { navigator.clipboard.writeText(text).catch(() => { const ta = document.createElement('textarea'); ta.value = text; ta.style.cssText = 'position:fixed;opacity:0'; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); ta.remove(); }); } function pick(selectors, test = () => true) { for (const sel of selectors) { for (const el of $$s(sel)) { if (insidePanel(el) || !visible(el)) continue; if (test(el)) return el; } } return null; } function findInput() { return pick([ 'textarea', '[contenteditable="true"]', 'div[role="textbox"]', 'input[type="text"]' ], el => el.id !== 'aa-lite-text' && !el.closest('#aa-lite-panel')); } function findStopButton() { const direct = pick([ 'button[aria-label*="Stop"]', 'button[aria-label*="stop"]', 'button[aria-label*="停止"]', 'button[data-testid*="stop"]' ]); if (direct) return direct; return $$s('button').find(btn => !insidePanel(btn) && visible(btn) && hasWord(textOf(btn), STOP_WORDS)) || null; } function distanceToInput(btn, input) { if (!btn || !input) return Number.MAX_SAFE_INTEGER; const b = btn.getBoundingClientRect(), i = input.getBoundingClientRect(); return Math.abs(b.left - i.right) + Math.abs(b.top - i.top); } function findSendButton() { const direct = pick([ 'button[aria-label*="Send"]', 'button[aria-label*="send"]', 'button[aria-label*="發送"]', 'button[aria-label*="发送"]', 'button[data-testid*="send"]', 'button[type="submit"]' ], btn => !btn.disabled); if (direct) return direct; const input = findInput(); const cands = $$s('button').filter(btn => { if (insidePanel(btn) || !visible(btn) || btn.disabled) return false; const t = textOf(btn); return hasWord(t, SEND_WORDS) || btn.type === 'submit'; }); if (!cands.length) return null; if (!input) return cands[0]; return cands.sort((a, b) => distanceToInput(a, input) - distanceToInput(b, input))[0]; } function readInput(el) { if (!el) return ''; return 'value' in el ? el.value : (el.textContent || ''); } function dispatchInput(el) { el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); } function setInputVal(el, text) { if (!el) return false; el.focus(); if ('value' in el) { const proto = el.tagName === 'TEXTAREA' ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype; const setter = Object.getOwnPropertyDescriptor(proto, 'value')?.set; setter ? setter.call(el, text) : (el.value = text); dispatchInput(el); return true; } try { document.execCommand('selectAll', false, null); const ok = document.execCommand('insertText', false, text); if (!ok) el.textContent = text; } catch { el.textContent = text; } dispatchInput(el); return true; } function pressEnter(el) { if (!el) return; ['keydown', 'keypress', 'keyup'].forEach(type => { el.dispatchEvent(new KeyboardEvent(type, { key: 'Enter', code: 'Enter', keyCode: 13, which: 13, bubbles: true, cancelable: true })); }); } function canSendNow() { const input = findInput(); if (!input || input.disabled || input.readOnly || input.getAttribute('aria-disabled') === 'true') return false; if (findStopButton()) return false; const sendBtn = findSendButton(); return sendBtn ? !sendBtn.disabled : true; } async function waitUntilReady(index, total) { while (!state.abort) { if (canSendNow()) return true; setStatus(`⏳ Part ${index + 1}/${total} waiting: previous response is still generating`); await sleepS(POLL_MS); } return false; } async function confirmSent(snapshot, timeout = 8000) { const start = Date.now(); while (!state.abort && Date.now() - start < timeout) { const input = findInput(); const current = readInput(input); if (findStopButton()) return true; if (current !== snapshot && current.length < snapshot.length) return true; if (current === '') return true; const sendBtn = findSendButton(); if (sendBtn && sendBtn.disabled && snapshot.trim()) return true; await sleepS(150); } return false; } async function trySend(text) { const input = findInput(); if (!input) return false; setInputVal(input, text); await sleepS(250); const btn = findSendButton(); if (btn && !btn.disabled) { btn.click(); if (await confirmSent(text)) return true; } pressEnter(input); return await confirmSent(text); } async function sendOne(text, index, total) { while (!state.abort) { if (!(await waitUntilReady(index, total))) return false; setStatus(`🚀 Sending Part ${index + 1}/${total}...`); if (await trySend(text)) return true; setStatus(`⚠️ Part ${index + 1} send failed to confirm, waiting to retry...`); await sleepS(1000); } return false; } async function autoSendAll() { if (!state.finals.length || state.sending) return; state.sending = true; state.abort = false; ui.send.disabled = true; setBusyControls(true); const gap = Math.max(1, parseInt(ui.gap.value, 10) || 3) * 1000; let completedAll = true; for (let i = 0; i < state.finals.length; i++) { if (state.abort) { completedAll = false; break; } if (!(await sendOne(state.finals[i], i, state.finals.length))) { completedAll = false; break; } state.sent[i] = true; render(); if (i < state.finals.length - 1 && !state.abort) { const end = Date.now() + gap; while (!state.abort && Date.now() < end) { const left = Math.ceil((end - Date.now()) / 1000); setStatus(`✅ Part ${i + 1} sent, waiting ${left} sec`); await sleepS(200); } } } if (completedAll && !state.abort && ui.finalOk.checked) { setStatus('🟦 All parts sent, waiting to send "OK"...'); if (!(await sendOne(FINAL_OK_TEXT, state.finals.length, state.finals.length + 1))) completedAll = false; } if (state.abort) setStatus('⏹️ Auto-send stopped'); else if (!completedAll) setStatus('⚠️ Auto-send incomplete'); else setStatus(ui.finalOk.checked ? '✅ All sending complete, "OK" sent' : '✅ All sending complete'); state.sending = false; ui.send.disabled = false; setBusyControls(false); } function pasteToChat(text) { const input = findInput(); if (!input) { copyText(text); setStatus('⚠️ Chat input box not found, copied to clipboard instead'); return; } setInputVal(input, text); input.focus(); setStatus('📤 Pasted into chat input box'); } // Event Bindings ui.toggle.addEventListener('click', () => ui.panel.classList.toggle('hide')); ui.close.addEventListener('click', () => ui.panel.classList.add('hide')); ui.text.addEventListener('input', scheduleAutoSplit); ui.copy.addEventListener('click', () => { if (!state.chunks.length && ui.text.value.trim()) autoSplitNow(false); if (!state.chunks.length) { setStatus('⚠️ No content to copy'); return; } copyText(state.chunks.join('')); setStatus('📋 Original text copied (without wait prompts)'); }); ui.clear.addEventListener('click', () => { if (state.sending) state.abort = true; clearTimeout(autoSplitTimer); ui.text.value = ''; resetSegments(); render(); setStatus('🗑️ Cleared'); }); ui.send.addEventListener('click', async () => { if (!state.finals.length && ui.text.value.trim()) autoSplitNow(false); if (!state.finals.length) { setStatus('⚠️ Please paste text first'); return; } if (state.sending) return; await autoSendAll(); }); ui.wait.addEventListener('change', () => { if (!state.sending && ui.text.value.trim()) autoSplitNow(true); }); ui.mode.addEventListener('change', () => { if (!state.sending && ui.text.value.trim()) autoSplitNow(true); }); ui.list.addEventListener('click', e => { const btn = e.target.closest('button[data-act]'); if (!btn) return; const item = btn.closest('.aa-item'); const i = Number(item?.dataset.i); if (Number.isNaN(i)) return; if (btn.dataset.act === 'copy') { copyText(state.finals[i]); setStatus(`📋 Part ${i + 1} copied`); } if (btn.dataset.act === 'paste') pasteToChat(state.finals[i]); }); document.addEventListener('keydown', e => { if (e.ctrlKey && e.shiftKey && e.key.toLowerCase() === 's') { e.preventDefault(); ui.panel.classList.toggle('hide'); if (!ui.panel.classList.contains('hide')) ui.text.focus(); } if (state.sending && e.key === 'Escape') { state.abort = true; setStatus('⏹️ Received stop command, aborting...'); } }); render(); console.log('✂️ Arena.ai Splitter Lite Loaded'); }; if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initSplitter); } else { // Delay slightly to ensure DOM is ready setTimeout(initSplitter, 0); } } // end splitter module // ═══════════════════════════════════════════════════════════════ // §3 Model Preset Pro Module // ═══════════════════════════════════════════════════════════════ if (isModuleEnabled('preset')) { (function initModelPreset() { const ROUTE = '/text/side-by-side'; const CLOAK_ID = '__arena_cloak__'; const PANEL_ID = '__arena_panel__'; const GM_CFG_KEY = 'arena_preset_cfg_v5'; const GM_MDL_KEY = 'arena_preset_mdl_v5'; const BRIDGE_MARK = '__arena_bridge_v5__'; const SEL = { btn: 'button[aria-haspopup="dialog"]', label: 'span.truncate, span[class*="truncate"]', dropdown: '[data-radix-popper-content-wrapper]', item: '[cmdk-item]', input: 'input[cmdk-input], input[type="search"], input[placeholder]', }; const Vault = { get(key, fallback = null) { try { const raw = GM_getValue(key, ''); if (raw) return JSON.parse(raw); } catch {} try { const raw = localStorage.getItem(key); if (raw) return JSON.parse(raw); } catch {} return fallback; }, set(key, value) { const raw = JSON.stringify(value); try { GM_setValue(key, raw); } catch {} try { localStorage.setItem(key, raw); } catch {} }, del(key) { try { GM_deleteValue(key); } catch {} try { localStorage.removeItem(key); } catch {} }, }; function loadCfg() { return Vault.get(GM_CFG_KEY, {}); } function saveCfg(c) { Vault.set(GM_CFG_KEY, c); } function getLeft() { return loadCfg().left || ''; } function getRight() { return loadCfg().right || ''; } function getLeftPub() { return loadCfg().leftPub || ''; } function getRightPub() { return loadCfg().rightPub|| ''; } function setLeft(display, pub) { const c = loadCfg(); c.left = display || ''; c.leftPub = pub || ''; c.ts = Date.now(); saveCfg(c); } function setRight(display, pub) { const c = loadCfg(); c.right = display || ''; c.rightPub = pub || ''; c.ts = Date.now(); saveCfg(c); } function saveModelCache(models) { Vault.set(GM_MDL_KEY, { models, ts: Date.now() }); } function loadModelCache() { const d = Vault.get(GM_MDL_KEY, null); if (d?.models?.length) { modelRegistry = d.models; registryReady = true; logP(`📦 Restored ${modelRegistry.length} models from Vault`); return true; } return false; } let modelRegistry = []; let registryReady = false; let navSeq = 0; let running = false; let failsafeTimer = null; let dataValueField = null; let panelMounted = false; // Cloak function injectCloak() { if (document.getElementById(CLOAK_ID)) return; const s = document.createElement('style'); s.id = CLOAK_ID; s.textContent = ` html.__arena_cloak button[aria-haspopup="dialog"] { visibility: hidden !important; } html.__arena_cloak [data-radix-popper-content-wrapper], html.__arena_cloak [data-radix-dialog-overlay], html.__arena_cloak [cmdk-dialog], html.__arena_cloak [role="dialog"][data-state="open"] { opacity: 0 !important; pointer-events: all !important; position: fixed !important; top: -99999px !important; left: -99999px !important; z-index: -1 !important; } html.__arena_cloak * { transition-duration: 0s !important; animation-duration: 0s !important; } `; (document.head || document.documentElement).appendChild(s); } function lockUI() { document.documentElement.classList.add('__arena_cloak'); clearTimeout(failsafeTimer); failsafeTimer = setTimeout(unlockUI, 12000); } function unlockUI() { clearTimeout(failsafeTimer); document.documentElement.classList.remove('__arena_cloak'); } injectCloak(); // Bridge function installBridge() { if (window[BRIDGE_MARK]) return; window[BRIDGE_MARK] = true; window.addEventListener('message', (ev) => { const d = ev?.data; if (!d || d.__arenaPreset__ !== 1 || d.type !== 'NEXTF_CHUNK') return; if (typeof d.payload !== 'string') return; const models = parseModelsFromPayload(d.payload); if (models.length > 0) buildRegistry(models); }, false); const code = `(function(){ try { if (window.__arenaPresetPageBridge) return; window.__arenaPresetPageBridge = true; const send = (payload) => { try { window.postMessage({ __arenaPreset__: 1, type: 'NEXTF_CHUNK', payload }, '*'); } catch {} }; const inspect = (entry) => { try { if (Array.isArray(entry) && typeof entry[1] === 'string' && entry[1].includes('initialModels')) send(entry[1]); } catch {} }; const patchArr = (arr) => { if (!Array.isArray(arr) || arr.__arenaBridgePatched) return; Object.defineProperty(arr, '__arenaBridgePatched', { value: true, configurable: true }); try { arr.forEach(inspect); } catch {} const orig = arr.push.bind(arr); arr.push = function(...args) { try { args.forEach(inspect); } catch {} return orig(...args); }; }; try { patchArr(window.__next_f); } catch {} try { let _backing = window.__next_f; Object.defineProperty(window, '__next_f', { configurable: true, enumerable: true, get() { return _backing; }, set(v) { _backing = v; patchArr(v); } }); } catch { const t = setInterval(() => { if (Array.isArray(window.__next_f)) { patchArr(window.__next_f); clearInterval(t); } }, 50); setTimeout(() => clearInterval(t), 8000); } } catch {} })();`; try { const s = document.createElement('script'); s.textContent = code; (document.documentElement || document.head).appendChild(s); s.remove(); } catch (e) { warnP('Bridge injection failed:', e); } } function parseModelsFromPayload(str) { const results = []; try { const regex = /"initialModels"\s*:\s*\[/g; let match; while ((match = regex.exec(str)) !== null) { const start = match.index + match[0].length - 1; let depth = 0, end = start; for (let i = start; i < str.length; i++) { if (str[i] === '[') depth++; else if (str[i] === ']') { depth--; if (depth === 0) { end = i + 1; break; } } } try { const cleaned = str.slice(start, end).replace(/"\$undefined"/g, 'null').replace(/\$undefined/g, 'null'); const arr = JSON.parse(cleaned); if (Array.isArray(arr) && arr.length > 0) results.push(...arr); } catch {} } } catch {} return results; } function buildRegistry(rawModels) { try { const map = new Map(); for (const m of rawModels) { const key = m.publicName || m.displayName || m.name; if (!key) continue; const existing = map.get(key); const rank = m.rank ?? Infinity; const existingRank = existing?._bestRank ?? Infinity; if (!existing || rank < existingRank) { m._bestRank = rank; map.set(key, m); } } modelRegistry = [...map.values()].sort((a, b) => (a._bestRank ?? Infinity) - (b._bestRank ?? Infinity)); registryReady = true; saveModelCache(modelRegistry); logP(`📋 Captured ${modelRegistry.length} models → Written to Vault`); refreshCountEl(); } catch (e) { warnP('buildRegistry exception:', e); } } function fallbackExtractFromDOM() { if (registryReady) return; try { for (const s of document.querySelectorAll('script')) { const t = s.textContent || ''; if (t.includes('initialModels')) { const models = parseModelsFromPayload(t); if (models.length > 0) { buildRegistry(models); return; } } } } catch {} } function norm(s) { return String(s).toLowerCase().replace(/[\s\-_.\/]+/g, ''); } function fuzzyP(query, candidate) { if (!query || !candidate) return 0; const nq = norm(query), nc = norm(candidate); if (nq === nc) return 10000; if (nc.startsWith(nq)) return 9000 + (1000 / candidate.length); if (nc.includes(nq)) return 8000 + (1000 / candidate.length); if (nq.startsWith(nc)) return 6000; const qt = query.toLowerCase().split(/[\s\-_.\/]+/).filter(Boolean); const ct = candidate.toLowerCase().split(/[\s\-_.\/]+/).filter(Boolean); let matched = 0; for (const q of qt) { if (ct.some(c => c.includes(q) || q.includes(c))) matched++; } if (matched > 0) return 2000 + (matched / qt.length) * 3000; return 0; } function searchModels(query) { if (!query || !query.trim()) return modelRegistry.slice(); const scored = modelRegistry.map(m => ({ model: m, score: Math.max( fuzzyP(query, m.displayName || ''), fuzzyP(query, m.publicName || ''), fuzzyP(query, m.name || ''), fuzzyP(query, m.organization|| '') ), })); return scored.filter(x => x.score > 0).sort((a, b) => b.score - a.score).map(x => x.model); } function resolveModel(userInput) { if (!userInput || modelRegistry.length === 0) return null; const exact = modelRegistry.find(m => m.publicName === userInput || m.displayName === userInput); if (exact) return exact; return searchModels(userInput)[0] || null; } function refreshCountEl() { const el = document.getElementById('__ap_count'); if (el) el.textContent = registryReady ? `${modelRegistry.length} models available` : 'Loading models...'; } function mountPanel() { if (panelMounted) return; panelMounted = true; const wrapper = document.createElement('div'); wrapper.id = PANEL_ID; wrapper.innerHTML = `
⚡ Model PresetGM Vault ✓
Auto-saves your selection and applies it every time you enter.
Loading models...
LEFT MODEL
RIGHT MODEL
✓ Saved, will auto-apply next time
`; document.body.appendChild(wrapper); const toggle = document.getElementById('__ap_toggle'); const card = document.getElementById('__ap_card'); const leftInput = document.getElementById('__ap_left_input'); const rightInput = document.getElementById('__ap_right_input'); const leftDD = document.getElementById('__ap_left_dd'); const rightDD = document.getElementById('__ap_right_dd'); const leftMatch = document.getElementById('__ap_left_match'); const rightMatch = document.getElementById('__ap_right_match'); const applyBtn = document.getElementById('__ap_apply'); const clearBtn = document.getElementById('__ap_clear'); const refreshBtn = document.getElementById('__ap_refresh'); const statusEl = document.getElementById('__ap_status'); const savedHint = document.getElementById('__ap_saved'); leftInput.value = getLeft(); rightInput.value = getRight(); refreshCountEl(); updateToggle(); function updateToggle() { if (getLeft() || getRight()) toggle.classList.add('saved'); else toggle.classList.remove('saved'); } function flashSaved() { savedHint.classList.add('show'); setTimeout(() => savedHint.classList.remove('show'), 2000); } toggle.addEventListener('click', e => { e.stopPropagation(); card.classList.toggle('open'); if (card.classList.contains('open')) { refreshCountEl(); updateMatch('left'); updateMatch('right'); leftInput.classList.toggle('saved', !!getLeft()); rightInput.classList.toggle('saved', !!getRight()); } }); document.addEventListener('click', e => { if (!wrapper.contains(e.target)) { card.classList.remove('open'); leftDD.classList.remove('open'); rightDD.classList.remove('open'); } }); function updateMatch(side) { const input = side === 'left' ? leftInput : rightInput; const matchEl = side === 'left' ? leftMatch : rightMatch; const val = input.value.trim(); if (!val) { matchEl.textContent = ''; matchEl.className = '__ap_matched'; return; } if (!registryReady) { matchEl.textContent = 'Waiting for model list...'; matchEl.className = '__ap_matched'; return; } const m = resolveModel(val); if (m) { matchEl.textContent = `✓ ${m.displayName || m.publicName} (${m.organization || '?'}) rank:${m._bestRank === Infinity ? '—' : m._bestRank}`; matchEl.className = '__ap_matched ok'; } else { matchEl.textContent = '✗ No match found'; matchEl.className = '__ap_matched fail'; } } function escP(s) { const d = document.createElement('div'); d.textContent = s; return d.innerHTML; } function renderDropdown(ddEl, query, side) { const results = searchModels(query).slice(0, 50); const currentPub = side === 'left' ? getLeftPub() : getRightPub(); const currentDis = side === 'left' ? getLeft() : getRight(); if (results.length === 0) { ddEl.innerHTML = '
No models found
'; ddEl.classList.add('open'); return; } ddEl.innerHTML = results.map(m => { const dn = m.displayName || m.publicName || m.name || '?'; const pn = m.publicName || ''; const org = m.organization|| ''; const rank = m._bestRank === Infinity ? '' : `#${m._bestRank}`; const sel = (pn && (pn === currentPub || pn === currentDis)) || dn === currentDis ? ' selected' : ''; return `
${escP(dn)} ${escP(org)} ${rank}
`; }).join(''); ddEl.classList.add('open'); } function onInput(side) { const input = side === 'left' ? leftInput : rightInput; const dd = side === 'left' ? leftDD : rightDD; const val = input.value.trim(); if (side === 'left') setLeft(val, ''); else setRight(val, ''); renderDropdown(dd, val, side); updateMatch(side); updateToggle(); } function onOptClick(e, side) { const opt = e.target.closest('.__ap_opt'); if (!opt) return; const input = side === 'left' ? leftInput : rightInput; const dd = side === 'left' ? leftDD : rightDD; const dis = opt.dataset.dis || opt.dataset.pub; const pub = opt.dataset.pub || ''; input.value = dis; if (side === 'left') setLeft(dis, pub); else setRight(dis, pub); dd.classList.remove('open'); updateMatch(side); updateToggle(); input.classList.toggle('saved', !!dis); flashSaved(); } leftInput.addEventListener('input', () => onInput('left')); rightInput.addEventListener('input', () => onInput('right')); leftInput.addEventListener('focus', () => renderDropdown(leftDD, leftInput.value.trim(), 'left')); rightInput.addEventListener('focus', () => renderDropdown(rightDD, rightInput.value.trim(), 'right')); leftInput.addEventListener('blur', () => setTimeout(() => leftDD.classList.remove('open'), 200)); rightInput.addEventListener('blur', () => setTimeout(() => rightDD.classList.remove('open'), 200)); leftDD.addEventListener('click', e => onOptClick(e, 'left')); rightDD.addEventListener('click', e => onOptClick(e, 'right')); applyBtn.addEventListener('click', async () => { statusEl.textContent = 'Applying...'; statusEl.className = '__ap_status'; card.classList.remove('open'); running = false; await apply(); setTimeout(() => { const lo = getLeft() && slotMatchesResolved(0, getLeftPub() || getLeft()); const ro = getRight() && slotMatchesResolved(1, getRightPub() || getRight()); if (lo && ro) { statusEl.textContent = '✅ Both models applied!'; statusEl.className = '__ap_status success'; } else if (lo || ro) { statusEl.textContent = `⚠️ ${lo ? 'Left ✓' : 'Left ✗'} | ${ro ? 'Right ✓' : 'Right ✗'}`; statusEl.className = '__ap_status error'; } else { statusEl.textContent = '❌ Failed — try Apply again'; statusEl.className = '__ap_status error'; } }, 800); }); clearBtn.addEventListener('click', () => { leftInput.value = ''; rightInput.value = ''; setLeft('', ''); setRight('', ''); leftInput.classList.remove('saved'); rightInput.classList.remove('saved'); updateMatch('left'); updateMatch('right'); updateToggle(); statusEl.textContent = 'Cleared'; statusEl.className = '__ap_status'; }); refreshBtn.addEventListener('click', () => { registryReady = false; dataValueField = null; refreshCountEl(); fallbackExtractFromDOM(); installBridge(); setTimeout(() => refreshCountEl(), 2000); }); } // DOM Manipulation const sleepP = ms => new Promise(r => setTimeout(r, ms)); function isVisibleP(el) { if (!el) return false; const r = el.getBoundingClientRect(); return r.width > 0 && r.height > 0; } function getText(el) { if (!el) return ''; const l = el.querySelector(SEL.label); return (l?.textContent || el.textContent || '').trim(); } function getModelButtons() { return [...document.querySelectorAll(SEL.btn)] .filter(isVisibleP) .filter(b => { const t = getText(b); return t && !/^(side by side|direct|battle|new chat|compare|login|image|video|code|search|text)$/i.test(t); }) .sort((a, b) => a.getBoundingClientRect().left - b.getBoundingClientRect().left) .slice(0, 2); } function probeDataValueField(dropdown) { if (dataValueField) return dataValueField; for (const item of dropdown.querySelectorAll('[cmdk-item]')) { const dv = item.getAttribute('data-value'); if (!dv) continue; for (const m of modelRegistry) { if (m.publicName === dv) { dataValueField = 'publicName'; return dataValueField; } if (m.displayName === dv) { dataValueField = 'displayName'; return dataValueField; } if (m.name === dv) { dataValueField = 'name'; return dataValueField; } } } dataValueField = 'publicName'; return dataValueField; } function getDataValue(model) { if (!model) return null; const f = dataValueField || 'publicName'; return model[f] || model.publicName || model.displayName || model.name; } function slotMatchesResolved(slotIdx, userInput) { const model = resolveModel(userInput); if (!model) return false; const btns = getModelButtons(); if (!btns[slotIdx]) return false; const label = getText(btns[slotIdx]).toLowerCase(); return [model.displayName, model.publicName, model.name] .filter(Boolean).some(n => label.includes(n.toLowerCase())); } function pressEsc() { document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', code: 'Escape', bubbles: true })); } function setNativeInput(el, val) { const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')?.set; if (setter) setter.call(el, val); else el.value = val; el.dispatchEvent(new Event('input', { bubbles: true })); } async function waitForDOM(fn, timeout = 3000) { const start = Date.now(); while (Date.now() - start < timeout) { const v = fn(); if (v) return v; await sleepP(60); } return null; } async function selectSlot(slotIdx, model, seq) { if (seq !== navSeq || !model) return false; const wantKey = model.publicName || model.displayName || ''; if (wantKey && slotMatchesResolved(slotIdx, wantKey)) return true; const btn = getModelButtons()[slotIdx]; if (!btn) return false; const isOpen = btn.getAttribute('data-state') === 'open' || btn.getAttribute('aria-expanded') === 'true'; if (!isOpen) btn.click(); const dropdown = await waitForDOM(() => document.querySelector(SEL.dropdown), 3000); if (!dropdown || seq !== navSeq) { pressEsc(); return false; } probeDataValueField(dropdown); const targetValue = getDataValue(model); if (!targetValue) { pressEsc(); return false; } let item = dropdown.querySelector(`[cmdk-item][data-value="${CSS.escape(targetValue)}"]`); if (!item) { const inp = dropdown.querySelector(SEL.input); if (inp) { setNativeInput(inp, model.displayName || model.publicName || targetValue); await sleepP(250); item = dropdown.querySelector(`[cmdk-item][data-value="${CSS.escape(targetValue)}"]`); } } if (!item) { let bestItem = null, bestScore = 0; for (const it of dropdown.querySelectorAll('[cmdk-item]')) { const dv = it.getAttribute('data-value') || ''; const s = Math.max( fuzzyP(targetValue, dv), fuzzyP(model.displayName || '', dv), fuzzyP(model.publicName || '', dv) ); if (s > bestScore) { bestScore = s; bestItem = it; } } if (bestScore >= 5000) item = bestItem; } if (item) { item.click(); await sleepP(40); } pressEsc(); await sleepP(40); return wantKey ? slotMatchesResolved(slotIdx, wantKey) : !!item; } async function apply() { if (running) return; if (!location.pathname.startsWith(ROUTE)) { unlockUI(); return; } const leftWant = getLeftPub() || getLeft(); const rightWant = getRightPub() || getRight(); if (!leftWant && !rightWant) { unlockUI(); return; } running = true; const seq = navSeq; try { lockUI(); if (!registryReady) { fallbackExtractFromDOM(); for (let i = 0; i < 50 && !registryReady; i++) await sleepP(100); } const leftModel = leftWant ? resolveModel(leftWant) : null; const rightModel = rightWant ? resolveModel(rightWant) : null; if (!leftModel && !rightModel) { warnP('Could not match any models'); unlockUI(); return; } await waitForDOM(() => getModelButtons().length >= 2, 8000); if (getModelButtons().length < 2 || seq !== navSeq) { unlockUI(); return; } if (leftModel) { for (let i = 0; i < 3 && seq === navSeq; i++) { if (await selectSlot(0, leftModel, seq)) break; await sleepP(300); } } await sleepP(60); if (rightModel) { for (let i = 0; i < 3 && seq === navSeq; i++) { if (await selectSlot(1, rightModel, seq)) break; await sleepP(300); } } await sleepP(500); if (seq === navSeq) unlockUI(); logP('✅ Completed', leftModel ? `Left: ${leftModel.displayName}` : 'Left: Skipped', rightModel ? `Right: ${rightModel.displayName}` : 'Right: Skipped' ); } catch (e) { warnP('apply() exception:', e); unlockUI(); } finally { running = false; } } // SPA Routing Monitor function onRouteChange() { navSeq++; running = false; if (location.pathname.startsWith(ROUTE)) { lockUI(); setTimeout(apply, 200); setTimeout(apply, 1500); } else { unlockUI(); } } const _push = history.pushState; history.pushState = function (...a) { const r = _push.apply(this, a); onRouteChange(); return r; }; const _replace = history.replaceState; history.replaceState = function (...a) { const r = _replace.apply(this, a); onRouteChange(); return r; }; window.addEventListener('popstate', onRouteChange); function logP(...a) { console.log('[Arena Preset]', ...a); } function warnP(...a) { console.warn('[Arena Preset]', ...a); } if (location.pathname.startsWith(ROUTE)) lockUI(); loadModelCache(); installBridge(); function onReadyP() { fallbackExtractFromDOM(); mountPanel(); if (location.pathname.startsWith(ROUTE) && (getLeft() || getRight())) { setTimeout(apply, 200); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', onReadyP); } else { onReadyP(); } const startObsP = () => { if (!document.body) return; let triggered = false; const mo = new MutationObserver(() => { if (!panelMounted && document.body) mountPanel(); if (!triggered && !running && location.pathname.startsWith(ROUTE) && getModelButtons().length >= 2 && (getLeft() || getRight())) { triggered = true; mo.disconnect(); apply(); } }); mo.observe(document.body, { childList: true, subtree: true }); }; if (document.body) startObsP(); else document.addEventListener('DOMContentLoaded', startObsP); })(); } // end preset module })();