// ==UserScript== // @name fuck-yuketang-font // @version 0.0.1 // @author mzwing // @description Fuck yuketang's font encryption, take the real characters back!!!!! // @license MIT // @homepage https://github.com/MZWNET/fuck-yuketang-font // @homepageURL https://github.com/MZWNET/fuck-yuketang-font // @source https://github.com/MZWNET/fuck-yuketang-font.git // @supportURL https://github.com/MZWNET/fuck-yuketang-font/issues // @match *://www.yuketang.cn/v2/web/cloud/student/exercise/* // @connect *.yuketang.cn // @connect fe-static-yuketang.yuketang.cn // @connect *.xuetangx.com // @grant GM_addStyle // @grant GM_xmlhttpRequest // @noframes // ==/UserScript== (function() { "use strict"; var s = new Set(); var _css = async (t) => { if (s.has(t)) return; s.add(t); ((c) => { if (typeof GM_addStyle === "function") GM_addStyle(c); else (document.head || document.documentElement).appendChild(document.createElement("style")).append(c); })(t); }; _css(" ._panel_13hok_1{z-index:2147483647;color:#fff;-webkit-user-select:none;user-select:none;background:#0f172ae6;border-radius:10px;max-width:260px;padding:10px 12px;font:13px/1.5 system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;position:fixed;bottom:16px;right:16px;box-shadow:0 8px 24px #0f172a40}._title_13hok_21{font-weight:700}._description_13hok_25{opacity:.82;margin-top:2px}._counter_13hok_30{opacity:.72;margin-top:4px}._actions_13hok_35{gap:8px;margin-top:8px;display:flex}._action_13hok_35{color:#fff;cursor:pointer;min-width:72px;font:inherit;background:#ffffff24;border:1px solid #ffffff3d;border-radius:6px;padding:4px 8px}._action_13hok_35:disabled{cursor:not-allowed;opacity:.46}._secondaryAction_13hok_57{background:0 0}._root_1emq5_1{all:initial}\n/*$vite$:1*/ "); var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports); var sharedConfig = { context: void 0, registry: void 0, effects: void 0, done: false, getContextId() { return getContextId(this.context.count); }, getNextContextId() { return getContextId(this.context.count++); } }; function getContextId(count) { const num = String(count), len = num.length - 1; return sharedConfig.context.id + (len ? String.fromCharCode(96 + len) : "") + num; } function setHydrateContext(context) { sharedConfig.context = context; } function nextHydrateContext() { return { ...sharedConfig.context, id: sharedConfig.getNextContextId(), count: 0 }; } var equalFn = (a, b) => a === b; var signalOptions = { equals: equalFn }; var ERROR = null; var runEffects = runQueue; var STALE = 1; var PENDING = 2; var UNOWNED = { owned: null, cleanups: null, context: null, owner: null }; var Owner = null; var Transition = null; var Scheduler = null; var ExternalSourceConfig = null; var Listener = null; var Updates = null; var Effects = null; var ExecCount = 0; function createRoot(fn, detachedOwner) { const listener = Listener, owner = Owner, unowned = fn.length === 0, current = detachedOwner === void 0 ? owner : detachedOwner, root = unowned ? UNOWNED : { owned: null, cleanups: null, context: current ? current.context : null, owner: current }, updateFn = unowned ? fn : () => fn(() => untrack(() => cleanNode(root))); Owner = root; Listener = null; try { return runUpdates(updateFn, true); } finally { Listener = listener; Owner = owner; } } function createSignal(value, options) { options = options ? Object.assign({}, signalOptions, options) : signalOptions; const s = { value, observers: null, observerSlots: null, comparator: options.equals || void 0 }; const setter = (value) => { if (typeof value === "function") if (Transition && Transition.running && Transition.sources.has(s)) value = value(s.tValue); else value = value(s.value); return writeSignal(s, value); }; return [readSignal.bind(s), setter]; } function createRenderEffect(fn, value, options) { const c = createComputation(fn, value, false, STALE); if (Scheduler && Transition && Transition.running) Updates.push(c); else updateComputation(c); } function createEffect(fn, value, options) { runEffects = runUserEffects; const c = createComputation(fn, value, false, STALE), s = SuspenseContext && useContext(SuspenseContext); if (s) c.suspense = s; if (!options || !options.render) c.user = true; Effects ? Effects.push(c) : updateComputation(c); } function untrack(fn) { if (!ExternalSourceConfig && Listener === null) return fn(); const listener = Listener; Listener = null; try { if (ExternalSourceConfig) return ExternalSourceConfig.untrack(fn); return fn(); } finally { Listener = listener; } } function onMount(fn) { createEffect(() => untrack(fn)); } function onCleanup(fn) { if (Owner === null); else if (Owner.cleanups === null) Owner.cleanups = [fn]; else Owner.cleanups.push(fn); return fn; } function startTransition(fn) { if (Transition && Transition.running) { fn(); return Transition.done; } const l = Listener; const o = Owner; return Promise.resolve().then(() => { Listener = l; Owner = o; let t; if (Scheduler || SuspenseContext) { t = Transition || (Transition = { sources: new Set(), effects: [], promises: new Set(), disposed: new Set(), queue: new Set(), running: true }); t.done || (t.done = new Promise((res) => t.resolve = res)); t.running = true; } runUpdates(fn, false); Listener = Owner = null; return t ? t.done : void 0; }); } var [transPending, setTransPending] = createSignal(false); function useContext(context) { let value; return Owner && Owner.context && (value = Owner.context[context.id]) !== void 0 ? value : context.defaultValue; } var SuspenseContext; function readSignal() { const runningTransition = Transition && Transition.running; if (this.sources && (runningTransition ? this.tState : this.state)) if ((runningTransition ? this.tState : this.state) === STALE) updateComputation(this); else { const updates = Updates; Updates = null; runUpdates(() => lookUpstream(this), false); Updates = updates; } if (Listener) { const observers = this.observers; if (!observers || observers[observers.length - 1] !== Listener) { const sSlot = observers ? observers.length : 0; if (!Listener.sources) { Listener.sources = [this]; Listener.sourceSlots = [sSlot]; } else { Listener.sources.push(this); Listener.sourceSlots.push(sSlot); } if (!observers) { this.observers = [Listener]; this.observerSlots = [Listener.sources.length - 1]; } else { observers.push(Listener); this.observerSlots.push(Listener.sources.length - 1); } } } if (runningTransition && Transition.sources.has(this)) return this.tValue; return this.value; } function writeSignal(node, value, isComp) { let current = Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value; if (!node.comparator || !node.comparator(current, value)) { if (Transition) { const TransitionRunning = Transition.running; if (TransitionRunning || !isComp && Transition.sources.has(node)) { Transition.sources.add(node); node.tValue = value; } if (!TransitionRunning) node.value = value; } else node.value = value; if (node.observers && node.observers.length) runUpdates(() => { for (let i = 0; i < node.observers.length; i += 1) { const o = node.observers[i]; const TransitionRunning = Transition && Transition.running; if (TransitionRunning && Transition.disposed.has(o)) continue; if (TransitionRunning ? !o.tState : !o.state) { if (o.pure) Updates.push(o); else Effects.push(o); if (o.observers) markDownstream(o); } if (!TransitionRunning) o.state = STALE; else o.tState = STALE; } if (Updates.length > 1e6) { Updates = []; throw new Error(); } }, false); } return value; } function updateComputation(node) { if (!node.fn) return; cleanNode(node); const time = ExecCount; runComputation(node, Transition && Transition.running && Transition.sources.has(node) ? node.tValue : node.value, time); if (Transition && !Transition.running && Transition.sources.has(node)) queueMicrotask(() => { runUpdates(() => { Transition && (Transition.running = true); Listener = Owner = node; runComputation(node, node.tValue, time); Listener = Owner = null; }, false); }); } function runComputation(node, value, time) { let nextValue; const owner = Owner, listener = Listener; Listener = Owner = node; try { nextValue = node.fn(value); } catch (err) { if (node.pure) if (Transition && Transition.running) { node.tState = STALE; node.tOwned && node.tOwned.forEach(cleanNode); node.tOwned = void 0; } else { node.state = STALE; node.owned && node.owned.forEach(cleanNode); node.owned = null; } node.updatedAt = time + 1; return handleError(err); } finally { Listener = listener; Owner = owner; } if (!node.updatedAt || node.updatedAt <= time) { if (node.updatedAt != null && "observers" in node) writeSignal(node, nextValue, true); else if (Transition && Transition.running && node.pure) { if (!Transition.sources.has(node)) node.value = nextValue; Transition.sources.add(node); node.tValue = nextValue; } else node.value = nextValue; node.updatedAt = time; } } function createComputation(fn, init, pure, state = STALE, options) { const c = { fn, state, updatedAt: null, owned: null, sources: null, sourceSlots: null, cleanups: null, value: init, owner: Owner, context: Owner ? Owner.context : null, pure }; if (Transition && Transition.running) { c.state = 0; c.tState = state; } if (Owner === null); else if (Owner !== UNOWNED) if (Transition && Transition.running && Owner.pure) if (!Owner.tOwned) Owner.tOwned = [c]; else Owner.tOwned.push(c); else if (!Owner.owned) Owner.owned = [c]; else Owner.owned.push(c); if (ExternalSourceConfig && c.fn) { const sourceFn = c.fn; const [track, trigger] = createSignal(void 0, { equals: false }); const ordinary = ExternalSourceConfig.factory(sourceFn, trigger); onCleanup(() => ordinary.dispose()); let inTransition; const triggerInTransition = () => startTransition(trigger).then(() => { if (inTransition) { inTransition.dispose(); inTransition = void 0; } }); c.fn = (x) => { track(); if (Transition && Transition.running) { if (!inTransition) inTransition = ExternalSourceConfig.factory(sourceFn, triggerInTransition); return inTransition.track(x); } return ordinary.track(x); }; } return c; } function runTop(node) { const runningTransition = Transition && Transition.running; if ((runningTransition ? node.tState : node.state) === 0) return; if ((runningTransition ? node.tState : node.state) === PENDING) return lookUpstream(node); if (node.suspense && untrack(node.suspense.inFallback)) return node.suspense.effects.push(node); const ancestors = [node]; while ((node = node.owner) && (!node.updatedAt || node.updatedAt < ExecCount)) { if (runningTransition && Transition.disposed.has(node)) return; if (runningTransition ? node.tState : node.state) ancestors.push(node); } for (let i = ancestors.length - 1; i >= 0; i--) { node = ancestors[i]; if (runningTransition) { let top = node, prev = ancestors[i + 1]; while ((top = top.owner) && top !== prev) if (Transition.disposed.has(top)) return; } if ((runningTransition ? node.tState : node.state) === STALE) updateComputation(node); else if ((runningTransition ? node.tState : node.state) === PENDING) { const updates = Updates; Updates = null; runUpdates(() => lookUpstream(node, ancestors[0]), false); Updates = updates; } } } function runUpdates(fn, init) { if (Updates) return fn(); let wait = false; if (!init) Updates = []; if (Effects) wait = true; else Effects = []; ExecCount++; try { const res = fn(); completeUpdates(wait); return res; } catch (err) { if (!wait) Effects = null; Updates = null; handleError(err); } } function completeUpdates(wait) { if (Updates) { if (Scheduler && Transition && Transition.running) scheduleQueue(Updates); else runQueue(Updates); Updates = null; } if (wait) return; let res; if (Transition) { if (!Transition.promises.size && !Transition.queue.size) { const sources = Transition.sources; const disposed = Transition.disposed; Effects.push.apply(Effects, Transition.effects); res = Transition.resolve; for (const e of Effects) { "tState" in e && (e.state = e.tState); delete e.tState; } Transition = null; runUpdates(() => { for (const d of disposed) cleanNode(d); for (const v of sources) { v.value = v.tValue; if (v.owned) for (let i = 0, len = v.owned.length; i < len; i++) cleanNode(v.owned[i]); if (v.tOwned) v.owned = v.tOwned; delete v.tValue; delete v.tOwned; v.tState = 0; } setTransPending(false); }, false); } else if (Transition.running) { Transition.running = false; Transition.effects.push.apply(Transition.effects, Effects); Effects = null; setTransPending(true); return; } } const e = Effects; Effects = null; if (e.length) runUpdates(() => runEffects(e), false); if (res) res(); } function runQueue(queue) { for (let i = 0; i < queue.length; i++) runTop(queue[i]); } function scheduleQueue(queue) { for (let i = 0; i < queue.length; i++) { const item = queue[i]; const tasks = Transition.queue; if (!tasks.has(item)) { tasks.add(item); Scheduler(() => { tasks.delete(item); runUpdates(() => { Transition.running = true; runTop(item); }, false); Transition && (Transition.running = false); }); } } } function runUserEffects(queue) { let i, userLength = 0; for (i = 0; i < queue.length; i++) { const e = queue[i]; if (!e.user) runTop(e); else queue[userLength++] = e; } if (sharedConfig.context) { if (sharedConfig.count) { sharedConfig.effects || (sharedConfig.effects = []); sharedConfig.effects.push(...queue.slice(0, userLength)); return; } setHydrateContext(); } if (sharedConfig.effects && (sharedConfig.done || !sharedConfig.count)) { queue = [...sharedConfig.effects, ...queue]; userLength += sharedConfig.effects.length; delete sharedConfig.effects; } for (i = 0; i < userLength; i++) runTop(queue[i]); } function lookUpstream(node, ignore) { const runningTransition = Transition && Transition.running; if (runningTransition) node.tState = 0; else node.state = 0; for (let i = 0; i < node.sources.length; i += 1) { const source = node.sources[i]; if (source.sources) { const state = runningTransition ? source.tState : source.state; if (state === STALE) { if (source !== ignore && (!source.updatedAt || source.updatedAt < ExecCount)) runTop(source); } else if (state === PENDING) lookUpstream(source, ignore); } } } function markDownstream(node) { const runningTransition = Transition && Transition.running; for (let i = 0; i < node.observers.length; i += 1) { const o = node.observers[i]; if (runningTransition ? !o.tState : !o.state) { if (runningTransition) o.tState = PENDING; else o.state = PENDING; if (o.pure) Updates.push(o); else Effects.push(o); o.observers && markDownstream(o); } } } function cleanNode(node) { let i; if (node.sources) while (node.sources.length) { const source = node.sources.pop(), index = node.sourceSlots.pop(), obs = source.observers; if (obs && obs.length) { const n = obs.pop(), s = source.observerSlots.pop(); if (index < obs.length) { n.sourceSlots[s] = index; obs[index] = n; source.observerSlots[index] = s; } } } if (node.tOwned) { for (i = node.tOwned.length - 1; i >= 0; i--) cleanNode(node.tOwned[i]); delete node.tOwned; } if (Transition && Transition.running && node.pure) reset(node, true); else if (node.owned) { for (i = node.owned.length - 1; i >= 0; i--) cleanNode(node.owned[i]); node.owned = null; } if (node.cleanups) { for (i = node.cleanups.length - 1; i >= 0; i--) node.cleanups[i](); node.cleanups = null; } if (Transition && Transition.running) node.tState = 0; else node.state = 0; } function reset(node, top) { if (!top) { node.tState = 0; Transition.disposed.add(node); } if (node.owned) for (let i = 0; i < node.owned.length; i++) reset(node.owned[i]); } function castError(err) { if (err instanceof Error) return err; return new Error(typeof err === "string" ? err : "Unknown error", { cause: err }); } function runErrors(err, fns, owner) { try { for (const f of fns) f(err); } catch (e) { handleError(e, owner && owner.owner || null); } } function handleError(err, owner = Owner) { const fns = ERROR && owner && owner.context && owner.context[ERROR]; const error = castError(err); if (!fns) throw error; if (Effects) Effects.push({ fn() { runErrors(error, fns, owner); }, state: STALE }); else runErrors(error, fns, owner); } var hydrationEnabled = false; function createComponent(Comp, props) { if (hydrationEnabled) { if (sharedConfig.context) { const c = sharedConfig.context; setHydrateContext(nextHydrateContext()); const r = untrack(() => Comp(props || {})); setHydrateContext(c); return r; } } return untrack(() => Comp(props || {})); } function reconcileArrays(parentNode, a, b) { let bLength = b.length, aEnd = a.length, bEnd = bLength, aStart = 0, bStart = 0, after = a[aEnd - 1].nextSibling, map = null; while (aStart < aEnd || bStart < bEnd) { if (a[aStart] === b[bStart]) { aStart++; bStart++; continue; } while (a[aEnd - 1] === b[bEnd - 1]) { aEnd--; bEnd--; } if (aEnd === aStart) { const node = bEnd < bLength ? bStart ? b[bStart - 1].nextSibling : b[bEnd - bStart] : after; while (bStart < bEnd) parentNode.insertBefore(b[bStart++], node); } else if (bEnd === bStart) while (aStart < aEnd) { if (!map || !map.has(a[aStart])) a[aStart].remove(); aStart++; } else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) { const node = a[--aEnd].nextSibling; parentNode.insertBefore(b[bStart++], a[aStart++].nextSibling); parentNode.insertBefore(b[--bEnd], node); a[aEnd] = b[bEnd]; } else { if (!map) { map = new Map(); let i = bStart; while (i < bEnd) map.set(b[i], i++); } const index = map.get(a[aStart]); if (index != null) if (bStart < index && index < bEnd) { let i = aStart, sequence = 1, t; while (++i < aEnd && i < bEnd) { if ((t = map.get(a[i])) == null || t !== index + sequence) break; sequence++; } if (sequence > index - bStart) { const node = a[aStart]; while (bStart < index) parentNode.insertBefore(b[bStart++], node); } else parentNode.replaceChild(b[bStart++], a[aStart++]); } else aStart++; else a[aStart++].remove(); } } } var $$EVENTS = "_$DX_DELEGATE"; function render(code, element, init, options = {}) { let disposer; createRoot((dispose) => { disposer = dispose; element === document ? code() : insert(element, code(), element.firstChild ? null : void 0, init); }, options.owner); return () => { disposer(); element.textContent = ""; }; } function template(html, isImportNode, isSVG, isMathML) { let node; const create = () => { const t = isMathML ? document.createElementNS("http://www.w3.org/1998/Math/MathML", "template") : document.createElement("template"); t.innerHTML = html; return isSVG ? t.content.firstChild.firstChild : isMathML ? t.firstChild : t.content.firstChild; }; const fn = isImportNode ? () => untrack(() => document.importNode(node || (node = create()), true)) : () => (node || (node = create())).cloneNode(true); fn.cloneNode = fn; return fn; } function delegateEvents(eventNames, document = window.document) { const e = document[$$EVENTS] || (document[$$EVENTS] = new Set()); for (let i = 0, l = eventNames.length; i < l; i++) { const name = eventNames[i]; if (!e.has(name)) { e.add(name); document.addEventListener(name, eventHandler); } } } function className(node, value) { if (isHydrating(node)) return; if (value == null) node.removeAttribute("class"); else node.className = value; } function insert(parent, accessor, marker, initial) { if (marker !== void 0 && !initial) initial = []; if (typeof accessor !== "function") return insertExpression(parent, accessor, initial, marker); createRenderEffect((current) => insertExpression(parent, accessor(), current, marker), initial); } function isHydrating(node) { return !!sharedConfig.context && !sharedConfig.done && (!node || node.isConnected); } function eventHandler(e) { if (sharedConfig.registry && sharedConfig.events) { if (sharedConfig.events.find(([el, ev]) => ev === e)) return; } let node = e.target; const key = `$$${e.type}`; const oriTarget = e.target; const oriCurrentTarget = e.currentTarget; const retarget = (value) => Object.defineProperty(e, "target", { configurable: true, value }); const handleNode = () => { const handler = node[key]; if (handler && !node.disabled) { const data = node[`${key}Data`]; data !== void 0 ? handler.call(node, data, e) : handler.call(node, e); if (e.cancelBubble) return; } node.host && typeof node.host !== "string" && !node.host._$host && node.contains(e.target) && retarget(node.host); return true; }; const walkUpTree = () => { while (handleNode() && (node = node._$host || node.parentNode || node.host)); }; Object.defineProperty(e, "currentTarget", { configurable: true, get() { return node || document; } }); if (sharedConfig.registry && !sharedConfig.done) sharedConfig.done = _$HY.done = true; if (e.composedPath) { const path = e.composedPath(); retarget(path[0]); for (let i = 0; i < path.length - 2; i++) { node = path[i]; if (!handleNode()) break; if (node._$host) { node = node._$host; walkUpTree(); break; } if (node.parentNode === oriCurrentTarget) break; } } else walkUpTree(); retarget(oriTarget); } function insertExpression(parent, value, current, marker, unwrapArray) { const hydrating = isHydrating(parent); if (hydrating) { !current && (current = [...parent.childNodes]); let cleaned = []; for (let i = 0; i < current.length; i++) { const node = current[i]; if (node.nodeType === 8 && node.data.slice(0, 2) === "!$") node.remove(); else cleaned.push(node); } current = cleaned; } while (typeof current === "function") current = current(); if (value === current) return current; const t = typeof value, multi = marker !== void 0; parent = multi && current[0] && current[0].parentNode || parent; if (t === "string" || t === "number") { if (hydrating) return current; if (t === "number") { value = value.toString(); if (value === current) return current; } if (multi) { let node = current[0]; if (node && node.nodeType === 3) node.data !== value && (node.data = value); else node = document.createTextNode(value); current = cleanChildren(parent, current, marker, node); } else if (current !== "" && typeof current === "string") current = parent.firstChild.data = value; else current = parent.textContent = value; } else if (value == null || t === "boolean") { if (hydrating) return current; current = cleanChildren(parent, current, marker); } else if (t === "function") { createRenderEffect(() => { let v = value(); while (typeof v === "function") v = v(); current = insertExpression(parent, v, current, marker); }); return () => current; } else if (Array.isArray(value)) { const array = []; const currentArray = current && Array.isArray(current); if (normalizeIncomingArray(array, value, current, unwrapArray)) { createRenderEffect(() => current = insertExpression(parent, array, current, marker, true)); return () => current; } if (hydrating) { if (!array.length) return current; if (marker === void 0) return current = [...parent.childNodes]; let node = array[0]; if (node.parentNode !== parent) return current; const nodes = [node]; while ((node = node.nextSibling) !== marker) nodes.push(node); return current = nodes; } if (array.length === 0) { current = cleanChildren(parent, current, marker); if (multi) return current; } else if (currentArray) if (current.length === 0) appendNodes(parent, array, marker); else reconcileArrays(parent, current, array); else { current && cleanChildren(parent); appendNodes(parent, array); } current = array; } else if (value.nodeType) { if (hydrating && value.parentNode) return current = multi ? [value] : value; if (Array.isArray(current)) { if (multi) return current = cleanChildren(parent, current, marker, value); cleanChildren(parent, current, null, value); } else if (current == null || current === "" || !parent.firstChild) parent.appendChild(value); else parent.replaceChild(value, parent.firstChild); current = value; } return current; } function normalizeIncomingArray(normalized, array, current, unwrap) { let dynamic = false; for (let i = 0, len = array.length; i < len; i++) { let item = array[i], prev = current && current[normalized.length], t; if (item == null || item === true || item === false); else if ((t = typeof item) === "object" && item.nodeType) normalized.push(item); else if (Array.isArray(item)) dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic; else if (t === "function") if (unwrap) { while (typeof item === "function") item = item(); dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic; } else { normalized.push(item); dynamic = true; } else { const value = String(item); if (prev && prev.nodeType === 3 && prev.data === value) normalized.push(prev); else normalized.push(document.createTextNode(value)); } } return dynamic; } function appendNodes(parent, array, marker = null) { for (let i = 0, len = array.length; i < len; i++) parent.insertBefore(array[i], marker); } function cleanChildren(parent, current, marker, replacement) { if (marker === void 0) return parent.textContent = ""; const node = replacement || document.createTextNode(""); if (current.length) { let inserted = false; for (let i = current.length - 1; i >= 0; i--) { const el = current[i]; if (node !== el) { const isParent = el.parentNode === parent; if (!inserted && !i) isParent ? parent.replaceChild(node, el) : parent.insertBefore(node, marker); else isParent && el.remove(); } else inserted = true; } } else parent.insertBefore(node, marker); return [node]; } var ENCRYPTED_FONT_CLASS = "xuetangx-com-encrypted-font"; var FONT_URL_PATTERN = /(https:\/\/[^"'\s)]*fe_font\/product\/exam_font_[\w-]+\.ttf)/i; var ROOT_ID = "fuck-yuketang-font-root"; var STATUS_EVENT = "fuck-yuketang-font:status"; var CONTROL_EVENT = "fuck-yuketang-font:control"; function createStatusBus(target = window) { return { emit: (message, decryptedCount, status = {}) => { target.dispatchEvent(new CustomEvent(STATUS_EVENT, { detail: { message, decryptedCount, ...status } })); } }; } var BLOCK_TAGS = new Set([ "ADDRESS", "ARTICLE", "ASIDE", "BLOCKQUOTE", "DD", "DIV", "DL", "DT", "FIELDSET", "FIGCAPTION", "FIGURE", "FOOTER", "FORM", "H1", "H2", "H3", "H4", "H5", "H6", "HEADER", "HR", "LI", "MAIN", "NAV", "OL", "P", "PRE", "SECTION", "TABLE", "TBODY", "TD", "TFOOT", "TH", "THEAD", "TR", "UL" ]); var SKIPPED_TAGS = new Set([ "SCRIPT", "STYLE", "NOSCRIPT", "TEMPLATE" ]); var PANEL_ATTRIBUTE = "data-fuck-yuketang-font-panel"; var EXERCISE_END_LINES = new Set([ "上一题", "已提交", "下一题", "批注" ]); function extractCopyablePlainText(root = document.body) { return formatExerciseLines(extractExerciseLines(collectText(root).split("\n").map((line) => normalizeInlineWhitespace(line)).filter((line) => line.length > 0))).join("\n"); } function collectText(node) { if (node.nodeType === Node.TEXT_NODE) return node.textContent ?? ""; if (!(node instanceof Element || node instanceof Document || node instanceof DocumentFragment)) return ""; if (node instanceof Element) { if (node.id === "fuck-yuketang-font-root" || node.hasAttribute(PANEL_ATTRIBUTE) || SKIPPED_TAGS.has(node.tagName)) return ""; if (node.tagName === "BR") return "\n"; } const childText = Array.from(node.childNodes).map(collectText).join(""); if (!(node instanceof Element) || !BLOCK_TAGS.has(node.tagName)) return childText; return `\n${childText}\n`; } function normalizeInlineWhitespace(text) { return text.replace(/[ \t\f\v\u00A0]+/g, " ").trim(); } function extractExerciseLines(lines) { const startIndex = lines.findIndex(isQuestionHeadingLine); if (startIndex === -1) return lines; const endIndex = lines.findIndex((line, index) => index > startIndex && isExerciseEndLine(line)); if (endIndex === -1) return lines.slice(startIndex); return lines.slice(startIndex, endIndex); } function isQuestionHeadingLine(line) { return /^\d+\..*题$/.test(line); } function isExerciseEndLine(line) { return line.startsWith("本题得分:") || line.startsWith("正确答案:") || EXERCISE_END_LINES.has(line); } function formatExerciseLines(lines) { const formatted = []; for (let index = 0; index < lines.length; index += 1) { const line = lines[index] ?? ""; const nextLine = lines[index + 1]; const heading = /^(\d+)\.(.*题)$/.exec(line); if (heading !== null) { const questionNumber = heading[1] ?? ""; const questionType = (heading[2] ?? "").trim(); if (nextLine !== void 0 && /^\(.+分\)$/.test(nextLine)) { formatted.push(`${questionNumber}. ${questionType} ${nextLine}`); index += 1; } else formatted.push(`${questionNumber}. ${questionType}`); continue; } if (/^[A-Z]$/.test(line) && nextLine !== void 0) { formatted.push(`${line}. ${nextLine}`); index += 1; continue; } formatted.push(line); } return formatted; } var StatusPanel_module_default = { panel: "_panel_13hok_1", title: "_title_13hok_21", description: "_description_13hok_25", counter: "_counter_13hok_30", actions: "_actions_13hok_35", action: "_action_13hok_35", secondaryAction: "_secondaryAction_13hok_57" }; var _tmpl$ = template(`