// ==UserScript== // @name [课易宝]-柠檬文才学堂 // @namespace kebaide.work // @version 1.1.1-beta // @description 柠檬文才学堂,学习专用插件,一键自动完成视频,自动完成作业,一建批量评论,考试一键答题 // @author zhouwu // @match *://*.wencaischool.net/* // @antifeature payment // @require https://cdn.bootcdn.net/ajax/libs/qrcodejs/1.0.0/qrcode.min.js // @connect kebaide.work // @run-at document-start // @grant GM_getValue // @grant GM_setValue // @grant GM_xmlhttpRequest // @grant unsafeWindow // @grant GM_info // ==/UserScript== var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); (function() { "use strict"; var _a; const isType = (obj, type) => Object.prototype.toString.call(obj) === `[object ${type.replace(/^[a-z]/, (s2) => s2.toUpperCase())}]`; function sleep(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); } function match(url, matchs) { if (Array.isArray(matchs)) { return matchs.some((m2) => match(url, m2)); } if (isType(matchs, "RegExp")) { return matchs.test(url); } else if (isType(matchs, "string")) { if (window.URLPattern) { const m2 = new window.URLPattern({ pathname: matchs }); return m2.test(url); } else { return url.includes(matchs); } } else if (isType(matchs, "function")) { return matchs(url); } return false; } function createIframeDocument(url) { return new Promise((resolve) => { var _a2; const iframe = document.createElement("iframe"); iframe.style.cssText = ` position: absolute; top: -9999px; left: -9999px; opacity: 0; `; if (url.startsWith("http")) { iframe.src = url; } else { iframe.src = "about:blank"; (_a2 = iframe.contentDocument) == null ? void 0 : _a2.write(url); } iframe.onload = () => { const doc = iframe.contentDocument; if (doc) { resolve({ document: doc, window: iframe.contentWindow, iframe }); } }; document.body.appendChild(iframe); }); } const token_key = "token"; async function getToken() { const token = GM_getValue(token_key); return token; } function setToken(token) { return GM_setValue(token_key, token); } function setStore(key, value, isQs = true) { return GM_setValue(key, value); } function getStore(key) { let val = GM_getValue(key); return val; } function uuidv4() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c2) { const r2 = Math.random() * 16 | 0, v2 = c2 == "x" ? r2 : r2 & 3 | 8; return v2.toString(16); }); } async function deviceId() { let id = getStore("deviceId"); if (!id) { id = localStorage.getItem("qk_deviceId"); } if (!id) { id = "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function(c2) { const r2 = Math.random() * 16 | 0; const v2 = c2 === "x" ? r2 : r2 & 3 | 8; return v2.toString(16); }).toUpperCase(); setStore("deviceId", id); localStorage.setItem("qk_deviceId", id); } return id; } const getCookie = (key) => { const cookie = document.cookie; const studentCookie = cookie.split("; ").find((row) => row.startsWith(key)); const p2 = new URLSearchParams(decodeURIComponent((studentCookie == null ? void 0 : studentCookie.split("=")[1]) || "")); return p2; }; const getUserCookie = () => { const p2 = getCookie("openlearning_COOKIE"); return p2.get("user_id"); }; function loadScript(url) { return new Promise(function(resolve, reject) { var script = document.createElement("script"); script.type = "text/javascript"; script.src = url; script.onload = resolve; script.onerror = reject; document.body.appendChild(script); }); } function qs(obj) { const params = new URLSearchParams(); for (const [key, value] of Object.entries(obj)) { params.append(key, String(value)); } return params.toString(); } function emdata(obj) { for (var i2 in obj) { obj[i2] = Encrypt(obj[i2]); } return obj; } const baseUrl = "https://service.kebaide.work/api"; async function request(obj) { let success = obj.success; let error = obj.error; let p2; if (!success) { p2 = new Promise((resolve, reject) => { success = resolve; error = reject; }); } const headers = obj.headers || {}; const token = await getToken(); headers["x-device-id"] = await deviceId(); if (token) { headers.Authorization = "Bearer " + token; } if (!obj.url.startsWith("http")) { obj.url = baseUrl + obj.url; } obj.headers = headers; obj.success = success; obj.error = error; obj.method = obj.method || "GET"; { obj.responseType = obj.dataType || "json"; delete obj.dataType; if (obj.method === "GET") { const u2 = new URL(obj.url); for (const [k2, v2] of Object.entries(obj.data || {})) { u2.searchParams.append(k2, v2); } delete obj.data; obj.url = u2.href; } else { obj.data = JSON.stringify(obj.data); obj.headers["Content-Type"] = "application/json"; } obj.onerror = error; obj.ontimeout = error; obj.onreadystatechange = (_a22) => { if (_a22.readyState === 4) { const { response, status } = _a22; if (status === 200) { if ((response == null ? void 0 : response.code) === 401) { error(response); } success(response); } else { error(response); } } }; } const _a2 = GM_xmlhttpRequest(obj); return p2 || _a2; } function postSchool(data) { return request({ url: "/schools", method: "POST", data }); } function putSchool(data, id) { return request({ url: "/schools/" + id, method: "PUT", data }); } function postMajor(data) { return request({ url: "/majors", method: "POST", data }); } function postCourse(data) { return request({ url: "/courses", method: "POST", data }); } function postStudent(data) { return request({ url: "/students", method: "POST", data }); } function postChapter(data) { return request({ url: "/chapters", method: "POST", data }); } function hasAcceleration(data) { return request({ url: "/courses/learning", method: "POST", data }); } function getChapter(id, data) { return request({ url: "/chapters/" + id, data }); } function logCreate(data, action = "auto") { return request({ url: `/logs?type=3&action=${action}&module=plugin&url=${encodeURIComponent(location.href)}`, method: "POST", data }); } function getStudent(id) { return request({ url: "/students/" + id }); } function doneRead(data) { return request({ url: "/user/readService", method: "POST", data }); } const _ErrorManager = class _ErrorManager { constructor() { __publicField(this, "errors", []); __publicField(this, "maxErrors", 100); __publicField(this, "errorHandlers", []); __publicField(this, "stopCreateErrLog", false); __publicField(this, "prevError"); this.initializeErrorHandlers(); } static getInstance() { if (!_ErrorManager.instance) { _ErrorManager.instance = new _ErrorManager(); } return _ErrorManager.instance; } initializeErrorHandlers() { window.addEventListener("error", (event) => { var _a2; this.handleError({ type: "framework", name: "UncaughtError", message: event.message, stack: (_a2 = event.error) == null ? void 0 : _a2.stack, timestamp: (/* @__PURE__ */ new Date()).toISOString(), context: { filename: event.filename, lineno: event.lineno, colno: event.colno } }); }); window.addEventListener("unhandledrejection", (event) => { var _a2, _b; this.handleError({ type: "framework", name: "UnhandledPromiseRejection", message: ((_a2 = event.reason) == null ? void 0 : _a2.message) || "Promise rejected", stack: (_b = event.reason) == null ? void 0 : _b.stack, timestamp: (/* @__PURE__ */ new Date()).toISOString(), context: { reason: event.reason } }); }); } handleError(error) { var _a2; if (error.stack !== ((_a2 = this.prevError) == null ? void 0 : _a2.stack) && !error.message.includes("chkSingleItemDisp")) { this.stopCreateErrLog || logCreate(error).catch((e2) => { this.stopCreateErrLog = true; }); } this.prevError = error; this.errors.unshift(error); if (this.errors.length > this.maxErrors) { this.errors.pop(); } this.errorHandlers.forEach((handler) => { try { handler(error); } catch (e2) { console.error("Error in error handler:", e2); } }); console.error(`[${error.type}] ${error.name}: ${error.message}`, error); } onError(handler) { this.errorHandlers.push(handler); } offError(handler) { const index = this.errorHandlers.indexOf(handler); if (index !== -1) { this.errorHandlers.splice(index, 1); } } getErrors() { return [...this.errors]; } clearErrors() { this.errors = []; } getErrorsByType(type) { return this.errors.filter((error) => error.type === type); } getErrorsByName(name) { return this.errors.filter((error) => error.name === name); } getLatestError() { return this.errors[0]; } }; __publicField(_ErrorManager, "instance"); let ErrorManager = _ErrorManager; class BaseEvent { constructor() { __publicField(this, "events"); __publicField(this, "errorManager"); this.events = /* @__PURE__ */ new Map(); this.errorManager = ErrorManager.getInstance(); } broadcast(message2) { if (unsafeWindow.top) unsafeWindow.top.postMessage({ type: "KEB_MESSAGE", data: message2 }, "*"); } on(event, handler) { try { if (!this.events.has(event)) { this.events.set(event, []); } this.events.get(event).push(handler); } catch (error) { this.handleError(error, "on"); } } off(event, handler) { try { if (!this.events.has(event)) return; const handlers = this.events.get(event); const index = handlers.indexOf(handler); if (index !== -1) { handlers.splice(index, 1); } } catch (error) { this.handleError(error, "off"); } } once(event, handler) { const onceHandler = (...args) => { handler(...args); this.off(event, onceHandler); }; this.on(event, onceHandler); } offAll(event) { if (event) { this.events.delete(event); } else { this.events.clear(); } } emit(event, ...args) { try { setTimeout(() => { const callbacks = this.events.get(event); if (callbacks) { callbacks.forEach((callback) => { try { callback(...args); } catch (error) { this.handleError(error, "callback"); } }); } }, 200); } catch (error) { this.handleError(error, "emit"); } } handleError(error, context) { const errorInfo = { type: this.getErrorType(), name: `${this.constructor.name}Error`, message: error.message || "Unknown error", stack: error.stack, timestamp: (/* @__PURE__ */ new Date()).toISOString(), context: { source: this.constructor.name, method: context, error } }; this.errorManager.handleError(errorInfo); } getErrorType() { const className = this.constructor.name; if (className.includes("Script")) return "script"; if (className.includes("Work")) return "work"; if (className.includes("Task")) return "task"; return "framework"; } } const _Store = class _Store extends BaseEvent { constructor(config) { super(); __publicField(this, "config"); __publicField(this, "data"); this.config = { persistent: false, ...config }; this.data = /* @__PURE__ */ new Map(); _Store.stores.set(config.name, this); } static getStore(name) { return _Store.stores.get(name); } set(key, value) { this.data.set(key, value); if (this.config.persistent) { this.saveToStorage(); } this.emit("dataChanged", { key, value, type: "set" }); } get(key) { return this.data.get(key); } delete(key) { this.data.delete(key); if (this.config.persistent) { this.saveToStorage(); } this.emit("dataChanged", { key, type: "delete" }); } clear() { this.data.clear(); if (this.config.persistent) { this.saveToStorage(); } this.emit("dataChanged", { type: "clear" }); } has(key) { return this.data.has(key); } getAll() { return new Map(this.data); } saveToStorage() { const data = Object.fromEntries(this.data); GM_setValue(`keb-store-${this.config.name}`, JSON.stringify(data)); } loadFromStorage() { const data = GM_getValue(`keb-store-${this.config.name}`); if (data) { const parsedData = JSON.parse(data); Object.entries(parsedData).forEach(([key, value]) => { this.data.set(key, value); }); } } initialize() { if (this.config.persistent) { this.loadFromStorage(); } this.emit("initialized"); } }; __publicField(_Store, "stores", /* @__PURE__ */ new Map()); let Store = _Store; const _StoreManager = class _StoreManager { constructor() { __publicField(this, "sharedStore"); __publicField(this, "privateStores"); this.sharedStore = new Store({ name: "shared", persistent: true }); this.privateStores = /* @__PURE__ */ new Map(); } static getInstance() { if (!_StoreManager.instance) { _StoreManager.instance = new _StoreManager(); } return _StoreManager.instance; } getSharedStore() { return this.sharedStore; } createPrivateStore(owner, config) { if (this.privateStores.has(owner)) { return this.privateStores.get(owner); } const store = new Store({ ...config, name: `${owner}-${config.name}` }); this.privateStores.set(owner, store); return store; } getPrivateStore(owner) { return this.privateStores.get(owner); } removePrivateStore(owner) { const store = this.privateStores.get(owner); if (store) { store.clear(); this.privateStores.delete(owner); } } initialize() { this.sharedStore.initialize(); this.privateStores.forEach((store) => store.initialize()); } }; __publicField(_StoreManager, "instance"); let StoreManager = _StoreManager; var n, l$1, u$2, i$1, r$1, o$1, e$1, f$2, c$1, s$1, a$1, h$1, p$1 = {}, y$1 = [], v$1 = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i, w$2 = Array.isArray; function d$1(n2, l2) { for (var u2 in l2) n2[u2] = l2[u2]; return n2; } function g$2(n2) { n2 && n2.parentNode && n2.parentNode.removeChild(n2); } function _$1(l2, u2, t2) { var i2, r2, o2, e2 = {}; for (o2 in u2) "key" == o2 ? i2 = u2[o2] : "ref" == o2 ? r2 = u2[o2] : e2[o2] = u2[o2]; if (arguments.length > 2 && (e2.children = arguments.length > 3 ? n.call(arguments, 2) : t2), "function" == typeof l2 && null != l2.defaultProps) for (o2 in l2.defaultProps) null == e2[o2] && (e2[o2] = l2.defaultProps[o2]); return m$1(l2, e2, i2, r2, null); } function m$1(n2, t2, i2, r2, o2) { var e2 = { type: n2, props: t2, key: i2, ref: r2, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: null == o2 ? ++u$2 : o2, __i: -1, __u: 0 }; return null == o2 && null != l$1.vnode && l$1.vnode(e2), e2; } function b() { return { current: null }; } function k$2(n2) { return n2.children; } function x$2(n2, l2) { this.props = n2, this.context = l2; } function S(n2, l2) { if (null == l2) return n2.__ ? S(n2.__, n2.__i + 1) : null; for (var u2; l2 < n2.__k.length; l2++) if (null != (u2 = n2.__k[l2]) && null != u2.__e) return u2.__e; return "function" == typeof n2.type ? S(n2) : null; } function C$2(n2) { var l2, u2; if (null != (n2 = n2.__) && null != n2.__c) { for (n2.__e = n2.__c.base = null, l2 = 0; l2 < n2.__k.length; l2++) if (null != (u2 = n2.__k[l2]) && null != u2.__e) { n2.__e = n2.__c.base = u2.__e; break; } return C$2(n2); } } function M$1(n2) { (!n2.__d && (n2.__d = true) && i$1.push(n2) && !$$2.__r++ || r$1 != l$1.debounceRendering) && ((r$1 = l$1.debounceRendering) || o$1)($$2); } function $$2() { for (var n2, u2, t2, r2, o2, f2, c2, s2 = 1; i$1.length; ) i$1.length > s2 && i$1.sort(e$1), n2 = i$1.shift(), s2 = i$1.length, n2.__d && (t2 = void 0, o2 = (r2 = (u2 = n2).__v).__e, f2 = [], c2 = [], u2.__P && ((t2 = d$1({}, r2)).__v = r2.__v + 1, l$1.vnode && l$1.vnode(t2), O$1(u2.__P, t2, r2, u2.__n, u2.__P.namespaceURI, 32 & r2.__u ? [o2] : null, f2, null == o2 ? S(r2) : o2, !!(32 & r2.__u), c2), t2.__v = r2.__v, t2.__.__k[t2.__i] = t2, z$2(f2, t2, c2), t2.__e != o2 && C$2(t2))); $$2.__r = 0; } function I$1(n2, l2, u2, t2, i2, r2, o2, e2, f2, c2, s2) { var a2, h2, v2, w2, d2, g2, _2 = t2 && t2.__k || y$1, m2 = l2.length; for (f2 = P$2(u2, l2, _2, f2, m2), a2 = 0; a2 < m2; a2++) null != (v2 = u2.__k[a2]) && (h2 = -1 == v2.__i ? p$1 : _2[v2.__i] || p$1, v2.__i = a2, g2 = O$1(n2, v2, h2, i2, r2, o2, e2, f2, c2, s2), w2 = v2.__e, v2.ref && h2.ref != v2.ref && (h2.ref && q$2(h2.ref, null, v2), s2.push(v2.ref, v2.__c || w2, v2)), null == d2 && null != w2 && (d2 = w2), 4 & v2.__u || h2.__k === v2.__k ? f2 = A$2(v2, f2, n2) : "function" == typeof v2.type && void 0 !== g2 ? f2 = g2 : w2 && (f2 = w2.nextSibling), v2.__u &= -7); return u2.__e = d2, f2; } function P$2(n2, l2, u2, t2, i2) { var r2, o2, e2, f2, c2, s2 = u2.length, a2 = s2, h2 = 0; for (n2.__k = new Array(i2), r2 = 0; r2 < i2; r2++) null != (o2 = l2[r2]) && "boolean" != typeof o2 && "function" != typeof o2 ? (f2 = r2 + h2, (o2 = n2.__k[r2] = "string" == typeof o2 || "number" == typeof o2 || "bigint" == typeof o2 || o2.constructor == String ? m$1(null, o2, null, null, null) : w$2(o2) ? m$1(k$2, { children: o2 }, null, null, null) : null == o2.constructor && o2.__b > 0 ? m$1(o2.type, o2.props, o2.key, o2.ref ? o2.ref : null, o2.__v) : o2).__ = n2, o2.__b = n2.__b + 1, e2 = null, -1 != (c2 = o2.__i = L$1(o2, u2, f2, a2)) && (a2--, (e2 = u2[c2]) && (e2.__u |= 2)), null == e2 || null == e2.__v ? (-1 == c2 && (i2 > s2 ? h2-- : i2 < s2 && h2++), "function" != typeof o2.type && (o2.__u |= 4)) : c2 != f2 && (c2 == f2 - 1 ? h2-- : c2 == f2 + 1 ? h2++ : (c2 > f2 ? h2-- : h2++, o2.__u |= 4))) : n2.__k[r2] = null; if (a2) for (r2 = 0; r2 < s2; r2++) null != (e2 = u2[r2]) && 0 == (2 & e2.__u) && (e2.__e == t2 && (t2 = S(e2)), B$2(e2, e2)); return t2; } function A$2(n2, l2, u2) { var t2, i2; if ("function" == typeof n2.type) { for (t2 = n2.__k, i2 = 0; t2 && i2 < t2.length; i2++) t2[i2] && (t2[i2].__ = n2, l2 = A$2(t2[i2], l2, u2)); return l2; } n2.__e != l2 && (l2 && n2.type && !u2.contains(l2) && (l2 = S(n2)), u2.insertBefore(n2.__e, l2 || null), l2 = n2.__e); do { l2 = l2 && l2.nextSibling; } while (null != l2 && 8 == l2.nodeType); return l2; } function H$1(n2, l2) { return l2 = l2 || [], null == n2 || "boolean" == typeof n2 || (w$2(n2) ? n2.some(function(n3) { H$1(n3, l2); }) : l2.push(n2)), l2; } function L$1(n2, l2, u2, t2) { var i2, r2, o2 = n2.key, e2 = n2.type, f2 = l2[u2]; if (null === f2 && null == n2.key || f2 && o2 == f2.key && e2 == f2.type && 0 == (2 & f2.__u)) return u2; if (t2 > (null != f2 && 0 == (2 & f2.__u) ? 1 : 0)) for (i2 = u2 - 1, r2 = u2 + 1; i2 >= 0 || r2 < l2.length; ) { if (i2 >= 0) { if ((f2 = l2[i2]) && 0 == (2 & f2.__u) && o2 == f2.key && e2 == f2.type) return i2; i2--; } if (r2 < l2.length) { if ((f2 = l2[r2]) && 0 == (2 & f2.__u) && o2 == f2.key && e2 == f2.type) return r2; r2++; } } return -1; } function T$2(n2, l2, u2) { "-" == l2[0] ? n2.setProperty(l2, null == u2 ? "" : u2) : n2[l2] = null == u2 ? "" : "number" != typeof u2 || v$1.test(l2) ? u2 : u2 + "px"; } function j$2(n2, l2, u2, t2, i2) { var r2; n: if ("style" == l2) if ("string" == typeof u2) n2.style.cssText = u2; else { if ("string" == typeof t2 && (n2.style.cssText = t2 = ""), t2) for (l2 in t2) u2 && l2 in u2 || T$2(n2.style, l2, ""); if (u2) for (l2 in u2) t2 && u2[l2] == t2[l2] || T$2(n2.style, l2, u2[l2]); } else if ("o" == l2[0] && "n" == l2[1]) r2 = l2 != (l2 = l2.replace(f$2, "$1")), l2 = l2.toLowerCase() in n2 || "onFocusOut" == l2 || "onFocusIn" == l2 ? l2.toLowerCase().slice(2) : l2.slice(2), n2.l || (n2.l = {}), n2.l[l2 + r2] = u2, u2 ? t2 ? u2.u = t2.u : (u2.u = c$1, n2.addEventListener(l2, r2 ? a$1 : s$1, r2)) : n2.removeEventListener(l2, r2 ? a$1 : s$1, r2); else { if ("http://www.w3.org/2000/svg" == i2) l2 = l2.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s"); else if ("width" != l2 && "height" != l2 && "href" != l2 && "list" != l2 && "form" != l2 && "tabIndex" != l2 && "download" != l2 && "rowSpan" != l2 && "colSpan" != l2 && "role" != l2 && "popover" != l2 && l2 in n2) try { n2[l2] = null == u2 ? "" : u2; break n; } catch (n3) { } "function" == typeof u2 || (null == u2 || false === u2 && "-" != l2[4] ? n2.removeAttribute(l2) : n2.setAttribute(l2, "popover" == l2 && 1 == u2 ? "" : u2)); } } function F$2(n2) { return function(u2) { if (this.l) { var t2 = this.l[u2.type + n2]; if (null == u2.t) u2.t = c$1++; else if (u2.t < t2.u) return; return t2(l$1.event ? l$1.event(u2) : u2); } }; } function O$1(n2, u2, t2, i2, r2, o2, e2, f2, c2, s2) { var a2, h2, p2, y2, v2, _2, m2, b2, S2, C2, M2, $2, P2, A2, H2, L2, T2, j2 = u2.type; if (null != u2.constructor) return null; 128 & t2.__u && (c2 = !!(32 & t2.__u), o2 = [f2 = u2.__e = t2.__e]), (a2 = l$1.__b) && a2(u2); n: if ("function" == typeof j2) try { if (b2 = u2.props, S2 = "prototype" in j2 && j2.prototype.render, C2 = (a2 = j2.contextType) && i2[a2.__c], M2 = a2 ? C2 ? C2.props.value : a2.__ : i2, t2.__c ? m2 = (h2 = u2.__c = t2.__c).__ = h2.__E : (S2 ? u2.__c = h2 = new j2(b2, M2) : (u2.__c = h2 = new x$2(b2, M2), h2.constructor = j2, h2.render = D$2), C2 && C2.sub(h2), h2.props = b2, h2.state || (h2.state = {}), h2.context = M2, h2.__n = i2, p2 = h2.__d = true, h2.__h = [], h2._sb = []), S2 && null == h2.__s && (h2.__s = h2.state), S2 && null != j2.getDerivedStateFromProps && (h2.__s == h2.state && (h2.__s = d$1({}, h2.__s)), d$1(h2.__s, j2.getDerivedStateFromProps(b2, h2.__s))), y2 = h2.props, v2 = h2.state, h2.__v = u2, p2) S2 && null == j2.getDerivedStateFromProps && null != h2.componentWillMount && h2.componentWillMount(), S2 && null != h2.componentDidMount && h2.__h.push(h2.componentDidMount); else { if (S2 && null == j2.getDerivedStateFromProps && b2 !== y2 && null != h2.componentWillReceiveProps && h2.componentWillReceiveProps(b2, M2), !h2.__e && null != h2.shouldComponentUpdate && false === h2.shouldComponentUpdate(b2, h2.__s, M2) || u2.__v == t2.__v) { for (u2.__v != t2.__v && (h2.props = b2, h2.state = h2.__s, h2.__d = false), u2.__e = t2.__e, u2.__k = t2.__k, u2.__k.some(function(n3) { n3 && (n3.__ = u2); }), $2 = 0; $2 < h2._sb.length; $2++) h2.__h.push(h2._sb[$2]); h2._sb = [], h2.__h.length && e2.push(h2); break n; } null != h2.componentWillUpdate && h2.componentWillUpdate(b2, h2.__s, M2), S2 && null != h2.componentDidUpdate && h2.__h.push(function() { h2.componentDidUpdate(y2, v2, _2); }); } if (h2.context = M2, h2.props = b2, h2.__P = n2, h2.__e = false, P2 = l$1.__r, A2 = 0, S2) { for (h2.state = h2.__s, h2.__d = false, P2 && P2(u2), a2 = h2.render(h2.props, h2.state, h2.context), H2 = 0; H2 < h2._sb.length; H2++) h2.__h.push(h2._sb[H2]); h2._sb = []; } else do { h2.__d = false, P2 && P2(u2), a2 = h2.render(h2.props, h2.state, h2.context), h2.state = h2.__s; } while (h2.__d && ++A2 < 25); h2.state = h2.__s, null != h2.getChildContext && (i2 = d$1(d$1({}, i2), h2.getChildContext())), S2 && !p2 && null != h2.getSnapshotBeforeUpdate && (_2 = h2.getSnapshotBeforeUpdate(y2, v2)), L2 = a2, null != a2 && a2.type === k$2 && null == a2.key && (L2 = N$1(a2.props.children)), f2 = I$1(n2, w$2(L2) ? L2 : [L2], u2, t2, i2, r2, o2, e2, f2, c2, s2), h2.base = u2.__e, u2.__u &= -161, h2.__h.length && e2.push(h2), m2 && (h2.__E = h2.__ = null); } catch (n3) { if (u2.__v = null, c2 || null != o2) if (n3.then) { for (u2.__u |= c2 ? 160 : 128; f2 && 8 == f2.nodeType && f2.nextSibling; ) f2 = f2.nextSibling; o2[o2.indexOf(f2)] = null, u2.__e = f2; } else for (T2 = o2.length; T2--; ) g$2(o2[T2]); else u2.__e = t2.__e, u2.__k = t2.__k; l$1.__e(n3, u2, t2); } else null == o2 && u2.__v == t2.__v ? (u2.__k = t2.__k, u2.__e = t2.__e) : f2 = u2.__e = V$1(t2.__e, u2, t2, i2, r2, o2, e2, c2, s2); return (a2 = l$1.diffed) && a2(u2), 128 & u2.__u ? void 0 : f2; } function z$2(n2, u2, t2) { for (var i2 = 0; i2 < t2.length; i2++) q$2(t2[i2], t2[++i2], t2[++i2]); l$1.__c && l$1.__c(u2, n2), n2.some(function(u3) { try { n2 = u3.__h, u3.__h = [], n2.some(function(n3) { n3.call(u3); }); } catch (n3) { l$1.__e(n3, u3.__v); } }); } function N$1(n2) { return "object" != typeof n2 || null == n2 || n2.__b && n2.__b > 0 ? n2 : w$2(n2) ? n2.map(N$1) : d$1({}, n2); } function V$1(u2, t2, i2, r2, o2, e2, f2, c2, s2) { var a2, h2, y2, v2, d2, _2, m2, b2 = i2.props, k2 = t2.props, x2 = t2.type; if ("svg" == x2 ? o2 = "http://www.w3.org/2000/svg" : "math" == x2 ? o2 = "http://www.w3.org/1998/Math/MathML" : o2 || (o2 = "http://www.w3.org/1999/xhtml"), null != e2) { for (a2 = 0; a2 < e2.length; a2++) if ((d2 = e2[a2]) && "setAttribute" in d2 == !!x2 && (x2 ? d2.localName == x2 : 3 == d2.nodeType)) { u2 = d2, e2[a2] = null; break; } } if (null == u2) { if (null == x2) return document.createTextNode(k2); u2 = document.createElementNS(o2, x2, k2.is && k2), c2 && (l$1.__m && l$1.__m(t2, e2), c2 = false), e2 = null; } if (null == x2) b2 === k2 || c2 && u2.data == k2 || (u2.data = k2); else { if (e2 = e2 && n.call(u2.childNodes), b2 = i2.props || p$1, !c2 && null != e2) for (b2 = {}, a2 = 0; a2 < u2.attributes.length; a2++) b2[(d2 = u2.attributes[a2]).name] = d2.value; for (a2 in b2) if (d2 = b2[a2], "children" == a2) ; else if ("dangerouslySetInnerHTML" == a2) y2 = d2; else if (!(a2 in k2)) { if ("value" == a2 && "defaultValue" in k2 || "checked" == a2 && "defaultChecked" in k2) continue; j$2(u2, a2, null, d2, o2); } for (a2 in k2) d2 = k2[a2], "children" == a2 ? v2 = d2 : "dangerouslySetInnerHTML" == a2 ? h2 = d2 : "value" == a2 ? _2 = d2 : "checked" == a2 ? m2 = d2 : c2 && "function" != typeof d2 || b2[a2] === d2 || j$2(u2, a2, d2, b2[a2], o2); if (h2) c2 || y2 && (h2.__html == y2.__html || h2.__html == u2.innerHTML) || (u2.innerHTML = h2.__html), t2.__k = []; else if (y2 && (u2.innerHTML = ""), I$1("template" == t2.type ? u2.content : u2, w$2(v2) ? v2 : [v2], t2, i2, r2, "foreignObject" == x2 ? "http://www.w3.org/1999/xhtml" : o2, e2, f2, e2 ? e2[0] : i2.__k && S(i2, 0), c2, s2), null != e2) for (a2 = e2.length; a2--; ) g$2(e2[a2]); c2 || (a2 = "value", "progress" == x2 && null == _2 ? u2.removeAttribute("value") : null != _2 && (_2 !== u2[a2] || "progress" == x2 && !_2 || "option" == x2 && _2 != b2[a2]) && j$2(u2, a2, _2, b2[a2], o2), a2 = "checked", null != m2 && m2 != u2[a2] && j$2(u2, a2, m2, b2[a2], o2)); } return u2; } function q$2(n2, u2, t2) { try { if ("function" == typeof n2) { var i2 = "function" == typeof n2.__u; i2 && n2.__u(), i2 && null == u2 || (n2.__u = n2(u2)); } else n2.current = u2; } catch (n3) { l$1.__e(n3, t2); } } function B$2(n2, u2, t2) { var i2, r2; if (l$1.unmount && l$1.unmount(n2), (i2 = n2.ref) && (i2.current && i2.current != n2.__e || q$2(i2, null, u2)), null != (i2 = n2.__c)) { if (i2.componentWillUnmount) try { i2.componentWillUnmount(); } catch (n3) { l$1.__e(n3, u2); } i2.base = i2.__P = null; } if (i2 = n2.__k) for (r2 = 0; r2 < i2.length; r2++) i2[r2] && B$2(i2[r2], u2, t2 || "function" != typeof n2.type); t2 || g$2(n2.__e), n2.__c = n2.__ = n2.__e = void 0; } function D$2(n2, l2, u2) { return this.constructor(n2, u2); } function E$1(u2, t2, i2) { var r2, o2, e2, f2; t2 == document && (t2 = document.documentElement), l$1.__ && l$1.__(u2, t2), o2 = (r2 = "function" == typeof i2) ? null : i2 && i2.__k || t2.__k, e2 = [], f2 = [], O$1(t2, u2 = (!r2 && i2 || t2).__k = _$1(k$2, null, [u2]), o2 || p$1, p$1, t2.namespaceURI, !r2 && i2 ? [i2] : o2 ? null : t2.firstChild ? n.call(t2.childNodes) : null, e2, !r2 && i2 ? i2 : o2 ? o2.__e : t2.firstChild, r2, f2), z$2(e2, u2, f2); } function G$1(n2, l2) { E$1(n2, l2, G$1); } function J$1(l2, u2, t2) { var i2, r2, o2, e2, f2 = d$1({}, l2.props); for (o2 in l2.type && l2.type.defaultProps && (e2 = l2.type.defaultProps), u2) "key" == o2 ? i2 = u2[o2] : "ref" == o2 ? r2 = u2[o2] : f2[o2] = null == u2[o2] && null != e2 ? e2[o2] : u2[o2]; return arguments.length > 2 && (f2.children = arguments.length > 3 ? n.call(arguments, 2) : t2), m$1(l2.type, f2, i2 || l2.key, r2 || l2.ref, null); } function K$1(n2) { function l2(n3) { var u2, t2; return this.getChildContext || (u2 = /* @__PURE__ */ new Set(), (t2 = {})[l2.__c] = this, this.getChildContext = function() { return t2; }, this.componentWillUnmount = function() { u2 = null; }, this.shouldComponentUpdate = function(n4) { this.props.value != n4.value && u2.forEach(function(n5) { n5.__e = true, M$1(n5); }); }, this.sub = function(n4) { u2.add(n4); var l3 = n4.componentWillUnmount; n4.componentWillUnmount = function() { u2 && u2.delete(n4), l3 && l3.call(n4); }; }), n3.children; } return l2.__c = "__cC" + h$1++, l2.__ = n2, l2.Provider = l2.__l = (l2.Consumer = function(n3, l3) { return n3.children(l3); }).contextType = l2, l2; } n = y$1.slice, l$1 = { __e: function(n2, l2, u2, t2) { for (var i2, r2, o2; l2 = l2.__; ) if ((i2 = l2.__c) && !i2.__) try { if ((r2 = i2.constructor) && null != r2.getDerivedStateFromError && (i2.setState(r2.getDerivedStateFromError(n2)), o2 = i2.__d), null != i2.componentDidCatch && (i2.componentDidCatch(n2, t2 || {}), o2 = i2.__d), o2) return i2.__E = i2; } catch (l3) { n2 = l3; } throw n2; } }, u$2 = 0, x$2.prototype.setState = function(n2, l2) { var u2; u2 = null != this.__s && this.__s != this.state ? this.__s : this.__s = d$1({}, this.state), "function" == typeof n2 && (n2 = n2(d$1({}, u2), this.props)), n2 && d$1(u2, n2), null != n2 && this.__v && (l2 && this._sb.push(l2), M$1(this)); }, x$2.prototype.forceUpdate = function(n2) { this.__v && (this.__e = true, n2 && this.__h.push(n2), M$1(this)); }, x$2.prototype.render = k$2, i$1 = [], o$1 = "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, e$1 = function(n2, l2) { return n2.__v.__b - l2.__v.__b; }, $$2.__r = 0, f$2 = /(PointerCapture)$|Capture$/i, c$1 = 0, s$1 = F$2(false), a$1 = F$2(true), h$1 = 0; var f$1 = 0; function u$1(e2, t2, n2, o2, i2, u2) { t2 || (t2 = {}); var a2, c2, p2 = t2; if ("ref" in p2) for (c2 in p2 = {}, t2) "ref" == c2 ? a2 = t2[c2] : p2[c2] = t2[c2]; var l2 = { type: e2, props: p2, key: n2, ref: a2, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: --f$1, __i: -1, __u: 0, __source: i2, __self: u2 }; if ("function" == typeof e2 && (a2 = e2.defaultProps)) for (c2 in a2) void 0 === p2[c2] && (p2[c2] = a2[c2]); return l$1.vnode && l$1.vnode(l2), l2; } function getDefaultExportFromCjs(x2) { return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2; } var classnames = { exports: {} }; (function(module) { (function() { var hasOwn = {}.hasOwnProperty; function classNames2() { var classes = ""; for (var i2 = 0; i2 < arguments.length; i2++) { var arg = arguments[i2]; if (arg) { classes = appendClass(classes, parseValue(arg)); } } return classes; } function parseValue(arg) { if (typeof arg === "string" || typeof arg === "number") { return arg; } if (typeof arg !== "object") { return ""; } if (Array.isArray(arg)) { return classNames2.apply(null, arg); } if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes("[native code]")) { return arg.toString(); } var classes = ""; for (var key in arg) { if (hasOwn.call(arg, key) && arg[key]) { classes = appendClass(classes, key); } } return classes; } function appendClass(value, newClass) { if (!newClass) { return value; } if (value) { return value + " " + newClass; } return value + newClass; } if (module.exports) { classNames2.default = classNames2; module.exports = classNames2; } else { window.classNames = classNames2; } })(); })(classnames); var classnamesExports = classnames.exports; const classNames = getDefaultExportFromCjs(classnamesExports); var t, r, u, i, o = 0, f = [], c = l$1, e = c.__b, a = c.__r, v = c.diffed, l = c.__c, m = c.unmount, s = c.__; function p(n2, t2) { c.__h && c.__h(r, n2, o || t2), o = 0; var u2 = r.__H || (r.__H = { __: [], __h: [] }); return n2 >= u2.__.length && u2.__.push({}), u2.__[n2]; } function d(n2) { return o = 1, h(D$1, n2); } function h(n2, u2, i2) { var o2 = p(t++, 2); if (o2.t = n2, !o2.__c && (o2.__ = [i2 ? i2(u2) : D$1(void 0, u2), function(n3) { var t2 = o2.__N ? o2.__N[0] : o2.__[0], r2 = o2.t(t2, n3); t2 !== r2 && (o2.__N = [r2, o2.__[1]], o2.__c.setState({})); }], o2.__c = r, !r.__f)) { var f2 = function(n3, t2, r2) { if (!o2.__c.__H) return true; var u3 = o2.__c.__H.__.filter(function(n4) { return !!n4.__c; }); if (u3.every(function(n4) { return !n4.__N; })) return !c2 || c2.call(this, n3, t2, r2); var i3 = o2.__c.props !== n3; return u3.forEach(function(n4) { if (n4.__N) { var t3 = n4.__[0]; n4.__ = n4.__N, n4.__N = void 0, t3 !== n4.__[0] && (i3 = true); } }), c2 && c2.call(this, n3, t2, r2) || i3; }; r.__f = true; var c2 = r.shouldComponentUpdate, e2 = r.componentWillUpdate; r.componentWillUpdate = function(n3, t2, r2) { if (this.__e) { var u3 = c2; c2 = void 0, f2(n3, t2, r2), c2 = u3; } e2 && e2.call(this, n3, t2, r2); }, r.shouldComponentUpdate = f2; } return o2.__N || o2.__; } function y(n2, u2) { var i2 = p(t++, 3); !c.__s && C$1(i2.__H, u2) && (i2.__ = n2, i2.u = u2, r.__H.__h.push(i2)); } function _(n2, u2) { var i2 = p(t++, 4); !c.__s && C$1(i2.__H, u2) && (i2.__ = n2, i2.u = u2, r.__h.push(i2)); } function A$1(n2) { return o = 5, T$1(function() { return { current: n2 }; }, []); } function F$1(n2, t2, r2) { o = 6, _(function() { if ("function" == typeof n2) { var r3 = n2(t2()); return function() { n2(null), r3 && "function" == typeof r3 && r3(); }; } if (n2) return n2.current = t2(), function() { return n2.current = null; }; }, null == r2 ? r2 : r2.concat(n2)); } function T$1(n2, r2) { var u2 = p(t++, 7); return C$1(u2.__H, r2) && (u2.__ = n2(), u2.__H = r2, u2.__h = n2), u2.__; } function q$1(n2, t2) { return o = 8, T$1(function() { return n2; }, t2); } function x$1(n2) { var u2 = r.context[n2.__c], i2 = p(t++, 9); return i2.c = n2, u2 ? (null == i2.__ && (i2.__ = true, u2.sub(r)), u2.props.value) : n2.__; } function P$1(n2, t2) { c.useDebugValue && c.useDebugValue(t2 ? t2(n2) : n2); } function g$1() { var n2 = p(t++, 11); if (!n2.__) { for (var u2 = r.__v; null !== u2 && !u2.__m && null !== u2.__; ) u2 = u2.__; var i2 = u2.__m || (u2.__m = [0, 0]); n2.__ = "P" + i2[0] + "-" + i2[1]++; } return n2.__; } function j$1() { for (var n2; n2 = f.shift(); ) if (n2.__P && n2.__H) try { n2.__H.__h.forEach(z$1), n2.__H.__h.forEach(B$1), n2.__H.__h = []; } catch (t2) { n2.__H.__h = [], c.__e(t2, n2.__v); } } c.__b = function(n2) { r = null, e && e(n2); }, c.__ = function(n2, t2) { n2 && t2.__k && t2.__k.__m && (n2.__m = t2.__k.__m), s && s(n2, t2); }, c.__r = function(n2) { a && a(n2), t = 0; var i2 = (r = n2.__c).__H; i2 && (u === r ? (i2.__h = [], r.__h = [], i2.__.forEach(function(n3) { n3.__N && (n3.__ = n3.__N), n3.u = n3.__N = void 0; })) : (i2.__h.forEach(z$1), i2.__h.forEach(B$1), i2.__h = [], t = 0)), u = r; }, c.diffed = function(n2) { v && v(n2); var t2 = n2.__c; t2 && t2.__H && (t2.__H.__h.length && (1 !== f.push(t2) && i === c.requestAnimationFrame || ((i = c.requestAnimationFrame) || w$1)(j$1)), t2.__H.__.forEach(function(n3) { n3.u && (n3.__H = n3.u), n3.u = void 0; })), u = r = null; }, c.__c = function(n2, t2) { t2.some(function(n3) { try { n3.__h.forEach(z$1), n3.__h = n3.__h.filter(function(n4) { return !n4.__ || B$1(n4); }); } catch (r2) { t2.some(function(n4) { n4.__h && (n4.__h = []); }), t2 = [], c.__e(r2, n3.__v); } }), l && l(n2, t2); }, c.unmount = function(n2) { m && m(n2); var t2, r2 = n2.__c; r2 && r2.__H && (r2.__H.__.forEach(function(n3) { try { z$1(n3); } catch (n4) { t2 = n4; } }), r2.__H = void 0, t2 && c.__e(t2, r2.__v)); }; var k$1 = "function" == typeof requestAnimationFrame; function w$1(n2) { var t2, r2 = function() { clearTimeout(u2), k$1 && cancelAnimationFrame(t2), setTimeout(n2); }, u2 = setTimeout(r2, 100); k$1 && (t2 = requestAnimationFrame(r2)); } function z$1(n2) { var t2 = r, u2 = n2.__c; "function" == typeof u2 && (n2.__c = void 0, u2()), r = t2; } function B$1(n2) { var t2 = r; n2.__c = n2.__(), r = t2; } function C$1(n2, t2) { return !n2 || n2.length !== t2.length || t2.some(function(t3, r2) { return t3 !== n2[r2]; }); } function D$1(n2, t2) { return "function" == typeof t2 ? t2(n2) : t2; } function g(n2, t2) { for (var e2 in t2) n2[e2] = t2[e2]; return n2; } function E(n2, t2) { for (var e2 in n2) if ("__source" !== e2 && !(e2 in t2)) return true; for (var r2 in t2) if ("__source" !== r2 && n2[r2] !== t2[r2]) return true; return false; } function C(n2, t2) { var e2 = t2(), r2 = d({ t: { __: e2, u: t2 } }), u2 = r2[0].t, o2 = r2[1]; return _(function() { u2.__ = e2, u2.u = t2, x(u2) && o2({ t: u2 }); }, [n2, e2, t2]), y(function() { return x(u2) && o2({ t: u2 }), n2(function() { x(u2) && o2({ t: u2 }); }); }, [n2]), e2; } function x(n2) { var t2, e2, r2 = n2.u, u2 = n2.__; try { var o2 = r2(); return !((t2 = u2) === (e2 = o2) && (0 !== t2 || 1 / t2 == 1 / e2) || t2 != t2 && e2 != e2); } catch (n3) { return true; } } function R(n2) { n2(); } function w(n2) { return n2; } function k() { return [false, R]; } var I = _; function N(n2, t2) { this.props = n2, this.context = t2; } function M(n2, e2) { function r2(n3) { var t2 = this.props.ref, r3 = t2 == n3.ref; return !r3 && t2 && (t2.call ? t2(null) : t2.current = null), e2 ? !e2(this.props, n3) || !r3 : E(this.props, n3); } function u2(e3) { return this.shouldComponentUpdate = r2, _$1(n2, e3); } return u2.displayName = "Memo(" + (n2.displayName || n2.name) + ")", u2.prototype.isReactComponent = true, u2.__f = true, u2; } (N.prototype = new x$2()).isPureReactComponent = true, N.prototype.shouldComponentUpdate = function(n2, t2) { return E(this.props, n2) || E(this.state, t2); }; var T = l$1.__b; l$1.__b = function(n2) { n2.type && n2.type.__f && n2.ref && (n2.props.ref = n2.ref, n2.ref = null), T && T(n2); }; var A = "undefined" != typeof Symbol && Symbol.for && Symbol.for("react.forward_ref") || 3911; function D(n2) { function t2(t3) { var e2 = g({}, t3); return delete e2.ref, n2(e2, t3.ref || null); } return t2.$$typeof = A, t2.render = t2, t2.prototype.isReactComponent = t2.__f = true, t2.displayName = "ForwardRef(" + (n2.displayName || n2.name) + ")", t2; } var L = function(n2, t2) { return null == n2 ? null : H$1(H$1(n2).map(t2)); }, O = { map: L, forEach: L, count: function(n2) { return n2 ? H$1(n2).length : 0; }, only: function(n2) { var t2 = H$1(n2); if (1 !== t2.length) throw "Children.only"; return t2[0]; }, toArray: H$1 }, F = l$1.__e; l$1.__e = function(n2, t2, e2, r2) { if (n2.then) { for (var u2, o2 = t2; o2 = o2.__; ) if ((u2 = o2.__c) && u2.__c) return null == t2.__e && (t2.__e = e2.__e, t2.__k = e2.__k), u2.__c(n2, t2); } F(n2, t2, e2, r2); }; var U = l$1.unmount; function V(n2, t2, e2) { return n2 && (n2.__c && n2.__c.__H && (n2.__c.__H.__.forEach(function(n3) { "function" == typeof n3.__c && n3.__c(); }), n2.__c.__H = null), null != (n2 = g({}, n2)).__c && (n2.__c.__P === e2 && (n2.__c.__P = t2), n2.__c.__e = true, n2.__c = null), n2.__k = n2.__k && n2.__k.map(function(n3) { return V(n3, t2, e2); })), n2; } function W(n2, t2, e2) { return n2 && e2 && (n2.__v = null, n2.__k = n2.__k && n2.__k.map(function(n3) { return W(n3, t2, e2); }), n2.__c && n2.__c.__P === t2 && (n2.__e && e2.appendChild(n2.__e), n2.__c.__e = true, n2.__c.__P = e2)), n2; } function P() { this.__u = 0, this.o = null, this.__b = null; } function j(n2) { var t2 = n2.__.__c; return t2 && t2.__a && t2.__a(n2); } function z(n2) { var e2, r2, u2; function o2(o3) { if (e2 || (e2 = n2()).then(function(n3) { r2 = n3.default || n3; }, function(n3) { u2 = n3; }), u2) throw u2; if (!r2) throw e2; return _$1(r2, o3); } return o2.displayName = "Lazy", o2.__f = true, o2; } function B() { this.i = null, this.l = null; } l$1.unmount = function(n2) { var t2 = n2.__c; t2 && t2.__R && t2.__R(), t2 && 32 & n2.__u && (n2.type = null), U && U(n2); }, (P.prototype = new x$2()).__c = function(n2, t2) { var e2 = t2.__c, r2 = this; null == r2.o && (r2.o = []), r2.o.push(e2); var u2 = j(r2.__v), o2 = false, i2 = function() { o2 || (o2 = true, e2.__R = null, u2 ? u2(l2) : l2()); }; e2.__R = i2; var l2 = function() { if (!--r2.__u) { if (r2.state.__a) { var n3 = r2.state.__a; r2.__v.__k[0] = W(n3, n3.__c.__P, n3.__c.__O); } var t3; for (r2.setState({ __a: r2.__b = null }); t3 = r2.o.pop(); ) t3.forceUpdate(); } }; r2.__u++ || 32 & t2.__u || r2.setState({ __a: r2.__b = r2.__v.__k[0] }), n2.then(i2, i2); }, P.prototype.componentWillUnmount = function() { this.o = []; }, P.prototype.render = function(n2, e2) { if (this.__b) { if (this.__v.__k) { var r2 = document.createElement("div"), o2 = this.__v.__k[0].__c; this.__v.__k[0] = V(this.__b, r2, o2.__O = o2.__P); } this.__b = null; } var i2 = e2.__a && _$1(k$2, null, n2.fallback); return i2 && (i2.__u &= -33), [_$1(k$2, null, e2.__a ? null : n2.children), i2]; }; var H = function(n2, t2, e2) { if (++e2[1] === e2[0] && n2.l.delete(t2), n2.props.revealOrder && ("t" !== n2.props.revealOrder[0] || !n2.l.size)) for (e2 = n2.i; e2; ) { for (; e2.length > 3; ) e2.pop()(); if (e2[1] < e2[0]) break; n2.i = e2 = e2[2]; } }; function Z(n2) { return this.getChildContext = function() { return n2.context; }, n2.children; } function Y(n2) { var e2 = this, r2 = n2.h; if (e2.componentWillUnmount = function() { E$1(null, e2.v), e2.v = null, e2.h = null; }, e2.h && e2.h !== r2 && e2.componentWillUnmount(), !e2.v) { for (var u2 = e2.__v; null !== u2 && !u2.__m && null !== u2.__; ) u2 = u2.__; e2.h = r2, e2.v = { nodeType: 1, parentNode: r2, childNodes: [], __k: { __m: u2.__m }, contains: function() { return true; }, appendChild: function(n3) { this.childNodes.push(n3), e2.h.appendChild(n3); }, insertBefore: function(n3, t2) { this.childNodes.push(n3), e2.h.insertBefore(n3, t2); }, removeChild: function(n3) { this.childNodes.splice(this.childNodes.indexOf(n3) >>> 1, 1), e2.h.removeChild(n3); } }; } E$1(_$1(Z, { context: e2.context }, n2.__v), e2.v); } function $$1(n2, e2) { var r2 = _$1(Y, { __v: n2, h: e2 }); return r2.containerInfo = e2, r2; } (B.prototype = new x$2()).__a = function(n2) { var t2 = this, e2 = j(t2.__v), r2 = t2.l.get(n2); return r2[0]++, function(u2) { var o2 = function() { t2.props.revealOrder ? (r2.push(u2), H(t2, n2, r2)) : u2(); }; e2 ? e2(o2) : o2(); }; }, B.prototype.render = function(n2) { this.i = null, this.l = /* @__PURE__ */ new Map(); var t2 = H$1(n2.children); n2.revealOrder && "b" === n2.revealOrder[0] && t2.reverse(); for (var e2 = t2.length; e2--; ) this.l.set(t2[e2], this.i = [1, 0, this.i]); return n2.children; }, B.prototype.componentDidUpdate = B.prototype.componentDidMount = function() { var n2 = this; this.l.forEach(function(t2, e2) { H(n2, e2, t2); }); }; var q = "undefined" != typeof Symbol && Symbol.for && Symbol.for("react.element") || 60103, G = /^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image(!S)|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/, J = /^on(Ani|Tra|Tou|BeforeInp|Compo)/, K = /[A-Z0-9]/g, Q = "undefined" != typeof document, X = function(n2) { return ("undefined" != typeof Symbol && "symbol" == typeof Symbol() ? /fil|che|rad/ : /fil|che|ra/).test(n2); }; function nn(n2, t2, e2) { return null == t2.__k && (t2.textContent = ""), E$1(n2, t2), "function" == typeof e2 && e2(), n2 ? n2.__c : null; } function tn(n2, t2, e2) { return G$1(n2, t2), "function" == typeof e2 && e2(), n2 ? n2.__c : null; } x$2.prototype.isReactComponent = {}, ["componentWillMount", "componentWillReceiveProps", "componentWillUpdate"].forEach(function(t2) { Object.defineProperty(x$2.prototype, t2, { configurable: true, get: function() { return this["UNSAFE_" + t2]; }, set: function(n2) { Object.defineProperty(this, t2, { configurable: true, writable: true, value: n2 }); } }); }); var en = l$1.event; function rn() { } function un() { return this.cancelBubble; } function on() { return this.defaultPrevented; } l$1.event = function(n2) { return en && (n2 = en(n2)), n2.persist = rn, n2.isPropagationStopped = un, n2.isDefaultPrevented = on, n2.nativeEvent = n2; }; var ln, cn = { enumerable: false, configurable: true, get: function() { return this.class; } }, fn = l$1.vnode; l$1.vnode = function(n2) { "string" == typeof n2.type && function(n3) { var t2 = n3.props, e2 = n3.type, u2 = {}, o2 = -1 === e2.indexOf("-"); for (var i2 in t2) { var l2 = t2[i2]; if (!("value" === i2 && "defaultValue" in t2 && null == l2 || Q && "children" === i2 && "noscript" === e2 || "class" === i2 || "className" === i2)) { var c2 = i2.toLowerCase(); "defaultValue" === i2 && "value" in t2 && null == t2.value ? i2 = "value" : "download" === i2 && true === l2 ? l2 = "" : "translate" === c2 && "no" === l2 ? l2 = false : "o" === c2[0] && "n" === c2[1] ? "ondoubleclick" === c2 ? i2 = "ondblclick" : "onchange" !== c2 || "input" !== e2 && "textarea" !== e2 || X(t2.type) ? "onfocus" === c2 ? i2 = "onfocusin" : "onblur" === c2 ? i2 = "onfocusout" : J.test(i2) && (i2 = c2) : c2 = i2 = "oninput" : o2 && G.test(i2) ? i2 = i2.replace(K, "-$&").toLowerCase() : null === l2 && (l2 = void 0), "oninput" === c2 && u2[i2 = c2] && (i2 = "oninputCapture"), u2[i2] = l2; } } "select" == e2 && u2.multiple && Array.isArray(u2.value) && (u2.value = H$1(t2.children).forEach(function(n4) { n4.props.selected = -1 != u2.value.indexOf(n4.props.value); })), "select" == e2 && null != u2.defaultValue && (u2.value = H$1(t2.children).forEach(function(n4) { n4.props.selected = u2.multiple ? -1 != u2.defaultValue.indexOf(n4.props.value) : u2.defaultValue == n4.props.value; })), t2.class && !t2.className ? (u2.class = t2.class, Object.defineProperty(u2, "className", cn)) : (t2.className && !t2.class || t2.class && t2.className) && (u2.class = u2.className = t2.className), n3.props = u2; }(n2), n2.$$typeof = q, fn && fn(n2); }; var an = l$1.__r; l$1.__r = function(n2) { an && an(n2), ln = n2.__c; }; var sn = l$1.diffed; l$1.diffed = function(n2) { sn && sn(n2); var t2 = n2.props, e2 = n2.__e; null != e2 && "textarea" === n2.type && "value" in t2 && t2.value !== e2.value && (e2.value = null == t2.value ? "" : t2.value), ln = null; }; var hn = { ReactCurrentDispatcher: { current: { readContext: function(n2) { return ln.__n[n2.__c].props.value; }, useCallback: q$1, useContext: x$1, useDebugValue: P$1, useDeferredValue: w, useEffect: y, useId: g$1, useImperativeHandle: F$1, useInsertionEffect: I, useLayoutEffect: _, useMemo: T$1, useReducer: h, useRef: A$1, useState: d, useSyncExternalStore: C, useTransition: k } } }; function dn(n2) { return _$1.bind(null, n2); } function mn(n2) { return !!n2 && n2.$$typeof === q; } function pn(n2) { return mn(n2) && n2.type === k$2; } function yn(n2) { return !!n2 && !!n2.displayName && ("string" == typeof n2.displayName || n2.displayName instanceof String) && n2.displayName.startsWith("Memo("); } function _n(n2) { return mn(n2) ? J$1.apply(null, arguments) : n2; } function bn(n2) { return !!n2.__k && (E$1(null, n2), true); } function Sn(n2) { return n2 && (n2.base || 1 === n2.nodeType && n2) || null; } var gn = function(n2, t2) { return n2(t2); }, En = function(n2, t2) { return n2(t2); }, Cn = k$2, xn = mn, Rn = { useState: d, useId: g$1, useReducer: h, useEffect: y, useLayoutEffect: _, useInsertionEffect: I, useTransition: k, useDeferredValue: w, useSyncExternalStore: C, startTransition: R, useRef: A$1, useImperativeHandle: F$1, useMemo: T$1, useCallback: q$1, useContext: x$1, useDebugValue: P$1, version: "18.3.1", Children: O, render: nn, hydrate: tn, unmountComponentAtNode: bn, createPortal: $$1, createElement: _$1, createContext: K$1, createFactory: dn, cloneElement: _n, createRef: b, Fragment: k$2, isValidElement: mn, isElement: xn, isFragment: pn, isMemo: yn, findDOMNode: Sn, Component: x$2, PureComponent: N, memo: M, forwardRef: D, flushSync: En, unstable_batchedUpdates: gn, StrictMode: Cn, Suspense: P, SuspenseList: B, lazy: z, __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: hn }; const HasShow = (props) => { var _a2; const show = props.show === void 0 ? true : props.show; if (mn(props.children)) { return _n(props.children, { style: { display: !show ? "none" : void 0, ...((_a2 = props.children.props) == null ? void 0 : _a2.style) || {} } }); } return u$1("span", { style: { display: !show ? "none" : void 0 }, children: props.children }); }; const IconButton = (props) => u$1("button", { disabled: props.disabled, onClick: props.onClick, style: props.style, "data-tooltip": props.tooltip, className: classNames("icon-btn", props.className, props.placement, { tooltip: props.tooltip }), children: props.icon ? u$1("i", { className: classNames("keb", props.icon) }) : props.children }); const RollBox = ({ logs = [], maxVisible = 5 }) => { const displayLogsRef = A$1([]); const [animating, setAnimating] = d(false); const [index, setIndex] = d(0); y(() => { setAnimating(true); setIndex(Math.max(0, displayLogsRef.current.length - 1)); setTimeout(() => { displayLogsRef.current = logs.slice(-maxVisible); setIndex((val) => Math.max(0, val - 1)); setAnimating(false); }, 300); }, [logs, maxVisible]); return u$1("div", { className: "rollbox-container", children: u$1("div", { className: `rollbox-list${animating ? " rolling" : ""}`, style: { transform: `translateY(${-index * 30}px)` }, children: displayLogsRef.current.map((log, idx) => u$1("div", { className: "rollbox-item", children: log }, idx)) }) }); }; const UI_EVENT_KEYS = { QUESTION: "ui.question", QUESTION_CLEAR: "ui.question.clear", TAB: "ui.tab", LOG: "ui.log", STATE: "ui.state", REFRESH: "ui.refresh", OPEN_RECHARGE: "ui.openRecharge" }; const ShopPaymentSuccess = "shop.payment.success"; const TASK_STATUS = { PENDING: "pending", RUNNING: "running", DONE: "done", SUCCESS: "success", ERROR: "error" }; function getUserInfo() { return request({ url: "/user/me" }); } function login(email, password) { return request({ url: "/user/login", method: "POST", data: { email, password } }); } function register(data) { return request({ url: "/user/register", method: "POST", data }); } function useTemp(data) { return request({ url: "/user/createAnonyUser", method: "POST", data }); } function sendVerifyCode(data) { return request({ url: "/user/sendCode", method: "POST", data }); } const globalState = { tab: "home", agree: 1, shop: { show: false, params: {} }, user: { id: "", nickname: "", avatar: "" }, state: {}, logs: [] }; const GlobalStore = K$1(globalState); GlobalStore.Consumer; const useGlobalStore = () => x$1(GlobalStore); const reducer = (state, action) => { switch (action.type) { case "set": return { ...state, ...action.payload }; case "update": return { ...state, ...action.payload }; case "refresh": return { ...state }; } return { ...state, ...action }; }; const GlobalStoreProvider = ({ children }) => { const [state, dispatch] = h(reducer, globalState); y(() => { var _a2, _b; const keb = Keb.getInstance(); const store = keb == null ? void 0 : keb.getStoreManager().getSharedStore(); if (store) { dispatch({ type: "set", payload: { agree: store.get("agree") } }); } if (keb) { keb.globalState = state; } keb == null ? void 0 : keb.on(UI_EVENT_KEYS.TAB, (tab) => dispatch({ type: "set", payload: { tab } })); keb == null ? void 0 : keb.on(UI_EVENT_KEYS.STATE, (payload) => dispatch({ type: "set", payload: { state: { ...state.state || {}, [payload.id]: { ...state.state[payload.id] || {}, ...payload.state } } } })); keb == null ? void 0 : keb.on(UI_EVENT_KEYS.LOG, (log) => dispatch({ type: "set", payload: { logs: state.logs.concat(log) } })); keb == null ? void 0 : keb.on(UI_EVENT_KEYS.REFRESH, () => dispatch({ type: "refresh" })); keb == null ? void 0 : keb.on(UI_EVENT_KEYS.OPEN_RECHARGE, (data) => dispatch({ type: "set", payload: { shop: { ...data, show: true } } })); const _agree = (_b = (_a2 = keb == null ? void 0 : keb.getStoreManager()) == null ? void 0 : _a2.getSharedStore()) == null ? void 0 : _b.get("agree"); dispatch({ type: "set", payload: { agree: _agree ?? 1 } }); return () => { keb == null ? void 0 : keb.offAll(UI_EVENT_KEYS.TAB); keb == null ? void 0 : keb.offAll(UI_EVENT_KEYS.LOG); keb == null ? void 0 : keb.offAll(UI_EVENT_KEYS.STATE); keb == null ? void 0 : keb.offAll(UI_EVENT_KEYS.REFRESH); keb == null ? void 0 : keb.offAll(UI_EVENT_KEYS.OPEN_RECHARGE); }; }, []); y(() => { const keb = Keb.getInstance(); keb && Object.assign(keb == null ? void 0 : keb.globalState, state); }, [state]); return u$1(GlobalStore.Provider, { value: { state, dispatch }, children }); }; const useTabState = (tab = "guide") => { const { state, dispatch } = x$1(GlobalStore); const changeTab = (t2) => { dispatch({ type: "set", payload: { tab: t2 } }); }; y(() => { changeTab(tab); }, []); return [state.tab, changeTab]; }; const useAgree = () => { const { state, dispatch } = x$1(GlobalStore); const setAgree = (agree) => { var _a2, _b; dispatch({ type: "set", payload: { agree } }); (_b = (_a2 = Keb.getInstance()) == null ? void 0 : _a2.getStoreManager().getSharedStore()) == null ? void 0 : _b.set("agree", agree); }; return [state.agree, setAgree]; }; const useShopState = () => { const { state, dispatch } = x$1(GlobalStore); const showShop = (data) => { dispatch({ type: "set", payload: { shop: { ...data, show: true } } }); }; const hideShop = () => { dispatch({ type: "set", payload: { shop: { show: false } } }); }; return [state.shop, showShop, hideShop]; }; const useUIState = (id = "") => { const { state, dispatch } = x$1(GlobalStore); const setState = (state2) => { dispatch({ type: "set", payload: { state: { ...state2.state, [id]: state2 } } }); }; return [state.state[id] || {}, setState]; }; const useUserState = () => { const { state, dispatch } = x$1(GlobalStore); const getUser = async (refresh = true) => { var _a2, _b, _c; if (!refresh && state.user.id) return; try { const res = await getUserInfo(); if (res.success) { const user = res.data; user.loadTime = Date.now(); dispatch({ type: "set", payload: { user } }); (_c = (_b = (_a2 = Keb.getInstance()) == null ? void 0 : _a2.getStoreManager()) == null ? void 0 : _b.getSharedStore()) == null ? void 0 : _c.set("user", user); } } catch (error) { console.error(error); } }; y(() => { var _a2, _b; const keb = Keb.getInstance(); const user = (_b = (_a2 = keb == null ? void 0 : keb.getStoreManager()) == null ? void 0 : _a2.getSharedStore()) == null ? void 0 : _b.get("user"); if ((user == null ? void 0 : user.loadTime) < Date.now() - 864e5) { dispatch({ type: "set", payload: { user } }); } else { getUser(false); } if (keb) { keb.getUserInfo = async function(refresh = true) { await getUser(refresh); return keb.getStoreManager().getSharedStore().get("user"); }; } }, []); return [state.user, getUser]; }; const questionStore = K$1(null); const questionReducer = (state, action) => { switch (action.type) { case "set": return { ...state, ...action.payload }; case "update": return { ...state, ...action.payload }; } return { ...state, ...action }; }; const QuestionStoreProvider = ({ children }) => { const [state, dispatch] = h(questionReducer, { questions: [] }); const setQuestions = (questions) => { state.questions.push(questions); dispatch({ type: "set", payload: { questions: [...state.questions] } }); }; const clearQuestions = () => { dispatch({ type: "set", payload: { questions: [] } }); }; y(() => { const keb = Keb.getInstance(); keb == null ? void 0 : keb.on(UI_EVENT_KEYS.QUESTION, setQuestions); keb == null ? void 0 : keb.on(UI_EVENT_KEYS.QUESTION_CLEAR, clearQuestions); return () => { keb == null ? void 0 : keb.offAll(UI_EVENT_KEYS.QUESTION); keb == null ? void 0 : keb.offAll(UI_EVENT_KEYS.QUESTION_CLEAR); }; }, []); return u$1(questionStore.Provider, { value: { state, dispatch }, children }); }; const Button = (props) => u$1("button", { ...props, type: props.htmlType, className: classNames("qk_button", props.className, props.type, props.block && "block"), style: props.style, onClick: props.onClick, children: props.children }); Button.defaultProps = { htmlType: "button", type: "primary" }; const Agreement = (props) => { const handleCancel = () => { var _a2; (_a2 = Keb.getInstance()) == null ? void 0 : _a2.destroy(); }; return u$1("div", { class: "agreement-wrapper", children: [u$1("div", { className: "agreement-content", children: [u$1("h1", { children: "用户协议与免责声明" }), u$1("p", { children: u$1("strong", { children: "本插件仅供学习研究用途,请勿用于非法用途或商业传播。使用前请仔细阅读以下条款:" }) }), u$1("h2", { children: "1. 使用范围" }), u$1("ul", { children: [u$1("li", { children: "本插件旨在帮助用户提高在线学习效率,适用于部分主流网课平台(如慕课、超星、智慧树等)。" }), u$1("li", { children: "插件功能包括但不限于视频播放加速、自动跳转下一节、作业/考试自动答题等。" })] }), u$1("h2", { children: "2. 用户责任" }), u$1("ul", { children: [u$1("li", { children: "用户须遵守所在平台的相关使用规定,若因使用本插件导致账号被封禁或其他后果,责任由用户自行承担。" }), u$1("li", { children: "禁止将插件用于任何违反法律法规、侵犯他人权益的行为,包括但不限于绕过平台安全机制、批量爬取数据、伪造身份认证等行为。" }), u$1("li", { children: u$1("strong", { children: "禁止利用本插件进行任何形式的计算机系统侵入、数据篡改、服务干扰等违法行为。如有违反,开发者将依法追究法律责任。" }) })] }), u$1("h2", { children: "3. 免责声明" }), u$1("ul", { children: [u$1("li", { children: [u$1("strong", { children: "技术风险:" }), "插件依赖网页结构运行,可能因平台更新导致功能失效或异常,开发者不承诺持续维护。"] }), u$1("li", { children: [u$1("strong", { children: "数据安全:" }), "插件不会收集用户隐私信息,但无法保证第三方平台的安全性,建议用户谨慎操作敏感内容。"] }), u$1("li", { children: [u$1("strong", { children: "准确性免责:" }), "自动答题功能基于预设逻辑或题库匹配,答案仅供参考,可能存在错误或遗漏,最终结果需用户自行核对。"] }), u$1("li", { children: [u$1("strong", { children: "法律免责:" }), "开发者不对用户在使用过程中违反国家法律法规所造成的后果承担责任,包括但不限于《中华人民共和国刑法》第285条(非法侵入计算机信息系统罪)、第286条(破坏计算机信息系统罪)等相关刑事责任。"] })] }), u$1("h2", { children: "4. 知识产权" }), u$1("p", { children: "插件代码及文档版权归开发者所有,禁止未经授权的修改、分发或商用。" }), u$1("h2", { children: "5. 终止使用" }), u$1("p", { children: "若用户违反上述条款,开发者有权随时终止插件服务,并保留追究其法律责任的权利。" }), u$1("h2", { children: "6. 其他" }), u$1("p", { children: "使用本插件即视为同意以上条款。开发者保留对协议的最终解释权,并可能根据实际情况更新内容。" })] }), u$1("div", { class: "agreement-footer", children: [u$1(Button, { type: "normal", onClick: handleCancel, children: "不用了" }), u$1(Button, { onClick: props.onConfirm, children: "我已阅读并同意以上协议" })] })] }); }; const Modal = (props) => { const [minWin, setMinWin] = d(false); const { state } = useGlobalStore(); const [agree, setAgree] = useAgree(); const modalBody = A$1(null); y(() => { if (props.draggable) { PanelBox.setupDraggable(modalBody.current); } return () => { PanelBox.stopDraggable(modalBody.current); }; }, [props.draggable]); return u$1(HasShow, { show: props.visible, children: u$1("div", { ref: modalBody, className: "k-modal", children: [props.overlay && u$1("div", { className: "k-modal-overlay", onClick: props.closeOnOverlayClick ? props.onClose : void 0 }), u$1("div", { className: classNames("k-modal-body", props.className, { min: minWin }), style: props.style, children: [u$1("div", { id: "modalHeader", className: "k-modal-header", children: [minWin ? u$1(RollBox, { maxVisible: 2, logs: state.logs }) : u$1("span", { children: props.title }), agree ? null : u$1("div", { className: "icons", children: [props.zoom && (minWin ? u$1(IconButton, { tooltip: "恢复窗口", icon: "icon-arrawsalt", className: "close-btn", placement: "bottom", onClick: () => setMinWin(false) }) : u$1(IconButton, { tooltip: "最小化", icon: "icon-shrink", className: "close-btn", placement: "bottom", onClick: () => setMinWin(true) })), props.showCloseButton && u$1(IconButton, { tooltip: "关闭面板", icon: "icon-close", className: "close-btn", placement: "bottom", onClick: props.onClose })] })] }), agree ? u$1(Agreement, { onConfirm: () => setAgree(0) }) : u$1(HasShow, { show: !minWin, children: u$1("div", { className: "k-modal-content", children: props.children }) }), props.footer] })] }) }); }; Modal.defaultProps = { draggable: true, showCloseButton: true }; const Loading = (props) => u$1("div", { ref: props.ref, className: classNames("loading-container", { fill: props.fill, absolute: props.absolute }, props.className), style: props.style, children: [props.loading && u$1("div", { className: "loading-spinner", children: [u$1("div", { className: "loading-icon", children: u$1("i", { className: "qk-icon icon-loading" }) }), props.text && u$1("div", { className: "loading-text", children: props.text })] }), props.children] }); Loading.defaultProps = { fill: true }; const LogItem = (props) => { props.type = props.type === "running" ? "loading" : props.type; return u$1("div", { class: classNames("log-entry", props.type, props.className, { "no-badge": props.type !== "loading" && !props.badge }), children: [props.type === "loading" && u$1(Loading, { loading: true, style: { width: "1.2em", height: "1.2em", marginRight: "4px" } }), props.children] }); }; LogItem.defaultProps = { badge: true }; const Title = (props) => u$1("div", { className: "title-bar", children: u$1("div", { className: "title-text", children: props.title || props.children }) }); const Guide = (props) => u$1("div", { ...props, className: classNames("panel-content", props.className), children: [u$1(Title, { children: "❕使用提示" }), u$1(LogItem, { type: "info", badge: false, children: [u$1("p", { children: "请手动进入视频、作业、考试页面,脚本会自动执行" }), u$1("p", { children: ["如脚本无法正常执行,请使用", u$1("span", { className: "red-word", children: "Chrome" }), "、", u$1("span", { className: "red-word", children: "Edge" }), "浏览器,火狐浏览器"] })] }), u$1(Title, { children: "🔥使用说明" }), u$1(LogItem, { type: "primary", badge: false, children: [u$1("p", { children: "1. 请手动进入视频、作业、考试页面,脚本会自动执行" }), u$1("p", { children: ["2. 如脚本无法正常执行,请使用", u$1("span", { className: "red-word", children: "Chrome" }), "、", u$1("span", { className: "red-word", children: "Edge" }), "浏览器,火狐浏览器"] })] })] }); const Topics = (props) => { var _a2, _b; const [activeTopic, setActiveTopic] = d(-1); const currentTopic = T$1(() => { var _a3; const topic = (_a3 = props.topics) == null ? void 0 : _a3[activeTopic]; return topic; }, [activeTopic, props.topics]); const handleClick = (i2) => { if (activeTopic === i2) { setActiveTopic(-1); return; } setActiveTopic(i2); }; return u$1(k$2, { children: [u$1("div", { className: "topics", children: (_a2 = props.topics) == null ? void 0 : _a2.map((topic, i2) => u$1("div", { className: classNames("topic-num", topic.status, { active: activeTopic === i2 }), onClick: () => handleClick(i2), children: i2 + 1 })) }), currentTopic && u$1(LogItem, { badge: false, type: currentTopic.status, children: [u$1("p", { children: currentTopic.title }), u$1("p", { dangerouslySetInnerHTML: { __html: (_b = currentTopic.options) == null ? void 0 : _b.replaceAll("_、_", "、").replaceAll("\n", "
") } }), u$1("p", { class: "answer-box", children: ["参考答案:", currentTopic.answer || "无"] })] })] }); }; const TabPanel = ({ children }) => u$1("div", { className: "tab-panel", children }); const Tabs = ({ defaultActiveKey, activeKey: controlledActiveKey, onChange, children, items }) => { const isControlled = controlledActiveKey !== void 0; const [internalActiveKey, setInternalActiveKey] = d(defaultActiveKey || ""); const activeKey = isControlled ? controlledActiveKey : internalActiveKey; const handleTabChange = (row) => { if (row.disabled) return; if (!isControlled) { setInternalActiveKey(row.tabKey); } onChange == null ? void 0 : onChange(row.tabKey); }; if (items) { const activeItem = items.find((item) => item.key === activeKey) || items[0]; return items.length ? u$1("div", { className: "tabs", children: [u$1("div", { className: "tabs-header", children: items.map((item) => u$1("div", { className: classNames("tab-title", { active: item.key === activeKey, disabled: item.disabled }), onClick: () => handleTabChange(item), children: item.label }, item.key)) }), u$1("div", { className: "tabs-content", children: u$1("div", { className: "tab-panel", children: activeItem == null ? void 0 : activeItem.children }) })] }) : null; } const tabs = Rn.Children.toArray(children).filter((child) => Rn.isValidElement(child) && child.type === TabPanel); const activeTab = tabs.find((tab) => tab.props.tabKey === activeKey) || tabs[0]; return tabs.length ? u$1("div", { className: "tabs", children: [u$1("div", { className: "tabs-header", children: tabs.map((tab) => u$1("div", { className: classNames("tab-title", { active: tab.props.tabKey === activeKey, disabled: tab.props.disabled }), onClick: () => handleTabChange(tab.props), children: tab.props.title }, tab.props.tabKey)) }), u$1("div", { className: "tabs-content", children: activeTab })] }) : null; }; Tabs.TabPanel = TabPanel; const Field = (props) => u$1("div", { className: classNames("info-row", props.className), style: props.style, children: [u$1("div", { className: "info-label", children: props.label }), u$1("div", { className: "info-value", children: props.children })] }); const Input = (props) => { const inputProps = { type: props.type, name: props.name, value: props.value, placeholder: props.placeholder, className: classNames("qk_input", props.className), style: props.style, autoComplete: props.autoComplete, autoFocus: props.autoFocus, disabled: props.disabled, readOnly: props.readOnly, onFocus: props.onFocus, onChange: (e2) => { var _a2, _b; (_b = props.onChange) == null ? void 0 : _b.call(props, (_a2 = e2.target) == null ? void 0 : _a2.value); }, onInput: props.onInput }; return u$1("input", { ...inputProps }); }; const Answer = (props) => { const [uiState, setUIState] = useUIState(props.script.uiComponentId); const [tabKey, setTabKey] = d(""); y(() => { props.script.estimatedScore = getStore("estimatedScore"); uiState.estimatedScore = props.script.estimatedScore; setUIState({ ...uiState }); }, []); const handleStart = () => { props.script.start(); }; const handleChange = (key, val) => { uiState[key] = val; setUIState({ ...uiState }); { props.script.estimatedScore = val; setStore("estimatedScore", val); } }; const dones = props.script.dones; y(() => { const last = dones[dones.length - 1]; setTabKey(last == null ? void 0 : last.examid); }, [uiState]); return u$1("div", { ...props, className: classNames("panel-content", props.className), children: [u$1(Title, { children: "🔥答题说明" }), u$1(LogItem, { type: "primary", badge: false, children: [u$1("p", { children: "1.每题将会扣除1积分" }), u$1("p", { children: "2.答题时请勿关闭页面,并等待答题完成,否则可能导致答题失败且扣除积分" })] }), u$1(Field, { label: "预估分数", children: u$1(Input, { placeholder: "75", value: uiState.estimatedScore, onChange: (v2) => handleChange("estimatedScore", v2), style: { width: "80px" } }) }), u$1(LogItem, { type: "error", children: "注意:预估分数越高,消耗的积分可能会增加" }), u$1("button", { disabled: uiState.done, className: "start-btn", onClick: handleStart, children: uiState.started ? uiState.stopped ? "继续" : "暂停" : "开始" }), uiState.done && u$1("p", { children: ["已完成作业,共", dones == null ? void 0 : dones.reduce((acc, cur) => { var _a2; return acc + (((_a2 = cur.questions) == null ? void 0 : _a2.length) || 0); }, 0), "道题"] }), u$1(Tabs, { activeKey: tabKey, onChange: setTabKey, children: dones.map((task, index) => task.questions && u$1(TabPanel, { tabKey: task.examid, title: "作业" + (index + 1), children: u$1(Topics, { topics: task.questions }) })) })] }); }; const typeMap = { 0: "临时用户", 1: "普通用户", 2: "机构用户", 3: "机构管理员", 9: "超级管理员" }; const Setting = (props) => { const [user] = useUserState(); const [_2, showShop] = useShopState(); const [state, setState] = d({}); y(() => { const keb = Keb.getInstance(); keb == null ? void 0 : keb.getConfig().then((config) => { setState(config); }); }, []); const handleOpenShop = () => { showShop({ title: "购买积分", params: { serviceType: 0 }, visible: true }); }; return u$1("div", { ...props, className: classNames("panel-content", props.className), children: [u$1(Title, { children: "用户信息" }), u$1(Field, { label: "用户名", children: user.nickname || "--" }), u$1(Field, { label: "邮箱", children: user.email || "--" }), u$1(Field, { label: "类型", children: typeMap[user.type] || "--" }), u$1(Field, { label: "积分", children: [user.points || "--", " ", u$1("span", { className: "span-btn", onClick: handleOpenShop, children: "充值" })] })] }); }; const Switch = (props) => u$1("button", { className: classNames("qk-switch", props.checked && "qk-switch-checked", props.loading && "loading", props.disabled && "disabled"), onClick: () => { var _a2; return (_a2 = props.onChange) == null ? void 0 : _a2.call(props, !props.checked); }, disabled: props.disabled || props.loading, children: [u$1("input", { checked: props.checked, type: "checkbox", disabled: props.disabled || props.loading }), u$1("span", { className: "qk-switch-track" }), u$1("span", { className: "qk-switch-handle" })] }); const Select = (props) => { var _a2; const { value, options, placeholder, className, style, disabled, onChange, defaultValue } = props; const [isOpen, setIsOpen] = d(false); const [selectedLabel, setSelectedLabel] = d(((_a2 = options.find((option) => option.value === defaultValue)) == null ? void 0 : _a2.label) || ""); const [dropdownStyle, setDropdownStyle] = d({ height: "0px" }); const selectRef = A$1(null); const valueRef = A$1(value || defaultValue); y(() => { var _a3; if (value === void 0 || value === "") { setSelectedLabel(((_a3 = options.find((option) => option.value === defaultValue)) == null ? void 0 : _a3.label) || ""); valueRef.current = defaultValue; return; } const selectedOption = options.find((option) => option.value === value); setSelectedLabel((selectedOption == null ? void 0 : selectedOption.label) || ""); valueRef.current = selectedOption == null ? void 0 : selectedOption.value; }, [value, options]); const handleOpen = (o2) => { if (o2 && selectRef.current) { const rect = selectRef.current.getBoundingClientRect(); setDropdownStyle({ position: "fixed", top: `${rect.bottom + window.scrollY}px`, left: `${rect.left + window.scrollX}px`, width: `${rect.width}px`, zIndex: 1e3 }); } setIsOpen(o2); }; y(() => { const handleClickOutside = (event) => { if (selectRef.current && !selectRef.current.contains(event.target) && !event.target.closest(".qk_select_dropdown")) { setIsOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); const handleSelect = (option) => { if (option.disabled) return; onChange == null ? void 0 : onChange(option.value); setSelectedLabel(option.label); valueRef.current = option.value; setIsOpen(false); }; return u$1("div", { ref: selectRef, className: classNames("qk_select_wrapper", className, { is_open: isOpen, is_disabled: disabled }), style, children: [u$1("div", { className: "qk_select_trigger", onClick: () => !disabled && handleOpen(!isOpen), children: [u$1("span", { className: classNames("qk_select_value", { placeholder: !selectedLabel }), children: selectedLabel || placeholder }), u$1("span", { className: "qk_select_arrow" })] }), isOpen && $$1(u$1("div", { className: "qk_select_dropdown", style: dropdownStyle, onClick: (e2) => e2.stopPropagation(), children: options.map((option) => u$1("div", { className: classNames("qk_select_option", { is_selected: option.value === valueRef.current, is_disabled: option.disabled }), onClick: () => handleSelect(option), children: option.label }, option.value)) }), document.body)] }); }; const playRateOptions = [0.75, 1, 1.25, 1.5, 2]; const VideoPanel = (props) => { var _a2, _b, _c; const [_2, showShop] = useShopState(); const script = props.script; const [uiState, setUIState] = useUIState(script.uiComponentId); const handleChange = (key, val) => { uiState[key] = val; setUIState({ ...uiState }); script.update(uiState); }; const openShop = () => { showShop({ title: "购买服务", content: "购买服务内容", params: { serviceType: 1 }, studentId: script.userId, visible: true }); }; const currentIndex = ((_a2 = uiState.courseLesson) == null ? void 0 : _a2.findIndex((lesson) => lesson.playUrl === uiState.currentPlayUrl || lesson.lessonId == uiState.lesson_id)) || 0; return u$1("div", { ...props, className: classNames("panel-content", props.className), children: [u$1(Title, { children: "🔥视频说明" }), u$1(LogItem, { type: "primary", badge: false, children: [u$1("p", { children: "1. 请根据以下设置播放网课视频" }), u$1("p", { children: "2. 如需一键完成服务,点击下方了解" })] }), u$1(LogItem, { type: "info", children: uiState.startAutoPlay ? uiState.done ? u$1("span", { children: "全部视频已完成" }) : u$1("span", { children: "正在进行加速服务" }) : u$1("span", { children: ["正在进行视频播放(", currentIndex + 1, "/", (_b = uiState.courseLesson) == null ? void 0 : _b.length, ")"] }) }), uiState.showExpedite && u$1("div", { className: "topics", children: (_c = uiState.courseLesson) == null ? void 0 : _c.map((item, i2) => u$1("div", { className: classNames("topic-num", item.status), children: i2 + 1 })) }), uiState.startAutoPlay || u$1(k$2, { children: [u$1(Title, { children: "播放设置" }), u$1(Field, { label: "自动切换", children: u$1(Switch, { checked: uiState.autoSwitch, onChange: handleChange.bind(null, "autoSwitch") }) }), u$1(Field, { label: "播放倍数", children: u$1(Select, { placeholder: "请选择倍数", value: uiState.videoRate || 1, options: playRateOptions.map((rate) => ({ label: rate, value: rate })), style: { width: "100px" }, onChange: handleChange.bind(null, "videoRate") }) })] }), props.children, u$1(LogItem, { type: "info", badge: false, children: [u$1("button", { disabled: !uiState.showExpedite || uiState.done, className: "start-btn", onClick: script.startExpedite.bind(script), children: uiState.startAutoPlay ? uiState.stopAutoPlay ? "开始" : "暂停" : "一键完成" }), uiState.showExpedite ? uiState.done ? u$1("p", { children: "已完成全部视频,请手动切换至下一个科目" }) : u$1("p", { children: "点击上面按钮一键完成课程" }) : u$1("p", { children: ["您还未开通本课程的一键完成服务,", u$1("a", { href: "javascript:void(0)", onClick: openShop, children: "点此进入" })] })] })] }); }; function getProductList(data) { return request({ url: "/products", data }); } function getCourseList(data) { return request({ url: "/coursesList", data }); } function createOrder(data) { return request({ url: "/orders", method: "POST", data }); } function createPaymentCode(data) { return request({ url: "/payment/alipay/" + data.orderId, data }); } function getPaymentStatus(data) { return request({ url: "/orders/status/" + data.orderId }); } function getPaymentStatusDirect(data) { return request({ url: "/payment/query/" + data.orderId }); } class MessageApi { constructor() { __publicField(this, "container", null); __publicField(this, "messages", /* @__PURE__ */ new Map()); __publicField(this, "document", (top == null ? void 0 : top.document) || window.document); } getContainer() { if (!this.container) { this.container = this.document.createElement("div"); this.container.className = "k-message-container"; this.document.body.appendChild(this.container); } return this.container; } generateId() { return `k-message-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; } createMessage(config) { const id = this.generateId(); const container = this.getContainer(); const messageElement = this.document.createElement("div"); messageElement.innerHTML = `
${config.content}
`; const messageNode = messageElement.firstChild; container.appendChild(messageNode); setTimeout(() => { messageNode.classList.add("k-message-show"); }, 10); const duration = config.duration !== void 0 ? config.duration : 3e3; if (duration > 0) { const timer = window.setTimeout(() => { this.removeMessage(id, config.onClose); }, duration); this.messages.set(id, timer); } return id; } removeMessage(id, onClose) { const container = this.getContainer(); const messageElement = this.document.getElementById(id); if (messageElement) { messageElement.classList.remove("k-message-show"); messageElement.classList.add("k-message-hide"); const timer = this.messages.get(id); if (timer) { clearTimeout(timer); this.messages.delete(id); } setTimeout(() => { if (messageElement.parentNode === container) { container.removeChild(messageElement); } if (container.children.length === 0 && this.container) { this.document.body.removeChild(this.container); this.container = null; } if (onClose) { onClose(); } }, 300); } } open(config) { const id = this.createMessage(config); return Promise.resolve(id); } info(content, duration) { return this.open({ content, type: "info", duration }); } success(content, duration) { return this.open({ content, type: "success", duration }); } warning(content, duration) { return this.open({ content, type: "warning", duration }); } error(content, duration) { return this.open({ content, type: "error", duration }); } loading(content, duration) { return this.open({ content, type: "info", duration }); } destroy(id) { if (id) { const timer = this.messages.get(id); if (timer) { clearTimeout(timer); this.messages.delete(id); } this.removeMessage(id); } else { this.messages.forEach((timer, messageId) => { clearTimeout(timer); this.removeMessage(messageId); }); this.messages.clear(); } } } const message$1 = new MessageApi(); class AlertApi { constructor() { __publicField(this, "container", null); } getContainer() { if (!this.container) { this.container = document.createElement("div"); top.document.body.appendChild(this.container); } return this.container; } alert(config, config2 = {}) { return new Promise((resolve) => { const configObj = typeof config === "string" ? { ...config2, content: config } : config; const { title = "提示", content, okText = "确定", onOk } = configObj; const handleOk = () => { onOk == null ? void 0 : onOk(); this.destroy(); resolve(); }; const handleClose = () => { this.destroy(); resolve(); }; const vnode = u$1(Modal, { title, visible: true, onClose: handleClose, draggable: false, showCloseButton: false, className: "k-alert-modal", footer: u$1("div", { class: "k-modal-footer", children: u$1(Button, { type: "primary", onClick: handleOk, children: okText }) }), children: u$1("div", { children: content }) }); const container = this.getContainer(); E$1(vnode, container); }); } destroy() { if (this.container) { E$1(null, this.container); if (this.container.parentNode) { this.container.parentNode.removeChild(this.container); } this.container = null; } } } const alertInstance = new AlertApi(); class ConfirmApi { constructor() { __publicField(this, "container", null); } getContainer() { if (!this.container) { this.container = document.createElement("div"); top.document.body.appendChild(this.container); } return this.container; } confirm(config) { return new Promise((resolve, reject) => { const { title = "确认", content, okText = "确定", cancelText = "取消", showRecharge = false, onOk, onCancel } = config; const handleOk = () => { onOk == null ? void 0 : onOk(); this.destroy(); resolve("ok"); }; const handleCancel = () => { onCancel == null ? void 0 : onCancel(); this.destroy(); reject("cancel"); }; const handleClose = () => { this.destroy(); reject("close"); }; const handleRecharge = () => { this.destroy(); resolve("charge"); }; const vnode = u$1(Modal, { title, visible: true, onClose: handleClose, draggable: false, showCloseButton: false, className: "k-confirm-modal", footer: u$1("div", { class: "k-modal-footer", children: [u$1(Button, { type: "normal", onClick: handleCancel, children: cancelText }), u$1(Button, { type: "danger", onClick: handleOk, children: okText }), showRecharge && u$1(Button, { onClick: handleRecharge, children: "去充值" })] }), children: u$1("div", { children: content }) }); const container = this.getContainer(); E$1(vnode, container); }); } destroy() { if (this.container) { E$1(null, this.container); if (this.container.parentNode) { this.container.parentNode.removeChild(this.container); } this.container = null; } } } const confirmInstance = new ConfirmApi(); const Message = { message: message$1, alert: alertInstance.alert.bind(alertInstance), confirm: confirmInstance.confirm.bind(confirmInstance) }; const ShopPanel = ({ visible, onClose }) => { var _a2; const [shopState, showShop, hideShop] = useShopState(); const [step, setStep] = d(1); const [products, setProducts] = d([]); const [selectedProduct, setSelectedProduct] = d(null); const [courses, setCourses] = d([]); const [selectedCourseIds, setSelectedCourseIds] = d([]); const [order, setOrder] = d(null); const [paymentLoading, setPaymentLoading] = d(false); const [paymentError, setPaymentError] = d(""); const [qrCodeUrl, setQrCodeUrl] = d(""); const refT = A$1(null); const [terms, setTerms] = d([]); const coursesRef = A$1([]); const lastTermCodeRef = A$1(""); const userId = shopState.studentId || ((_a2 = Keb.getInstance()) == null ? void 0 : _a2.userId) || getUserCookie() || ""; const [showStudentNo, setShowStudentNo] = d(!userId); const [studentNo, setStudentNo] = d(""); const getProducts = async () => { try { const params = shopState.params || {}; const res = await getProductList(params); if (res.success) { setProducts(res.data.list); } } catch (error) { console.error("获取商品列表失败:", error); } }; y(() => { if (visible || shopState.show) { getProducts(); } }, [visible, shopState]); const handleSelectProduct = (product) => { var _a3, _b; if (!product) { message$1.error("请选择商品服务"); return; } setSelectedProduct(product); if (product.serviceType === 1) { const keb = Keb.getInstance(); const _userId = studentNo || userId; lastTermCodeRef.current = (_b = (_a3 = keb == null ? void 0 : keb.getStoreManager()) == null ? void 0 : _a3.getSharedStore()) == null ? void 0 : _b.get("lastTermCode"); if (!lastTermCodeRef.current) { const d2 = /* @__PURE__ */ new Date(); lastTermCodeRef.current = d2.getFullYear() + (d2.getMonth() < 6 ? "0" : "1"); } if (!_userId) { message$1.error("请先输入学生学号"); return; } if (!courses.length) { getCourseList({ userId: _userId }).then((res) => { var _a4; if (res.success) { if (!((_a4 = res.data) == null ? void 0 : _a4.length)) { setShowStudentNo(true); } coursesRef.current = res.data; const termMap = {}; const list = res.data.filter((course) => { if (!termMap[course.termCode]) { termMap[course.termCode] = course.term; } return course.termCode === lastTermCodeRef.current; }); setCourses(list); setSelectedCourseIds(list.filter((course) => course.online === 1).map((course) => course.id)); setTerms(Object.keys(termMap).map((termCode) => ({ label: `第${termMap[termCode]}期`, value: termCode }))); } else { message$1.error("获取课程列表失败:" + res.msg); setShowStudentNo(true); } }).catch((error) => { message$1.error("获取课程列表失败:" + error.message); }); } else { setSelectedCourseIds(courses.filter((course) => course.online === 1).map((course) => course.id)); } } else { setSelectedCourseIds([]); } }; const handleSelectTerm = (termCode) => { const list = coursesRef.current.filter((course) => course.termCode === termCode); setCourses(list); setSelectedCourseIds(termCode === lastTermCodeRef.current ? list.filter((course) => course.online === 1).map((course) => course.id) : []); }; const handleSelectCourse = (course) => { if (course.online === 0) { message$1.error("本课程没有在线网课,请勿选择"); return; } if (selectedCourseIds.includes(course.id)) { setSelectedCourseIds(selectedCourseIds.filter((id) => id !== course.id)); } else { const updatedCourseIds = [...selectedCourseIds, course.id]; setSelectedCourseIds(updatedCourseIds); } }; const handleNext = () => { if (selectedProduct) { if (selectedProduct.serviceType === 1 && !selectedCourseIds.length) { message$1.error("请至少选择一门课程"); return; } setStep(2); createOrder({ productId: selectedProduct.id, courseIds: selectedCourseIds, studentId: getUserCookie() || shopState.studentId }).then((res) => { if (res.success) { setPaymentLoading(true); setOrder(res.data); createPaymentCode({ orderId: res.data.orderId }).then((res2) => { if (res2.success) { setQrCodeUrl(res2.data.qrCode); } }).finally(() => { setPaymentLoading(false); }); } }); } }; y(() => { if (order) { paymentStatus(); } return () => { if (refT.current) { clearTimeout(refT.current); } }; }, [order]); y(() => { if (refT.current) { clearTimeout(refT.current); } }, [step]); const paymentStatus = (poll = true) => { refT.current = setTimeout(async () => { var _a3; const res = await getPaymentStatus({ orderId: order.orderId }); if (res.success) { if (res.data === "paid") { setStep(3); (_a3 = Keb.getInstance()) == null ? void 0 : _a3.emit(ShopPaymentSuccess, { order, product: selectedProduct }); } else if (res.data === "pending") { if (poll) { paymentStatus(); } } } }, 5e3); }; const handlePaymentSuccess = () => { getPaymentStatusDirect({ orderId: order.orderId }).then((res) => { var _a3; if (res.success && res.data) { setStep(3); (_a3 = Keb.getInstance()) == null ? void 0 : _a3.emit(ShopPaymentSuccess, { order, product: selectedProduct }); } else { setPaymentError("请确认已支付成功"); } }); }; const handleClose = () => { onClose == null ? void 0 : onClose(); hideShop(); setTimeout(() => { setStep(1); setSelectedProduct(null); }, 300); }; const QRCodeComponent = ({ type, url }) => { const divRef = A$1(null); y(() => { if (divRef.current && url) { const qr = new QRCode(divRef.current, { text: url, width: 200, height: 200, colorDark: "#000000", colorLight: "#ffffff", correctLevel: QRCode.CorrectLevel.H }); return () => qr.clear(); } }, [url]); return u$1("div", { className: `qr-code active`, children: [u$1("div", { ref: divRef, className: "qr-code-img" }), u$1("div", { className: "payment-label", children: "支付宝" })] }); }; return u$1(Modal, { visible: shopState.show, onClose: handleClose, className: "shop-panel", title: shopState.title || "购买服务", children: [step === 1 && u$1("div", { className: "step-one", children: [u$1("h3", { children: "请选择您要购买的服务" }), u$1("div", { className: "product-list", children: products.map((product) => u$1("div", { className: classNames("product-item", (selectedProduct == null ? void 0 : selectedProduct.id) === product.id ? "selected" : ""), onClick: () => handleSelectProduct(product), children: [u$1("div", { className: "product-info", children: [u$1("h4", { children: product.name }), u$1("p", { children: product.description })] }), u$1("div", { className: "product-price", children: ["¥", product.price] })] })) }), (selectedProduct == null ? void 0 : selectedProduct.serviceType) === 1 && u$1("div", { className: "course-list-wrapper", children: [showStudentNo && u$1("div", { className: "student-input", children: [u$1(Input, { placeholder: "请输入学生学号", value: studentNo, onChange: (v2) => setStudentNo(v2) }), u$1(Button, { onClick: () => handleSelectProduct(selectedProduct), children: "确认" })] }), u$1("div", { className: "course-header", children: [u$1("h3", { children: ["请选择课程", u$1("span", { className: "course-count", children: ["(已选择", selectedCourseIds.length, "门)"] })] }), terms.length > 1 && u$1("div", { className: "course-term", children: u$1(Select, { defaultValue: lastTermCodeRef.current, onChange: handleSelectTerm, options: terms }) })] }), u$1("p", { className: "course-tip", children: "默认选择本学生本学期的所有课程,请自行取消选择不需要的课程,以免多购买" }), u$1("div", { className: classNames("course-list"), children: courses.map((course) => u$1("div", { className: classNames("course-item", selectedCourseIds.includes(course.id) ? "selected" : ""), onClick: () => handleSelectCourse(course), children: u$1("h4", { children: course.name }) })) })] }), u$1("div", { className: "modal-footer", children: [u$1(Button, { onClick: handleClose, children: "取消" }), u$1(Button, { disabled: !selectedProduct, onClick: handleNext, type: "primary", children: "下一步" })] })] }), step === 2 && u$1("div", { className: "step-two", children: [u$1("h3", { children: "确认订单并支付" }), selectedProduct && u$1("div", { className: "order-summary", children: [u$1("div", { className: "order-item", children: [u$1("span", { children: "服务项目:" }), u$1("span", { children: selectedProduct.name })] }), u$1("div", { className: "order-item", children: [u$1("span", { children: "服务描述:" }), u$1("span", { children: selectedProduct.description })] }), u$1("div", { className: "order-item", children: [u$1("span", { children: "价格:" }), u$1("span", { children: ["¥", selectedProduct.price] })] }), u$1("div", { className: "order-item", children: [u$1("span", { children: "数量:" }), u$1("span", { children: selectedCourseIds.length || 1 })] }), u$1("div", { className: "order-item", children: [u$1("span", { children: "总价格:" }), u$1("span", { className: "price-value", children: ["¥", (selectedProduct.price * (selectedCourseIds.length || 1)).toFixed(2)] })] })] }), u$1("h3", { children: "请扫码支付" }), u$1("div", { className: "payment-wrapper", children: [u$1("div", { className: "payment-method", children: u$1("div", { className: "qr-codes", children: u$1(Loading, { loading: paymentLoading, children: u$1(QRCodeComponent, { type: "alipay", url: qrCodeUrl }) }) }) }), u$1("div", { className: "payment-right", children: [u$1("div", { className: "payment-tip", children: u$1("p", { children: "请使用手机支付宝扫描左侧二维码完成支付" }) }), u$1("div", { className: "payment-status" }), u$1("div", { className: "payment-error", children: paymentError })] })] }), u$1("div", { className: "modal-footer", children: [u$1(Button, { onClick: () => setStep(1), children: "上一步" }), u$1(Button, { onClick: handlePaymentSuccess, type: "primary", children: "我已支付" })] })] }), step === 3 && u$1("div", { className: "step-three", children: [u$1("div", { className: "success-icon", children: "✓" }), u$1("h3", { children: "购买成功!" }), u$1("p", { children: ["您已成功购买 ", selectedProduct == null ? void 0 : selectedProduct.name] }), u$1("p", { children: "服务已激活,感谢您的购买!" }), u$1("div", { className: "modal-footer", children: u$1(Button, { onClick: handleClose, type: "primary", children: "关闭" }) })] })] }); }; const FormDataContext = K$1({ formData: {}, handleChange: () => { }, keys: [] }); const FormErrContext = K$1({ errData: {}, setErrData: () => { } }); const handleFocus = (target, name) => { if (!target) return; const targetEl = target.querySelector(`[name="${name}"]`); if (targetEl) { targetEl.focus(); targetEl.scrollIntoView({ behavior: "smooth", block: "center" }); } }; function getFormPropsData(props) { const { name, value, rules, initialValue } = props; return { name, value: value || initialValue, initialValue, rules }; } function validate(props, target) { const { rules, value, name } = props; const ret = { value, message: "" }; try { const f2 = rules.find((rule, index) => { const { required, message: message2, pattern, callback, len, min, max, type } = rule; if (callback) { const valid = callback(value); if (valid != void 0 && !valid) { ret.message = valid.message || message2; return true; } } if (required && !value) { ret.message = message2; return true; } if (pattern && !pattern.test(value)) { ret.message = message2; return true; } if (len && value.length !== len) { ret.message = message2; return true; } if (min && value.length < min) { ret.message = message2; return true; } if (max && value.length > max) { ret.message = message2; return true; } if (type === "email" && !/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]{2,})+$/.test(value)) { ret.message = message2; return true; } if (type === "phone" && !/^1[3-9]\d{9}$/.test(value)) { ret.message = message2; return true; } if (type === "url" && !/^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/.test(value)) { ret.message = message2; return true; } if (type === "number" && !/^\d+$/.test(value)) { ret.message = message2; return true; } if (type === "integer" && !/^\d+$/.test(value)) { ret.message = message2; return true; } return false; }); if (f2) { handleFocus(target, name); return ret; } } catch (error) { ret.message = error.message; handleFocus(target, name); return ret; } } const FormItem = (props) => { var _a2, _b; const { formData, handleChange: handleFormChange, keys } = x$1(FormDataContext); const { errData, setErrData } = x$1(FormErrContext); const contorl = A$1(null); const [error, setError] = d(errData[props.name]); y(() => { if (!props.name) return; const p2 = getFormPropsData({ ...formData[props.name], ...props }); formData[props.name] = p2; keys[props.name] = true; return () => { delete keys[props.name]; }; }, [props.rules, props.name, props.initialValue]); y(() => { setError(errData[props.name]); }, [errData]); const handleChange = (value) => { var _a3, _b2, _c; if (typeof value === "object" && value !== null) { value = value.target ? value.target.value : value; } const formProps = formData[props.name]; formProps.value = value; handleFormChange(props.name, { ...formProps }); (_c = (_a3 = props.children) == null ? void 0 : (_b2 = _a3.props).onChange) == null ? void 0 : _c.call(_b2, value); const errs = Array.isArray(formProps.rules) && validate(formProps, contorl.current); if (errs) { setError(errs.message); errData[props.name] = errs.message; } else { setError(null); delete errData[props.name]; } setErrData({ ...errData }); }; const children = Array.isArray(props.children) ? props.children : J$1(props.children, { ...props.children.props, name: props.name, onChange: handleChange, value: (_a2 = formData[props.name]) == null ? void 0 : _a2.value }); if (props.noStyle) { return children; } const required = props.required || ((_b = props.rules) == null ? void 0 : _b.some((rule) => rule.required)); const className = classNames("qk-form-item", props.className, props.extra || props.help || error ? "qk-form-item-has-extra" : ""); return u$1("div", { className, style: props.style, children: [props.label && u$1("div", { className: "qk-form-item-label", children: [required && u$1("span", { className: "qk-form-item-required", children: "*" }), props.label] }), u$1("div", { ref: contorl, className: classNames("qk-form-item-content", error && "error"), children }), error && u$1("div", { className: "qk-form-item-error", children: error }), props.extra && u$1("div", { className: "qk-form-item-extra", children: props.extra }), props.help && u$1("div", { className: "qk-form-item-help", children: props.help })] }); }; const Form = (props) => { props.form = props.form || {}; const [formData, setFormData] = d({}); const filedKeys = A$1({}); const [errData, setErrData] = d({}); props.form.getFieldValue = (name) => { if (name && !filedKeys.current[name]) return void 0; if (name) { return formData[name].value; } return Object.keys(formData).reduce((acc, cur) => { if (filedKeys.current[cur]) { acc[cur] = formData[cur].value; } return acc; }, {}); }; props.form.setFieldsValue = (values) => { Object.keys(values).forEach((key) => { formData[key].value = values[key]; }); setFormData({ ...formData }); }; props.form.validateFields = (callback, keys) => { const errors = {}; let hasError = false; let message2 = ""; let p2; if (Array.isArray(callback)) { keys = callback; callback = void 0; } if (!callback) { p2 = new Promise((resolve, reject) => { callback = (errors2, values) => { if (errors2) { reject(errors2); } else { resolve(values); } }; }); } if (!keys) { keys = Object.keys(filedKeys.current); } for (const key of keys) { const valid = Array.isArray(formData[key].rules) && validate(formData[key]); if (valid) { hasError = true; errors[key] = valid.message; message2 = message2 || valid.message; } } setErrData(errors); if (hasError) { callback(message2); } else { callback(null, props.form.getFieldValue()); } return p2; }; props.form.resetFields = () => { setFormData(Object.keys(formData).reduce((acc, key) => { acc[key] = getFormPropsData(formData[key]); acc[key].value = acc[key].initialValue; }, {})); }; const handleChange = (name, value) => { const formProps = getFormPropsData(value); setFormData({ ...formData, [name]: formProps }); }; const handleSubmit = (e2) => { props.onSubmit(e2); }; return u$1(FormDataContext.Provider, { value: { formData, handleChange, keys: filedKeys.current }, children: u$1(FormErrContext.Provider, { value: { errData, setErrData }, children: u$1("form", { onSubmit: handleSubmit, children: props.children }) }) }); }; Form.useForm = () => { const formRef = A$1({}); return formRef.current; }; Form.Item = FormItem; const LoginRegister = (props) => { const form = Form.useForm(); const [isRegisterMode, setIsRegisterMode] = d(false); const [captchaLoading, setCaptchaLoading] = d(false); const [loading, setLoading] = d(false); const [countdown, setCountdown] = d(0); const [errors, setErrors] = d({}); const handleSendVerifyCode = async () => { form.validateFields(["email"]).then(async (values) => { const { email } = values; setCaptchaLoading(true); try { await sendVerifyCode({ email, type: !isRegisterMode ? "login" : "register" }); setCountdown(60); const timer = setInterval(() => { setCountdown((prev) => { if (prev <= 1) { clearInterval(timer); return 0; } return prev - 1; }); }, 1e3); } catch (error) { setErrors({ general: error.message || "发送验证码失败" }); } finally { setCaptchaLoading(false); } }); }; const handleSubmit = async (e2) => { e2.preventDefault(); setErrors({}); form.validateFields().then(async (values) => { var _a2; setLoading(true); try { const { email, password } = values; const res = !isRegisterMode ? await login(email, password) : await register(values); if (res.success) { setToken(res.data); (_a2 = props.onLoginSuccess) == null ? void 0 : _a2.call(props); } else { setErrors({ general: res.msg || "登录失败,请稍后重试" }); } } catch (error) { setErrors({ general: error.message || "登录失败" }); } finally { setLoading(false); } }); }; async function handleCreateTemp() { var _a2; setLoading(true); try { const res = await useTemp(); if (res.success) { setToken(res.data); (_a2 = props.onLoginSuccess) == null ? void 0 : _a2.call(props); } else { setErrors({ general: res.msg || "error" }); } } catch (error) { setErrors({ general: (error == null ? void 0 : error.message) || "network error" }); } finally { setLoading(false); } } const ruleConfirmPassword = (value) => { if (value !== form.getFieldValue("password")) { throw new Error("两次输入的密码不一致"); } }; return u$1("div", { className: "login-register-panel", children: [u$1(Title, { children: isRegisterMode ? "用户登录" : "用户注册" }), errors.general && u$1("div", { className: "error-message general-error", children: errors.general }), u$1(Loading, { loading, children: u$1(Form, { form, onSubmit: handleSubmit, children: [u$1(FormItem, { name: "email", rules: [{ required: true, message: "请输入用户邮箱" }, { type: "email", message: "请输入正确的邮箱" }], children: u$1(Input, { placeholder: "用户邮箱" }) }), isRegisterMode && u$1(FormItem, { name: "code", rules: [{ required: true, message: "请输入验证码" }], children: [u$1(FormItem, { name: "code", noStyle: true, children: u$1(Input, { style: { flex: 1, marginRight: "10px" }, placeholder: "验证码" }) }), u$1(Loading, { loading: captchaLoading, fill: false, children: u$1(Button, { type: "primary", disabled: !!countdown, style: { width: "100px" }, onClick: handleSendVerifyCode, children: countdown ? `${countdown}秒后再获取` : "获取验证码" }) })] }), u$1(FormItem, { name: "password", rules: [{ required: true, message: "请输入用户密码" }], children: u$1(Input, { type: "password", placeholder: "用户密码" }) }), isRegisterMode && u$1(FormItem, { name: "password_confirm", rules: [{ required: true, message: "请再次输入密码" }, { callback: ruleConfirmPassword }], children: u$1(Input, { type: "password", placeholder: "确认密码" }) }), u$1(FormItem, { children: u$1(Button, { block: true, htmlType: "submit", children: isRegisterMode ? "注册" : "登录" }) }), u$1("div", { class: "hint center", children: [isRegisterMode ? u$1(k$2, { children: [u$1("span", { class: "text", children: "已有账号?" }), u$1("span", { class: "to-register-btn span-btn", onClick: () => setIsRegisterMode(false), children: "立即登录" })] }) : u$1(k$2, { children: [u$1("span", { class: "text", children: "还没账号?" }), u$1("span", { class: "to-register-btn span-btn", onClick: () => setIsRegisterMode(true), children: "立即注册" })] }), u$1("span", { class: "temp", children: ["或", u$1("span", { class: "span-btn", onClick: handleCreateTemp, children: "先不登录" }), ",直接使用"] })] })] }) })] }); }; function TopicComponent(props) { const [state, setState] = d({ topic: "", num: "" }); const script = props.script; const handleChange = (key, value) => { setState({ ...state, [key]: value }); }; const handleSubmit = () => { props.script.postTopic({ content: state.topic, num: state.num || 5 }); }; return u$1("div", { ...props, className: classNames("panel-content", props.className), children: [u$1(Title, { children: "请按以下设置发送话题" }), u$1(LogItem, { type: "primary", badge: false, children: u$1("p", { children: "文才学堂话题" }) }), u$1(Field, { label: "话题内容", children: u$1(Input, { placeholder: "好好学习,天天向上", value: state.topic, style: { width: "140px" }, onChange: (value) => handleChange("topic", value) }) }), u$1(Field, { label: "连发数量", children: u$1(Input, { placeholder: "5", value: state.num, style: { width: "80px" }, onChange: (value) => handleChange("num", value) }) }), u$1(Button, { block: true, disabled: script.started, onClick: handleSubmit, children: script.started ? "正在发布" + script.index + "条话题" : "提交" })] }); } const Exam = (props) => { const script = props.script; const questions = script.questions; const [uiState] = useUIState(props.script.uiComponentId); const [spaceTime, setSpaceTime] = d(""); const handleSetSpaceTime = (v2) => { setSpaceTime(v2); script.spaceTime = parseInt(v2) * 1e3 || 2e3; }; const handleStart = () => { script == null ? void 0 : script.fillFn(); }; return u$1("div", { ...props, className: classNames("panel-content", props.className), children: [u$1(Title, { children: "🔥答题说明" }), u$1(LogItem, { type: "primary", badge: false, children: [u$1("p", { children: "1.每题将会扣除1积分" }), u$1("p", { children: "2.答题过程中请勿关闭页面,否则任务将答题失效且会扣除积分" }), u$1("p", { children: "3.每题间隔时间默认2秒,可自定义设置,单位秒" }), u$1("p", { children: "4.间隔时间不能设置太小,否则可能会报太频繁,最好用默认值" }), u$1("p", { children: "5.点击开始按钮后,请等待任务自动完成,勿手动操作" })] }), u$1(Field, { label: "每题间隔时间", children: u$1(Input, { value: spaceTime, placeholder: "2s", style: { width: "50px" }, onChange: handleSetSpaceTime }) }), u$1(Topics, { topics: questions }), u$1("button", { disabled: uiState.done, className: "start-btn", onClick: handleStart, children: uiState.started ? uiState.stopped ? "继续" : "暂停" : "开始" }), uiState.done && u$1(LogItem, { type: "success", children: ["已完成全部题目,", script.errIndex.length ? `其中${script.errIndex.join(",")}等题答案查询失败,请自行检查` : "请手动提交"] })] }); }; const ISpace = (props) => { const [uiState, setUIState] = useUIState(props.script.uiComponentId); const script = props.script; const handleStart = () => { props.script.start(); }; return u$1("div", { ...props, className: classNames("panel-content", props.className), children: [u$1(Title, { children: "🔥资源加速说明" }), u$1(LogItem, { type: "primary", badge: false, children: [u$1("p", { children: "1.本功能适用于必须使用手机客户端才能完成的任务,且算入成绩的" }), u$1("p", { children: "2.每个资源将会扣除5积分" })] }), u$1(Field, { label: "是否下载或打开资源", children: u$1(Switch, { checked: uiState.download, onChange: (v2) => setUIState({ ...uiState, download: v2 }) }) }), u$1(Title, { children: "资源列表" }), script.documentList.map((item, index) => u$1(LogItem, { type: item.status, badge: true, children: u$1("p", { style: { margin: 0 }, children: item.title }) }, index)), u$1("button", { disabled: uiState.done, className: "start-btn", onClick: handleStart, children: uiState.started ? uiState.stopped ? "继续" : "暂停" : "开始" })] }); }; const version = (_a = GM_info == null ? void 0 : GM_info.script) == null ? void 0 : _a.version; const components = { guide: Guide, answer: Answer, exam: Exam, video: VideoPanel, topic: TopicComponent, ispace: ISpace }; const SafeComponentWrapper = ({ component: Component, script }) => { if (!Component) return null; try { return u$1(Component, { script }); } catch (error) { console.error("Error rendering iframe component:", error); return u$1("div", { children: "Error loading component" }); } }; function App() { const [user, getUser] = useUserState(); const [activePanel, setActivePanel] = useTabState("guide"); const [visible, setVisible] = d(false); const [dynamicComponents, setDynamicComponents] = d({}); const [activeComponent, setActiveComponent] = d(null); const [isLoginPage, setIsLoginPage] = d(false); const [_2, showShop] = useShopState(); const handlePanelChange = (panel) => { setActivePanel(panel); setActiveComponent(panel); }; y(() => { const uiManager2 = UIManager.getInstance(); const handleComponentRegister = (component) => { setDynamicComponents((prev) => ({ ...prev, [component.id]: component.component })); if (activeComponent === null) { setActiveComponent(component.id); setActivePanel(component.id); } }; const handleComponentUnregister = (id) => { setDynamicComponents((prev) => { const newComponents = { ...prev }; delete newComponents[id]; return newComponents; }); }; const handleActiveComponentChange = (id) => { setActiveComponent(id); setActivePanel(id); }; uiManager2.on("uiComponentRegistered", handleComponentRegister); uiManager2.on("uiComponentUnregistered", handleComponentUnregister); uiManager2.on("activeComponentChanged", handleActiveComponentChange); const components2 = uiManager2.getUIComponents(); const initialComponents = {}; components2.forEach((comp) => { initialComponents[comp.id] = comp.component; }); setDynamicComponents(initialComponents); const activeId = uiManager2.getActiveComponentId(); if (activeId) { setActiveComponent(activeId); setActivePanel(activeId); } return () => { uiManager2.off("uiComponentRegistered", handleComponentRegister); uiManager2.off("uiComponentUnregistered", handleComponentUnregister); uiManager2.off("activeComponentChanged", handleActiveComponentChange); }; }, []); const uiManager = UIManager.getInstance(); const registeredComponents = uiManager.getUIComponents(); const isSetting = activeComponent === "setting"; const hint = [!user.email && u$1("p", { children: ["当前使用临时账户,为保证权益,请及时", u$1("span", { className: "span-btn", onClick: () => setIsLoginPage(true), children: "登陆账号" })] }), user.points < 50 && u$1("p", { children: ["当前积分不足50,可能影响做题结果,请及时", u$1("span", { className: "span-btn", onClick: () => showShop({ params: { serviceType: 0 }, title: "充值积分" }), children: "充值" })] })].filter(Boolean); return u$1("div", { children: [u$1(Modal, { title: "🙆🏻‍♂️欢迎使用Keb脚本🙆🏻‍♂️", className: "app-modal", visible: true, zoom: true, showCloseButton: false, children: [!user.id || isLoginPage ? u$1(LoginRegister, { onLoginSuccess: () => getUser() && setIsLoginPage(false) }) : u$1("div", { children: [hint.length ? u$1(LogItem, { type: "warning", badge: false, children: hint }) : null, registeredComponents.map((comp) => { const Component = components[comp.id]; return u$1(HasShow, { show: activeComponent === comp.id, children: Component ? u$1(Component, { script: comp == null ? void 0 : comp.script, children: u$1(SafeComponentWrapper, { component: comp == null ? void 0 : comp.component, script: comp == null ? void 0 : comp.script }) }) : u$1(SafeComponentWrapper, { component: comp == null ? void 0 : comp.component, script: comp == null ? void 0 : comp.script }) }, comp.id); }), registeredComponents.length > 0 && u$1(HasShow, { show: isSetting, children: u$1(Setting, {}) }), u$1("div", { className: "action-bar", children: [registeredComponents.map((comp) => u$1("div", { className: `action-item ${activeComponent === comp.id ? "active" : ""}`, children: u$1(IconButton, { icon: activeComponent === comp.id ? `${comp == null ? void 0 : comp.icon}-fill` : comp == null ? void 0 : comp.icon, tooltip: comp == null ? void 0 : comp.name, onClick: () => handlePanelChange(comp.id) }) }, comp.id)), registeredComponents.length > 0 && u$1("div", { className: `action-item ${isSetting ? "active" : ""}`, children: u$1(IconButton, { icon: isSetting ? "icon-settings-fill" : "icon-settings", tooltip: "设置", onClick: () => handlePanelChange("setting") }) })] })] }), version && u$1("div", { class: "version", children: ["当前版本", version] })] }), u$1(ShopPanel, { visible, onClose: () => setVisible(false) })] }); } class PanelBox extends BaseEvent { constructor(config) { super(); __publicField(this, "config"); __publicField(this, "container"); __publicField(this, "root"); __publicField(this, "isInitialized"); __publicField(this, "append"); __publicField(this, "isTopWindow"); this.config = { width: 300, height: 400, position: "right", draggable: true, resizable: false, visible: false, ...config }; this.isInitialized = false; this.append = false; this.isTopWindow = unsafeWindow.top === unsafeWindow; } initialize() { if (this.isInitialized || !this.isTopWindow) return; if (this.config.visible) { this.show(); } this.isInitialized = true; this.emit("initialized"); } createContainer() { if (!this.isTopWindow) return; const div = document.createElement("div"); div.id = "keb-app"; E$1(u$1(GlobalStoreProvider, { children: u$1(QuestionStoreProvider, { children: u$1(App, {}) }) }), div); this.root = div; this.container = div.querySelector(".k-modal-body"); this.setupEventListeners(); } addCss() { if (!this.isTopWindow) return; const link = document.createElement("link"); link.rel = "stylesheet"; link.href = "https://at.alicdn.com/t/c/font_4940441_d1vnstng9uk.css"; const doc = document; doc == null ? void 0 : doc.head.appendChild(link); const style = document.createElement("style"); style.textContent = `:root { /* color-scheme: light dark; */ /* color: rgba(255, 255, 255, 0.87); */ /* background-color: #242424; */ font-synthesis: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;}a { font-weight: 500; color: #646cff; text-decoration: inherit;}a:hover { color: #535bf2;}#keb-app { --primary-color: #007bff; --primary-color-hover: #2b81dc; --secondary-color: #6c757d; --success-color: #60c177; --info-color: #17a2b8; --warning-color: #f49e65; --danger-color: #f16257; --done-color: #90be6d; --await-color: #b5c3d0; --light-color: #f8f9fa; --dark-color: #343a40; --text-color: #212529; --border-color: #dee2e6; --glass-background: rgba(255, 255, 255, 0.6); --disabled-color: #b1b1b1; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;}* { margin: 0; padding: 0; font-size: 12px; box-sizing: border-box;}p { margin: 0.5em 0; line-height: 1.4; font-size: 12px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;}.k-modal-body.app-modal { top: 50px; right: 50px; transform: unset;}.vip-badge { background: #ffc107; color: #fff; padding: 2px 6px; border-radius: 4px; font-size: 12px;}.action-bar { display: flex; /* justify-content: center; */ gap: 16px; margin-top: 8px; padding-top: 4px; border-top: 1px solid #eee;}.action-bar .action-item { position: relative; cursor: pointer;}.action-bar .action-item.active::after { content: ''; position: absolute; top: -4px; left: 0; width: 100%; height: 2px; background: #007bff; border-radius: 2px;}.version { position: absolute; right: 10px; bottom: 2px; text-align: right; color: #999; font-size: 11px; background-color: white; /* margin-top: 6px; */}.note { font-size: 12px; color: #ff5722; background: rgba(255, 87, 34, 0.1); padding: 4px; border-radius: 6px; margin: 6px 0; line-height: 1.4;}.red-word { color: #ff5722; font-weight: 500;}.log-box { height: 300px; overflow-y: auto; background: rgba(214, 214, 214, 0.6); backdrop-filter: blur(5px); padding: 8px; border-radius: 8px; margin: 0px 0 8px; line-height: 1.4; font-size: 12px;}.start-btn { display: block; background: #2b81dc; color: #fff; padding: 8px 16px; border-radius: 20px; cursor: pointer; text-align: center; margin: 16px auto; font-size: 14px; font-weight: 500; transition: all 0.2s linear; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); border: none; outline: none;}.start-btn:hover { background: #007bff; transform: scale(1.05);}.start-btn:disabled { background: #b1b1b1; cursor: not-allowed;}.panel-content { max-height: 80vh; overflow-y: auto;}.k-message-container { position: fixed; top: 24px; left: 50%; transform: translateX(-50%); z-index: 10000; width: fit-content; max-width: 80%;}.k-message { position: relative; display: flex; align-items: center; padding: 6px 8px; margin-bottom: 16px; border-radius: 4px; background: #fff; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); opacity: 0; transform: translateY(-100%); transition: opacity 0.3s, transform 0.3s;}.k-message.k-message-show { opacity: 1; transform: translateY(0);}.k-message.k-message-hide { opacity: 0; transform: translateY(-100%);}.k-message.k-message-info { border: 1px solid #cecdcd; background-color: #ffffff;}.k-message.k-message-success { border: 1px solid #95eb53; background-color: #e3f5d0;}.k-message.k-message-warning { border: 1px solid #f9dc7e; background-color: #faf3cf;}.k-message.k-message-error { border: 1px solid #f7837d; background-color: #fcd9d4;}.k-message .k-message-content { flex: 1; font-size: 14px; line-height: 1.5;}.k-alert-modal .k-modal-body,.k-confirm-modal .k-modal-body { min-width: 300px; max-width: 500px;}.k-alert-modal .k-modal-header,.k-confirm-modal .k-modal-header { color: #333; padding-left: 14px; font-weight: 700;}.k-alert-modal .k-modal-content,.k-confirm-modal .k-modal-content { padding: 10px 20px; display: flex; align-items: center;}.k-alert-modal .k-modal-footer,.k-confirm-modal .k-modal-footer { padding: 0 10px 10px; text-align: right;}.k-alert-modal .k-modal-footer .qk_button,.k-confirm-modal .k-modal-footer .qk_button { margin-left: 10px;}.k-alert-modal .k-modal-footer .qk_button:first-child,.k-confirm-modal .k-modal-footer .qk_button:first-child { margin-left: 0;}.qk_button { border-radius: 4px; padding: 4px 8px; background: #007bff; color: white; border: none; cursor: pointer; transition: all 0.3s linear; position: relative;}.qk_button:disabled { background: #b1b1b1; cursor: not-allowed;}.qk_button.block { display: block; width: 100%;}.qk_button.normal { background: transparent; color: #212529; border: 1px solid #dee2e6;}.qk_button.normal:not(:disabled):hover { border-color: #007bff; color: #007bff;}.qk_button.danger { background: #f16257; color: white;}.qk_button.danger:not(:disabled):hover { opacity: 0.8;}.qk_button.primary:not(:disabled):hover { opacity: 0.8;}.k-modal { position: fixed; z-index: 999;}.k-modal input,.k-modal p,.k-modal textarea { font-size: 12px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;}.k-modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); z-index: 1000;}.k-modal-body { position: fixed; top: 50%; right: 50%; background: white; width: 320px; font-size: 12px; border-radius: 12px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); z-index: 1001; transform: translate(50%, -50%);}.k-modal-header { position: relative; background: var(--primary-color); color: white; padding: 6px 8px; font-size: 14px; font-weight: 500; display: flex; justify-content: space-between; align-items: center; border-radius: 12px 12px 0 0;}.k-modal-header .icons { position: absolute; right: 3px; top: 50%; display: flex; align-items: center; transform: translateY(-50%);}.k-modal .min .k-modal-header { border-radius: 8px; padding: 3px 4px;}.k-modal-header .close-btn { color: white; background: none; border: none; font-size: 14px; cursor: pointer; opacity: 0.8; transition: opacity 0.2s; line-height: 1; padding: 4px;}.k-modal-header .close-btn:hover { opacity: 1;}.k-modal-content { padding: 8px 8px 16px;}.k-modal-footer { display: flex; justify-content: flex-end;}.icon-btn { background: none; border: none; color: var(--primary-color); cursor: pointer; padding: 6px; border-radius: 50%; transition: all 0.2s; position: relative; font-size: 16px;}.icon-btn:disabled { color: #b1b1b1; cursor: not-allowed;}.icon-btn.tooltip:not(:disabled)::after { position: absolute; bottom: 100%; left: 50%; transform: translateX(-50%); background: rgba(0, 0, 0, 0.8); color: white; padding: 4px 8px; border-radius: 4px; font-size: 12px; white-space: nowrap; margin-bottom: 4px;}.icon-btn.tooltip:not(:disabled).bottom::after { bottom: unset; top: 100%;}.icon-btn.tooltip:not(:disabled):hover::after { content: attr(data-tooltip);}.icon-btn:not(:disabled):hover { background: rgba(33, 150, 243, 0.1);}.rollbox-container { overflow: hidden; height: 30px; width: 100%; color: #fff;}.rollbox-list.rolling { transition: transform 0.3s;}.rollbox-item { height: 30px; line-height: 30px; padding: 0 8px;}.agreement-wrapper { top: 35px; left: 0; width: 100%; padding: 10px; padding-top: 0; padding-right: 0; z-index: 9; font-size: 12px;}.agreement-wrapper .agreement-content { height: 300px; padding: 14px; padding-right: 16px; overflow-y: auto;}.agreement-wrapper .agreement-content h1 { font-size: 1.5em; text-align: center;}.agreement-wrapper .agreement-content h2 { font-size: 1.2em; margin-bottom: 10px;}.agreement-wrapper .agreement-content ul { margin-left: 1em; padding-left: 1em;}.agreement-wrapper .agreement-content ul li { margin-bottom: 10px;}.agreement-wrapper .agreement-footer { padding: 10px 20px 0; padding-left: 40px; display: flex; justify-content: space-evenly;}.login-register-panel { padding: 0 10px 10px;}.login-register-panel .hint { font-size: 12px;}.login-register-panel .hint.center { text-align: center;}.login-register-panel .hint .span-btn { margin-left: 0;}.login-register-panel .error-message { color: #ff4d4f; font-size: 12px; margin-bottom: 12px; padding: 4px 8px; background-color: #fff2f0; border: 1px solid #ffccc7; border-radius: 4px;}.login-register-panel .error-message.general-error { margin-top: 10px;}.span-btn { color: #535bf2; border: 1px dashed #535bf2; border-radius: 4px; padding: 2px 4px; cursor: pointer; font-size: 12px; margin-left: 6px; line-height: 1;}.span-btn:hover { opacity: 0.8;}.log-entry { position: relative; padding: 4px; padding-left: 16px; margin-bottom: 6px; background: var(--glass-background); backdrop-filter: blur(5px); border-radius: 4px; border: 1px solid var(--border-color);}.log-entry.success::before,.log-entry.done::before,.log-entry.info::before,.log-entry.pending::before,.log-entry.warning::before,.log-entry.danger::before,.log-entry.error::before { content: ''; position: absolute; top: 50%; left: 4px; transform: translateY(-50%); width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0;}.log-entry.loading,.log-entry.running { display: flex; flex-wrap: wrap; padding-left: 0.6em; border-left: 3px solid var(--success-color);}.log-entry.loading .loading-spinner,.log-entry.running .loading-spinner { background: unset;}.log-entry.no-badge { padding-left: 0.6em;}.log-entry.no-badge::before { background-color: transparent !important;}.log-entry.success,.log-entry.done { border-left: 3px solid var(--success-color);}.log-entry.success::before,.log-entry.done::before { background: var(--success-color);}.log-entry.info,.log-entry.pending { border-left: 3px solid var(--info-color);}.log-entry.info::before,.log-entry.pending::before { background: var(--info-color);}.log-entry.warning { border-left: 3px solid var(--warning-color);}.log-entry.warning::before { background: var(--warning-color);}.log-entry.error { border-left: 3px solid var(--danger-color);}.log-entry.error::before { background: var(--danger-color);}.log-entry.primary { border-left: 3px solid var(--primary-color);}.log-entry.primary::before { background: var(--primary-color);}.step-one,.step-two,.step-three { padding: 10px; padding-bottom: 0; min-height: 300px; display: flex; flex-direction: column;}.k-modal-body.shop-panel { top: 50%; left: 50%; width: 500px; transform: translate(-50%, -50%);}.k-modal-body.shop-panel h3 { margin: 0; font-size: 16px;}.k-modal-body.shop-panel h4 { margin: 0;}.product-list { flex: 1; margin: 15px 0;}.product-list .product-item { border: 1px solid #e0e0e0; border-radius: 8px; padding: 6px 8px; margin-bottom: 10px; cursor: pointer; transition: all 0.3s ease;}.product-list .product-item:hover { border-color: #1890ff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);}.product-list .product-item.selected { border-color: #1890ff; background-color: #e6f7ff; box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);}.product-list .product-item .product-info h4 { font-size: 14px; color: #333;}.product-list .product-item .product-info p { margin: 0; color: #666; font-size: 12px;}.product-list .product-item .product-price { font-size: 18px; font-weight: bold; color: #ff4d4f; text-align: right; margin-top: 10px;}.student-input { display: flex; justify-content: flex-end; margin-bottom: 8px;}.student-input .qk_input { width: 180px; margin-right: 4px;}.course-tip { margin: 10px 0; color: #ff4d4f; font-size: 14px; font-weight: bold;}.course-header { display: flex; align-items: center; justify-content: space-between;}.course-list { flex: 1; margin: 15px 0; display: flex; flex-wrap: wrap; gap: 6px;}.course-list .course-item { border: 1px solid #e0e0e0; border-radius: 8px; padding: 6px 8px; cursor: pointer; transition: all 0.3s ease;}.course-list .course-item:hover { border-color: #1890ff; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);}.course-list .course-item.selected { border-color: #1890ff; background-color: #e6f7ff; box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);}.course-list .course-item h4 { font-size: 14px; color: #333;}.course-count { margin-left: 4px; color: #666; font-size: 12px; vertical-align: bottom;}.order-summary { flex: 1; margin: 10px 0;}.order-summary .order-item { display: flex; justify-content: space-between; padding: 6px 0; border-bottom: 1px solid #f0f0f0;}.order-summary .order-item .price-value { color: #ff4d4f; font-size: 18px;}.order-summary .order-item:last-child { font-weight: bold; border-bottom: 2px dashed #939393; margin-top: 6px;}.order-summary .order-item:last-child span { font-size: 14px;}.payment-wrapper { display: flex; align-items: center; padding: 0 10px;}.payment-method { margin: 10px 0;}.payment-method .qr-codes { display: flex; justify-content: space-around; gap: 20px;}.payment-method .qr-code { text-align: center; cursor: pointer; padding: 6px; border-radius: 8px; transition: all 0.3s ease;}.payment-method .qr-code:hover { background-color: #f5f5f5;}.payment-method .qr-code.active { background-color: #e6f7ff; border: 1px solid #1890ff; box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);}.payment-method .qr-code .qr-code-img,.payment-method .qr-code img { width: 160px; height: 160px; object-fit: contain; border: 1px solid #ddd; border-radius: 4px;}.payment-method .qr-code .payment-label { font-size: 14px; color: #333;}.payment-right { flex: 1; margin-left: 10px;}.payment-right .payment-error { margin-top: 10px; color: #ff4d4f; font-size: 14px; text-align: center;}.payment-tip { margin: 10px 0; padding: 10px; background-color: #fffbe6; border: 1px solid #ffe58f; border-radius: 4px;}.payment-tip p { margin: 0; color: #d48806;}.step-three { text-align: center; align-items: center; justify-content: center;}.step-three .success-icon { width: 80px; height: 80px; line-height: 80px; font-size: 48px; color: #52c41a; border: 3px solid #52c41a; border-radius: 50%; margin: 0 auto 20px;}.step-three h3 { font-size: 24px; color: #333; margin-bottom: 10px;}.step-three p { color: #666; margin-bottom: 5px;}.modal-footer { display: flex; justify-content: flex-end; gap: 10px; padding-top: 10px; border-top: 1px solid #f0f0f0;}.title-bar { position: relative; display: flex; align-items: center; justify-content: space-between; margin: 8px 0;}.title-bar .title-text { font-size: 14px; padding: 0 10px;}.title-bar::before { content: ''; flex: 1 1 0; height: 1px; background-color: #e2e2e2;}.title-bar::after { content: ''; flex: 1; height: 1px; background-color: #e2e2e2;}.topics { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 6px;}.topics .topic-num { position: relative; width: 24px; height: 24px; border-radius: 4px; background: var(--light-color); border: 1px solid var(--border-color); display: flex; align-items: center; justify-content: center; font-size: 12px; color: var(--text-color); cursor: pointer; transition: all 0.2s ease; overflow: hidden;}.topics .topic-num.loading,.topics .topic-num.running { cursor: not-allowed; opacity: 0.5;}.topics .topic-num.loading::after,.topics .topic-num.running::after { content: ''; position: absolute; top: 1px; left: 1px; width: 21px; height: 21px; border-left: 1px solid var(--primary-color); border-radius: 50%; animation: loading 1s linear infinite; z-index: 1;}.topics .topic-num.await,.topics .topic-num.pending { background: var(--await-color); color: white;}.topics .topic-num.success { background: var(--success-color); color: white;}.topics .topic-num.done { background: var(--done-color); color: white;}.topics .topic-num.info { background: var(--info-color); color: white;}.topics .topic-num.warning,.topics .topic-num.stop { background: var(--warning-color); color: white;}.topics .topic-num.danger,.topics .topic-num.error { background: var(--danger-color); color: white;}.topics .topic-num.cancel,.topics .topic-num.abort { background: var(--await-color); color: white;}.topics .topic-num.active { outline: 3px solid var(--primary-color); outline-offset: -3px;}.answer-box { font-size: 12px; color: #333; font-weight: bold; background: rgba(128, 127, 126, 0.3); padding: 4px 8px; border-radius: 6px; margin: 4px 0; line-height: 1.4;}.info-row { display: flex; align-items: center; justify-content: space-between; /* margin-bottom: 4px; */ padding: 4px 0; font-size: 13px; color: #333;}.info-label { color: #666;}.info-value { flex: 1; display: flex; align-items: center; justify-content: flex-end;}.tabs .tabs-header { display: flex; border-bottom: 1px solid #e8e8e8;}.tabs .tabs-header .tab-title { padding: 4px 14px; cursor: pointer; transition: color 0.3s; position: relative;}.tabs .tabs-header .tab-title.disabled { cursor: not-allowed; color: #ccc;}.tabs .tabs-header .tab-title:hover { color: #1890ff;}.tabs .tabs-header .tab-title.active { color: #1890ff;}.tabs .tabs-header .tab-title.active::after { content: ''; position: absolute; bottom: -1px; left: 0; right: 0; height: 2px; background-color: #1890ff;}.tabs .tabs-content { padding: 8px 0;}.qk_input { width: 100%; padding: 4px 8px; border: 1px solid #dee2e6; border-radius: 4px; transition: all 0.3s linear;}.qk_input:hover { border-color: #2b81dc;}.qk_input:focus,.qk_input:focus-visible { border-color: #2b81dc; box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.2); outline: none;}.qk_input:disabled { background: #f5f5f5; border-color: #e0e0e0; cursor: not-allowed;}.qk-switch { display: inline-block; width: 28px; height: 16px; position: relative; cursor: pointer; border: none; background: transparent;}.qk-switch input { display: none;}.qk-switch:disabled { cursor: not-allowed; opacity: 0.5;}.qk-switch.qk-switch-checked .qk-switch-track { background-color: #007bff;}.qk-switch.qk-switch-checked .qk-switch-handle { left: calc(100% - 16px);}.qk-switch .qk-switch-track { width: 100%; height: 100%; border-radius: 16px; background-color: #ccc; transition: background-color 0.2s; position: absolute; top: 0; left: 0; z-index: 1;}.qk-switch.loading::after { content: ''; display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 16px; background-color: rgba(255, 255, 255, 0.5); z-index: 1; cursor: wait;}.qk-switch.loading .qk-switch-handle::after { animation: loading 0.6s linear infinite; width: 12px; height: 12px; content: ""; position: absolute; top: 1px; left: 1px; border-top: 1px solid #007bff; border-radius: 50%; z-index: 2;}@keyframes loading { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); }}.qk-switch .qk-switch-handle { width: 14px; height: 14px; border-radius: 50%; background-color: #fff; transition: all 0.2s; position: absolute; top: 1px; left: 1px; z-index: 2;}.qk_select { width: 100%; padding: 4px 8px; border: 1px solid #dee2e6; border-radius: 4px; transition: all 0.3s linear; background-color: #fff; cursor: pointer; appearance: none; background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e"); background-repeat: no-repeat; background-position: right 8px center; background-size: 16px; padding-right: 32px;}.qk_select:hover { border-color: #2b81dc;}.qk_select:focus,.qk_select:focus-visible { border-color: #2b81dc; box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.2); outline: none;}.qk_select:disabled { background-color: #f5f5f5; border-color: #e0e0e0; cursor: not-allowed; opacity: 0.7;}.qk_select option { padding: 8px;}.qk_select_wrapper { position: relative; width: 100%; user-select: none;}.qk_select_wrapper.is_disabled { cursor: not-allowed; opacity: 0.7;}.qk_select_wrapper.is_disabled .qk_select_trigger { background-color: #f5f5f5; border-color: #e0e0e0; pointer-events: none;}.qk_select_trigger { width: 100%; padding: 4px 24px 4px 8px; border: 1px solid #dee2e6; border-radius: 4px; transition: all 0.3s linear; background-color: #fff; cursor: pointer; position: relative; display: flex; align-items: center;}.qk_select_trigger:hover { border-color: #2b81dc;}.qk_select_trigger:focus,.qk_select_trigger:focus-visible { border-color: #2b81dc; box-shadow: 0 0 0 2px rgba(33, 150, 243, 0.2); outline: none;}.qk_select_value { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px;}.qk_select_value.placeholder { color: #999;}.qk_select_arrow { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e"); background-repeat: no-repeat; background-position: center; background-size: contain; transition: transform 0.3s; color: #999;}.is_open .qk_select_arrow { transform: translateY(-50%) rotate(180deg);}.qk_select_dropdown { position: absolute; top: 100%; left: 0; right: 0; margin-top: 4px; background: #fff; border: 1px solid #dee2e6; border-radius: 4px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); z-index: 1000; max-height: 256px; overflow-y: auto; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;}.qk_select_option { padding: 4px 12px; cursor: pointer; transition: all 0.3s; color: #333;}.qk_select_option:hover { background-color: #f5f5f5;}.qk_select_option.is_selected { color: #007bff; background-color: #e6f7ff;}.qk_select_option.is_disabled { color: #999; cursor: not-allowed; background-color: #f5f5f5;}.qk_select_option.is_disabled:hover { background-color: #f5f5f5;}.qk-form-item { margin-bottom: 12px; position: relative; display: flex; flex-direction: column; justify-content: center; align-items: stretch; width: 100%;}.qk-form-item.qk-form-item-has-extra { margin-bottom: 6px;}.qk-form-item .qk-form-item-label { font-size: 14px; color: #333; margin-bottom: 8px; text-align: left; font-weight: bold; line-height: 1.5rem;}.qk-form-item .qk-form-item-label.required { color: #f16257;}.qk-form-item .qk-form-item-content { flex: 1; display: flex; justify-content: space-between;}.qk-form-item .qk-form-item-error { color: #f16257; font-size: 12px; margin-top: 4px; line-height: 1; text-align: left;}.qk-form-item .qk-form-item-help { color: #6c757d; font-size: 12px; margin-top: 4px; line-height: 1; text-align: left;}.qk-form-item .qk-form-item-extra { color: #6c757d; font-size: 12px; margin-top: 4px; line-height: 1; text-align: left;}.qk-form-item .error .qk_input { border-color: #f16257; box-shadow: 0 0 0 2px #ffebeb;}.loading-container { position: relative;}.loading-container.fill { width: 100%; height: 100%;}.loading-container.absolute { position: absolute; top: 0; left: 0; right: 0; bottom: 0;}.loading-container .loading-spinner { position: absolute; top: 0; left: 0; right: 0; bottom: 0; display: flex; justify-content: center; align-items: center; background-color: rgba(64, 64, 64, 0.6); z-index: 9; cursor: wait; border-radius: inherit;}.loading-container .loading-spinner .loading-icon { font-size: 14px; width: 1em; height: 1em; border: 2px solid #ccc; border-top: 2px solid #3498db; border-radius: 50%; animation: spin 1s linear infinite;}@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); }}.loading-container .loading-spinner .loading-text { margin-left: 4px; font-size: 14px; color: #007bff;}`; doc == null ? void 0 : doc.head.appendChild(style); } setupEventListeners() { if (!this.isTopWindow) return; if (this.config.resizable) { this.setupResizable(); } } static setupDraggable(target, container) { if (!target) return; if (target.__draggable === false) { target.__draggable = true; return; } if (target.__draggable) return; let isDragging = false; let startX; let startY; let startLeft; let startTop; const _target = target; target.__draggable = true; _target.addEventListener("mousedown", (e2) => { container = container || _target.querySelector(".k-modal-body"); const header = container.querySelector(".k-modal-header"); let target2 = e2.target; while (target2) { if (target2 === header) { isDragging = true; break; } target2 = target2.parentElement; } if (isDragging) { isDragging = true; startX = e2.clientX; startY = e2.clientY; startLeft = container.offsetLeft; startTop = container.offsetTop; } }); document.addEventListener("mousemove", (e2) => { if (!isDragging || !_target.__draggable) return; const deltaX = e2.clientX - startX; const deltaY = e2.clientY - startY; if (container) container.style.left = `${startLeft + deltaX}px`; if (container) container.style.top = `${startTop + deltaY}px`; }); document.addEventListener("mouseup", () => { isDragging = false; }); } static stopDraggable(target) { if (!target) return; target.__draggable = false; } setupDraggable() { PanelBox.setupDraggable(this.root); } setupResizable() { if (!this.isTopWindow) return; const resizer = document.createElement("div"); resizer.className = "keb-panel-resizer"; resizer.style.cssText = ` position: absolute; right: 0; bottom: 0; width: 10px; height: 10px; cursor: se-resize; `; let isResizing = false; let startX; let startY; let startWidth; let startHeight; resizer.addEventListener("mousedown", (e2) => { this.container = this.root.querySelector(".k-modal-body"); isResizing = true; startX = e2.clientX; startY = e2.clientY; startWidth = this.container.offsetWidth; startHeight = this.container.offsetHeight; }); document.addEventListener("mousemove", (e2) => { if (!isResizing) return; const deltaX = e2.clientX - startX; const deltaY = e2.clientY - startY; this.container.style.width = `${startWidth + deltaX}px`; this.container.style.height = `${startHeight + deltaY}px`; }); document.addEventListener("mouseup", () => { isResizing = false; }); this.container.appendChild(resizer); } destroy() { if (!this.isTopWindow) return; this.root && this.root.remove(); } show() { if (!this.append) { this.createContainer(); const doc = document; doc == null ? void 0 : doc.body.appendChild(this.root); this.addCss(); this.append = true; } this.root && (this.root.style.display = "block"); this.emit("shown"); } hide() { if (!this.isTopWindow) { window.parent.postMessage({ type: "KEB_UI_MESSAGE", action: "hidePanel" }, "*"); return; } this.root && (this.root.style.display = "none"); this.emit("hidden"); } getContainer() { return this.root; } isVisible() { return this.root ? this.root.style.display !== "none" : false; } } const _UIManager = class _UIManager extends BaseEvent { constructor() { super(); __publicField(this, "panelBox", null); __publicField(this, "uiComponents"); __publicField(this, "activeComponentId", null); __publicField(this, "isTopWindow"); this.uiComponents = /* @__PURE__ */ new Map(); this.isTopWindow = unsafeWindow.top === unsafeWindow; } static getInstance() { const top2 = unsafeWindow.top || unsafeWindow; if (!top2.__keb_ui_manager_instance) { top2.__keb_ui_manager_instance = new _UIManager(); } return top2.__keb_ui_manager_instance; } createPanel(config) { if (!this.isTopWindow) { return null; } if (this.panelBox) { throw new Error(`Panel with id ${config.id} already exists. Please use a unique id.`); } const panel = new PanelBox(config); this.panelBox = panel; panel.initialize(); this.emit("panelCreated", panel); return panel; } removePanel() { if (!this.isTopWindow) { return; } const panel = this.panelBox; if (panel) { panel.destroy(); this.panelBox = null; } } showPanel() { const panel = this.panelBox || this.createPanel({ id: "keb", title: "Keb", resizable: false }); if (panel && this.uiComponents.size > 0) { panel.show(); } } hidePanel() { if (!this.isTopWindow) { window.parent.postMessage({ type: "KEB_UI_MESSAGE", action: "hidePanel" }, "*"); return; } const panel = this.panelBox; if (panel) { panel.hide(); } } registerUIComponent(component) { this.uiComponents.set(component.id, component); this.emit("uiComponentRegistered", component); this.showPanel(); } unregisterUIComponent(id) { this.uiComponents.delete(id); this.emit("uiComponentUnregistered", id); if (this.activeComponentId === id) { this.activeComponentId = null; } if (this.uiComponents.size === 0) { this.hidePanel(); } } getUIComponents() { return Array.from(this.uiComponents.values()); } setActiveComponent(id) { if (this.uiComponents.has(id)) { this.activeComponentId = id; this.emit("activeComponentChanged", id); } } getActiveComponentId() { return this.activeComponentId || this.uiComponents.keys().next().value || null; } getUIComponent(id) { return this.uiComponents.get(id); } isTopLevelWindow() { return this.isTopWindow; } }; __publicField(_UIManager, "instance"); let UIManager = _UIManager; unsafeWindow.addEventListener("message", (event) => { if (event.data && event.data.type === "KEB_MESSAGE" && event.data.data.type === "initialize") { unsafeWindow.keb = Keb.getInstance(); } }); const _Keb = class _Keb extends BaseEvent { constructor() { super(); __publicField(this, "pages"); __publicField(this, "isInitialized"); __publicField(this, "storeManager"); __publicField(this, "logs", []); __publicField(this, "errorManager"); __publicField(this, "UIPanel"); __publicField(this, "globalState", {}); __publicField(this, "isTopWindow"); __publicField(this, "userId", sessionStorage.getItem("keb_wxzy_studentId") || void 0); this.pages = /* @__PURE__ */ new Map(); this.isInitialized = false; this.storeManager = StoreManager.getInstance(); this.errorManager = ErrorManager.getInstance(); this.UIPanel = UIManager.getInstance(); this.isTopWindow = unsafeWindow.top === unsafeWindow; } static getInstance() { const top2 = unsafeWindow.top || unsafeWindow; if (!top2.keb) { if (!_Keb.instance && unsafeWindow.top === unsafeWindow) { _Keb.instance = new _Keb(); _Keb.instance.initialize(); } else { top2.postMessage({ type: "KEB_MESSAGE", data: { type: "initialize" } }, "*"); } if (_Keb.instance) { top2.keb = _Keb.instance; } } return top2.keb; } initialize() { if (this.isInitialized) return; unsafeWindow.addEventListener("message", this.handleMessage.bind(this)); this.initializeDOMObserver(); this.UIPanel.showPanel(); this.storeManager.initialize(); this.initConfig(); this.isInitialized = true; this.emit("initialized"); } destroy() { this.pages.forEach((page) => { page.destroy(); }); this.offAll(); this.UIPanel.removePanel(); } initConfig() { const globalStore = this.storeManager.getSharedStore(); const defaultConfig = { exerciseInterval: "", autoPlay: true, autoNext: true, autoSubmit: true, autoFill: true, questionLib: 1, questionLibKey: "" }; const config = { ...defaultConfig, ...globalStore.get("config") }; this.storeManager.getSharedStore().set("config", config); this.on("setting", (config2) => { globalStore.set("config", config2); }); return config; } handleMessage(event) { if (event.data && event.data.type === "KEB_MESSAGE") { const payload = event.data.data; this.emit(payload.type, payload.data); } } initializeDOMObserver() { if (!this.isTopWindow) return; if (document.body) { const observer = new MutationObserver((mutations) => { this.emit("domChanged", mutations); }); observer.observe(document.body, { childList: true, subtree: true, attributes: true }); } } log(message2) { this.logs.push(message2); this.emit(UI_EVENT_KEYS.LOG, this.logs); } async getConfig() { return this.initConfig(); } registerPage(pageId, pageInstance) { this.pages.set(pageId, pageInstance); this.emit("pageRegistered", pageId); } getPage(pageId) { return this.pages.get(pageId); } getStoreManager() { return this.storeManager; } getErrorManager() { return this.errorManager; } async getUserInfo(refresh = true) { return this.storeManager.getSharedStore().get("user"); } start(type = "answer") { console.log("开始", type); this.emit("start", type); } openRecharge(params) { this.emit(UI_EVENT_KEYS.OPEN_RECHARGE, params); } }; __publicField(_Keb, "instance"); let Keb = _Keb; class Page extends BaseEvent { constructor(config) { super(); __publicField(this, "config"); __publicField(this, "scripts"); __publicField(this, "keb", null); this.config = config; this.scripts = /* @__PURE__ */ new Map(); this.initialize(); } initialize() { if (this.shouldRun()) { this.syncGetKeb().then((keb) => { this.keb = keb; keb == null ? void 0 : keb.registerPage(this.config.id, this); }); this.loadScripts(); this.emit("initialized"); } } async syncGetKeb(timeout = 5e3) { return new Promise((resolve) => { const t2 = Date.now(); const interval = setInterval(() => { const keb = Keb.getInstance(); if (keb) { clearInterval(interval); resolve(keb); } if (Date.now() - t2 > timeout) { clearInterval(interval); resolve(null); } }, 500); }); } shouldRun() { const url = window.location.href; if (this.config.match && match(url, this.config.match)) { return true; } return false; } loadScripts() { if (!this.config.scripts) return; this.config.scripts.forEach((script) => { if (typeof script === "function") { const scriptInstance = new script(this); this.scripts.set(script.name, scriptInstance); } }); } removeScript(scriptName) { this.scripts.delete(scriptName); } getScript(scriptName) { return this.scripts.get(scriptName); } getKeb() { return this.keb || Keb.getInstance(); } destroy() { this.offAll(); } getStoreManager() { var _a2; return (_a2 = this.keb) == null ? void 0 : _a2.getStoreManager(); } } const scriptState = {}; const ScriptStore = K$1(scriptState); const SET_STATE = "__SET_STATE__"; ScriptStore.Consumer; const createScriptComponent = (Component, defaultState) => { const ScriptStore2 = K$1(defaultState); return (props) => u$1(ScriptStore2.Provider, { value: defaultState, children: u$1(Component, { ...props }) }); }; class Script extends BaseEvent { constructor(page, config) { super(); __publicField(this, "config"); __publicField(this, "page"); __publicField(this, "storeManager"); __publicField(this, "isRunning"); __publicField(this, "state", {}); __publicField(this, "disabled"); __publicField(this, "sharedStore"); __publicField(this, "privateStore"); __publicField(this, "uiComponentId", ""); __publicField(this, "started", false); __publicField(this, "stopped", false); __publicField(this, "done", false); __publicField(this, "user"); __publicField(this, "name"); this.page = page; this.config = config; this.state = config.state || {}; this.name = config.name; this.isRunning = false; this.storeManager = page.getStoreManager(); if (this.storeManager) { this.sharedStore = this.storeManager.getSharedStore(); this.privateStore = this.storeManager.createPrivateStore(`${this.config.name}`, { name: "script-store", persistent: false }); } if (config.matchs && !match(window.location.href, config.matchs)) { this.disabled = true; return; } if (config.autoStart) { config.loadTime ? setTimeout(() => { this.initialize(); }, config.loadTime || 0) : this.initialize(); } window.addEventListener("beforeunload", () => { this.isRunning = false; this.destroy(); }); } destroy() { var _a2; this.unregisterUIComponent(); this.page.removeScript(this.config.name); (_a2 = this.storeManager) == null ? void 0 : _a2.removePrivateStore(this.config.name); this.refreshUI(); } initialize() { if (this.isRunning || this.disabled) return; this.eventUser(); this.isRunning = true; this.emit("initialized"); } eventUser() { const keb = this.getKeb(); this.getUserInfo(); keb == null ? void 0 : keb.on(ShopPaymentSuccess, (data) => { if (data.product.serviceType === 0) { this.getUserInfo(); } }); } getPage() { return this.page; } getKeb() { return this.page.getKeb(); } getVersion() { return this.config.version; } getStoreManager() { return this.storeManager; } async registerUIComponent(id, name, icon, component) { const keb = await this.page.syncGetKeb(); const uiManager = keb == null ? void 0 : keb.UIPanel; const Component = component && createScriptComponent(component, this.state || {}); this.uiComponentId = id; uiManager == null ? void 0 : uiManager.registerUIComponent({ id, name, icon, script: this, component: Component }); this.setUIState(this.state || {}); } unregisterUIComponent() { if (this.uiComponentId) { const keb = this.getKeb(); const uiManager = keb == null ? void 0 : keb.UIPanel; uiManager == null ? void 0 : uiManager.unregisterUIComponent(this.uiComponentId); this.uiComponentId = ""; } } setState(state) { Object.assign(this.state, state); this.emit(SET_STATE, state); } getState() { return this.state || {}; } setUIQuestion(questions, tab = true) { const keb = this.getKeb(); keb == null ? void 0 : keb.emit(UI_EVENT_KEYS.QUESTION, questions); tab && (keb == null ? void 0 : keb.emit(UI_EVENT_KEYS.TAB, this.uiComponentId)); } showUI() { this.broadcast({ type: UI_EVENT_KEYS.TAB, data: this.uiComponentId }); } getUIState() { if (!this.uiComponentId) return {}; const keb = this.getKeb(); return (keb == null ? void 0 : keb.globalState.state[this.uiComponentId]) || {}; } setUIState(state) { if (this.uiComponentId) { Object.assign(this.state, state); this.broadcast({ type: UI_EVENT_KEYS.STATE, data: { id: this.uiComponentId, state: { ...this.state, ...state } } }); } else { this.state = { ...this.state, ...state }; } } refreshUI() { this.broadcast({ type: UI_EVENT_KEYS.REFRESH }); } openRecharge(params) { this.broadcast({ type: UI_EVENT_KEYS.OPEN_RECHARGE, data: params }); } getUserInfo() { var _a2; (_a2 = this.getKeb()) == null ? void 0 : _a2.getUserInfo().then((user) => { this.user = user; }); } log(message2) { this.broadcast({ type: UI_EVENT_KEYS.LOG, data: `[${this.config.name}] ${message2}` }); } update(state) { } } const _HttpRequestMonitor = class _HttpRequestMonitor { constructor() { __publicField(this, "listeners", /* @__PURE__ */ new Map()); __publicField(this, "requets", /* @__PURE__ */ new Map()); } startMonitoring() { const xhr = XMLHttpRequest.prototype; this.watchXhr(xhr); } markProcessed(requestId, type) { if (!_HttpRequestMonitor.processedRequests.has(requestId)) { _HttpRequestMonitor.processedRequests.set(requestId, /* @__PURE__ */ new Set()); } const processedTypes = _HttpRequestMonitor.processedRequests.get(requestId); if (processedTypes.has(type)) { return false; } processedTypes.add(type); return true; } watch(match2, fn2) { this.listeners.set(match2, fn2); } trigger(params, args, type) { for (const [m2, fn2] of this.listeners) { if (match(params[1], m2)) { fn2(args, type); } } } hasWatch(url) { for (const [m2] of this.listeners) { if (match(url, m2)) { return true; } } return false; } uuidv4() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c2) { const r2 = Math.random() * 16 | 0, v2 = c2 == "x" ? r2 : r2 & 3 | 8; return v2.toString(16); }); } watchXhr(xhr) { const that = this; const open = xhr.open; let openArgs = []; let url; xhr.open = function() { var _a2, _b; const id = this.requestId || that.uuidv4(); this.requestId = id; openArgs = Array.from(arguments); url = openArgs[1]; if (that.hasWatch(url)) { const instance = this; const response = (_a2 = Object.getOwnPropertyDescriptor(xhr, "response")) == null ? void 0 : _a2.get; const responseText = (_b = Object.getOwnPropertyDescriptor(xhr, "responseText")) == null ? void 0 : _b.get; Reflect.defineProperty(instance, "response", { get: function() { const content = response == null ? void 0 : response.call(instance); if (that.markProcessed(instance.requestId, "response")) { that.response(content, instance.requestId); } return content; } }); Reflect.defineProperty(instance, "responseText", { get: function() { const content = responseText == null ? void 0 : responseText.call(instance); if (that.markProcessed(instance.requestId, "responseText")) { that.responseText(content, instance); } return content; } }); } return open.apply(this, arguments); }; const send = xhr.send; xhr.send = function(data) { if (that.hasWatch(url)) { if (that.markProcessed(this.requestId, "request")) { that.request(this, [...openArgs, data]); } } return send.apply(this, arguments); }; const setRequestHeader = xhr.setRequestHeader; xhr.setRequestHeader = function(name, value) { return setRequestHeader.apply(this, arguments); }; } watchFetch() { const that = this; const fetch2 = window.fetch; window.fetch = function() { const requestId = that.uuidv4(); return new Promise((resolve, reject) => { const res = fetch2.apply(this, arguments); if (that.markProcessed(requestId, "fetch_request")) { that.request(res, arguments); } res.then((res2) => { const response = res2; const _json = response.json; response.json = async function() { const content = await _json.apply(this, arguments); if (that.markProcessed(requestId, "fetch_response")) { that.response(content); } return content; }; const _text = response.text; response.text = async function() { const content = await _text.apply(this, arguments); if (that.markProcessed(requestId, "fetch_responseText")) { that.responseText(content, response); } return content; }; const _blob = response.blob; response.blob = async function() { const content = await _blob.apply(this, arguments); if (that.markProcessed(requestId, "fetch_blob")) { that.response(content); } return content; }; resolve(response); }).catch(reject); }); }; } request(xhr, args) { this.requets.set(xhr.requestId, args); this.trigger(args, args, XMLHttpRequest.OPENED); } response(content, id) { console.log("[返回参数]", content); const args = this.requets.get(id); this.trigger(args, content, XMLHttpRequest.DONE); } responseText(content, xhr) { const args = this.requets.get(xhr.requestId); if (isType(content, "string")) { content = content.trim(); try { content = JSON.parse(content); this.trigger(args, content, XMLHttpRequest.DONE); } catch (error) { } } } }; __publicField(_HttpRequestMonitor, "processedRequests", /* @__PURE__ */ new Map()); let HttpRequestMonitor = _HttpRequestMonitor; class WcxtCollection extends Script { constructor(page) { super(page, { name: "wcxtzy", description: "文才学堂作业脚本", version: "1.0.0", author: "Keb Framework", autoStart: true }); __publicField(this, "httpObserver"); __publicField(this, "studentId", ""); __publicField(this, "schoolId"); __publicField(this, "majorId", ""); __publicField(this, "termList", []); const http = new HttpRequestMonitor(); this.httpObserver = http; http.startMonitoring(); this.schoolId = getStore("schoolId"); http.watch((match2) => match2 == null ? void 0 : match2.includes("new_index.action?req=getIndexInfo"), this.school.bind(this)); http.watch((match2) => match2 == null ? void 0 : match2.includes("user_info.action?req=getUserInfo"), this.major.bind(this)); http.watch((match2) => match2 == null ? void 0 : match2.includes("desktop.action?req=getDesktopInfo"), this.student.bind(this)); http.watch((url) => url == null ? void 0 : url.endsWith("student_learn.action?req=getTerm"), this.term.bind(this)); http.watch((url) => url == null ? void 0 : url.includes("student_learn.action?req=getStudentLearnInfo"), this.course.bind(this)); } school(data, type) { if (type === XMLHttpRequest.DONE) { const d2 = data.data; const _data = dedata(d2); _data.learnLevelVoList; postSchool({ name: _data.schoolName, website: location.href, loginSite: location.href }).then((res) => { if (res.success) { this.schoolId = res.data.id; setStore("schoolId", res.data.id, false); } }); } } major(data, type) { if (type === XMLHttpRequest.DONE) { const d2 = data.data; const _data = dedata(d2); const businessNames = _data._businessName.split("-"); const majorName = businessNames[2] || _data._businessName; postMajor({ name: majorName, code: _data._businessCode, level: _data._eduLevelName, schoolId: this.schoolId }).then((res) => { if (res.success) { this.majorId = res.data.id; } }); } } student(data, type) { if (type === XMLHttpRequest.DONE) { const d2 = data.data; const _data = dedata(d2); this.studentId = _data.studentId; if (this.schoolId) { putSchool({ code: _data.schoolCode }, this.schoolId); } sessionStorage.setItem("keb_wxzy_studentId", _data.studentId); postStudent({ studentName: _data.studentName, studentNo: _data.studentNo, studentId: _data.studentId, uid: _data.learningUserId, schoolId: this.schoolId }); } } term(data, type) { if (type === XMLHttpRequest.DONE) { const d2 = data.data; const list = dedata(d2); this.termList = list; const last = list[list.length - 1]; this.sharedStore.set("lastTermCode", last.termCode); } } course(data, type) { if (type === XMLHttpRequest.DONE) { const d2 = data.data; const _data = dedata(d2); postCourse({ studentNo: _data.courseInfoList[0].studentNo, list: _data.courseInfoList.filter((item) => item.courseId).map((item) => { var _a2, _b; return { name: item.courseName, code: item.courseId, term: item.term, termCode: (_b = (_a2 = this.termList) == null ? void 0 : _a2.find((term) => term.term === item.term)) == null ? void 0 : _b.termCode, schoolId: item.schoolId, online: Number(item.progressTotalScore > 0) }; }) }); } } } function observerElement(selector, callback) { return new Promise((resolve) => { const observer = new MutationObserver(() => { const el = document.querySelector(selector); if (el) { callback(el); observer.disconnect(); } }); observer.observe(document.body, { childList: true, subtree: true }); resolve(observer); }); } function querySelector(selector, timeout = 5e3) { return new Promise(async (resolve, reject) => { const el = document.querySelector(selector); if (el) { resolve(el); } else { const observer = await observerElement(selector, resolve); timeout && setTimeout(() => { observer.disconnect(); reject(new Error(`Element ${selector} not found`)); }, timeout); } }); } function isVueComponent(el) { return (el == null ? void 0 : el.__vue__) !== void 0; } class WcxtVideoScript extends Script { constructor(page) { super(page, { name: "wcxtvideo", description: "文才学堂视频脚本", matchs: "*/courseware/*.html", version: "1.0.0", author: "Keb Framework", autoStart: true, loadTime: 1e3 }); __publicField(this, "video"); __publicField(this, "httpObserver"); __publicField(this, "userId", ""); __publicField(this, "showExpedite", false); __publicField(this, "courseLesson", []); __publicField(this, "autoIndex", 0); __publicField(this, "istate", {}); __publicField(this, "stopAutoPlay", true); __publicField(this, "startAutoPlay", false); __publicField(this, "currentPlayUrl", ""); const http = new HttpRequestMonitor(); this.httpObserver = http; http.startMonitoring(); http.watch((url) => url == null ? void 0 : url.includes("newApp_learn_course.action?req=getCourseScormItemList"), (content, type) => { if (type === XMLHttpRequest.DONE) { const listCourseLesson = content.debugData.listCourseLesson; this.postCourseware(listCourseLesson); } }); http.watch((url) => url == null ? void 0 : url.includes("newApp_use_energy.action?req=getUserAuthority"), (content, type) => { if (type === XMLHttpRequest.DONE) { const userId = content.debugData.userId; this.userId = userId; } }); http.watch((url) => url == null ? void 0 : url.includes("sync_mooc.action?req=getStuChapterSignature"), (content, type) => { if (type === XMLHttpRequest.OPENED) { try { let data = content[3]; const p2 = new URLSearchParams(data); const id = Decrypt(decodeURIComponent(p2.get("lesson_id") || "")); this.setUIState({ lesson_id: id }); } catch (error) { console.error(error); } } }); } initialize() { super.initialize(); this.execute(); this.getExpediteAuthority(); this.registerUIComponent("video", "视频", "icon-video"); const keb = this.getKeb(); keb == null ? void 0 : keb.on(ShopPaymentSuccess, (data) => { if ((data == null ? void 0 : data.product.serviceType) === 1) { this.getExpediteAuthority(); } }); } postCourseware(list) { list.forEach((item) => { item.status = TASK_STATUS.PENDING; }); this.setUIState({ courseLesson: list.filter((item) => item.lessonType === "scorm_content") }); postChapter({ list }).then((res) => { if (res.success) { this.courseLesson = res.data; } }); } async getExpediteAuthority() { var _a2; if (!unsafeWindow.getQueryString) return false; const courseId = getQueryString("course_id"); const userid = ((_a2 = this.getKeb()) == null ? void 0 : _a2.userId) || this.userId || getQueryString("user_id"); const res = await hasAcceleration({ courseId, userid }); this.showExpedite = res.success && res.data; this.setUIState({ showExpedite: this.showExpedite }); return this.showExpedite; } startExpedite() { if (!this.showExpedite) { return Message.alert("未检测到该学生的该课程有一键完成服务,请开通后重试"); } if (!this.startAutoPlay) { this.autoIndex = 0; this.startAutoPlay = true; } if (this.stopAutoPlay) { this.stopAutoPlay = false; this.log("开始自动播放"); this.next(); } else { this.stopAutoPlay = true; } this.setUIState({ stopAutoPlay: this.stopAutoPlay, startAutoPlay: this.startAutoPlay }); } async getRowItemInfo(row) { const res = await getChapter(row.id, { user_id: getQueryString("user_id") }); if (res.success) { const obj = JSON.parse(res.data.content); const data = Object.assign({}, res.data, obj); let energy = false; if (!data.isFree && data.useEnergyNum) { energy = await this.useEnergy(data.aid, data.courseId); } else if (data.isFree) { energy = true; } if (!energy) { message$1.error(data.lessonName + "需要消耗能量不足, 任务已暂停"); this.stopAutoPlay = true; this.setUIState({ stopAutoPlay: this.stopAutoPlay }); return false; } return data; } } async useEnergy(siid, courseId) { var params = { learning_user_id: getQueryString("user_id"), course_id: courseId, type_code: "progress", item_id: siid }, url = urlStart + "/newApp_use_energy.action?req=saveUseEnergyInfo", res = getData(url, params), ret = false; if (res.code == 1e3) { ret = true; var data = dedata(res.data); $("#lastEnergy").text(data); } else { message$1.error(res.message); } return ret; } async saveSubmit(row) { row.status = TASK_STATUS.RUNNING; this.setUIState({ courseLesson: this.courseLesson }); const item = await this.getRowItemInfo(row); if (!item) { this.stopAutoPlay = true; message$1.error("数据异常,请联系管理员"); return; } var params = { user_id: getQueryString("user_id"), course_id: item.courseId, time: item.timeLen, item_id: item.aid, view_time: item.timeLen, last_view_time: item.timeLen - 1, video_length: item.timeLen, learning_user_id: this.userId }, url = urlStart + "/learning.action?req=submitScormAndHistorySave", res = getData(url, params); if (res.code == 1e3) { var data = dedata(res.data); if (data.isFinish) { this.log("课程:" + item.lessonName + "完成"); row.status = TASK_STATUS.SUCCESS; this.setUIState({ courseLesson: this.courseLesson }); setTimeout(() => { if (!this.stopAutoPlay) { this.autoIndex++; this.next(); } }, 1e3); } } else { message$1.error(res.message); } } async next() { if (this.autoIndex >= this.courseLesson.length) { if (this.autoIndex) { this.stopAutoPlay = true; this.setUIState({ done: true, stopAutoPlay: true }); this.log("所有课程已完成"); return Message.alert("所有课程已完成,点击确认刷新", { onOk: () => { location.reload(); } }); } return message$1.error("没有可播放的课程,请联系客服或管理员"); } const item = this.courseLesson[this.autoIndex]; this.log("开始处理课程:" + (item.lessonName || item.title)); if (!item.parentId) { this.autoIndex++; item.status = TASK_STATUS.SUCCESS; return this.next(); } if (item.isFinish) { this.autoIndex++; return this.next(); } this.saveSubmit(item); } execute() { querySelector("video").then((el) => { var _a2; this.video = el; this.currentPlayUrl = this.video.src; this.setUIState({ currentPlayUrl: this.currentPlayUrl }); const nativeSet = (_a2 = Object.getOwnPropertyDescriptor(this.video, "src")) == null ? void 0 : _a2.set; Reflect.defineProperty(this.video, "src", { get: () => this.currentPlayUrl, set: (value) => { this.currentPlayUrl = value; this.setUIState({ currentPlayUrl: this.currentPlayUrl }); nativeSet == null ? void 0 : nativeSet.call(this.video, value); } }); this.initEvent(); }); } initEvent() { var _a2; this.play(); (_a2 = this.video) == null ? void 0 : _a2.addEventListener("timeupdate", () => { if (this.video.currentTime >= this.video.duration) ; }); } playbackRate() { if (!this.video) return; const state = this.istate; this.video.playbackRate = state.videoRate || 1; this.video.play(); } update(state) { this.istate = state; this.playbackRate(); this.log(`正在进行${state.videoRate || 1}倍速播放`); if (state.autoSwitch) { ifPlayNext && (ifPlayNext.checked = true); } } play() { this.playbackRate(); } } function queryQuestion(data) { return request({ url: "/questions/query", method: "POST", data }); } function queryQuestionDone(data) { return request({ url: "/questions/queryEnd", method: "POST", data }); } function addQuestions(data) { return request({ url: "/questions", method: "POST", data }); } const message = Message.message; class WcxtExamScript extends Script { constructor(page) { super(page, { name: "wcxtExam", description: "文才学堂考试脚本", matchs: "*/exam/index.html", autoStart: true, loadTime: 1e3 }); __publicField(this, "answers", []); __publicField(this, "questions", []); __publicField(this, "errIndex", []); __publicField(this, "spaceTime", 2e3); __publicField(this, "QAIndex", ["A", "B", "C", "D", "E", "F", "J"]); __publicField(this, "currentIndex", 0); __publicField(this, "httpObserver"); __publicField(this, "doDoneKeys", /* @__PURE__ */ new Map()); __publicField(this, "typeIndex", { 3: 1, 4: 2, 1: 3, 2: 4, 5: 5, 12: 6 }); const http = new HttpRequestMonitor(); this.httpObserver = http; http.startMonitoring(); } initialize() { super.initialize(); this.httpObserver.watch((match2) => match2 == null ? void 0 : match2.includes("examModular_exam_item.action?req=getLastExam"), () => { setTimeout(() => { this.initStart(); }, 1e3); }); this.registerUIComponent("exam", "考试", "icon-computer"); } async labelClick(arr, els, i2 = 0) { return new Promise((resolve) => { if (i2 >= arr.length) { resolve(true); return; } const ai = arr[i2]; const label = els[ai]; if (!label) { this.labelClick(arr, els, i2 + 1).then(resolve); return; } label.click(); setTimeout(async () => { const result = await this.labelClick(arr, els, i2 + 1); resolve(result); }, this.spaceTime); }); } async simClick(el, qa = {}, index) { const box = el.querySelector(".ansbox"); let answer = qa.answer || ""; if (box == null ? void 0 : box.classList.contains("radioAnswer")) { let qais = []; const solutions = box.querySelectorAll(".perRad label"); const options = Array.prototype.map.call(solutions, (solution, index2) => { const option = (solution.innerText || "").split("."); const [no, ...content] = option; return { serial_no: no ? no.trim() : String(index2), content: content.join(".").trim(), el: solution }; }); if (answer) { answer = this.compareOptions(options, qa); qais = answer.split("").map((a2) => this.QAIndex.indexOf(a2)).filter((i2) => i2 !== -1); } await this.labelClick(qais, solutions); } else if (box == null ? void 0 : box.classList.contains("txtAnswer")) { const textarea = box.querySelector(".showTextarea textarea"); if (textarea) { textarea.value = answer; textarea.dispatchEvent(new Event("input", { bubbles: true })); textarea.dispatchEvent(new Event("change", { bubbles: true })); } } else if (box == null ? void 0 : box.classList.contains("inputAnswer")) { const input = box.querySelector(".perInp input"); if (input) { input.value = answer; input.dispatchEvent(new Event("input", { bubbles: true })); input.dispatchEvent(new Event("change", { bubbles: true })); } } } generateOptions(el) { const box = el.querySelector(".ansbox"); if (box == null ? void 0 : box.classList.contains("radioAnswer")) { const solutions = box.querySelectorAll(".perRad label"); const options = Array.prototype.map.call(solutions, (solution, index) => { const option = (solution.innerText || "").split("."); const [no, ...content] = option; return { serial_no: no ? no.trim() : String(index), content: content.join(".").trim(), el: solution }; }); return options.map((option) => `${option.serial_no}_、_${option.content}`).join("\n"); } return ""; } compareOptions(options, answer) { const { options: answerOptions, answer: userAnswer } = answer; if (options && answerOptions) { const userAnswers = userAnswer.split(""); const indexs = userAnswers.map((userAnswer2) => this.QAIndex.indexOf(userAnswer2.toUpperCase())); const _aoptions = answerOptions.split("\n"); const ans = _aoptions.map((option, index) => { const [serial_no, content] = option.split("_、_"); return { serial_no, content, isRight: indexs.includes(index) }; }).filter((option) => option.isRight); return options.filter((option) => ans.some((a2) => a2.content === option.content)).map((option) => option.serial_no).join(""); } return userAnswer; } collectQuestion() { const list = document.querySelectorAll(".tmList"); let index = 1; const questions = []; list.forEach((el) => { var _a2; const tmc = el.querySelector(".tmc"); const type = tmc ? parseInt(tmc.getAttribute("ttype") || "0") : 0; if ([5, 12].includes(type)) { const l2 = tmc.querySelectorAll(".stmc"); const q2 = ((_a2 = tmc.querySelector(".tmFillCont")) == null ? void 0 : _a2.innerHTML) || ""; l2.forEach((el2) => { const question = this.generateQuestion(el2, q2); question.no = question.no || index; questions.push(question); index++; }); } else { const question = this.generateQuestion(el); question.no = question.no || index; questions.push(question); index++; } }); return questions; } generateQuestion(el, s2 = "") { var _a2; let title = [s2, ((_a2 = el.querySelector(".tmTitleTxt")) == null ? void 0 : _a2.innerHTML) || ""].filter(Boolean).join("::"); title = title.replace(/\n|\t/g, "").trim().replace(/\s{3,}/g, " "); const options = this.generateOptions(el); const question = { el, title, options, status: TASK_STATUS.PENDING }; return question; } async autoQA() { var _a2; this.log("开始自动答题"); this.questions = this.collectQuestion(); if (!this.questions.length) { Message.alert("没有发现题目,请确认已进入考试页面"); return; } this.log("收集题目完成"); message.success("正在进行考试做题"); this.started = true; this.setUIState({ started: true }); if (!((_a2 = this.answers) == null ? void 0 : _a2.length)) { this.collectionVue(); } this.currentIndex = 0; this.doNext(); } async doNext() { const question = this.questions[this.currentIndex]; if (!question) { if (this.currentIndex) { Message.alert("已全部完成" + (this.errIndex.length ? ` 其中${this.errIndex.join(",")}等题随机生成,请自行检查` : "")); } this.queryQuestionDone(this.questions.filter((q2) => q2.status === TASK_STATUS.DONE)); this.setUIState({ done: true, started: false }); this.done = true; return; } if (this.stopped) { return; } if (this.user.points < 1 && !this.doDoneKeys.has(question.questionKey)) { Message.alert(`积分不足,请先充值后继续,当前任务已暂停,还剩${this.questions.length - this.currentIndex}题`); this.stopped = true; this.setUIState({ stopped: true }); this.queryQuestionDone(this.questions.filter((q2) => q2.status === TASK_STATUS.DONE)); return; } this.log(`开始处理第${this.currentIndex + 1}题`); const qa = await this.queryQuestionAnswer(question); if (!(qa == null ? void 0 : qa.answer)) { this.errIndex.push(this.currentIndex); message.error(`题目${this.currentIndex}未找到答案,请自行检查`); qa.status = TASK_STATUS.ERROR; } else { this.doDoneKeys.set(question.questionKey, qa.queryId); this.user && this.user.points--; await sleep(this.spaceTime); await this.simClick(question.el, qa, this.currentIndex); qa.status = TASK_STATUS.DONE; } this.currentIndex++; this.refreshUI(); this.doNext(); } async queryQuestionAnswer(q2) { const question = this.answers.find((a2) => a2.title === q2.title || a2.title.includes(q2.title)); q2.status = TASK_STATUS.RUNNING; this.refreshUI(); if (question == null ? void 0 : question.answer) { Object.assign(q2, question); return q2; } try { const res = await queryQuestion({ ...q2, ...question, ai: 1 }); if (res.success) { Object.assign(q2, res.data); return q2; } } catch (error) { console.log("queryQuestionAnswer", error); } return q2; } async fillFn() { if (this.started) { if (this.stopped) { this.stopped = false; this.setUIState({ stopped: false }); this.doNext(); return; } else { this.stopped = true; this.setUIState({ stopped: true }); this.queryQuestionDone(this.questions.filter((q2) => q2.status === TASK_STATUS.DONE)); } return; } this.errIndex = []; if (this.user.points < 30) { Message.alert("积分不足,无法完成任务,请先充值"); return; } else if (this.user.points < 35) { Message.confirm({ title: "是否继续?", content: "积分不足,可能无法完成全部任务", showRecharge: true }).then((result) => { if (result === "ok") { this.autoQA(); } else if (result === "charge") { this.openRecharge({ params: { serviceType: 0 } }); } }); return; } await this.autoQA(); } collectionVue() { var _a2; const comp = (_a2 = document.querySelector("#paperExam")) == null ? void 0 : _a2.__vue__; if (!comp) return false; const answerList = comp.answerList; const qas = []; let fillCont = "", fillCount = 0; answerList.forEach((item) => { var _a3, _b; let a2 = "", o2 = ""; if ([5, 12].includes(+item.itemType)) { if (item.itemName === fillCont && fillCount > 0) { fillCount--; return; } fillCont = item.itemName || ""; fillCount = item.questions.length; item.questions.forEach((row) => { var _a4, _b2; a2 = ((_a4 = row.itemAnswer) == null ? void 0 : _a4.map((o22) => o22.optionContent).join("")) || ""; o2 = ((_b2 = item.optionNodes) == null ? void 0 : _b2.map((o22) => `${o22.option}_、_${o22.optionContent}`).join("\n")) || ""; qas.push({ title: (item.itemName + "::" + row.itemName).replace(/\n|\t/g, "").trim().replace(/\s{3,}/g, " "), answer: a2, questionKey: item.itemId, type: this.typeIndex[item.itemType] || 9, options: o2 }); }); } else { a2 = ((_a3 = item.itemAnswer) == null ? void 0 : _a3.map((o22) => o22.optionContent).join("")) || ""; o2 = ((_b = item.optionNodes) == null ? void 0 : _b.map((o22) => `${o22.option}_、_${o22.optionContent}`).join("\n")) || ""; qas.push({ title: item.itemName.replace(/\n|\t/g, "").trim().replace(/\s{3,}/g, " "), answer: a2, questionKey: item.itemId, type: this.typeIndex[item.itemType] || 9, options: o2 }); } }); this.answers = qas; if (qas.every((q2) => q2.answer)) { this.saveQA(qas); } return true; } async saveQA(qa) { await addQuestions({ list: qa }); } async queryQuestionDone(questions) { await queryQuestionDone({ list: questions.filter((item) => item.answer).map((item) => { const queryId = item.queryId || this.doDoneKeys.get(item.questionKey) || uuidv4(); return { queryId, questionId: item.id }; }) }); this.getUserInfo(); } initStart() { querySelector("#paperRight", 0).then(async (right) => { const paperExam = await querySelector("#paperExam"); if (isVueComponent(paperExam)) { this.collectionVue(); } else { Message.alert("页面与脚本不匹配,请联系管理员修复"); } }); } } function disposeAnswer(ans = "") { var _a2; ans = Array.isArray(ans) ? ans.join("|") : ans || ""; if (ans.startsWith("答")) return ans.substring(2); return ((_a2 = /\[参考答案:([^\]]+)\]/gi.exec(ans)) == null ? void 0 : _a2[1]) || ans; } function disposeOptions(el) { const options = []; const opt = (el == null ? void 0 : el.querySelectorAll("tr")) || []; if (opt.length === 1) { const oText = el.innerText; const regex = /\([A-Z]\)[^\(]*/g; const matches = oText.match(regex); if (matches && matches.length > 1) { matches.forEach((match2) => { var _a2; const option = (_a2 = match2.match(/\([A-Z]\)/)) == null ? void 0 : _a2[0]; if (!option) return; const content = match2.replace(option, "").trim(); options.push([option.replace(/\(|\)/g, ""), content].filter(Boolean).join("_、_").trim()); }); } else { const content = oText.replace(/\(([A-Z])\)/g, "").trim(); const serial_no = RegExp.$1 || ""; options.push([serial_no, content].filter(Boolean).join("_、_").trim()); } } else opt.forEach((o2) => { const oText = o2.innerText; const arr = oText.split(" ").filter(Boolean); if (arr.length > 1) { let [serial_no, content] = arr; if (/^\([A-Z]\)$/.test(serial_no)) { serial_no = serial_no.replaceAll(/\(|\)/g, ""); } options.push([serial_no, content].filter(Boolean).join("_、_").trim()); } else { const content = oText.replace(/\(([A-Z])\)/g, "").trim(); const serial_no = RegExp.$1 || ""; options.push([serial_no, content].filter(Boolean).join("_、_").trim()); } }); return options; } const QAIndex = ["A", "B", "C", "D", "E", "F", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]; class WcxtzyScript extends Script { constructor(page) { super(page, { name: "wcxtzy", description: "文才学堂作业脚本", matchs: ["*/learning/learn_homework.jsp"], version: "1.0.0", author: "Keb Framework", autoStart: true, loadTime: 1e3 }); __publicField(this, "workList", []); __publicField(this, "currentConfig"); __publicField(this, "doQuestionIndex", 0); __publicField(this, "dones", []); __publicField(this, "doneKeys", /* @__PURE__ */ new Set()); __publicField(this, "queryDonekeys", /* @__PURE__ */ new Map()); __publicField(this, "estimatedScore", 75); } initialize() { super.initialize(); this.registerUIComponent("answer", "作业", "icon-computer"); this.log("初始化完成"); } start() { const state = this.getUIState(); if (this.started) { if (state.done) { Message.alert("所有任务已完成,请勿重复操作"); return; } if (state.stopped) { this.stopped = false; this.startTask(); return; } else { this.stopped = true; this.setUIState({ stopped: true }); return; } } if (this.user.points < 40) { Message.alert("积分不足,无法完成任务,请充值"); return; } else if (this.user.points < 75) { Message.confirm({ title: "是否继续?", content: "积分不足,可能无法完成全部任务", okText: "仍然继续", showRecharge: true }).then((result) => { if (result === "ok") { this.getPageConfig(); } else if (result === "charge") { this.openRecharge({ params: { serviceType: 0 } }); } }); return; } this.getPageConfig(); } getPageConfig() { this.started = true; this.setUIState({ started: true }); this.log("开始获取作业列表"); const workList = document.querySelectorAll("td[examid]"); for (let i2 = 0; i2 < workList.length; i2++) { const pageConfig = { examid: "", sExamStatus: "", sContentId: "", baseurl: "" }; const element = workList[i2]; const examid = element.getAttribute("examid") || ""; const sContentId = element.getAttribute("contentid"); pageConfig.examid = examid; pageConfig.sContentId = sContentId || ""; pageConfig.baseurl = $fn.getLearningWeb(); this.workList.push(pageConfig); } this.startNextTask(); } async startNextTask() { const pageConfig = this.workList.shift(); if (!pageConfig) { if (this.dones.length) { this.verifyAnswer(); this.log("所有任务完成"); } this.done = true; return; } this.currentConfig = pageConfig; if (!this.dones.includes(this.currentConfig)) { this.dones.push(this.currentConfig); this.refreshUI(); } await this.fetchDocument(); let questions = await this.getQuestionOption2("question"); if (pageConfig.type === "answer") { this.saveAnswer(questions.filter((question) => question.answer)); pageConfig.answers = questions; if (Number(pageConfig.score) >= Number(this.estimatedScore)) { pageConfig.verifyed = true; return this.startNextTask(); } await this.fetchDocument(); questions = await this.getQuestionOption2("question"); } questions.forEach((question) => { question.status = TASK_STATUS.PENDING; }); pageConfig.questions = questions; this.refreshUI(); this.doQuestions(); } async fetchDocument() { var _a2, _b, _c; const pageConfig = this.currentConfig; const { examid, sContentId, baseurl } = pageConfig; const chech = await fetch(`${baseurl}/course/check_pre_index.jsp?content_id=${sContentId}`).then((res) => res.text()); if (chech.indexOf("ERROR:") > -1) return message$1.error("数据错误,请联系管理员或手动完成作业"); const sUrl = baseurl + "/exam/portal/exam_info.jsp?content_id=" + sContentId + "&type=work&is_make_up=undefined"; let html = await fetch(sUrl).then((res) => res.text()); html = html.replace(/\\/g, ""); let scoreId = (_a2 = html.match(/sScoreId\s?=\s?"([\d\w]+)"/)) == null ? void 0 : _a2[1]; const sExamStatus = ((_b = /sExamStatus\s?=\s?"(\w+)"/.exec(html)) == null ? void 0 : _b[1]) || ""; const score = ((_c = html.match(/(\d+)\(\d+\/10\d\)/)) == null ? void 0 : _c[1]) || 0; pageConfig.sExamStatus = sExamStatus; pageConfig.score = score; pageConfig.scoreId = scoreId; if (sExamStatus === "reexamine" && !pageConfig.answerDocument) { const params = $wapper.api.getURLParams($wapper.api.setQueryString("reexamine", "0", sUrl)); const viewUrl = `${baseurl}/exam/portal/view_answer.jsp?exam_id=${examid}&score_id=${scoreId}&${params}`; const iframe = await createIframeDocument(viewUrl); if (iframe) { this.currentConfig.answerDocument = iframe.document; } } else { const url = $api.fn.getActionURL(`com.lemon.learning.exam.StudentExamAction?op=before_exam&exam_id=${examid}&reexam=${sExamStatus == "reexamine" ? "1" : "0"}&script=parent.afterCheckExam()&type=work`); const viewUrl = location.origin + url; await fetch(viewUrl); const params = `exam_id=${examid}&type=work&content_id=${sContentId}&type=work&is_make_up=undefined`; await fetch(`${baseurl}/exam/portal/exam_console.htm?${params}`); await fetch(`${baseurl}/exam/portal/exam_left.jsp?${params}`); const iframe = await createIframeDocument(`${baseurl}/exam/portal/exam.jsp?${params}`); if (iframe) { this.currentConfig.document = iframe.document; } } } async verifyAnswer(index = 0) { this.log("开始验证答案"); if (index >= this.dones.length) { const _i = this.dones.findIndex((pageConfig2) => !pageConfig2.verifyed); if (_i > -1) { this.verifyAnswer(_i); return; } this.log("所有任务验证完成"); this.stopped = true; this.setUIState({ done: true, stopped: true }); Message.alert("所有任务任务完成,点确认刷新页面", { onOk: () => { location.reload(); } }); return; } const pageConfig = this.dones[index]; if (pageConfig.verifyed) { this.verifyAnswer(index + 1); return; } this.currentConfig = pageConfig; delete pageConfig.answerDocument; await this.fetchDocument(); const _questions = await this.getQuestionOption2("answer"); pageConfig.answers = _questions; const questions = pageConfig.questions; questions.forEach((question, index2) => { let answerO = _questions[index2] || {}; if (!(answerO.questionKey === question.questionKey || answerO.title === question.title)) { answerO = _questions.find((q2) => q2.questionKey === question.questionKey && q2.title === question.title); answerO = answerO || _questions[index2] || {}; } if (question.answer === answerO.answer) { question.status = TASK_STATUS.SUCCESS; question.isRight = 1; } else { question.status = TASK_STATUS.ERROR; question.isRight = 0; } }); this.refreshUI(); await this.saveAnswer(_questions); this.queryQuestionDone(questions); pageConfig.verifyed = true; this.refreshUI(); if (Number(pageConfig.score) < Number(this.estimatedScore)) { this.workList.push(pageConfig); this.startNextTask(); } else { this.verifyAnswer(index + 1); } } async getQuestionOption2(type = "question") { var _a2, _b, _c; let list = []; if (type === "answer") { const doc = ((_a2 = this.currentConfig) == null ? void 0 : _a2.answerDocument) || document; list = doc.querySelectorAll("tr[id^=trScore_]"); } else { let doc = (_b = this.currentConfig) == null ? void 0 : _b.document; if (!doc) { doc = ((_c = this.currentConfig) == null ? void 0 : _c.answerDocument) || document; type = "answer"; list = doc.querySelectorAll("tr[id^=trScore_]"); } else { list = doc.querySelectorAll("table[keylist]"); } } const questions = []; const iframe = await createIframeDocument(""); this.currentConfig.type = type; list.forEach((el) => { var _a3; const script = el.querySelector("script"); if (!iframe.window) { return; } const _key = el.getAttribute("keylist"); if (type === "question" && !_key) return; iframe.window.$wapper = { api: { getDisplayFormat: function(str) { var _a4, _b2, _c2, _d, _e, _f, _g, _h, _i, _j, _k; const div = document.createElement("div"); div.innerHTML = str; (_a4 = div.querySelector("link")) == null ? void 0 : _a4.remove(); (_b2 = div.querySelector("script")) == null ? void 0 : _b2.remove(); div.querySelectorAll("img").forEach((img, i2) => { const tNode = document.createTextNode(`[${img.alt || "img" + i2}](${img.src})`); img.replaceWith(tNode); }); if (div.children.length === 1) { const child = div.children[0]; if (child.tagName === "TABLE") { const titleEl = div.querySelector("tr:nth-child(1)"); const oBar = div.querySelector("table[optiontype]"); let type2 = (oBar == null ? void 0 : oBar.getAttribute("optiontype")) || ""; let title = (titleEl == null ? void 0 : titleEl.innerText.replace(/\n|\t/g, "")) || "", answer = "", key = ""; let options = []; if (["radio", "checkbox"].includes(type2)) { const text = div.innerText; key = ((_c2 = oBar == null ? void 0 : oBar.querySelector(`input[type=${type2}]`)) == null ? void 0 : _c2.getAttribute("name")) || ((_d = oBar == null ? void 0 : oBar.querySelector(`${type2}`)) == null ? void 0 : _d.getAttribute("name")) || ""; const answerM = text.match(/\[参考答案:[^\]]+\]|答[::][^<]*/gi); answer = disposeAnswer(answerM || ""); options = disposeOptions(oBar); } else { const expend = div.querySelector('a[id^="td_"]'); if (expend) { let id = expend.id; id = id.replace("_control", ""); title = title.split("提交的答题")[0]; const answerEl = div.querySelector("#" + id); answer = disposeAnswer((answerEl == null ? void 0 : answerEl.innerText) || ""); const textarea = div.querySelector("*[id^=lemonysoft_item_]"); key = (textarea == null ? void 0 : textarea.getAttribute("id")) || ""; type2 = "textarea"; } else { const inputs = child.querySelectorAll("input"); const ids = Array.prototype.map.call(inputs, (input) => { const nobar = input.nextElementSibling; let answer2 = ""; if (nobar) { const answerM = nobar.innerText.match(/\[参考答案:[^\]]+\]|答[::][^<]*/gi); answer2 = disposeAnswer(answerM || ""); const core = nobar.nextElementSibling; if ((core == null ? void 0 : core.tagName) === "FONT") { core.remove(); } nobar.remove(); } return { id: input.id, answer: answer2 }; }); title = div.innerText.replace(/\n|\t/g, "").trim(); key = ids.map((item) => item.id).join(","); answer = ids.map((item) => item.answer && `${item.answer}(${item.id})`).filter(Boolean).join("|"); type2 = "input"; } if (!key) { key = ((_e = div.querySelector("textarea[name^=lemonysoft_item_]")) == null ? void 0 : _e.getAttribute("name")) || ""; type2 = "textarea"; } } questions.push({ target: el, options: options.join("\n"), title: title.replace(/\s{3,}/g, " ").trim(), answer, questionKey: key, type: type2 }); } else { const oBar = div.querySelector("table[optiontype]"); let type2 = (oBar == null ? void 0 : oBar.getAttribute("optiontype")) || ""; let answer = "", key = "", title = div.innerText.replace(/\n|\t/g, ""); let options = []; if (["radio", "checkbox"].includes(type2)) { const text = div.innerText; title = title.split(oBar == null ? void 0 : oBar.innerText.replace(/\n|\t/g, ""))[0].trim(); key = ((_f = oBar == null ? void 0 : oBar.querySelector(`input[type=${type2}]`)) == null ? void 0 : _f.getAttribute("name")) || ((_g = oBar == null ? void 0 : oBar.querySelector(`${type2}`)) == null ? void 0 : _g.getAttribute("name")) || ""; const answerM = text.match(/\[参考答案:[^\]]+\]|答[::][^<]*/gi); answer = disposeAnswer(answerM || ""); options = disposeOptions(oBar); } else { const expend = div.querySelector('a[id^="td_"]'); if (expend) { let id = expend.id; id = id.replace("_control", ""); title = title.split("提交的答题")[0]; const answerEl = div.querySelector("#" + id); answer = disposeAnswer((answerEl == null ? void 0 : answerEl.innerText) || ""); const textarea = div.querySelector("*[id^=lemonysoft_item_]"); key = (textarea == null ? void 0 : textarea.getAttribute("id")) || ""; type2 = "textarea"; } else { const inputs = child.querySelectorAll("input"); const ids = Array.prototype.map.call(inputs, (input) => { const nobar = input.nextElementSibling; let answer2 = ""; if (nobar) { const answerM = nobar.innerText.match(/\[参考答案:[^\]]+\]|答[::][^<]*/gi); answer2 = disposeAnswer(answerM || ""); const core = nobar.nextElementSibling; if ((core == null ? void 0 : core.tagName) === "FONT") { core.remove(); } nobar.remove(); } return { id: input.id, answer: answer2 }; }); title = div.innerText.replace(/\n|\t/g, "").trim(); key = ids.map((item) => item.id).join(","); answer = ids.map((item) => item.answer && `${item.answer}(${item.id})`).filter(Boolean).join("|"); type2 = "input"; } if (!key) { key = ((_h = div.querySelector("textarea[name^=lemonysoft_item_]")) == null ? void 0 : _h.getAttribute("name")) || ""; type2 = "textarea"; } } const question = { target: el, title: title.replace(/\s{3,}/g, " ").trim(), options: options == null ? void 0 : options.join("\n"), questionKey: key, answer, type: type2 }; questions.push(question); } } else if (div.children.length > 1) { const text = div.innerText.replace(/\n|\t/g, ""); const oBar = div.querySelector("table[optiontype]"); let type2 = (oBar == null ? void 0 : oBar.getAttribute("optiontype")) || ""; let key = "", options = [], answer = "", title = ""; if (["radio", "checkbox"].includes(type2)) { const [t2, aText] = text.split(oBar == null ? void 0 : oBar.innerText.replace(/\n|\t/g, "")); title = t2; key = ((_i = oBar == null ? void 0 : oBar.querySelector(`input[type=${type2}]`)) == null ? void 0 : _i.getAttribute("name")) || ((_j = oBar == null ? void 0 : oBar.querySelector(`${type2}`)) == null ? void 0 : _j.getAttribute("name")) || ""; options = disposeOptions(oBar); answer = disposeAnswer(aText); } else { const expend = div.querySelector('a[id^="td_"]'); if (expend) { let id = expend.id; id = id.replace("_control", ""); if (div.children[0]) { title = div.children[0].innerText || div.children[0].textContent || ""; title = title.replace(/\n|\t/g, "").trim(); } const answerEl = div.querySelector("#" + id); answer = disposeAnswer((answerEl == null ? void 0 : answerEl.innerText) || ""); const textarea = div.querySelector("*[id^=lemonysoft_item_]"); key = (textarea == null ? void 0 : textarea.getAttribute("id")) || ""; type2 = "textarea"; } else { const inputs = div.querySelectorAll("input"); const ids = Array.prototype.map.call(inputs, (input) => { const nobar = input.nextElementSibling; let answer2 = ""; if (nobar) { const answerM = nobar.innerText.match(/\[参考答案:[^\]]+\]|答[::][^<]*/gi); answer2 = disposeAnswer(answerM || ""); const core = nobar.nextElementSibling; if ((core == null ? void 0 : core.tagName) === "FONT") { core.remove(); } nobar.remove(); } return { id: input.id, answer: answer2 }; }); title = div.innerText.replace(/\n|\t/g, "").trim(); key = ids.map((item) => item.id).join(","); answer = ids.map((item) => item.answer && `${item.answer}(${item.id})`).filter(Boolean).join("|"); type2 = "input"; } if (!key) { key = ((_k = div.querySelector("textarea[name^=lemonysoft_item_]")) == null ? void 0 : _k.getAttribute("name")) || ""; type2 = "textarea"; } } questions.push({ target: el, title: title.replace(/\s{3,}/g, " ").trim(), type: type2, options: options.join("\n"), answer, questionKey: key }); } return ""; } } }; const newScript = document.createElement("script"); newScript.innerHTML = (script == null ? void 0 : script.innerHTML) || ""; if (iframe.document) { iframe.document.write = () => { }; } (_a3 = iframe.document) == null ? void 0 : _a3.body.appendChild(newScript); }); return questions; } async doQuestions() { this.doQuestionIndex = 0; this.doNext(); } async doNext() { var _a2, _b, _c; if (this.stopped) { await this.ajaxSubmit(false); this.queryQuestionDone(((_a2 = this.currentConfig) == null ? void 0 : _a2.questions.filter((question2) => question2.status === TASK_STATUS.DONE)) || []); Message.alert("任务已暂停"); return; } const questions = ((_b = this.currentConfig) == null ? void 0 : _b.questions) || []; const question = questions[this.doQuestionIndex]; if (this.user.points <= 0 && !this.doneKeys.has(question.questionKey)) { Message.alert("积分不足,请充值,当前任务已暂停"); await this.ajaxSubmit(false); this.queryQuestionDone(((_c = this.currentConfig) == null ? void 0 : _c.questions.filter((question2) => question2.status === TASK_STATUS.DONE)) || []); this.pause(); return; } if (!question && this.doQuestionIndex >= questions.length) { try { await this.ajaxSubmit(true, "work"); this.startNextTask(); } catch (error) { console.log(error); } return; } this.log(`开始处理第${this.doQuestionIndex + 1}题`); question.status = TASK_STATUS.RUNNING; this.refreshUI(); const _question = await this.queryServer(question); if (_question == null ? void 0 : _question.answer) { _question.answer = this.compareOptions(question, _question); } Object.assign(question, _question); if (question == null ? void 0 : question.answer) { this.doneKeys.add(question.questionKey); this.user && this.user.points--; } question.status = TASK_STATUS.DONE; this.refreshUI(); this.doQuestionIndex++; this.doNext(); } compareOptions(question, answer = {}) { const { options } = question; const { options: answerOptions, answer: userAnswer = "" } = answer || {}; if (options && answerOptions) { const userAnswers = userAnswer.split(""); const indexs = userAnswers.map((userAnswer2) => QAIndex.indexOf(userAnswer2.toUpperCase())); const _aoptions = answerOptions.split("\n"); const ans = _aoptions.map((option, index) => { const [serial_no, content] = option.split("_、_"); return { serial_no, content, isRight: indexs.includes(index) }; }).filter((option) => option.isRight); const _qops = options.split("\n"); const qops = _qops.map((option) => { const [serial_no, content] = option.split("_、_"); return { serial_no, content }; }); return qops.filter((option) => ans.some((a2) => a2.content === option.content)).map((option) => option.serial_no).join(""); } return userAnswer; } pause() { this.setUIState({ stopped: true }); } startTask() { if (this.user.points <= 0) { Message.alert("积分不足,请充值再继续做题"); return; } this.setUIState({ stopped: false }); this.doNext(); } async queryServer(question) { var _a2; const answers = ((_a2 = this.currentConfig) == null ? void 0 : _a2.answers) || []; if (answers.length > 0) { const answer = answers.find((answer2) => answer2.title === question.title || answer2.questionKey === question.questionKey); if (answer) { return answer; } } const res = await queryQuestion(question); if (res.success) { return res.data; } } async ajaxSubmit(b_out, type) { return new Promise(async (resolve, reject) => { const { examid, questions } = this.currentConfig || {}; let url = $api.fn.getActionURL(`com.lemon.learning.exam.StudentExamAction?op=submit_exam&exam_id=${examid}&b_out=${+b_out}&item_id=&type=${type}&r=${Math.random()}`, true); url = location.origin + url; if (!(questions == null ? void 0 : questions.length)) { return reject("没有题目,请联系管理员"); } const params = new URLSearchParams(); questions.filter((question) => question.status === TASK_STATUS.DONE).forEach((question) => { if (question.type === "input") { const keys = question.questionKey.split(","); const values = question.answer.split("|"); keys.forEach((key, index) => { const val = values.find((value) => value.includes(key)); val && params.append(key, val.replace(`(${key})`, "")); }); } else { params.append(question.questionKey, question.answer); } }); $.ajax({ url, type: "post", data: params.toString(), success: (res) => { resolve(res); }, error: (err) => { reject(err); } }); }); } async saveAnswer(questions) { questions.length && await addQuestions({ list: questions }); } async queryQuestionDone(questions) { await queryQuestionDone({ list: questions.map((item) => { const queryId = item.queryId || this.queryDonekeys.get(item.questionKey) || uuidv4(); this.queryDonekeys.set(item.questionKey, queryId); return { queryId, questionId: item.id, isRight: item.isRight || 1 }; }) }); this.getUserInfo(); } } class WcxtTopic extends Script { constructor(page) { super(page, { name: "文才学堂话题", matchs: "*/coursePost/index.html", version: "1.0.0", author: "Keb Framework", autoStart: true, loadTime: 1e3 }); __publicField(this, "maxNum", 5); __publicField(this, "started", false); __publicField(this, "index", 0); __publicField(this, "done", false); } initialize() { this.registerUIComponent("topic", "话题", "icon-computer"); } async postTopic(data, i2 = 1) { if (this.done) { Message.alert("话题已发布完成,请勿重复运行"); return; } this.log("正在发布第" + i2 + "条话题"); this.started = true; this.maxNum = data.num; this.index = i2; this.refreshUI(); var params = { user_id: getQueryString("userId"), course_id: getQueryString("courseId"), school_code: getQueryString("schoolCode"), grade_code: getQueryString("gradeCode"), course_code: getQueryString("courseCode"), content: data.content || "好好学习,天天向上", is_ask: data.ifAsk || "0", img_url: data.articleImgs || "", time: 0 }, url = urlStart + "/forum_article.action?req=publishArticle"; getData(url, params); if (i2 < this.maxNum) { this.log("发布第" + i2 + "条话题结束"); await sleep(1e3); this.postTopic(data, i2 + 1); } else { this.started = false; this.done = true; this.refreshUI(); Message.alert("话题全部发布完成,点击确认刷新页面").then(() => { location.reload(); }); } } } class WcxtISpaceScript extends Script { constructor(page) { super(page, { name: "WcxtISpace", matchs: "*/learning/learn_ispace.jsp", autoStart: true, loadTime: 1e3 }); __publicField(this, "phoneParams", { phone_type: "android", current_version: "150", app_release: "wencaixuetang" }); __publicField(this, "studentParams", {}); __publicField(this, "course_code", ""); __publicField(this, "course_id", ""); __publicField(this, "user_id", ""); __publicField(this, "spendPoints", 5); __publicField(this, "documentList", []); __publicField(this, "currentIndex", 0); __publicField(this, "points", 0); } async initialize() { super.initialize(); this.registerUIComponent("ispace", "学习资料", "icon-computer"); const cookie = getCookie("openlearning_COOKIE"); this.studentParams = { student_type: cookie.get("user_type"), school_code: cookie.get("user_school_code"), grade_code: cookie.get("cur_grade_code"), user_id: cookie.get("user_id") }; this.course_code = cookie.get("course_code") || cookie.get("cur_course_code") || ""; const p2 = new URLSearchParams(location.search); this.course_id = p2.get("course_id") || ""; const student = await getStudent(cookie.get("user_id")); this.user_id = student.studentId; await this.loadScript(); await this.getList(); } async getList() { await this.getDocumentNeed(); this.documentList = await this.getDocumentList() || []; this.documentList.forEach((item) => { item.status = TASK_STATUS.PENDING; }); this.refreshUI(); } async start() { if (this.started) { if (this.done) { Message.alert("所有任务已完成,请勿重复操作"); return; } if (this.stopped) { this.stopped = false; this.setUIState({ stopped: false }); this.nextTask(); return; } else { this.stopped = true; this.setUIState({ stopped: true }); return; } } if (this.user.points < this.documentList.length * this.spendPoints) { Message.alert("积分不足,无法完成任务,请先充值"); return; } if (!unsafeWindow.Encrypt) { await this.loadScript(); await this.getList(); } this.setUIState({ started: true, stopped: false }); this.currentIndex = 0; this.nextTask(); } async nextTask() { if (this.currentIndex < this.documentList.length) { if (this.stopped) { this.log("任务已暂停"); this.doneRead(); return; } const item = this.documentList[this.currentIndex]; item.status = TASK_STATUS.RUNNING; this.refreshUI(); this.log(`开始处理第 ${this.currentIndex + 1} 个资源`); const state = this.getUIState(); if (state.download) { window.open(item.sourceUrl, "_blank"); } if (item.allowOpen && !item.isFinish) { this.currentIndex++; await this.doneDocumentContent(item.scormItemId); await this.upPoints(item.scormItemId); await sleep(1e3); item.status = TASK_STATUS.SUCCESS; this.points += this.spendPoints; this.nextTask(); } else { this.currentIndex++; item.status = TASK_STATUS.SUCCESS; this.nextTask(); } this.refreshUI(); } else { if (!this.currentIndex) { message$1.info("本课程没有阅读资源或加载失败"); return; } this.log("资源阅读全部完成"); this.done = true; this.setUIState({ done: true }); this.doneRead(); Message.alert("资源阅读全部完成,点击确认刷新", { onOk: () => { location.reload(); } }); } } async loadScript() { await loadScript("https://learning.wencaischool.net/openlearning/separation/vendors/aes/aes.js"); await loadScript("https://learning.wencaischool.net/openlearning/separation/vendors/aes/aesF.js"); } getDocumentNeed() { const url = location.origin + "/openlearning/newApp_learning_course_info.action?req=learnContentDocumentEnterCheckNew"; const data = emdata({ ...this.phoneParams, ...this.studentParams, learning_user_id: this.studentParams.user_id, user_id: this.user_id, course_code: this.course_code }); data.type = "1"; return new Promise(function(resolve, reject) { $.ajax({ url, type: "POST", data: qs(data), dataType: "json", success: function(response) { resolve(response); }, error: function(xhr, status, error) { reject(error); } }); }); } getDocumentList() { const url = location.origin + "/openlearning/newApp_learn_type.action?req=getLearnContentDocumentList"; const data = emdata({ ...this.phoneParams, ...this.studentParams, course_id: this.course_id, content_type: "ispace" }); data.type = "1"; return new Promise(function(resolve, reject) { $.ajax({ url, type: "POST", data: qs(data), dataType: "text", success: function(response) { const res = JSON.parse(response, (key, value, context) => { if (key === "scormItemId") { return context.source; } return value; }); resolve(res.debugData); }, error: function(xhr, status, error) { reject(error); } }); }); } doneDocumentContent(item_id) { const url = location.origin + "/openlearning/newApp_Scorm.action?req=submitText"; const data = emdata({ ...this.phoneParams, ...this.studentParams, course_id: this.course_id, item_id, time: "100" }); data.type = "1"; return new Promise(function(resolve, reject) { $.ajax({ url, type: "POST", data: qs(data), dataType: "json", success: function(response) { resolve(response); }, error: function(xhr, status, error) { reject(error); } }); }); } upPoints(item_id) { const url = location.origin + "/openlearning/newApp_point.action?req=savePoints"; const data = emdata({ ...this.phoneParams, ...this.studentParams, learning_user_id: this.studentParams.user_id, course_code: this.course_code, item_id, learn_type: "ispace", user_id: this.user_id }); data.type = "1"; return new Promise(function(resolve, reject) { $.ajax({ url, type: "POST", data: qs(data), success: function(response) { resolve(response); }, error: function(xhr, status, error) { reject(error); } }); }); } async doneRead() { await doneRead({ points: this.points }); this.getUserInfo(); this.points = 0; } } new Page({ id: "all-page", match: (url) => url.includes("wencaischool.net"), scripts: [WcxtCollection, WcxtExamScript, WcxtzyScript] }); new Page({ id: "video-page", match: "*/courseware/*.html", scripts: [WcxtVideoScript] }); new Page({ id: "topic-page", match: "*/coursePost/index.html", scripts: [WcxtTopic] }); new Page({ id: "ispace-page", match: "*/learning/learn_ispace.jsp", scripts: [WcxtISpaceScript] }); })();