答题助手|超星学习通|学起plus|💯自动答题|▶️一键操作|🏆超全题库(每日更新、自动收录)

已完美兼容、学习通、学起plus 完美应付测试,全自动答题;后续需要完善其他平台请进群进行反馈

// ==UserScript==
// @name         答题助手|超星学习通|学起plus|💯自动答题|▶️一键操作|🏆超全题库(每日更新、自动收录)
// @namespace    http://tampermonkey.net/
// @version      0.3.6.6
// @description  已完美兼容、学习通、学起plus  完美应付测试,全自动答题;后续需要完善其他平台请进群进行反馈
// @author       艾凌科技工作室
// @match        *://exam.chinaedu.net/*
// @match        *://mooc1-2.chaoxing.com/exam-ans/mooc2/exam/*
// @match        *://mooc1.chaoxing.com/mooc-ans/mooc2/work/*
// @match        *://mooc1-api.chaoxing.com/exam-ans/mooc2/exam*
// @match        *://mooc1.chaoxing.com/mycourse/studentstudy*
// @match        https://mooc1.chaoxing.com/mooc-ans/knowledge/*
// @match        https://mooc2-ans.chaoxing.com/*
// @require      https://greasyfork.org/scripts/445293/code/TyprMd5.js
// @match        https://mooc1.chaoxing.com/*
// @license      This script is protected. You may not copy, modify, or redistribute it without explicit permission.
// @match        https://mooc2-ans.chaoxing.com/*
// @resource     Table https://www.forestpolice.org/ttf/2.0/table.json
// @run-at       document-start
// @grant        GM_xmlhttpRequest
// @grant        GM_getResourceText
// @grant        unsafeWindow
// @connect      *

// ==/UserScript==

(function () {
    'use strict';

    // iframe内部的postMessage处理(用于跨域通信)
    if (window !== window.top) {
        // 当前在iframe中,监听来自父页面的消息
        window.addEventListener('message', function(event) {
            if (event.data && event.data.source === 'chapter_list_handler') {
                if (event.data.type === 'FIND_PENDING_TASKS') {
                    // 查找待完成任务点
                    const chapterElements = document.querySelectorAll('.chapter_item, [onclick*="toOld"], .catalog_title');
                    let hasElements = false;

                    for (const element of chapterElements) {
                        const pendingTask = element.querySelector('.catalog_jindu .bntHoverTips') ||
                                          element.querySelector('.bntHoverTips') ||
                                          element.querySelector('[class*="catalog_points"]');

                        if (pendingTask && pendingTask.textContent.includes('待完成任务点')) {
                            hasElements = true;
                            break;
                        }
                    }

                    // 响应父页面
                    const response = {
                        type: 'PENDING_TASKS_FOUND',
                        hasElements: hasElements,
                        elementsCount: chapterElements.length
                    };
                    event.source.postMessage(response, '*');

                } else if (event.data.type === 'CLICK_FIRST_PENDING_TASK') {
                    // 点击第一个待完成任务点
                    const chapterElements = document.querySelectorAll('.chapter_item, [onclick*="toOld"], .catalog_title');

                    for (const element of chapterElements) {
                        const pendingTask = element.querySelector('.catalog_jindu .bntHoverTips') ||
                                          element.querySelector('.bntHoverTips') ||
                                          element.querySelector('[class*="catalog_points"]');

                        if (pendingTask && pendingTask.textContent.includes('待完成任务点')) {
                            const clickableElement = element.querySelector('[onclick]') ||
                                                   element.closest('[onclick]') ||
                                                   element;

                            setTimeout(() => {
                                clickableElement.click();
                                console.log('✅ [iframe] 已点击待完成任务点章节');
                            }, 500);
                            break;
                        }
                    }
                }
            }
        });
    }

    const originalAddEventListener = EventTarget.prototype.addEventListener;
    const blockedEvents = ['visibilitychange', 'blur', 'focusout', 'mouseleave', 'beforeunload', 'pagehide'];

    EventTarget.prototype.addEventListener = function(type, listener, options) {
        if (blockedEvents.includes(type)) {
            return;
        }
        return originalAddEventListener.call(this, type, listener, options);
    };


    try {
        Object.defineProperty(document, 'hidden', {
            get: () => false,
            configurable: true
        });

        Object.defineProperty(document, 'visibilityState', {
            get: () => 'visible',
            configurable: true
        });


        Object.defineProperty(document, 'webkitHidden', {
            get: () => false,
            configurable: true
        });
        Object.defineProperty(document, 'mozHidden', {
            get: () => false,
            configurable: true
        });
        Object.defineProperty(document, 'msHidden', {
            get: () => false,
            configurable: true
        });

        Object.defineProperty(document, 'webkitVisibilityState', {
            get: () => 'visible',
            configurable: true
        });
        Object.defineProperty(document, 'mozVisibilityState', {
            get: () => 'visible',
            configurable: true
        });
        Object.defineProperty(document, 'msVisibilityState', {
            get: () => 'visible',
            configurable: true
        });
    } catch (e) {

    }


    document.hasFocus = () => true;

    // 完全按照正确版本添加removeEventListener拦截
    const oldRemove = EventTarget.prototype.removeEventListener;
    EventTarget.prototype.removeEventListener = function(...args) {
        if (args.length !== 0) {
            const eventType = args[0];
            if (blockedEvents.includes(eventType)) {
                console.log(`[${new Date().toLocaleTimeString()}] [防切屏] 阻止移除 ${eventType} 监听器`);
                return; // 不允许移除
            }
        }
        return oldRemove.call(this, ...args);
    };

    // 添加正确版本的全局变量
    const processedIframes = new WeakSet();

    function injectHooksToDocument(doc, context = 'main') {
        if (!doc || doc._hooksInjected) return;

        try {

            const docWindow = doc.defaultView || doc.parentWindow;
            if (docWindow && docWindow.EventTarget) {
                const originalAdd = docWindow.EventTarget.prototype.addEventListener;
                docWindow.EventTarget.prototype.addEventListener = function(type, listener, options) {
                    if (blockedEvents.includes(type)) {
                        return;
                    }
                    return originalAdd.call(this, type, listener, options);
                };
            }


            Object.defineProperty(doc, 'hidden', {
                get: () => false,
                configurable: true
            });
            Object.defineProperty(doc, 'visibilityState', {
                get: () => 'visible',
                configurable: true
            });


            doc.hasFocus = () => true;

            doc._hooksInjected = true;

        } catch (e) {

        }
    }







    // 添加正确版本的processIframes函数
    function processIframes(doc = document, context = 'main', depth = 0) {
        if (depth > 5) return;

        try {
            const iframes = doc.querySelectorAll('iframe');
            iframes.forEach((iframe, index) => {
                if (processedIframes.has(iframe)) return;

                try {
                    const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
                    if (!iframeDoc) return;

                    const iframeContext = `${context}-iframe-${index}`;

                    // 注入防切屏钩子到iframe
                    injectHooksToDocument(iframeDoc, iframeContext);

                    // 递归处理嵌套iframe
                    processIframes(iframeDoc, iframeContext, depth + 1);

                    processedIframes.add(iframe);

                } catch (e) {
                    // 跨域限制,忽略
                }
            });
        } catch (e) {
            console.warn(`[${new Date().toLocaleTimeString()}] [iframe检测] iframe处理失败:`, e);
        }
    }

    const clearWindowHandlers = () => {
        if (window.onblur !== null) {
            window.onblur = null;

        }
        if (window.onfocus !== null) {
            window.onfocus = null;

        }
        if (window.onbeforeunload !== null) {
            window.onbeforeunload = null;

        }
    };

    setInterval(clearWindowHandlers, 5000); // 窗口处理器清理间隔调整为5秒
    clearWindowHandlers();

    const pageWindow = (typeof unsafeWindow !== 'undefined') ? unsafeWindow : window;
    const pageDocument = pageWindow.document;

    pageWindow._paq = [];

    const originalCreateElement = pageDocument.createElement;
    pageDocument.createElement = function (tagName) {
        if (tagName.toLowerCase() === 'script') {
            const script = originalCreateElement.call(pageDocument, tagName);
            const originalSrcSetter = Object.getOwnPropertyDescriptor(HTMLScriptElement.prototype, 'src').set;

            Object.defineProperty(script, 'src', {
                set: function (value) {
                    if (value.includes('piwik.js')) {
                        return;
                    }
                    originalSrcSetter.call(this, value);
                },
                configurable: true
            });

            return script;
        }
        return originalCreateElement.call(pageDocument, tagName);
    };


    pageDocument.onkeydown = null;
    pageDocument.addEventListener('keydown', function (e) {

        if (e.keyCode === 123 ||
            (e.ctrlKey && e.shiftKey && e.keyCode === 73) ||
            (e.shiftKey && e.keyCode === 121)) {
            e.stopImmediatePropagation();
            return;
        }
    }, true);


    pageWindow.oncontextmenu = null;
    pageWindow.addEventListener('contextmenu', function (e) {
        e.stopImmediatePropagation();
    }, true);


    pageWindow.alert = function (message) {
        if (message && message.includes("请勿打开控制台")) {
            return;
        }
    };

    pageWindow.close = function () {

    };

    Object.defineProperty(pageWindow, 'console', {
        value: pageWindow.console,
        writable: false,
        configurable: false
    });
    const SERVER_CONFIG = {
        apiUrl: 'https://www.toptk.xyz/api',
        answerApiUrl: 'https://www.toptk.xyz/api',
        timeout: 30000
    };

    const GLOBAL_STATE = {
        isAnswering: false,
        isChapterTesting: false,
        lastAnswerTime: 0
    };

    const SITES = {
        XUEQI: {
            name: '学起',
            host: 'exam.chinaedu.net',
            getQuestions: getXueqiQuestions,
            selectAnswer: selectXueqiAnswer,
        },
        CHAOXING: {
            name: '超星学习通',
            host: 'mooc1.chaoxing.com',
            getQuestions: getChaoxingQuestions,
            selectAnswer: selectChaoxingAnswer,
        },

    };
    let currentSite = null;

    function detectSite() {
        const currentHost = window.location.hostname;
        const currentUrl = window.location.href;

        // 检测已知站点
        for (const key in SITES) {
            if (currentHost.includes(SITES[key].host)) {
                currentSite = SITES[key];
                logMessage(`[站点检测] 已识别: ${currentSite.name}`, 'success');
                return currentSite;
            }
        }


        if (currentHost.includes('chaoxing') ||
            currentUrl.includes('chaoxing') ||
            document.querySelector('.questionLi') ||
            document.querySelector('.mark_name') ||
            document.querySelector('[typename]') ||
            document.querySelector('.workTextWrap') ||
            document.title.includes('超星') ||
            document.title.includes('学习通') ||
            currentUrl.includes('work') ||
            currentUrl.includes('exam')) {

            currentSite = SITES.CHAOXING;


            let pageType = '未知';
            if (currentUrl.includes('/exam-ans/mooc2/exam/')) {
                pageType = '考试';
                currentSite.pageType = 'exam';

            } else if (currentUrl.includes('/mooc-ans/mooc2/work/')) {
                pageType = '作业';
                currentSite.pageType = 'homework';

            } else if (currentUrl.includes('/mooc-ans/work/doHomeWorkNew/')) {
                pageType = '章节测验';
                currentSite.pageType = 'chapter_test';

            } else if (currentUrl.includes('/mooc-ans/api/work/')) {
                pageType = '章节测验';
                currentSite.pageType = 'chapter_test';

            } else if (currentUrl.includes('/ananas/modules/work/')) {
                pageType = '章节测验';
                currentSite.pageType = 'chapter_test';

            } else {

                const isHomeworkPage = document.querySelector('.questionLi[typename]') !== null;
                pageType = isHomeworkPage ? '作业' : '考试';
                currentSite.pageType = isHomeworkPage ? 'homework' : 'exam';

            }

            logMessage(`[站点检测] 通过特征识别: ${currentSite.name} - ${pageType}页面`, 'success');
            return currentSite;
        }


        if (currentHost.includes('chinaedu') ||
            currentUrl.includes('exam') ||
            document.querySelector('.questionItem') ||
            document.querySelector('.queStemC') ||
            document.title.includes('学起') ||
            document.title.includes('考试')) {

            currentSite = SITES.XUEQI;
            logMessage(`[站点检测] 通过特征识别: ${currentSite.name}`, 'success');
            return currentSite;
        }


        const hasQuestionElements = document.querySelector('[class*="question"], [id*="question"], .exam, .test, .quiz');
        if (hasQuestionElements) {
            currentSite = SITES.CHAOXING;
            logMessage(`[站点检测] 通用题目页面,使用: ${currentSite.name}`, 'warning');
            return currentSite;
        }

        currentSite = SITES.XUEQI;
        logMessage(`[站点检测] 未识别当前站点, 使用默认解析器: ${currentSite.name}`, 'warning');
        return currentSite;
    }

    function gmFetch(url, options = {}) {
        return new Promise((resolve, reject) => {
            const {
                method = 'GET',
                headers = {},
                body = null,
                timeout = SERVER_CONFIG.timeout
            } = options;

            GM_xmlhttpRequest({
                method: method,
                url: url,
                headers: headers,
                data: body,
                timeout: timeout,
                onload: function (response) {
                    const result = {
                        ok: response.status >= 200 && response.status < 300,
                        status: response.status,
                        statusText: response.statusText,
                        json: () => {
                            try {
                                return Promise.resolve(JSON.parse(response.responseText));
                            } catch (error) {
                                return Promise.reject(new Error(`Invalid JSON response: ${error.message}`));
                            }
                        },
                        text: () => Promise.resolve(response.responseText)
                    };
                    resolve(result);
                },
                onerror: function (error) {
                    reject(new Error(`Request failed: ${error.error || 'Network error'}`));
                },
                ontimeout: function () {
                    reject(new Error('Request timeout'));
                }
            });
        });
    }

    const TokenManager = {
        TOKEN_KEY: 'user_token',

        _requestCache: new Map(),
        _lastRequestTime: 0,
        _minRequestInterval: 500,

        async _throttleRequest(key, requestFn, cacheTime = 30000) {
            const now = Date.now();


            if (this._requestCache.has(key)) {
                const cached = this._requestCache.get(key);
                if (now - cached.timestamp < cacheTime) {
                    return cached.result;
                }
            }

            let actualInterval = this._minRequestInterval;
            if (key.includes('validate') || key.includes('verify')) {
                actualInterval = 200;
            } else if (key.includes('check') || key.includes('status')) {
                actualInterval = 100;
            }


            const timeSinceLastRequest = now - this._lastRequestTime;
            if (timeSinceLastRequest < actualInterval) {
                const waitTime = actualInterval - timeSinceLastRequest;
                await new Promise(resolve => setTimeout(resolve, waitTime));
            }

            this._lastRequestTime = Date.now();

            try {
                const result = await requestFn();
                this._requestCache.set(key, {
                    result: result,
                    timestamp: Date.now()
                });
                return result;
            } catch (error) {
                if (!error.message.includes('429') && !error.message.includes('网络')) {
                    this._requestCache.delete(key);
                }
                throw error;
            }
        },


        getToken() {
            return localStorage.getItem(this.TOKEN_KEY);
        },


        setToken(token) {
            localStorage.setItem(this.TOKEN_KEY, token);
        },


        clearToken() {
            localStorage.removeItem(this.TOKEN_KEY);

            this._requestCache.clear();
        },


        async checkVisitorStatus() {
            const cacheKey = 'check_visitor_status';

            return await this._throttleRequest(cacheKey, async () => {
                const response = await gmFetch(`${SERVER_CONFIG.apiUrl}/user/check-visitor`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    timeout: SERVER_CONFIG.timeout
                });

                if (!response.ok) {
                    throw new Error(`检测访问者状态失败: ${response.status} ${response.statusText}`);
                }

                const result = await response.json();

                if (result.success) {

                    if (result.data.isNewUser && result.data.userToken) {
                        this.setToken(result.data.userToken);


                        return {
                            success: true,
                            hasToken: true,
                            token: result.data.userToken,
                            userInfo: result.data.userInfo,
                            message: result.data.message
                        };
                    }


                    if (!result.data.isNewUser && result.data.userToken) {
                        this.setToken(result.data.userToken);

                        return {
                            success: true,
                            hasToken: true,
                            token: result.data.userToken,
                            userInfo: result.data.userInfo,
                            message: result.data.message
                        };
                    }
                }
                if (result.data && result.data.needsToken) {

                    return {
                        success: false,
                        needsToken: true,
                        message: result.data.message || '请输入您的用户Token'
                    };
                }

                throw new Error(result.message || '检测访问者状态失败');
            }, 120000);
        },


        async verifyUserToken(userToken) {
            const cacheKey = `verify_${userToken.substring(0, 16)}`;

            return await this._throttleRequest(cacheKey, async () => {
                const response = await gmFetch(`${SERVER_CONFIG.apiUrl}/user/verify-token`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        userToken: userToken
                    }),
                    timeout: SERVER_CONFIG.timeout
                });

                if (!response.ok) {
                    let errorMessage = `Token验证失败: ${response.status} ${response.statusText}`;

                    try {
                        const result = await response.json();
                        errorMessage = result.message || errorMessage;
                    } catch (parseError) {

                        try {
                            const errorText = await response.text();
                            errorMessage = errorText || errorMessage;
                        } catch (textError) {

                        }
                    }


                    throw new Error(errorMessage);
                }

                const result = await response.json();


                if (!result.success) {
                    const errorMessage = result.message || 'Token验证失败';

                    throw new Error(errorMessage);
                }

                this.setToken(result.data.userToken);

                return {
                    success: true,
                    token: result.data.userToken,
                    userInfo: result.data.userInfo,
                    message: result.data.message
                };
            }, 300000);
        },


        async promptUserToken() {
            try {
                const userToken = prompt(
                    '🔐 请输入您的用户Token\n\n' +
                    '如果您是首次使用,系统会在首次访问时自动为您创建Token。\n' +
                    '如果您已有Token,请输入完整的64位Token字符串:'
                );

                if (!userToken) {
                    throw new Error('用户取消输入Token');
                }

                if (userToken.length !== 64) {
                    throw new Error('Token格式不正确,应为64位字符串');
                }

                return await this.verifyUserToken(userToken);
            } catch (error) {

                throw error;
            }
        },


        async _validateToken(token) {
            const cacheKey = `validate_${token.substring(0, 16)}`;

            return await this._throttleRequest(cacheKey, async () => {

                const response = await gmFetch(`${SERVER_CONFIG.apiUrl}/user/info`, {
                    method: 'GET',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-User-Token': token
                    },
                    timeout: SERVER_CONFIG.timeout
                });

                if (!response.ok) {

                    return false;
                }

                const result = await response.json();

                return result.success;
            }, 60000);
        },

        async getValidToken() {
            let token = this.getToken();


            if (token) {

                const isValid = await this._validateToken(token);
                if (isValid) {

                    return token;
                }

                this.clearToken();
            }
            try {
                const result = await this.initialize();
                if (result.success && result.hasToken) {
                    return this.getToken();
                }
            } catch (error) {

            }
            throw new Error('Token获取失败,请刷新页面重试');
        },

        async getUserInfo() {
            try {
                const token = await this.getValidToken();

                const response = await gmFetch(`${SERVER_CONFIG.apiUrl}/user/info`, {
                    method: 'GET',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-User-Token': token
                    },
                    timeout: SERVER_CONFIG.timeout
                });

                if (!response.ok) {
                    throw new Error(`获取用户信息失败: ${response.status} ${response.statusText}`);
                }

                const result = await response.json();

                if (!result.success) {
                    throw new Error(result.message || '获取用户信息失败');
                }

                return result.userInfo;

            } catch (error) {

                throw error;
            }
        },

        async initialize() {
            try {
                const storedToken = this.getToken();

                if (storedToken) {
                    const isValid = await this._validateToken(storedToken);
                    if (isValid) {

                        return {
                            success: true,
                            hasToken: true,
                            token: storedToken,
                            message: '欢迎回来!Token已自动加载。'
                        };
                    } else {
                        this.clearToken();
                    }
                }


                return await this.showTokenSelectionDialog();

            } catch (error) {

                return {
                    success: false,
                    error: error.message,
                    message: '初始化失败,请刷新页面重试'
                };
            }
        },

        async showTokenSelectionDialog() {
            return new Promise((resolve) => {

                const dialogHTML = `
                    <div id="token-dialog" style="
                        position: fixed;
                        top: 0;
                        left: 0;
                        width: 100%;
                        height: 100%;
                        background: rgba(0, 0, 0, 0.7);
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        z-index: 10000;
                        font-family: Arial, sans-serif;
                    ">
                        <div style="
                            background: white;
                            padding: 30px;
                            border-radius: 10px;
                            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
                            max-width: 500px;
                            width: 90%;
                            text-align: center;
                        ">
                            <h3 style="margin: 0 0 20px 0; color: #333;">🎯 TK星球答题系统</h3>
                            <p style="color: #666; margin: 0 0 25px 0; line-height: 1.5;">
                                请选择您的Token获取方式:
                            </p>
                            
                            <div style="margin: 20px 0;">
                                <button id="create-new-token" style="
                                    background: #007bff;
                                    color: white;
                                    border: none;
                                    padding: 12px 30px;
                                    margin: 0 10px;
                                    border-radius: 5px;
                                    cursor: pointer;
                                    font-size: 16px;
                                    transition: background 0.3s;
                                " onmouseover="this.style.background='#0056b3'" onmouseout="this.style.background='#007bff'">
                                    🆕 生成新Token
                                </button>
                                
                                <button id="input-existing-token" style="
                                    background: #28a745;
                                    color: white;
                                    border: none;
                                    padding: 12px 30px;
                                    margin: 0 10px;
                                    border-radius: 5px;
                                    cursor: pointer;
                                    font-size: 16px;
                                    transition: background 0.3s;
                                " onmouseover="this.style.background='#1e7e34'" onmouseout="this.style.background='#28a745'">
                                    📝 填写已有Token
                                </button>
                            </div>
                            
                            <div id="token-input-area" style="display: none; margin-top: 20px;">
                                <input type="text" id="token-input" placeholder="请输入您的Token" style="
                                    width: 100%;
                                    padding: 12px;
                                    border: 2px solid #ddd;
                                    border-radius: 5px;
                                    font-size: 14px;
                                    box-sizing: border-box;
                                    margin-bottom: 15px;
                                " />
                                
                                <button id="verify-token" style="
                                    background: #17a2b8;
                                    color: white;
                                    border: none;
                                    padding: 10px 25px;
                                    margin: 0 10px;
                                    border-radius: 5px;
                                    cursor: pointer;
                                    font-size: 14px;
                                " onmouseover="this.style.background='#117a8b'" onmouseout="this.style.background='#17a2b8'">
                                    验证Token
                                </button>
                                
                                <button id="cancel-input" style="
                                    background: #6c757d;
                                    color: white;
                                    border: none;
                                    padding: 10px 25px;
                                    margin: 0 10px;
                                    border-radius: 5px;
                                    cursor: pointer;
                                    font-size: 14px;
                                " onmouseover="this.style.background='#545b62'" onmouseout="this.style.background='#6c757d'">
                                    取消
                                </button>
                            </div>
                            
                            <div id="dialog-message" style="
                                margin-top: 15px;
                                padding: 10px;
                                border-radius: 5px;
                                display: none;
                            "></div>
                        </div>
                    </div>
                `;


                document.body.insertAdjacentHTML('beforeend', dialogHTML);

                const dialog = document.getElementById('token-dialog');
                const createBtn = document.getElementById('create-new-token');
                const inputBtn = document.getElementById('input-existing-token');
                const inputArea = document.getElementById('token-input-area');
                const tokenInput = document.getElementById('token-input');
                const verifyBtn = document.getElementById('verify-token');
                const cancelBtn = document.getElementById('cancel-input');
                const messageDiv = document.getElementById('dialog-message');


                const showMessage = (message, type = 'info') => {
                    messageDiv.style.display = 'block';
                    messageDiv.textContent = message;

                    if (type === 'error') {
                        messageDiv.style.background = '#f8d7da';
                        messageDiv.style.color = '#721c24';
                        messageDiv.style.border = '1px solid #f5c6cb';
                    } else if (type === 'success') {
                        messageDiv.style.background = '#d4edda';
                        messageDiv.style.color = '#155724';
                        messageDiv.style.border = '1px solid #c3e6cb';
                    } else {
                        messageDiv.style.background = '#d1ecf1';
                        messageDiv.style.color = '#0c5460';
                        messageDiv.style.border = '1px solid #bee5eb';
                    }
                };


                const closeDialog = () => {
                    dialog.remove();
                };


                createBtn.addEventListener('click', async () => {
                    try {
                        createBtn.disabled = true;
                        createBtn.textContent = '生成中...';
                        showMessage('正在生成新Token...', 'info');

                        const result = await this.checkVisitorStatus();

                        if (result.success && result.hasToken) {

                            showMessage(`Token生成成功!`, 'success');


                            const tokenDisplay = document.createElement('div');
                            tokenDisplay.style.cssText = `
                                background: #f8f9fa;
                                border: 2px solid #28a745;
                                border-radius: 5px;
                                padding: 10px;
                                margin: 10px 0;
                                font-family: monospace;
                                font-size: 12px;
                                word-break: break-all;
                                cursor: pointer;
                                text-align: center;
                            `;
                            tokenDisplay.textContent = result.token;
                            tokenDisplay.title = '点击复制Token';


                            tokenDisplay.addEventListener('click', async () => {
                                try {
                                    await navigator.clipboard.writeText(result.token);
                                    showMessage('Token已复制到剪贴板!', 'success');
                                } catch (err) {

                                    const textArea = document.createElement('textarea');
                                    textArea.value = result.token;
                                    document.body.appendChild(textArea);
                                    textArea.select();
                                    document.execCommand('copy');
                                    document.body.removeChild(textArea);
                                    showMessage('Token已复制到剪贴板!', 'success');
                                }
                            });


                            const rechargeNotice = document.createElement('div');
                            rechargeNotice.style.cssText = `
                                background: #fff3cd;
                                border: 1px solid #ffeaa7;
                                border-radius: 5px;
                                padding: 10px;
                                margin: 10px 0;
                                font-size: 14px;
                                color: #856404;
                                text-align: center;
                            `;
                            rechargeNotice.innerHTML = `
                                ⚠️ <strong>重要提示</strong><br/>
                                新用户默认1000次查询机会,请充值后使用答题功能。<br/>
                                请妥善保存您的Token,它是您的唯一凭证!
                            `;


                            messageDiv.parentNode.insertBefore(tokenDisplay, messageDiv.nextSibling);
                            messageDiv.parentNode.insertBefore(rechargeNotice, tokenDisplay.nextSibling);


                            createBtn.textContent = '开始答题';
                            createBtn.onclick = () => {
                                closeDialog();
                                resolve({
                                    success: true,
                                    hasToken: true,
                                    token: result.token,
                                    message: '新Token已生成,您可以开始答题了!'
                                });
                            };
                        } else {
                            throw new Error(result.message || 'Token生成失败');
                        }
                    } catch (error) {

                        showMessage('生成Token失败: ' + error.message, 'error');
                        createBtn.disabled = false;
                        createBtn.textContent = '🆕 生成新Token';
                    }
                });


                inputBtn.addEventListener('click', () => {
                    inputArea.style.display = 'block';
                    tokenInput.focus();
                });


                verifyBtn.addEventListener('click', async () => {
                    const token = tokenInput.value.trim();
                    if (!token) {
                        showMessage('请输入Token', 'error');
                        return;
                    }

                    try {
                        verifyBtn.disabled = true;
                        verifyBtn.textContent = '验证中...';
                        showMessage('正在验证Token...', 'info');

                        const result = await this.verifyUserToken(token);

                        if (result.success) {
                            showMessage('Token验证成功!', 'success');
                            setTimeout(() => {
                                closeDialog();
                                resolve({
                                    success: true,
                                    hasToken: true,
                                    token: result.token,
                                    message: 'Token验证成功,您可以开始答题了!'
                                });
                            }, 1500);
                        } else {
                            throw new Error(result.message || 'Token验证失败');
                        }
                    } catch (error) {

                        showMessage('Token验证失败: ' + error.message, 'error');
                        verifyBtn.disabled = false;
                        verifyBtn.textContent = '验证Token';
                    }
                });


                cancelBtn.addEventListener('click', () => {
                    inputArea.style.display = 'none';
                    tokenInput.value = '';
                    messageDiv.style.display = 'none';
                });


                tokenInput.addEventListener('keypress', (e) => {
                    if (e.key === 'Enter') {
                        verifyBtn.click();
                    }
                });
            });
        }
    };

    function handleSubmitConfirmDialog() {
        const documents = [
            document,
            window.parent?.document,
            window.top?.document
        ].filter(doc => doc);

        let confirmDialog = null;
        let foundInDocument = null;

        for (const doc of documents) {
            try {
                confirmDialog = doc.querySelector('.popBottom');
                if (confirmDialog) {
                    foundInDocument = doc;

                    break;
                }
            } catch (error) {

            }
        }

        if (!confirmDialog) {
            return false;
        }


        const targetDoc = foundInDocument || document;


        const popContent = targetDoc.querySelector('#popcontent');
        if (!popContent || !popContent.textContent.includes('确认提交')) {
            return false;
        }


        const submitBtn = targetDoc.querySelector('#popok');
        if (!submitBtn) {
            return false;
        }


        try {
            submitBtn.click();
            console.log('✅ [提交确认] 已点击提交按钮');


            GLOBAL_STATE.lastAnswerTime = Date.now();
            GLOBAL_STATE.isAnswering = false;
            GLOBAL_STATE.isChapterTesting = false;

            console.log('📝 [提交确认] 章节测验已完成,状态已重置');




            return true;
        } catch (error) {
            console.warn('❌ [提交确认] 点击提交按钮失败:', error);
            return false;
        }
    }

    function monitorSubmitDialog() {
        let checkCount = 0;
        const maxChecks = 10;

        const checkInterval = setInterval(() => {
            checkCount++;


            const dialogHandled = handleSubmitConfirmDialog();


            if (dialogHandled || checkCount >= maxChecks) {
                clearInterval(checkInterval);
            }
        }, 1000);

    }


    function getXueqiQuestions() {
        try {
            const questions = [];


            const examTypeElement = document.querySelector('.test-part .f18.c_2d4.fb');
            const examType = examTypeElement ? examTypeElement.textContent.trim() : '未知题型';


            const examInfoElement = document.querySelector('.test-part .c_dan');

            const questionElements = document.querySelectorAll('.questionItem');

            questionElements.forEach((questionEl, index) => {
                const questionData = {
                    type: examType,
                    questionType: '',
                    number: index + 1,
                    stem: '',
                    options: [],
                    score: ''
                };


                if (questionEl.classList.contains('singItem') || questionEl.querySelector('.singItem')) {
                    questionData.questionType = '单选题';
                } else if (questionEl.classList.contains('judge') || questionEl.querySelector('.judge')) {
                    questionData.questionType = '判断题';
                } else if (questionEl.classList.contains('Mutli') || questionEl.querySelector('.Mutli')) {
                    questionData.questionType = '多选题';
                } else {
                    questionData.questionType = '未知题型';
                }


                const stemElement = questionEl.querySelector('.queStemC');
                if (stemElement) {

                    const numberEl = stemElement.querySelector('.din.fb.mr10');
                    if (numberEl) {
                        questionData.number = numberEl.textContent.trim();
                    }


                    const contentEls = stemElement.querySelectorAll('.din');
                    if (contentEls.length > 1) {

                        const contentEl = contentEls[1];
                        if (contentEl) {

                            const tableSpan = contentEl.querySelector('table span');
                            if (tableSpan) {
                                questionData.stem = tableSpan.textContent.trim();
                            }

                            else {
                                const pEl = contentEl.querySelector('p');
                                if (pEl) {
                                    questionData.stem = pEl.textContent.trim();
                                } else {

                                    const textContent = contentEl.textContent.trim();

                                    questionData.stem = textContent.replace(/\s+/g, ' ').trim();
                                }
                            }
                        }
                    }


                    if (!questionData.stem) {

                        const allText = stemElement.textContent.trim();

                        const cleanText = allText.replace(/^\d+\.\s*/, '').replace(/(\d+分)$/, '').trim();
                        if (cleanText) {
                            questionData.stem = cleanText;
                        }
                    }


                    const scoreEl = stemElement.querySelector('.f13.c_dan var');
                    if (scoreEl) {
                        questionData.score = scoreEl.textContent.trim() + '分';
                    }
                }


                if (questionData.questionType === '判断题') {

                    const judgeButtons = questionEl.querySelectorAll('.JudgeBtn input');
                    judgeButtons.forEach((btn, idx) => {
                        const value = btn.value.trim();
                        questionData.options.push({
                            label: idx === 0 ? 'T' : 'F',
                            content: value,
                            element: btn
                        });
                    });
                } else if (questionData.questionType === '多选题') {

                    const optionElements = questionEl.querySelectorAll('dd.clearfix');
                    optionElements.forEach(optionEl => {
                        const optionLabel = optionEl.querySelector('.duplexCheck');
                        const optionContent = optionEl.querySelector('div');

                        if (optionLabel && optionContent) {
                            questionData.options.push({
                                label: optionLabel.textContent.trim(),
                                content: optionContent.textContent.trim(),
                                element: optionEl
                            });
                        }
                    });
                } else {

                    const optionElements = questionEl.querySelectorAll('dd.clearfix');
                    optionElements.forEach(optionEl => {
                        const optionLabel = optionEl.querySelector('.singleCheck');
                        const optionContent = optionEl.querySelector('div');

                        if (optionLabel && optionContent) {
                            questionData.options.push({
                                label: optionLabel.textContent.trim(),
                                content: optionContent.textContent.trim(),
                                element: optionEl
                            });
                        }
                    });
                }


                questions.push(questionData);
            });

            return questions;
        } catch (error) {
            return [];
        }
    }


    function getChaoxingQuestions() {
        try {
            logMessage('🔍 [超星] 开始解析题目...', 'info');
            const questions = [];
            const currentUrl = window.location.href;


            let pageType = '未知';
            let isExamPage = false;
            let isHomeworkPage = false;
            let isChapterTestPage = false;

            if (currentUrl.includes('/exam-ans/mooc2/exam/')) {
                pageType = '考试';
                isExamPage = true;

            } else if (currentUrl.includes('/mooc-ans/mooc2/work/')) {
                pageType = '作业';
                isHomeworkPage = true;

            } else if (currentUrl.includes('/mooc-ans/work/doHomeWorkNew/') ||
                currentUrl.includes('/mooc-ans/api/work/') ||
                currentUrl.includes('/ananas/modules/work/')) {
                pageType = '章节测验';
                isChapterTestPage = true;

            } else {

                const hasTypenameAttr = document.querySelector('.questionLi[typename]') !== null;
                if (hasTypenameAttr) {
                    pageType = '作业';
                    isHomeworkPage = true;

                } else {
                    pageType = '考试';
                    isExamPage = true;

                }
            }


            const questionElements = document.querySelectorAll('.questionLi');

            if (questionElements.length === 0) {
                logMessage('⚠️ [超星] 未找到题目元素 (.questionLi),请确认页面结构。', 'warning');
                return [];
            }

            logMessage(`[超星] 发现 ${questionElements.length} 个题目容器 (${pageType}页面)。`, 'info');

            questionElements.forEach((questionEl, index) => {
                try {
                    const questionData = {
                        type: '超星学习通',
                        questionType: '未知题型',
                        number: index + 1,
                        stem: '',
                        options: [],
                        score: '',
                        questionId: ''
                    };


                    let questionId = questionEl.getAttribute('data') ||
                        questionEl.id?.replace('sigleQuestionDiv_', '') || '';


                    if (!questionId) {
                        const optionWithQid = questionEl.querySelector('[qid]');
                        if (optionWithQid) {
                            questionId = optionWithQid.getAttribute('qid');

                        }
                    }

                    questionData.questionId = questionId;


                    if (isHomeworkPage) {

                        const typeNameAttr = questionEl.getAttribute('typename');
                        if (typeNameAttr) {
                            questionData.questionType = typeNameAttr;
                            console.log(`[作业页面] 从typename属性获取题型: ${typeNameAttr}`);
                        }
                    } else if (isExamPage) {

                        const markNameEl = questionEl.querySelector('h3.mark_name');
                        if (markNameEl) {
                            const typeScoreSpan = markNameEl.querySelector('span.colorShallow');
                            if (typeScoreSpan) {
                                const typeScoreText = typeScoreSpan.textContent.trim();

                                const match = typeScoreText.match(/\(([^,)]+)(?:,\s*([^)]+))?\)/);
                                if (match) {
                                    questionData.questionType = match[1].trim();
                                    if (match[2]) {
                                        questionData.score = match[2].trim();
                                    }
                                    console.log(`[考试页面] 从span.colorShallow获取题型: ${questionData.questionType}`);
                                }
                            }
                        }
                    }


                    const markNameEl = questionEl.querySelector('h3.mark_name');
                    if (markNameEl) {

                        const titleText = markNameEl.childNodes[0]?.textContent?.trim() || '';
                        const numberMatch = titleText.match(/^(\d+)\./);
                        if (numberMatch) {
                            questionData.number = numberMatch[1];
                        }


                        let stemText = '';

                        if (isExamPage) {

                            const stemDiv = markNameEl.querySelector('div[style*="overflow:hidden"]');
                            if (stemDiv) {
                                stemText = stemDiv.textContent.trim();

                            } else {

                                const fullText = markNameEl.textContent.trim();
                                stemText = fullText.replace(/^\d+\.\s*/, '');
                                const typePattern = /^\s*\((单选题|多选题|判断题|填空题)(?:,\s*[^)]+)?\)\s*/;
                                stemText = stemText.replace(typePattern, '').trim();

                            }
                        } else if (isHomeworkPage) {

                            const fullText = markNameEl.textContent.trim();

                            stemText = fullText.replace(/^\d+\.\s*/, '');

                            const typePattern = /^\s*\((单选题|多选题|判断题|填空题)(?:,\s*[^)]+)?\)\s*/;
                            stemText = stemText.replace(typePattern, '').trim();

                        }

                        questionData.stem = stemText;


                        if (!questionData.questionType || questionData.questionType === '未知题型') {

                            if (questionData.stem && (
                                questionData.stem.includes('____') ||
                                questionData.stem.includes('()') ||
                                questionData.stem.includes('()') ||
                                questionData.stem.includes('_____') ||
                                questionData.stem.includes('填空') ||
                                questionData.stem.includes('空白')
                            )) {
                                questionData.questionType = '填空题';

                            } else {

                                questionData.questionType = '单选题';

                            }
                        }
                    }



                    const answerContainer = questionEl.querySelector('.stem_answer');
                    const hasInputElements = questionEl.querySelectorAll('input[type="text"], textarea').length > 0;


                    const hasBlankItems = questionEl.querySelectorAll('.blankItemDiv').length > 0;
                    const hasUEditor = questionEl.querySelectorAll('textarea[name*="answerEditor"]').length > 0;
                    const hasTiankongSize = questionEl.querySelector('input[name*="tiankongsize"]');


                    const typeElement = questionEl.querySelector('.colorShallow');
                    const typeText = typeElement ? typeElement.textContent : '';
                    const isBlankQuestionByType = typeText.includes('填空题') || typeText.includes('【填空题】');

                    if ((hasInputElements || hasBlankItems || hasUEditor || hasTiankongSize || isBlankQuestionByType) &&
                        questionData.questionType !== '填空题') {
                        questionData.questionType = '填空题';
                    }

                    if (questionData.questionType !== '填空题') {
                        if (answerContainer) {
                            const optionElements = answerContainer.querySelectorAll('.clearfix.answerBg');

                            optionElements.forEach(optionEl => {

                                const labelSpan = optionEl.querySelector('.num_option, .num_option_dx');

                                const contentDiv = optionEl.querySelector('.answer_p');

                                if (labelSpan && contentDiv) {
                                    let label = labelSpan.textContent.trim();
                                    let content = '';


                                    const pElement = contentDiv.querySelector('p');
                                    if (pElement) {
                                        content = pElement.textContent.trim();

                                        if (questionData.questionType === '判断题') {
                                            if (content === '对') {
                                                label = 'T';
                                                content = '正确';
                                            } else if (content === '错') {
                                                label = 'F';
                                                content = '错误';
                                            }
                                        }
                                    } else {
                                        content = contentDiv.textContent.trim();
                                    }

                                    questionData.options.push({
                                        label: label,
                                        content: content,
                                        element: optionEl,
                                        dataValue: labelSpan.getAttribute('data') || label,
                                        qid: labelSpan.getAttribute('qid') || questionData.questionId,
                                        isMultipleChoice: questionData.questionType === '多选题'
                                    });
                                }
                            });
                        }
                    } else {


                        const stemAnswerEl = questionEl.querySelector('.stem_answer');
                        if (stemAnswerEl) {

                            const answerContainers = stemAnswerEl.querySelectorAll('.Answer');

                            answerContainers.forEach((answerContainer, index) => {

                                const textareaEl = answerContainer.querySelector('textarea[name*="answerEditor"]');
                                const iframe = answerContainer.querySelector('iframe');
                                const ueditorContainer = answerContainer.querySelector('.edui-editor');

                                if (textareaEl) {
                                    const editorId = textareaEl.id || textareaEl.name;


                                    let ueditorInstanceName = null;
                                    if (iframe && iframe.src) {
                                        const match = iframe.src.match(/ueditorInstant(\d+)/);
                                        if (match) {
                                            ueditorInstanceName = `ueditorInstant${match[1]}`;
                                        }
                                    }


                                    let iframeBody = null;
                                    try {
                                        if (iframe && iframe.contentDocument && iframe.contentDocument.body) {
                                            iframeBody = iframe.contentDocument.body;
                                        }
                                    } catch (e) {

                                    }

                                    questionData.options.push({
                                        label: `填空${index + 1}`,
                                        content: '',
                                        element: textareaEl,
                                        dataValue: '',
                                        isFillInBlank: true,
                                        inputType: 'ueditor',
                                        editorId: editorId,
                                        ueditorContainer: ueditorContainer,
                                        iframe: iframe,
                                        iframeBody: iframeBody,
                                        ueditorInstanceName: ueditorInstanceName,
                                        answerContainer: answerContainer
                                    });
                                } else {

                                    const inputEl = answerContainer.querySelector('input[type="text"], textarea');
                                    if (inputEl) {
                                        questionData.options.push({
                                            label: `填空${index + 1}`,
                                            content: '',
                                            element: inputEl,
                                            dataValue: '',
                                            isFillInBlank: true,
                                            inputType: 'normal',
                                            answerContainer: answerContainer
                                        });
                                    }
                                }
                            });


                            if (answerContainers.length === 0) {
                                const inputElements = stemAnswerEl.querySelectorAll('input[type="text"], textarea');
                                inputElements.forEach((inputEl, index) => {
                                    questionData.options.push({
                                        label: `填空${index + 1}`,
                                        content: '',
                                        element: inputEl,
                                        dataValue: '',
                                        isFillInBlank: true,
                                        inputType: 'normal'
                                    });
                                });
                            }
                        }


                        if (questionData.options.length === 0) {
                            questionData.options.push({
                                label: '填空1',
                                content: '',
                                element: null,
                                dataValue: '',
                                isFillInBlank: true,
                                isVirtual: true
                            });
                        }
                    }


                    if (questionData.stem && (questionData.options.length > 0 || questionData.questionType === '填空题')) {
                        questions.push(questionData);
                    } else {
                        logMessage(`⚠️ [超星] 第 ${index + 1} 题数据不完整,跳过`, 'warning');
                    }

                } catch (e) {
                    logMessage(`❌ [超星] 解析第 ${index + 1} 题时出错: ${e.message}`, 'error');
                }
            });

            if (questions.length > 0) {
                logMessage(`✅ [超星] 成功解析 ${questions.length} 道题目`, 'success');


                const typeCount = {};
                questions.forEach(q => {
                    typeCount[q.questionType] = (typeCount[q.questionType] || 0) + 1;
                });

                const typeStats = Object.entries(typeCount)
                    .map(([type, count]) => `${type}:${count}`)
                    .join(' ');
                logMessage(`📊 [超星] 题型分布: ${typeStats}`, 'info');
            } else {
                logMessage('❌ [超星] 未能解析到任何题目', 'error');
            }

            return questions;

        } catch (error) {
            logMessage(`❌ [超星] 题目解析失败: ${error.message}`, 'error');
            return [];
        }
    }


    function getExamQuestions() {
        try {

            if (!currentSite) {
                detectSite();
            }


            const selectors = [
                '.questionLi',
                '.questionItem',
                '.question-item',
                '.exam-question',
                '[class*="question"]'
            ];

            let foundElements = [];
            let usedSelector = '';

            for (const selector of selectors) {
                const elements = document.querySelectorAll(selector);
                if (elements.length > 0) {
                    foundElements = elements;
                    usedSelector = selector;
                    break;
                }
            }

            if (foundElements.length === 0) {
                return [];
            }

            console.log(`✅ [调试] 使用选择器 "${usedSelector}" 找到 ${foundElements.length} 个题目元素`);


            if (currentSite && typeof currentSite.getQuestions === 'function') {
                console.log('🔍 [调试] 调用站点专用解析函数:', currentSite.name);
                const questions = currentSite.getQuestions();
                console.log('🔍 [调试] 解析结果:', questions.length, '道题目');
                return questions;
            } else {
                console.warn('⚠️ [调试] 站点解析函数不存在,尝试通用解析');
                return tryGenericParsing(foundElements, usedSelector);
            }

        } catch (error) {
            console.error('❌ [调试] 获取题目时出错:', error);
            return [];
        }
    }


    function tryGenericParsing(elements, selector) {
        const questions = [];

        elements.forEach((el, index) => {
            try {
                const questionData = {
                    type: '通用解析',
                    questionType: '未知题型',
                    number: index + 1,
                    stem: '',
                    options: [],
                    score: ''
                };


                const textContent = el.textContent.trim();
                if (textContent.length > 10) {
                    questionData.stem = textContent.substring(0, 200) + (textContent.length > 200 ? '...' : '');


                    if (textContent.includes('单选') || textContent.includes('Single')) {
                        questionData.questionType = '单选题';
                    } else if (textContent.includes('多选') || textContent.includes('Multiple')) {
                        questionData.questionType = '多选题';
                    } else if (textContent.includes('判断') || textContent.includes('True') || textContent.includes('False')) {
                        questionData.questionType = '判断题';
                    }

                    questions.push(questionData);
                    console.log(`🔍 [调试] 通用解析题目 ${index + 1}:`, questionData.questionType, questionData.stem.substring(0, 50) + '...');
                }
            } catch (error) {
                console.warn(`⚠️ [调试] 通用解析第 ${index + 1} 题失败:`, error.message);
            }
        });

        console.log(`✅ [调试] 通用解析完成,共 ${questions.length} 道题目`);
        return questions;
    }




    async function callCloudAPI(questionData) {
        try {
            const token = await TokenManager.getValidToken();

            const requestData = {
                question: questionData.stem,
                questionType: questionData.questionType,
                options: questionData.options.map(opt => ({
                    label: opt.label,
                    content: opt.content
                }))
            };


            if (questionData.questionType === '填空题') {
                requestData.options = [];
                requestData.fillInBlank = true;
            }

            const response = await gmFetch(`${SERVER_CONFIG.answerApiUrl}/answer`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-User-Token': token
                },
                body: JSON.stringify(requestData),
                timeout: SERVER_CONFIG.timeout
            });


            if (response.status === 429) {
                logMessage('⚠️ 请求过于频繁,等待10秒后继续...', 'warning');

                await new Promise(resolve => {
                    let remaining = 10;
                    const countdownInterval = setInterval(() => {
                        if (remaining <= 0) {
                            clearInterval(countdownInterval);
                            resolve();
                            return;
                        }

                        const statusElement = document.getElementById('question-count');
                        if (statusElement) {
                            statusElement.textContent = `⏳ 限流等待中... ${remaining}s`;
                        }
                        remaining--;
                    }, 1000);
                });

                throw new Error('429_RATE_LIMIT_HANDLED');
            }

            if (!response.ok) {
                if (response.status === 401) {
                    TokenManager.clearToken();
                    throw new Error('Token无效或已过期,请刷新页面重新获取Token');
                }

                let errorText = `API请求失败: ${response.status} ${response.statusText}`;
                try {
                    const errorResponse = await response.json();
                    if (errorResponse.message) {
                        errorText = `API请求失败: ${errorResponse.message}`;
                    }
                } catch (jsonError) {
                    try {
                        const textResponse = await response.text();
                        if (textResponse) {
                            errorText = `API请求失败: ${response.status} ${response.statusText} - ${textResponse.substring(0, 200)}`;
                        }
                    } catch (textError) {

                    }
                }
                throw new Error(errorText);
            }

            const result = await response.json();

            if (!result.success) {
                throw new Error(result.message || '云端分析失败');
            }


            if (result.quota) {
                logMessage(result.quota.message, 'info');

            }


            result.data.cached = result.cached || false;
            result.data.responseTime = result.data.responseTime || 0;

            return result.data;

        } catch (error) {
            console.error('❌ [客户端API] 调用失败:', error.message);


            if (error.message.includes('Token') || error.message.includes('token')) {
                logMessage('❌ Token验证失败,请刷新页面重新获取Token', 'error');
                throw new Error('Token验证失败,请刷新页面重新获取Token');
            }

            throw error;
        }
    }



    async function autoAnswerAllQuestions(delay = 1000) {
        try {

            if (GLOBAL_STATE.isAnswering || GLOBAL_STATE.isChapterTesting) {
                logMessage('⏸️ 已有答题任务在进行中,请稍后再试', 'warning');
                return [];
            }

            GLOBAL_STATE.isAnswering = true;

            const questions = getExamQuestions();

            if (!questions || !Array.isArray(questions) || questions.length === 0) {
                logMessage('❌ 批量答题失败: 未找到题目', 'error');
                return [];
            }

            logMessage(`🚀 开始自动答题,共 ${questions.length} 道题目`, 'info');

            // 更新答题窗口状态
            addTestLog(`开始考试答题,共 ${questions.length} 道题目`, 'info');
            {
                const typeCount = {};
                questions.forEach(q => {
                    const t = q.questionType || '未知题型';
                    typeCount[t] = (typeCount[t] || 0) + 1;
                });
                const typeStats = Object.entries(typeCount).map(([t, c]) => `${t}:${c}`).join(' ');
                if (typeStats) addTestLog(`题型:${typeStats}`, 'info');
            }
            updateTestProgress(0, questions.length);

            const results = [];
            for (let i = 0; i < questions.length; i++) {
                // 更新答题窗口进度
                updateTestProgress(i + 1, questions.length);

                const statusElement = document.getElementById('question-count');
                if (statusElement) {
                    statusElement.textContent = `📝 答题进度: ${i + 1}/${questions.length} (${Math.round((i + 1) / questions.length * 100)}%)`;
                }
                try {
                    const result = await answerSingleQuestion(i);
                    if (result) {
                        results.push(result);
                    } else {
                        logMessage(`❌ 第 ${i + 1} 题答题失败`, 'error');
                    }
                } catch (error) {
                    logMessage(`❌ 第 ${i + 1} 题出错: ${error.message}`, 'error');
                }


                if (i < questions.length - 1) {
                    await new Promise(resolve => {
                        let remaining = Math.ceil(delay / 1000);
                        const countdownInterval = setInterval(() => {
                            if (remaining <= 0) {
                                clearInterval(countdownInterval);
                                resolve();
                                return;
                            }

                            if (statusElement) {
                                statusElement.textContent = `⏳ 等待中... ${remaining}s (第${i + 2}题准备中)`;
                            }

                            remaining--;
                        }, 1000);
                    });
                }
            }

            setTimeout(() => {
                updateQuestionCount();
            }, 1000);

            if (results.length === questions.length) {
                logMessage(`🎉 自动答题完成!全部成功 (${results.length}/${questions.length})`, 'success');
            } else {
                logMessage(`⚠️ 自动答题完成,成功: ${results.length}/${questions.length}`, 'warning');
            }

            return results;
        } catch (error) {
            logMessage(`❌ 批量答题失败: ${error.message}`, 'error');
            return [];
        } finally {

            GLOBAL_STATE.isAnswering = false;
            GLOBAL_STATE.lastAnswerTime = Date.now();
        }
    }


    async function fillAnswers(questions, answers) {
        if (!questions || questions.length === 0) {
            logMessage('❌ 没有题目需要填写答案', 'error');
            return { success: false, message: '没有题目需要填写答案' };
        }

        if (!answers || answers.length === 0) {
            logMessage('❌ 没有获取到答案', 'error');
            return { success: false, message: '没有获取到答案' };
        }

        let successCount = 0;
        const results = [];

        for (let i = 0; i < Math.min(questions.length, answers.length); i++) {
            const question = questions[i];
            const answer = answers[i];

            try {

                logQuestionAnswer(question.stem, answer.answer, question.questionType);

                const result = await fillSingleAnswer(question, answer);
                results.push(result);

                if (result.success) {
                    successCount++;
                    logMessage(`✅ 第${i + 1}题填写成功`, 'success');
                } else {
                    logMessage(`❌ 第${i + 1}题填写失败: ${result.message}`, 'error');
                }


                await new Promise(resolve => setTimeout(resolve, 500));

            } catch (error) {
                logMessage(`❌ 第${i + 1}题处理异常: ${error.message}`, 'error');
                results.push({ success: false, message: error.message });
            }
        }

        const message = `答题完成:成功 ${successCount}/${questions.length} 题`;
        logMessage(message, successCount > 0 ? 'success' : 'error');

        return {
            success: successCount > 0,
            message: message,
            successCount: successCount,
            totalCount: questions.length,
            results: results
        };
    }


    function selectXueqiAnswer(questionIndex, answer) {
        try {
            const questionElements = document.querySelectorAll('.questionItem');

            if (questionIndex >= questionElements.length) {
                console.log('题目索引超出范围');
                return false;
            }

            const questionEl = questionElements[questionIndex];


            if (questionEl.classList.contains('judge') || questionEl.querySelector('.judge')) {

                const judgeButtons = questionEl.querySelectorAll('.JudgeBtn input');

                for (let btn of judgeButtons) {
                    const btnValue = btn.value.trim();

                    if ((answer === 'T' && btnValue === '正确') ||
                        (answer === 'F' && btnValue === '错误')) {


                        btn.click();


                        const judgeBtn = btn.parentElement;
                        judgeBtn.style.backgroundColor = '#e8f5e8';
                        setTimeout(() => {
                            judgeBtn.style.backgroundColor = '';
                        }, 1000);

                        return true;
                    }
                }
            } else if (questionEl.classList.contains('Mutli') || questionEl.querySelector('.Mutli')) {

                const options = questionEl.querySelectorAll('dd.clearfix');


                if (!answer || typeof answer !== 'string' || answer.length === 0) {
                    console.error('多选题答案无效:', answer);
                    return false;
                }

                let answersToSelect;
                try {

                    answersToSelect = [...answer];
                } catch (err) {
                    console.error('多选题答案转换失败:', err);
                    return false;
                }

                let successCount = 0;

                for (let option of options) {
                    const optionLabel = option.querySelector('.duplexCheck');
                    if (optionLabel) {
                        const labelText = optionLabel.textContent.trim();

                        if (answersToSelect && answersToSelect.includes(labelText)) {

                            option.click();


                            option.style.backgroundColor = '#e8f5e8';
                            setTimeout(() => {
                                option.style.backgroundColor = '';
                            }, 1000);

                            successCount++;
                        }
                    }
                }

                return answersToSelect && successCount === answersToSelect.length;
            } else {

                const options = questionEl.querySelectorAll('dd.clearfix');

                for (let option of options) {
                    const optionLabel = option.querySelector('.singleCheck');
                    if (optionLabel && optionLabel.textContent.trim() === answer) {

                        option.click();


                        option.style.backgroundColor = '#e8f5e8';
                        setTimeout(() => {
                            option.style.backgroundColor = '';
                        }, 1000);

                        return true;
                    }
                }
            }

            return false;
        } catch (error) {
            console.error('选择答案失败:', error);
            return false;
        }
    }


    function selectChaoxingAnswer(questionIndex, answer) {
        try {
            logMessage(`🎯 [超星] 选择第 ${questionIndex + 1} 题答案: ${answer}`, 'info');
            const questions = getExamQuestions();
            const questionData = questions[questionIndex];

            if (!questionData) {
                logMessage(`❌ [超星] 第 ${questionIndex + 1} 题数据未找到`, 'error');
                return false;
            }


            if (questionData.questionType === '填空题') {
                return selectFillInBlankAnswer(questionData, answer);
            }


            let answersToSelect = [];
            if (questionData.questionType === '判断题') {

                if (answer === 'T' || answer === 'true' || answer === '对') {
                    answersToSelect = ['T'];
                } else if (answer === 'F' || answer === 'false' || answer === '错') {
                    answersToSelect = ['F'];
                } else {

                    const option = questionData.options.find(opt => opt.label === answer);
                    if (option && option.dataValue) {
                        answersToSelect = [option.dataValue === 'true' ? 'T' : 'F'];
                    } else {
                        answersToSelect = [answer];
                    }
                }
            } else {

                answersToSelect = [...answer.toUpperCase()];
            }

            let successCount = 0;
            const questionId = questionData.questionId;


            if (questionData.questionType === '多选题') {
                return new Promise(async (resolve) => {
                    for (let i = 0; i < answersToSelect.length; i++) {
                        const ans = answersToSelect[i];


                        const targetOption = questionData.options.find(opt => opt.label === ans);

                        if (targetOption && targetOption.element) {

                            const isSelected = targetOption.element.classList.contains('hasBeenTo') ||
                                targetOption.element.classList.contains('selected') ||
                                targetOption.element.querySelector('.num_option, .num_option_dx')?.classList.contains('hasBeenTo');

                            if (isSelected) {

                                successCount++;
                                continue;
                            }


                            try {

                                const isHomeworkPage = document.querySelector('.questionLi[typename]') !== null;
                                if (isHomeworkPage) {

                                    if (typeof pageWindow.addMultipleChoice === 'function') {
                                        pageWindow.addMultipleChoice(targetOption.element);

                                    } else {
                                        targetOption.element.click();
                                        logMessage(`✅ [超星] 通过click()选择选项 ${ans}`, 'success');
                                    }
                                } else {

                                    const optionQid = targetOption.qid || questionId;
                                    let success = false;



                                    if (typeof pageWindow.saveMultiSelect === 'function' && optionQid) {
                                        try {
                                            pageWindow.saveMultiSelect(targetOption.element, optionQid);

                                            success = true;
                                        } catch (e) {
                                            console.log(`[超星] saveMultiSelect失败:`, e.message);
                                        }
                                    }


                                    if (!success && typeof pageWindow.addMultipleChoice === 'function') {
                                        try {
                                            pageWindow.addMultipleChoice(targetOption.element);

                                            success = true;
                                        } catch (e) {
                                            console.log(`[超星] addMultipleChoice失败:`, e.message);
                                        }
                                    }


                                    if (!success) {
                                        try {
                                            targetOption.element.click();
                                            logMessage(`✅ [超星] 通过click()选择选项 ${ans}`, 'success');
                                            success = true;
                                        } catch (e) {
                                            console.log(`[超星] click失败:`, e.message);
                                        }
                                    }

                                    if (!success) {
                                        logMessage(`❌ [超星] 所有方法都失败,无法选择多选题选项 ${ans}`, 'error');
                                    }
                                }


                                targetOption.element.style.backgroundColor = '#e8f5e8';
                                targetOption.element.style.border = '2px solid #4ade80';

                                setTimeout(() => {
                                    targetOption.element.style.backgroundColor = '';
                                    targetOption.element.style.border = '';
                                }, 2000);

                                successCount++;


                                if (i < answersToSelect.length - 1) {
                                    await new Promise(resolve => setTimeout(resolve, 300));
                                }

                            } catch (clickError) {

                            }
                        } else {

                        }
                    }


                    const success = successCount > 0;
                    if (success) {

                    } else {

                    }
                    resolve(success);
                });
            } else {

                answersToSelect.forEach(ans => {

                    let targetOption = null;

                    if (questionData.questionType === '判断题') {

                        targetOption = questionData.options.find(opt =>
                            opt.label === ans ||
                            (ans === 'T' && (opt.dataValue === 'true' || opt.content === '正确' || opt.content === '对')) ||
                            (ans === 'F' && (opt.dataValue === 'false' || opt.content === '错误' || opt.content === '错'))
                        );
                    } else {

                        targetOption = questionData.options.find(opt => opt.label === ans);
                    }

                    if (targetOption && targetOption.element) {

                        const isSelected = targetOption.element.classList.contains('hasBeenTo') ||
                            targetOption.element.classList.contains('selected') ||
                            targetOption.element.querySelector('.num_option, .num_option_dx')?.classList.contains('hasBeenTo');

                        if (isSelected) {

                            successCount++;
                            return;
                        }


                        try {

                            const isHomeworkPage = document.querySelector('.questionLi[typename]') !== null;


                            if (isHomeworkPage) {

                                if (typeof pageWindow.addChoice === 'function') {
                                    pageWindow.addChoice(targetOption.element);
                                    logMessage(`✅ [超星] 通过addChoice()选择选项 ${ans}`, 'success');
                                } else {
                                    targetOption.element.click();
                                    logMessage(`✅ [超星] 通过click()选择选项 ${ans}`, 'success');
                                }
                            } else {

                                const optionQid = targetOption.qid || questionId;
                                if (typeof pageWindow.saveSingleSelect === 'function' && optionQid) {
                                    pageWindow.saveSingleSelect(targetOption.element, optionQid);
                                    logMessage(`✅ [超星] 通过saveSingleSelect()选择选项 ${ans}`, 'success');
                                } else {

                                    targetOption.element.click();
                                    logMessage(`✅ [超星] 通过click()选择选项 ${ans}`, 'success');
                                }
                            }


                            targetOption.element.style.backgroundColor = '#e8f5e8';
                            targetOption.element.style.border = '2px solid #4ade80';

                            setTimeout(() => {
                                targetOption.element.style.backgroundColor = '';
                                targetOption.element.style.border = '';
                            }, 2000);

                            successCount++;

                        } catch (clickError) {
                            logMessage(`❌ [超星] 点击选项 ${ans} 失败: ${clickError.message}`, 'error');
                            console.error('[超星] 点击错误详情:', clickError);
                        }
                    } else {
                        logMessage(`⚠️ [超星] 未找到答案选项 '${ans}'`, 'warning');
                        console.log('[超星] 可用选项:', questionData.options.map(opt => `${opt.label}(${opt.content})`));
                    }
                });
            }


            const success = successCount > 0;
            if (success) {
                logMessage(`✅ [超星] 第 ${questionIndex + 1} 题答案选择完成 (${successCount}/${answersToSelect.length})`, 'success');
            } else {
                logMessage(`❌ [超星] 第 ${questionIndex + 1} 题答案选择失败`, 'error');
            }

            return success;

        } catch (error) {
            logMessage(`❌ [超星] 选择答案时出错: ${error.message}`, 'error');
            console.error('[超星] 答案选择错误:', error);
            return false;
        }
    }


    function selectFillInBlankAnswer(questionData, answer) {
        try {
            logMessage(`📝 [填空题] 填入答案: ${answer}`, 'info');


            const fillInBlankOptions = questionData.options.filter(opt => opt.isFillInBlank);

            if (fillInBlankOptions.length === 0) {
                logMessage(`❌ [填空题] 未找到输入框`, 'error');
                return false;
            }

            let successCount = 0;


            let answers = [];
            if (answer.includes('|')) {
                answers = answer.split('|').map(a => a.trim());
                logMessage(`📝 [填空题] 使用|分隔,解析出${answers.length}个答案: ${answers.join(', ')}`, 'info');
            } else if (answer.includes(',')) {
                answers = answer.split(',').map(a => a.trim());
                logMessage(`📝 [填空题] 使用,分隔,解析出${answers.length}个答案: ${answers.join(', ')}`, 'info');
            } else if (answer.includes(',')) {
                answers = answer.split(',').map(a => a.trim());
                logMessage(`📝 [填空题] 使用,分隔,解析出${answers.length}个答案: ${answers.join(', ')}`, 'info');
            } else {
                answers = [answer.trim()];
                logMessage(`📝 [填空题] 单个答案: ${answers[0]}`, 'info');
            }

            fillInBlankOptions.forEach((option, index) => {

                if (index >= answers.length) {
                    logMessage(`⚠️ [填空题] 填空${index + 1}没有对应答案,跳过`, 'warning');
                    return;
                }
                const answerText = answers[index];
                logMessage(`📝 [填空题] 准备填入填空${index + 1}: "${answerText}"`, 'info');

                if (option.element) {
                    try {
                        if (option.inputType === 'ueditor') {

                            const editorId = option.editorId;
                            logMessage(`🔍 [填空题] UEditor ID: ${editorId}`, 'info');

                            let ueditorSuccess = false;


                            if (option.iframeBody) {
                                try {
                                    option.iframeBody.innerHTML = `<p>${answerText}<br></p>`;


                                    const inputEvent = new Event('input', { bubbles: true });
                                    option.iframeBody.dispatchEvent(inputEvent);

                                    logMessage(`✅ [填空题] 直接操作iframeBody填空${index + 1}已填入: ${answerText}`, 'success');
                                    ueditorSuccess = true;
                                    successCount++;
                                } catch (error) {
                                    logMessage(`⚠️ [填空题] 直接操作iframeBody失败: ${error.message}`, 'warning');
                                }
                            }


                            if (typeof window.UE !== 'undefined') {
                                let editor = null;


                                if (window.UE.getEditor) {
                                    editor = window.UE.getEditor(editorId);
                                }


                                if (!editor && window.UE.instants && option.ueditorInstanceName) {
                                    editor = window.UE.instants[option.ueditorInstanceName];
                                }

                                logMessage(`🔍 [填空题] UEditor实例状态: ${editor ? '找到' : '未找到'} (ID: ${editorId})`, 'info');

                                if (editor && editor.setContent) {
                                    editor.setContent(answerText);
                                    logMessage(`✅ [填空题] UEditor setContent填空${index + 1}已填入: ${answerText}`, 'success');
                                    ueditorSuccess = true;
                                    successCount++;
                                } else if (editor && editor.execCommand) {

                                    editor.execCommand('inserthtml', answerText);
                                    logMessage(`✅ [填空题] UEditor execCommand填空${index + 1}已填入: ${answerText}`, 'success');
                                    ueditorSuccess = true;
                                    successCount++;
                                } else if (editor && editor.body) {

                                    editor.body.innerHTML = `<p>${answerText}<br></p>`;
                                    logMessage(`✅ [填空题] UEditor body操作填空${index + 1}已填入: ${answerText}`, 'success');
                                    ueditorSuccess = true;
                                    successCount++;
                                } else {
                                    logMessage(`⚠️ [填空题] UEditor实例方法不可用,尝试其他方法`, 'warning');
                                }
                            } else {
                                logMessage(`⚠️ [填空题] UE对象不存在,尝试其他方法`, 'warning');
                            }


                            if (!ueditorSuccess && option.iframe) {
                                try {
                                    const iframe = option.iframe;
                                    logMessage(`🔍 [填空题] 重新尝试获取iframe body: ${iframe.id}`, 'info');


                                    const tryGetIframeBody = (attempts = 0) => {
                                        try {
                                            if (iframe.contentDocument && iframe.contentDocument.body) {
                                                const iframeBody = iframe.contentDocument.body;


                                                if (iframeBody.contentEditable === 'true' || iframeBody.classList.contains('view')) {
                                                    iframeBody.innerHTML = `<p>${answerText}<br></p>`;


                                                    const events = ['input', 'change', 'keyup', 'blur'];
                                                    events.forEach(eventType => {
                                                        try {
                                                            const event = new iframe.contentWindow.Event(eventType, { bubbles: true });
                                                            iframeBody.dispatchEvent(event);
                                                        } catch (e) {

                                                        }
                                                    });

                                                    logMessage(`✅ [填空题] iframe重新获取填空${index + 1}已填入: ${answerText}`, 'success');
                                                    ueditorSuccess = true;
                                                    successCount++;
                                                    return true;
                                                } else {
                                                    logMessage(`⚠️ [填空题] iframe body不可编辑`, 'warning');
                                                }
                                            }
                                        } catch (e) {
                                            logMessage(`⚠️ [填空题] iframe访问失败 (尝试${attempts + 1}): ${e.message}`, 'warning');
                                        }


                                        if (attempts < 2) {
                                            setTimeout(() => tryGetIframeBody(attempts + 1), 200);
                                        }
                                        return false;
                                    };

                                    tryGetIframeBody();

                                } catch (error) {
                                    logMessage(`⚠️ [填空题] iframe重新获取失败: ${error.message}`, 'warning');
                                }
                            }


                            if (!ueditorSuccess && option.iframe) {
                                try {
                                    const iframe = option.iframe;
                                    if (iframe.contentDocument && iframe.contentWindow) {
                                        const iframeDoc = iframe.contentDocument;
                                        const iframeBody = iframeDoc.body;

                                        if (iframeBody) {

                                            iframeBody.innerHTML = '';


                                            const p = iframeDoc.createElement('p');
                                            p.textContent = answerText;
                                            p.appendChild(iframeDoc.createElement('br'));
                                            iframeBody.appendChild(p);


                                            const inputEvent = new Event('input', { bubbles: true });
                                            iframeBody.dispatchEvent(inputEvent);

                                            logMessage(`✅ [填空题] 模拟操作填空${index + 1}已填入: ${answerText}`, 'success');
                                            ueditorSuccess = true;
                                            successCount++;
                                        }
                                    }
                                } catch (error) {
                                    logMessage(`⚠️ [填空题] 模拟操作失败: ${error.message}`, 'warning');
                                }
                            }


                            if (!ueditorSuccess && option.iframe) {
                                try {
                                    const iframe = option.iframe;
                                    logMessage(`🔍 [填空题] 使用保存的iframe引用: ${iframe.id}`, 'info');

                                    const setIframeContent = () => {
                                        try {
                                            if (iframe.contentDocument && iframe.contentDocument.body) {
                                                const body = iframe.contentDocument.body;
                                                body.innerHTML = `<p>${answerText}<br></p>`;


                                                if (iframe.contentWindow) {
                                                    const inputEvent = new iframe.contentWindow.Event('input', { bubbles: true });
                                                    body.dispatchEvent(inputEvent);
                                                }

                                                logMessage(`✅ [填空题] 使用iframe引用填空${index + 1}已填入: ${answerText}`, 'success');
                                                ueditorSuccess = true;
                                                successCount++;
                                                return true;
                                            }
                                        } catch (e) {
                                            logMessage(`⚠️ [填空题] iframe内容设置失败: ${e.message}`, 'warning');
                                        }
                                        return false;
                                    };


                                    if (!setIframeContent()) {
                                        setTimeout(setIframeContent, 200);
                                    }

                                } catch (error) {
                                    logMessage(`⚠️ [填空题] iframe引用操作失败: ${error.message}`, 'warning');
                                }
                            }
                        } else {

                            const element = option.element;


                            logMessage(`🔍 [填空题] 元素类型: ${element.tagName}, name: ${element.name}, id: ${element.id}`, 'info');


                            element.value = answerText;


                            if (element.value === answerText) {
                                logMessage(`✅ [填空题] 值设置成功: ${element.value}`, 'info');
                            } else {
                                logMessage(`❌ [填空题] 值设置失败,期望: ${answerText}, 实际: ${element.value}`, 'error');
                            }


                            const events = ['input', 'change', 'blur', 'keyup'];
                            events.forEach(eventType => {
                                const event = new Event(eventType, { bubbles: true, cancelable: true });
                                element.dispatchEvent(event);
                            });


                            element.focus();
                            setTimeout(() => {
                                element.blur();
                            }, 100);

                            logMessage(`✅ [填空题] 普通填空${index + 1}已填入: ${answerText}`, 'success');
                            successCount++;
                        }


                        if (option.element.style) {
                            option.element.style.backgroundColor = '#e8f5e8';
                            option.element.style.border = '2px solid #4ade80';

                            setTimeout(() => {
                                option.element.style.backgroundColor = '';
                                option.element.style.border = '';
                            }, 2000);
                        }


                        setTimeout(() => {
                            const currentValue = option.element.value;
                            if (currentValue === answerText) {
                                logMessage(`✅ [填空题] 验证成功,填空${index + 1}当前值: ${currentValue}`, 'success');
                            } else {
                                logMessage(`❌ [填空题] 验证失败,填空${index + 1}期望: ${answerText}, 实际: ${currentValue}`, 'error');
                                logMessage(`💡 [填空题] 请手动检查并填入答案: ${answerText}`, 'warning');
                            }
                        }, 1000);

                    } catch (error) {
                        logMessage(`❌ [填空题] 填空${index + 1}填入失败: ${error.message}`, 'error');
                        console.error(`[填空题] 详细错误:`, error);
                    }
                } else if (option.isVirtual) {

                    logMessage(`📝 [填空题] 虚拟填空${index + 1}答案: ${answerText}`, 'info');
                    logMessage(`💡 [填空题] 请手动将答案"${answerText}"填入对应位置`, 'warning');
                    successCount++;
                } else {
                    logMessage(`❌ [填空题] 填空${index + 1}没有找到输入框`, 'error');
                }
            });

            const success = successCount > 0;
            if (success) {
                logMessage(`✅ [填空题] 答案填入完成 (${successCount}/${fillInBlankOptions.length})`, 'success');
            } else {
                logMessage(`❌ [填空题] 答案填入失败`, 'error');
            }

            return success;

        } catch (error) {
            logMessage(`❌ [填空题] 填入答案时出错: ${error.message}`, 'error');
            return false;
        }
    }


    async function selectAnswer(questionIndex, answer) {
        if (!currentSite) detectSite();
        if (currentSite && typeof currentSite.selectAnswer === 'function') {
            const result = currentSite.selectAnswer(questionIndex, answer);

            if (result && typeof result.then === 'function') {
                return await result;
            }
            return result;
        }

        return false;
    }




    function makeDraggable(element, handle) {
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;

        handle.onmousedown = dragMouseDown;

        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            element.style.top = (element.offsetTop - pos2) + "px";
            element.style.left = (element.offsetLeft - pos1) + "px";
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }


    function logMessage(message, type = 'info') {
        const logArea = document.getElementById('log-display');
        if (!logArea) return;

        const timestamp = new Date().toLocaleTimeString('zh-CN', { hour12: false });
        const colors = {
            'info': '#6c757d',
            'success': '#28a745',
            'warning': '#ffc107',
            'error': '#dc3545',
            'question': '#007bff',
            'answer': '#17a2b8'
        };

        const logEntry = document.createElement('div');
        logEntry.style.cssText = `
            margin-bottom: 8px;
            padding: 8px 12px;
            border-radius: 6px;
            background: white;
            border-left: 3px solid ${colors[type] || colors.info};
            font-size: 12px;
            line-height: 1.4;
            box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
        `;

        const timeSpan = document.createElement('span');
        timeSpan.style.cssText = `
            color: #6c757d;
            font-weight: 500;
            margin-right: 8px;
        `;
        timeSpan.textContent = `[${timestamp}]`;

        const messageSpan = document.createElement('span');
        messageSpan.style.color = colors[type] || colors.info;
        messageSpan.textContent = message;

        logEntry.appendChild(timeSpan);
        logEntry.appendChild(messageSpan);
        logArea.appendChild(logEntry);
        logArea.scrollTop = logArea.scrollHeight;


        if (logArea.children.length > 50) {
            logArea.removeChild(logArea.firstChild);
        }
    }


    function logQuestionAnswer(question, answer, questionType = '') {
        const logArea = document.getElementById('log-display');
        if (!logArea) return;

        const timestamp = new Date().toLocaleTimeString('zh-CN', { hour12: false });

        const logEntry = document.createElement('div');
        logEntry.style.cssText = `
            margin-bottom: 12px;
            padding: 12px;
            border-radius: 8px;
            background: linear-gradient(135deg, #f8f9ff 0%, #fff 100%);
            border: 1px solid #e3f2fd;
            font-size: 12px;
            line-height: 1.5;
        `;

        const timeSpan = document.createElement('div');
        timeSpan.style.cssText = `
            color: #666;
            font-weight: 500;
            margin-bottom: 6px;
            font-size: 11px;
        `;
        timeSpan.textContent = `[${timestamp}] ${questionType}`;

        const questionDiv = document.createElement('div');
        questionDiv.style.cssText = `
            color: #333;
            margin-bottom: 6px;
            font-weight: 500;
        `;
        questionDiv.textContent = question.length > 80 ? question.substring(0, 80) + '...' : question;

        const answerDiv = document.createElement('div');
        answerDiv.style.cssText = `
            color: #28a745;
            font-weight: 600;
            padding: 4px 8px;
            background: rgba(40, 167, 69, 0.1);
            border-radius: 4px;
            display: inline-block;
        `;
        answerDiv.textContent = `答案:${answer}`;

        logEntry.appendChild(timeSpan);
        logEntry.appendChild(questionDiv);
        logEntry.appendChild(answerDiv);
        logArea.appendChild(logEntry);
        logArea.scrollTop = logArea.scrollHeight;


        if (logArea.children.length > 50) {
            logArea.removeChild(logArea.firstChild);
        }
    }




    async function answerSingleQuestion(questionIndex) {
        try {
            const questions = getExamQuestions();

            if (!questions || questionIndex >= questions.length) {
                logMessage(`❌ 第 ${questionIndex + 1} 题: 题目不存在`, 'error');
                return null;
            }

            const questionData = questions[questionIndex];
            logMessage(`📝 正在答第 ${questionIndex + 1} 题: ${questionData.questionType}`, 'info');

            // 更新答题窗口
            updateCurrentQuestion(questionData.stem, questionData.questionType);
            addTestLog(`正在处理第 ${questionIndex + 1} 题`, 'info');


            const apiResponse = await callCloudAPI(questionData);

            if (!apiResponse || !apiResponse.answer) {
                logMessage(`❌ 第 ${questionIndex + 1} 题: 未获取到答案`, 'error');
                return null;
            }

            const answer = apiResponse.answer.trim();
            logMessage(`💡 第 ${questionIndex + 1} 题答案: ${answer}`, 'success');

            // 更新答题窗口
            updateCurrentAnswer(answer);
            addTestLog(`获取到答案: ${answer}`, 'success');

            const selectSuccess = await selectAnswer(questionIndex, answer);

            if (selectSuccess) {
                logMessage(`✅ 第 ${questionIndex + 1} 题答题成功,选择答案${answer}`, 'success');
                addTestLog(`第 ${questionIndex + 1} 题答题成功,选择答案${answer}`, 'success');
                return {
                    questionIndex: questionIndex + 1,
                    answer: answer,
                    success: true
                };
            } else {
                logMessage(`❌ 第 ${questionIndex + 1} 题: 答案选择失败`, 'error');
                return null;
            }

        } catch (error) {
            logMessage(`❌ 第 ${questionIndex + 1} 题答题异常: ${error.message}`, 'error');
            return null;
        }
    }


    async function autoStartAnswering() {
        try {

            await new Promise(resolve => setTimeout(resolve, 1500));

            const currentUrl = window.location.href;
            logMessage(`🔍 当前页面URL: ${currentUrl}`, 'info');


            if (currentUrl.includes('exam-ans/exam/test/reVersionTestStartNew')) {

                logMessage('📄 检测到考试开始页面,查找整卷预览按钮...', 'info');

                // 显示考试答题窗口
                showExamWindow();
                addTestLog('检测到考试开始页面', 'info');

                const previewButton = document.querySelector('.sub-button a.completeBtn');
                if (previewButton && previewButton.textContent.includes('整卷预览')) {
                    logMessage('📄 找到整卷预览按钮,将自动点击...', 'info');
                    setTimeout(() => {
                        if (typeof pageWindow.topreview === 'function') {
                            logMessage('⚡️ 直接调用页面函数 topreview()。', 'info');
                            pageWindow.topreview();
                        } else {
                            logMessage('⚠️ 页面函数 topreview 不存在,回退到模拟点击。', 'warning');
                            previewButton.click();
                        }
                    }, 1500);
                    return;
                } else {
                    logMessage('❌ 未找到整卷预览按钮', 'warning');
                }
            }
            else if (currentUrl.includes('exam-ans/mooc2/exam/preview')) {

                logMessage('📝 检测到答题预览页面,开始自动答题...', 'info');

                // 显示考试答题窗口
                showExamWindow();
                addTestLog('检测到考试预览页面,开始答题', 'info');


                const questions = getExamQuestions();
                if (questions && questions.length > 0) {
                    logMessage(`发现 ${questions.length} 道题目,开始自动答题`, 'success');
                    const results = await autoAnswerAllQuestions(2000);

                    if (results.length > 0) {
                        logMessage(`自动答题完成,成功 ${results.length} 题`, 'success');
                    } else {
                        logMessage('自动答题未成功,请检查页面', 'warning');
                    }
                } else {
                    logMessage('未发现题目,可能页面还在加载中', 'info');
                }
            }
            else {

                logMessage('🔍 其他页面,使用通用检测逻辑...', 'info');


                if (currentSite && currentSite.name === '超星学习通') {
                    const previewButton = document.querySelector('.sub-button a.completeBtn');
                    if (previewButton && previewButton.textContent.includes('整卷预览')) {
                        logMessage('📄 检测到单题模式,将自动点击"整卷预览"...', 'info');
                        setTimeout(() => {
                            if (typeof pageWindow.topreview === 'function') {
                                logMessage('⚡️ 直接调用页面函数 topreview()。', 'info');
                                pageWindow.topreview();
                            } else {
                                logMessage('⚠️ 页面函数 topreview 不存在,回退到模拟点击。', 'warning');
                                previewButton.click();
                            }
                        }, 1500);
                        return;
                    }
                }


                const questions = getExamQuestions();
                if (questions && questions.length > 0) {
                    logMessage(`发现 ${questions.length} 道题目,开始自动答题`, 'success');
                    const results = await autoAnswerAllQuestions(2000);

                    if (results.length > 0) {
                        logMessage(`自动答题完成,成功 ${results.length} 题`, 'success');
                    } else {
                        logMessage('自动答题未成功,请检查页面', 'warning');
                    }
                } else {
                    logMessage('未发现题目,可能不是答题页面', 'info');
                }
            }
        } catch (error) {
            logMessage(`自动答题启动失败: ${error.message}`, 'error');
        }
    }


    async function initializeApp() {
        try {


            // createControlWindow(); // 已删除悬浮窗调用


            window.addEventListener('unhandledrejection', event => {
                if (event.reason && event.reason.message && event.reason.message.includes('429')) {
                    logMessage('⚠️ 请求过于频繁,请稍后重试', 'warning');
                }
            });


            detectSite();


            const tokenResult = await TokenManager.initialize();

            if (!tokenResult.hasToken) {
                logMessage('❌ Token未设置,请先配置Token', 'error');
                // 继续尝试自动启动逻辑(用户可在后续弹窗中完成Token)
            }


            // 检测到答题页面,启动答题功能
            if (currentSite) {
                logMessage('📝 答题页面检测成功,自动答题功能已启动', 'success');
                logMessage('📝 章节测验自动答题功能已启用', 'info');
                logMessage('📝 作业自动答题功能已启用', 'info');
                logMessage('📝 考试自动答题功能已启用', 'info');
                // 不再提前返回,继续执行自动启动逻辑
            }

            logMessage('✅ 云端AI答题助手启动完成', 'success');


            await autoStartAnswering();

        } catch (error) {
            logMessage(`❌ 初始化失败: ${error.message}`, 'error');
        }
    }


    if (pageWindow.AI_ASSISTANT_INITIALIZED) {
        return;
    }
    pageWindow.AI_ASSISTANT_INITIALIZED = true;

    if (pageDocument.readyState === 'loading') {
        pageDocument.addEventListener('DOMContentLoaded', () => {
            setTimeout(initializeApp, 800);
        });
    } else {
        setTimeout(initializeApp, 800);
    }


    function updateTaskStatus() {
        // 简化的任务状态更新,只显示答题相关状态
        let currentTask = '空闲';
        if (GLOBAL_STATE.isAnswering) {
            currentTask = '答题中';
        } else if (GLOBAL_STATE.isChapterTesting) {
            currentTask = '章节测试';
        }

        // 如果页面上有任务状态显示元素,更新它们
        const currentTaskEl = document.getElementById('currentTask');
        if (currentTaskEl) {
            currentTaskEl.textContent = currentTask;
        }
    }

    // 创建答题状态窗口(支持章节测试和考试)
    function createAnswerWindow(windowType = 'chapter') {
        const windowId = 'answerWindow';
        if (document.getElementById(windowId)) {
            return; // 窗口已存在
        }

        // 根据窗口类型设置标题
        const windowTitle = windowType === 'exam' ? '📝 考试答题助手' : '📝 章节测试答题助手';

        const windowDiv = document.createElement('div');
        windowDiv.id = windowId;
        windowDiv.innerHTML = `
            <div class="test-window-header">
                <span id="windowTitle">${windowTitle}</span>
                <button class="test-window-close">×</button>
            </div>
            <div class="test-window-content">
                <div class="announcement-info">
                    <div class="announcement-title">📢 公告</div>
                    <div class="announcement-content">
                        有问题及时反馈群号:
                        <span class="group-number">923349555</span>
                        <div id="scriptAnnouncement" style="margin-top:8px;color:#1f2937;"></div>
                    </div>
                </div>
                <div class="token-info">
                    <span id="tokenCount">Token: 加载中...</span>
                </div>
                <div class="progress-info">
                    <span id="progressInfo">准备中...</span>
                </div>
                <div class="current-question">
                    <div class="question-title">当前题目:</div>
                    <div id="currentQuestionText">等待开始...</div>
                </div>
                <div class="current-answer">
                    <div class="answer-title">选择答案:</div>
                    <div id="currentAnswerText">-</div>
                </div>
                <div class="test-log">
                    <div class="log-title">答题日志:</div>
                    <div id="testLogContent"></div>
                </div>
            </div>
        `;

        // 添加样式
        const style = document.createElement('style');
        style.textContent = `
            #answerWindow {
                position: fixed;
                top: 20px;
                right: 20px;
                width: 350px;
                max-height: 550px;
                background: white;
                border: 1px solid #ddd;
                border-radius: 8px;
                box-shadow: 0 4px 12px rgba(0,0,0,0.15);
                z-index: 10000;
                font-family: Arial, sans-serif;
                font-size: 12px;
                overflow: hidden;
            }

            .test-window-header {
                background: #f5f5f5;
                padding: 10px 15px;
                border-bottom: 1px solid #ddd;
                display: flex;
                justify-content: space-between;
                align-items: center;
                font-weight: bold;
                cursor: move;
            }

            .test-window-close {
                background: none;
                border: none;
                font-size: 18px;
                cursor: pointer;
                padding: 0;
                width: 20px;
                height: 20px;
                display: flex;
                align-items: center;
                justify-content: center;
                border-radius: 3px;
            }

            .test-window-close:hover {
                background: #e0e0e0;
            }

            .test-window-content {
                padding: 15px;
                max-height: 470px;
                overflow-y: auto;
            }

            .announcement-info {
                background: #fff3cd;
                border: 1px solid #ffeaa7;
                padding: 8px 10px;
                border-radius: 4px;
                margin-bottom: 10px;
                font-size: 11px;
            }

            .announcement-title {
                font-weight: bold;
                color: #856404;
                margin-bottom: 4px;
            }

            .announcement-content {
                color: #856404;
                line-height: 1.4;
            }

            .group-number {
                font-weight: bold;
                color: #d63384;
                cursor: pointer;
                text-decoration: underline;
            }

            .group-number:hover {
                color: #b02a5b;
            }

            .token-info {
                background: #e8f4fd;
                padding: 8px 10px;
                border-radius: 4px;
                margin-bottom: 10px;
                font-weight: bold;
                color: #0066cc;
            }

            .progress-info {
                background: #f0f8ff;
                padding: 8px 10px;
                border-radius: 4px;
                margin-bottom: 10px;
                font-weight: bold;
                color: #333;
            }

            .current-question, .current-answer {
                margin-bottom: 12px;
                padding: 8px;
                border: 1px solid #eee;
                border-radius: 4px;
                background: #fafafa;
            }

            .question-title, .answer-title, .log-title {
                font-weight: bold;
                margin-bottom: 5px;
                color: #333;
            }

            #currentQuestionText {
                color: #555;
                line-height: 1.4;
                max-height: 60px;
                overflow-y: auto;
            }

            #currentAnswerText {
                color: #007bff;
                font-weight: bold;
            }

            .test-log {
                margin-top: 10px;
                border-top: 1px solid #eee;
                padding-top: 10px;
            }

            #testLogContent {
                max-height: 120px;
                overflow-y: auto;
                font-size: 11px;
                line-height: 1.3;
                color: #666;
                background: #f9f9f9;
                padding: 8px;
                border-radius: 4px;
                border: 1px solid #eee;
            }

            .log-entry {
                margin-bottom: 3px;
                padding: 2px 0;
            }

            .log-success {
                color: #28a745;
            }

            .log-error {
                color: #dc3545;
            }

            .log-info {
                color: #17a2b8;
            }
        `;

        document.head.appendChild(style);
        document.body.appendChild(windowDiv);

        // 绑定事件
        bindAnswerWindowEvents();

        // 更新Token信息
        updateTokenDisplay();

        // 拉取脚本公告
        try {
            fetch('/portal/api/announcements?type=script', { credentials: 'include' })
                .then(r => r.json())
                .then(d => {
                    if (d && d.success && d.data && d.data.content) {
                        const el = document.getElementById('scriptAnnouncement');
                        if (el) el.innerHTML = d.data.content.replace(/\n/g, '<br>');
                    }
                })
                .catch(() => {});
        } catch (e) {}
     }

    // 绑定答题窗口事件
    function bindAnswerWindowEvents() {
        const testWindow = document.getElementById('answerWindow');
        const closeBtn = testWindow.querySelector('.test-window-close');
        const header = testWindow.querySelector('.test-window-header');

        // 关闭按钮
        closeBtn.addEventListener('click', () => {
            testWindow.style.display = 'none';
        });

        // 拖拽功能
        let isDragging = false;
        let dragOffset = { x: 0, y: 0 };

        header.addEventListener('mousedown', (e) => {
            isDragging = true;
            const rect = testWindow.getBoundingClientRect();
            dragOffset.x = e.clientX - rect.left;
            dragOffset.y = e.clientY - rect.top;
            header.style.cursor = 'grabbing';
            e.preventDefault();
        });

        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;

            const x = e.clientX - dragOffset.x;
            const y = e.clientY - dragOffset.y;

            const maxX = window.innerWidth - testWindow.offsetWidth;
            const maxY = window.innerHeight - testWindow.offsetHeight;

            testWindow.style.left = Math.max(0, Math.min(x, maxX)) + 'px';
            testWindow.style.top = Math.max(0, Math.min(y, maxY)) + 'px';
            testWindow.style.right = 'auto';
        });

        document.addEventListener('mouseup', () => {
            if (isDragging) {
                isDragging = false;
                header.style.cursor = 'move';
            }
        });

        // 群号点击复制功能
        const groupNumber = testWindow.querySelector('.group-number');
        if (groupNumber) {
            groupNumber.addEventListener('click', () => {
                const groupNum = '923349555';
                if (navigator.clipboard) {
                    navigator.clipboard.writeText(groupNum).then(() => {
                        const originalText = groupNumber.textContent;
                        groupNumber.textContent = '已复制!';
                        setTimeout(() => {
                            groupNumber.textContent = originalText;
                        }, 2000);
                    }).catch(() => {
                        alert(`请手动复制群号: ${groupNum}`);
                    });
                } else {
                    // 降级方案
                    const textArea = document.createElement('textarea');
                    textArea.value = groupNum;
                    document.body.appendChild(textArea);
                    textArea.select();
                    try {
                        document.execCommand('copy');
                        const originalText = groupNumber.textContent;
                        groupNumber.textContent = '已复制!';
                        setTimeout(() => {
                            groupNumber.textContent = originalText;
                        }, 2000);
                    } catch (err) {
                        alert(`请手动复制群号: ${groupNum}`);
                    }
                    document.body.removeChild(textArea);
                }
            });
        }
    }

    // 更新Token显示
    async function updateTokenDisplay() {
        try {
            console.log('[Token显示] 开始获取用户信息...');
            const userInfo = await TokenManager.getUserInfo();
            console.log('[Token显示] 获取到用户信息:', userInfo);

            const tokenElement = document.getElementById('tokenCount');

            if (tokenElement && userInfo) {
                // 使用remainingCount或remaining_queries字段
                const remainingQueries = userInfo.remainingCount || userInfo.remaining_queries || 0;
                tokenElement.textContent = `Token: ${remainingQueries} 次`;
                console.log(`[Token显示] 剩余查询次数: ${remainingQueries}`);
            } else {
                if (tokenElement) {
                    tokenElement.textContent = 'Token: 无法获取用户信息';
                }
                console.warn('[Token显示] 用户信息获取失败, userInfo:', userInfo);
            }
        } catch (error) {
            console.error('[Token显示] 获取失败:', error);
            const tokenElement = document.getElementById('tokenCount');
            if (tokenElement) {
                if (error.message.includes('Token未设置')) {
                    tokenElement.textContent = 'Token: 未设置';
                } else if (error.message.includes('Token无效')) {
                    tokenElement.textContent = 'Token: 无效或过期';
                } else {
                    tokenElement.textContent = `Token: 获取失败 (${error.message})`;
                }
            }
        }
    }

    // 更新答题进度
    function updateTestProgress(current, total) {
        const progressElement = document.getElementById('progressInfo');
        if (progressElement) {
            progressElement.textContent = `进度: ${current}/${total} (${Math.round(current/total*100)}%)`;
        }
    }

    // 更新当前题目
    function updateCurrentQuestion(questionText, questionType) {
        const questionElement = document.getElementById('currentQuestionText');
        if (questionElement) {
            const displayText = questionText.length > 100 ?
                questionText.substring(0, 100) + '...' : questionText;
            questionElement.textContent = `[${questionType}] ${displayText}`;
        }
    }

    // 更新当前答案
    function updateCurrentAnswer(answer) {
        const answerElement = document.getElementById('currentAnswerText');
        if (answerElement) {
            answerElement.textContent = answer || '-';
        }
    }

    // 添加日志条目
    function addTestLog(message, type = 'info') {
        const logContent = document.getElementById('testLogContent');
        if (logContent) {
            const logEntry = document.createElement('div');
            logEntry.className = `log-entry log-${type}`;
            logEntry.textContent = `${new Date().toLocaleTimeString()} - ${message}`;

            logContent.appendChild(logEntry);
            logContent.scrollTop = logContent.scrollHeight;

            // 限制日志条目数量
            const entries = logContent.querySelectorAll('.log-entry');
            if (entries.length > 20) {
                entries[0].remove();
            }
        }
    }

    // 显示答题窗口(通用)
    function showAnswerWindow(windowType = 'chapter') {
        createAnswerWindow(windowType);
        const testWindow = document.getElementById('answerWindow');
        if (testWindow) {
            testWindow.style.display = 'block';
            const windowTitle = windowType === 'exam' ? '考试答题窗口已启动' : '章节测试窗口已启动';
            addTestLog(windowTitle, 'info');
        }
    }

    // 显示章节测试窗口(兼容旧函数名)
    function showChapterTestWindow() {
        showAnswerWindow('chapter');
    }

    // 显示考试窗口
    function showExamWindow() {
        showAnswerWindow('exam');
    }

    // 更新窗口标题
    function updateWindowTitle(windowType) {
        const titleElement = document.getElementById('windowTitle');
        if (titleElement) {
            const title = windowType === 'exam' ? '📝 考试答题助手' : '📝 章节测试答题助手';
            titleElement.textContent = title;
        }
    }

    function base64ToUint8Array(base64) {
        var data = window.atob(base64);
        var buffer = new Uint8Array(data.length);
        for (var i = 0; i < data.length; ++i) {
            buffer[i] = data.charCodeAt(i);
        }
        return buffer;
    }
    function chaoxingFontDecrypt(doc = document) {

        var $tip = Array.from(doc.querySelectorAll('style')).find(style =>
            (style.textContent || style.innerHTML || '').includes('font-cxsecret')
        );
        if (!$tip) return false;


        var fontText = $tip.textContent || $tip.innerHTML;
        var fontMatch = fontText.match(/base64,([\w\W]+?)'/);
        if (!fontMatch || !fontMatch[1]) return false;

        var font = Typr.parse(base64ToUint8Array(fontMatch[1]))[0];


        var table = JSON.parse(GM_getResourceText('Table'));
        var match = {};

        for (var i = 19968; i < 40870; i++) {
            var glyph = Typr.U.codeToGlyph(font, i);
            if (!glyph) continue;

            var path = Typr.U.glyphToPath(font, glyph);
            var pathMD5 = md5(JSON.stringify(path)).slice(24);

            if (table[pathMD5]) {
                match[i] = table[pathMD5];
            }
        }


        var elements = doc.querySelectorAll('.font-cxsecret');
        elements.forEach(function (element) {
            var html = element.innerHTML;

            for (var key in match) {
                if (match[key]) {
                    var keyChar = String.fromCharCode(key);
                    var valueChar = String.fromCharCode(match[key]);
                    var regex = new RegExp(keyChar, 'g');
                    html = html.replace(regex, valueChar);
                }
            }

            element.innerHTML = html;
            element.classList.remove('font-cxsecret');
        });

        return elements.length > 0;
    }


    window.restartMainInterval = function () {
        if (window.mainIntervalId) {
            clearInterval(window.mainIntervalId);
        }
    };


    window.restorePage = function () {

        let restoredCount = 0;


        const decryptedElements = document.querySelectorAll('[data-decrypted="true"]');
        decryptedElements.forEach(element => {

            element.classList.add('font-cxsecret');
            element.removeAttribute('data-decrypted');
            restoredCount++;
        });


        const originalDecryptedElements = document.querySelectorAll('[data-decrypted-original="true"]');
        originalDecryptedElements.forEach(element => {
            element.classList.add('font-cxsecret');
            element.removeAttribute('data-decrypted-original');
            element.style.background = '';
            element.style.borderColor = '';
            restoredCount++;
        });


        const inlineDecryptedElements = document.querySelectorAll('[data-decrypted-inline="true"]');
        inlineDecryptedElements.forEach(element => {
            element.removeAttribute('data-decrypted-inline');
            restoredCount++;
        });
        return {
            restoredCount: restoredCount,
            success: restoredCount > 0
        };
    };


    window.applyChaoxingFontDecryptOriginal = function () {

        try {

            const allStyles = document.querySelectorAll('style');
            let $tip = null;

            for (const style of allStyles) {
                const content = style.textContent || style.innerHTML || '';
                if (content.includes('font-cxsecret')) {
                    $tip = style;
                    break;
                }
            }

            if (!$tip) {
                console.log('ℹ️ [原版解密] 未找到font-cxsecret样式');
                return false;
            }

            console.log('✅ [原版解密] 找到font-cxsecret样式');


            const fontSecretElements = document.querySelectorAll('.font-cxsecret');
            if (fontSecretElements.length === 0) {
                console.log('ℹ️ [原版解密] 未找到.font-cxsecret元素');
                return false;
            }

            console.log(`✅ [原版解密] 找到 ${fontSecretElements.length} 个加密元素`);



            let processedCount = 0;

            fontSecretElements.forEach((element, index) => {
                try {
                    const originalText = element.textContent || '';


                    element.classList.remove('font-cxsecret');
                    element.setAttribute('data-decrypted-original', 'true');

                    const newText = element.textContent || '';

                    console.log(`  元素 ${index + 1}: "${originalText.substring(0, 30)}..." → "${newText.substring(0, 30)}..."`);
                    processedCount++;

                } catch (error) {
                    console.log(`⚠️ [原版解密] 处理元素 ${index + 1} 失败:`, error.message);
                }
            });

            return processedCount > 0;

        } catch (error) {
            console.log('❌ [原版解密] 执行失败:', error.message);
            return false;
        }
    };


    window.decodePageTexts = async function () {
        console.log('🔄 [批量解码] 开始解码页面中的所有乱码文本...');

        try {

            const mapping = await buildAIDecodingMapping();

            if (Object.keys(mapping).length === 0) {
                console.log('⚠️ 未获取到有效的字符映射表');
                return false;
            }


            const elements = document.querySelectorAll('.fontLabel, .after, .CeYan *');
            let decodedCount = 0;

            for (const element of elements) {
                const originalText = element.textContent || '';
                if (originalText && /[\u5600-\u56FF]/.test(originalText)) {
                    let decodedText = originalText;


                    for (const [garbled, decoded] of Object.entries(mapping)) {
                        decodedText = decodedText.replace(new RegExp(garbled, 'g'), decoded);
                    }

                    if (decodedText !== originalText) {



                        decodedCount++;
                    }
                }
            }

            console.log(`✅ 批量解码完成,共处理 ${decodedCount} 个文本`);
            return true;

        } catch (error) {
            console.log(`❌ 批量解码失败: ${error.message}`);
            return false;
        }
    };


    async function handleChapterTest(testFrames) {
        for (const frame of testFrames) {
            if (!frame.accessible || !frame.doc) {
                console.log('❌ [章节测验] iframe不可访问,跳过');
                continue;
            }

            const doc = frame.doc;
            const iframeWindow = frame.iframe ? frame.iframe.contentWindow : window;


            const completedStatus = doc.querySelector('.testTit_status_complete');
            if (completedStatus && completedStatus.textContent.includes('已完成')) {
                console.log('✅ [章节测验] 检测到已完成状态,跳过答题');
                return true;
            }


            const completedDiv = doc.querySelector('.fr.testTit_status.testTit_status_complete');
            if (completedDiv && completedDiv.textContent.includes('已完成')) {
                console.log('✅ [章节测验] 检测到已完成状态(方式2),跳过答题');
                return true;
            }


            chaoxingFontDecrypt(doc);


            const questions = doc.querySelectorAll('.singleQuesId');
            console.log(`📄 共 ${questions.length} 道题目`);


            if (questions.length === 0) {
                continue;
            }


            GLOBAL_STATE.isChapterTesting = true;
            GLOBAL_STATE.isAnswering = true;
            console.log('🚀 [章节测验] 开始答题流程');

            // 显示答题窗口
            showChapterTestWindow();
            addTestLog(`开始处理章节测验,共 ${questions.length} 道题目`, 'info');
            updateTestProgress(0, questions.length);


            for (let i = 0; i < questions.length; i++) {
                const qEl = questions[i];
                const typeText = qEl.querySelector('.newZy_TItle')?.innerText || '未知类型';
                let content = qEl.querySelector('.fontLabel')?.innerText?.trim() || '';


                content = content.replace(/【[^】]*题】/g, '').trim();
                console.log(`📝 [${i + 1}/${questions.length}] ${typeText}`);

                // 更新答题窗口
                updateTestProgress(i + 1, questions.length);
                updateCurrentQuestion(content, typeText);
                addTestLog(`正在处理第 ${i + 1} 题`, 'info');


                const options = qEl.querySelectorAll('li');

                const optionsData = [];


                const cleanQuestionType = typeText.replace(/【|】/g, '');

                options.forEach(opt => {
                    let spanElement = null;
                    let label = '';


                    if (cleanQuestionType.includes('多选题')) {
                        spanElement = opt.querySelector('span.num_option_dx');
                    } else {
                        spanElement = opt.querySelector('span.num_option');
                    }

                    label = spanElement?.innerText || '';
                    const aElement = opt.querySelector('a.after');
                    const text = aElement?.innerText || '';
                    const dataValue = spanElement?.getAttribute('data') || '';

                    if (label && text) {
                        optionsData.push({
                            label: label,
                            content: text,
                            value: dataValue,
                            element: opt,
                            questionType: cleanQuestionType
                        });
                    }
                });


                try {
                    const cleanQuestionType = typeText.replace(/【|】/g, '');
                    const questionData = {
                        stem: content,
                        questionType: cleanQuestionType,
                        options: optionsData
                    };

                    const apiResponse = await callCloudAPI(questionData);

                    if (apiResponse && apiResponse.answer) {
                        const answer = apiResponse.answer.trim();
                        console.log(`  ✅ 答案: ${answer}`);

                        // 更新答题窗口
                        updateCurrentAnswer(answer);
                        addTestLog(`获取到答案: ${answer}`, 'success');

                        console.log(`🎯 [答题] 选择答案: ${answer}`);

                        if (cleanQuestionType.includes('填空题')) {

                            console.log(`📝 [填空题] 开始处理填空题`);


                            const blankItems = qEl.querySelectorAll('.blankItemDiv');



                            console.log(`📝 [填空题] 找到 ${blankItems.length} 个填空项`);


                            let answerParts = [];
                            if (typeof answer === 'string') {

                                if (answer.includes('|')) {
                                    answerParts = answer.split('|');
                                } else if (answer.includes(';')) {
                                    answerParts = answer.split(';');
                                } else if (answer.includes(';')) {
                                    answerParts = answer.split(';');
                                } else if (answer.includes(',')) {
                                    answerParts = answer.split(',');
                                } else if (answer.includes(',')) {
                                    answerParts = answer.split(',');
                                } else {
                                    answerParts = [answer];
                                }
                            } else {
                                answerParts = [answer];
                            }

                            console.log(`📝 [填空题] 答案分割结果:`, answerParts);


                            blankItems.forEach((blankItem, blankIndex) => {
                                if (blankIndex < answerParts.length) {
                                    const answerText = answerParts[blankIndex].trim();
                                    console.log(`📝 [填空题] 第${blankIndex + 1}空填入: ${answerText}`);
                                    addTestLog(`填空题第${blankIndex + 1}空填入: ${answerText}`, 'success');


                                    const editorTextarea = blankItem.querySelector('textarea[name*="answerEditor"]');

                                    if (editorTextarea) {
                                        const editorId = editorTextarea.id;

                                        try {
                                            let fillSuccess = false;


                                            if (iframeWindow && iframeWindow.UE && iframeWindow.UE.getEditor) {
                                                try {
                                                    const editor = iframeWindow.UE.getEditor(editorId);
                                                    if (editor && editor.setContent) {
                                                        editor.setContent(answerText);
                                                        fillSuccess = true;
                                                    }
                                                } catch (ueError) {

                                                }
                                            }


                                            if (!fillSuccess) {
                                                editorTextarea.value = answerText;


                                                const events = ['input', 'change', 'blur', 'keyup'];
                                                events.forEach(eventType => {
                                                    try {

                                                        const event = new (iframeWindow || window).Event(eventType, { bubbles: true });
                                                        editorTextarea.dispatchEvent(event);
                                                    } catch (eventError) {

                                                        const event = doc.createEvent('Event');
                                                        event.initEvent(eventType, true, true);
                                                        editorTextarea.dispatchEvent(event);
                                                    }
                                                });

                                                fillSuccess = true;
                                            }


                                            if (!fillSuccess) {
                                                const inpDiv = blankItem.querySelector('.InpDIV');
                                                if (inpDiv) {
                                                    inpDiv.innerHTML = answerText;
                                                    inpDiv.textContent = answerText;
                                                    fillSuccess = true;
                                                }
                                            }

                                        } catch (error) {

                                        }
                                    }
                                }
                            });

                        } else if (cleanQuestionType.includes('判断题')) {
                            for (const opt of options) {
                                const text = opt.querySelector('a')?.innerText || '';
                                if ((answer === 'T' && (text === '对' || text === '正确' || text === '是')) ||
                                    (answer === 'F' && (text === '错' || text === '错误' || text === '否'))) {
                                    opt.click();
                                    console.log(`    🎯 已选择: ${text}`);
                                    addTestLog(`判断题已选择: ${text}`, 'success');
                                    break;
                                }
                            }
                        } else if (cleanQuestionType.includes('多选题')) {

                            for (const opt of options) {
                                const spanElement = opt.querySelector('span.num_option_dx');
                                const label = spanElement?.innerText || '';

                                if (answer.includes(label)) {

                                    if (typeof iframeWindow.addMultipleChoice === 'function') {
                                        try {
                                            iframeWindow.addMultipleChoice(opt);
                                            console.log(`    🎯 已选择多选项: ${label}`);
                                            addTestLog(`多选题已选择: ${label}`, 'success');
                                        } catch (error) {
                                            opt.click();
                                            console.log(`    🎯 已选择多选项: ${label} (备用)`);
                                            addTestLog(`多选题已选择: ${label} (备用方式)`, 'success');
                                        }
                                    } else {
                                        opt.click();
                                        console.log(`    🎯 已选择多选项: ${label}`);
                                        addTestLog(`多选题已选择: ${label}`, 'success');
                                    }
                                }
                            }
                        } else {

                            for (const opt of options) {
                                const spanElement = opt.querySelector('span.num_option');
                                const label = spanElement?.innerText || '';

                                if (answer.includes(label)) {
                                    opt.click();
                                    console.log(`    🎯 已选择: ${label}`);
                                    addTestLog(`单选题已选择: ${label}`, 'success');
                                    break;
                                }
                            }
                        }
                    }
                } catch (error) {
                    console.log(`  ❌ 答题异常: ${error.message}`);
                    addTestLog(`答题异常: ${error.message}`, 'error');
                }

                await new Promise(resolve => setTimeout(resolve, 1000));
            }

            console.log('✅ [章节测验] 答题完成,准备提交');
            addTestLog('所有题目答题完成,准备提交测验', 'success');
            updateCurrentQuestion('答题完成', '准备提交');
            updateCurrentAnswer('等待提交...');
            GLOBAL_STATE.isAnswering = false;


            setTimeout(() => {
                if (iframeWindow.btnBlueSubmit) {
                    iframeWindow.btnBlueSubmit();
                    console.log('✅ [自动提交] 测验提交成功');
                    addTestLog('测验已自动提交', 'success');
                    updateCurrentAnswer('已提交');


                    setTimeout(() => {
                        monitorSubmitDialog();
                    }, 500);
                }
            }, 2000);


            return true;
        }

        return false;
    }


    // 检测是否为章节测验页面
    function isChapterTestPage() {
        const url = window.location.href;
        // 章节测验页面特征
        return url.includes('/mooc-ans/work/doHomeWorkNew/') ||
               url.includes('/mooc-ans/api/work/') ||
               url.includes('/ananas/modules/work/') ||
               // 也检查页面DOM特征
               document.querySelector('.singleQuesId') ||
               document.querySelector('.CeYan h3') ||
               document.querySelector('.questionLi') ||
               document.querySelector('.newZy_TItle');
    }

    // 答题系统启动
    console.log(`📝 [答题系统] 超星学习通答题助手已启动`);

    if (isChapterTestPage()) {
        console.log(`📝 [系统启动] 检测到章节测验页面,启动答题系统`);

        // 立即显示答题窗口
        showChapterTestWindow();
        addTestLog('检测到章节测验页面,答题助手已启动', 'info');

        setTimeout(async () => {
            console.log(`📝 [章节测验] 页面加载完成,开始处理测验`);

            // 查找章节测验iframe
            const testFrames = [];
            const iframes = document.querySelectorAll('iframe');

            for (const iframe of iframes) {
                try {
                    const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
                    if (iframeDoc) {
                        // 检查是否是章节测验iframe
                        if (iframeDoc.querySelector('.singleQuesId') ||
                            iframeDoc.querySelector('.CeYan h3') ||
                            iframeDoc.querySelector('.questionLi')) {
                            testFrames.push({
                                iframe: iframe,
                                doc: iframeDoc,
                                accessible: true,
                                type: 'CHAPTER_TEST'
                            });
                        }
                    }
                } catch (e) {
                    // 跨域iframe,跳过
                }
            }

            // 如果没有找到iframe,检查当前页面是否直接包含测验
            if (testFrames.length === 0) {
                if (document.querySelector('.singleQuesId') ||
                    document.querySelector('.CeYan h3') ||
                    document.querySelector('.questionLi')) {
                    testFrames.push({
                        iframe: null,
                        doc: document,
                        accessible: true,
                        type: 'CHAPTER_TEST'
                    });
                }
            }

            if (testFrames.length > 0) {
                console.log(`📝 [章节测验] 找到 ${testFrames.length} 个测验框架,开始处理`);
                addTestLog(`找到 ${testFrames.length} 个测验框架,开始处理`, 'info');
                await handleChapterTest(testFrames);
            } else {
                console.log(`❌ [章节测验] 未找到测验内容`);
                addTestLog('未找到测验内容,请检查页面', 'error');
                updateCurrentQuestion('未找到测验内容', '检查页面');
            }
        }, 2000);
    } else {
        console.log(`❓ [系统启动] 未识别的页面类型`);
        console.log(`🔍 [调试信息] 当前URL: ${window.location.href}`);
        console.log(`🔍 [调试信息] 页面标题: ${document.title}`);
    }

    console.log('✅ 系统优化 答题助手已启动,专注于章节测验、作业和考试功能');

    // 添加全局函数,方便手动调用
    window.showChapterTestWindow = showChapterTestWindow;
    window.showExamWindow = showExamWindow;
    window.showAnswerWindow = showAnswerWindow;
    window.addTestLog = addTestLog;
    window.updateTestProgress = updateTestProgress;
    window.updateCurrentQuestion = updateCurrentQuestion;
    window.updateCurrentAnswer = updateCurrentAnswer;
    window.updateWindowTitle = updateWindowTitle;
})();