// ==UserScript== // @name 题海 x 划词搜题 // @version 3.0.2 // @namespace 题海官方团队 // @description 所有网页均支持划词搜题,支持截图搜题,也可输入文本搜题悬浮窗可拖动可关闭,可个性化设置解除网页禁止复制限制适用于各类问答,网课问题,竞赛问题,专业术语,业务名称,情景问题,在线作业等 // @author 题海官方团队 // @match *://*/* // @grant GM_info // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_getResourceText // @run-at document-end // @connect itihey.com // @connect appwk.baidu.com // @resource Table https://tihai.oss-cn-hangzhou.aliyuncs.com/cx_table.json // @require https://registry.npmmirror.com/html2canvas-pro/2.0.4/files/dist/html2canvas-pro.min.js // @antifeature membership 关注微信公众号 // @icon data:image/png;base64,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 // ==/UserScript== ; (function() { "use strict"; const KEY = "hc3_config"; const DEFAULTS = { auto_search: false, cut_search: true, remove_limit: true, fixed_modal: true, out_iframe: true, auto_close: true }; function load() { let saved = {}; try { saved = JSON.parse(GM_getValue(KEY) || "{}"); } catch (e) {} const old = GM_getValue("defaultConfig"); if (old !== undefined) { try { saved = Object.assign({}, JSON.parse(old), saved); } catch (e) {} GM_deleteValue("defaultConfig"); } const cfg = {}; for (const k in DEFAULTS) cfg[k] = typeof saved[k] === "boolean" ? saved[k] : DEFAULTS[k]; return cfg; } const config = load(); GM_setValue(KEY, JSON.stringify(config)); function setConfig(key, value, persist) { config[key] = value; if (persist !== false) GM_setValue(KEY, JSON.stringify(config)); } const POS_KEY = "hc3_lock_pos"; const lockPos = { get() { try { return JSON.parse(GM_getValue(POS_KEY) || "null"); } catch (e) { return null; } }, set(p) { GM_setValue(POS_KEY, JSON.stringify(p)); }, clear() { GM_deleteValue(POS_KEY); } }; const auth = { token() { return typeof GM_getValue("token") === "string" ? GM_getValue("token") : ""; }, name() { return GM_getValue("id") || ""; }, uid() { return GM_getValue("uid") || ""; }, save(token, name, uid) { GM_setValue("token", token); GM_setValue("id", name || ""); if (uid !== undefined) GM_setValue("uid", uid || ""); }, clear() { GM_setValue("token", ""); GM_setValue("id", ""); GM_setValue("uid", ""); } }; const BASE = "https://platform.itihey.com"; function NeedLoginError() { this.name = "NeedLoginError"; this.message = "请先登录"; } NeedLoginError.prototype = Object.create(Error.prototype); function request(opt) { return new Promise(function(resolve, reject) { const headers = { "Content-Type": "application/json;charset=utf-8", Version: GM_info.script.version }; const token = auth.token(); if (token) headers["Authorization"] = "Bearer " + token; GM_xmlhttpRequest({ method: opt.method || "GET", url: opt.url, headers: headers, data: opt.body === undefined ? undefined : JSON.stringify(opt.body), timeout: 15e3, onload(r) { if (r.status === 401) return reject(new NeedLoginError()); let data = null; try { data = JSON.parse(r.responseText); } catch (e) {} if (r.status >= 400 || data === null) return reject(new Error("请求失败(" + r.status + "),请稍后重试")); resolve(data); }, onerror() { reject(new Error("网络错误,请稍后重试")); }, ontimeout() { reject(new Error("请求超时,请稍后重试")); } }); }); } const api = { queryAnswer(word) { return request({ method: "POST", url: BASE + "/consumer/ws/huaci", body: { word: word } }); }, getPayUrl(checkIndex) { return request({ url: BASE + "/consumer/ws/pay?checkIndex=" + checkIndex }); }, unlockLimit() { return request({ method: "POST", url: BASE + "/consumer/ws/unlock" }); }, loginQR() { return request({ url: BASE + "/consumer/wechat/qrcode" }); }, loginCheck(id) { return request({ url: BASE + "/consumer/wechat/check?id=" + encodeURIComponent(id) }); }, profile() { return request({ url: BASE + "/consumer/profile" }); }, payStatus(orderNo) { return request({ url: BASE + "/consumer/pay/status?order_no=" + encodeURIComponent(orderNo) }); } }; function ocrBase64(base64) { return new Promise(function(resolve, reject) { GM_xmlhttpRequest({ method: "POST", url: "https://appwk.baidu.com/naapi/api/totxt", headers: { "Content-type": "application/x-www-form-urlencoded" }, responseType: "json", data: "image=" + encodeURIComponent(base64), onload(r) { try { resolve(r.response.words_result.map(function(i) { return i.words; }).join("")); } catch (e) { resolve(""); } }, onerror() { reject(new Error("OCR 请求失败")); }, ontimeout() { reject(new Error("OCR 请求超时")); } }); }); } const PANEL_CSS = ` :host { all: initial; } * { box-sizing: border-box; margin: 0; padding: 0; font-family: -apple-system,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',sans-serif; } .panel { width: 400px; background: #fff; border: 1px solid #e3e6f0; border-radius: 12px; box-shadow: 0 16px 100px rgba(0,0,0,.2), 0 4px 16px rgba(0,0,0,.08); overflow: hidden; font-size: 14px; color: #333; transform: scale(.92); opacity: 0; transition: transform .12s ease-out, opacity .12s ease-out; } .panel.in { transform: scale(1); opacity: 1; } .hd { display: flex; align-items: center; gap: 6px; padding: 8px 12px; background: #f6f8fa; border-bottom: 1px solid #eef0f4; cursor: move; user-select: none; font-size: 13px; color: #586069; } .hd .logo { width: 18px; height: 18px; border-radius: 50%; flex: none; } .hd .title { font-weight: 600; color: #527aef; cursor: pointer; } .hd .sp { flex: 1; } .hd button { all: unset; cursor: pointer; padding: 2px 8px; border-radius: 4px; font-size: 13px; color: #586069; } .hd button:hover { background: rgba(27,31,35,.08); } .hd .lock { padding: 3px 6px; opacity: .35; } .hd .lock:hover { opacity: .7; } .hd .lock svg { width: 14px; height: 14px; display: block; fill: currentColor; } .hd .lock .i-on { display: none; } .hd .lock.on { opacity: 1; color: #527aef; } .hd .lock.on .i-on { display: block; } .hd .lock.on .i-off { display: none; } .hd .close { font-size: 16px; line-height: 1; } .bd { max-height: 480px; overflow-y: auto; padding: 14px 15px; background: #fff; } .bd::-webkit-scrollbar { width: 6px; } .bd::-webkit-scrollbar-thumb { background: #d8dce6; border-radius: 3px; } .bd::-webkit-scrollbar-thumb:hover { background: #c2c8d6; } /* 搜索区:v2 原版布局——灰底圆角输入框 + 整宽蓝色按钮 */ .searchbar { margin-bottom: 12px; } .searchbar textarea { display: block; width: 100%; resize: vertical; min-height: 76px; max-height: 160px; padding: 8px 10px; border: 1px solid transparent; border-radius: 10px; outline: none; font-size: 14px; line-height: 1.6; color: #333; background: #f5f6fa; transition: border-color .15s, box-shadow .15s; } .searchbar textarea:focus { border-color: #527aef; box-shadow: 0 0 0 2px rgba(82,122,239,.15); background: #fff; } .searchbar .btn { margin-top: 8px; width: 100%; } .btn { all: unset; display: block; cursor: pointer; padding: 8px 0; border-radius: 8px; font-size: 15px; background: #527aef; color: #f0f8ff; text-align: center; transition: background .12s; } .btn:hover { background: #4169e0; } .btn:active { background: rgba(56,97,214,.9); } .btn.ghost { background: #fff; color: #527aef; border: 1px solid #527aef; } .btn.ghost:hover { background: #f0f4fe; } .btn.block { margin: 8px auto 0; width: auto; min-width: 160px; padding: 8px 18px; } /* 结果卡片:v2 原版「题目一」标题 + 蓝色渐变下划线条 */ .item { background: #fff; border: 1px solid #f0f1f5; border-radius: 10px; padding: 12px 14px 4px; margin-bottom: 12px; transition: box-shadow .15s, border-color .15s; } .item:hover { border-color: #dfe6fa; box-shadow: 0 4px 14px rgba(82,122,239,.08); } .item .ttl-row { display: flex; align-items: baseline; gap: 8px; } .item .ttl { color: #222; font-size: 16px; font-weight: 600; line-height: 22px; white-space: nowrap; } .item .ttl .bar { display: block; margin-top: -7px; width: 24px; height: 6px; border-radius: 3px; background: linear-gradient(90deg, rgba(82,122,239,0) 0%, #527aef 100%); } .item .badge { font-size: 11px; color: #527aef; background: #eef2fe; border-radius: 3px; padding: 1px 6px; white-space: nowrap; } .item .q { margin: 10px 1px 0; font-size: 14px; line-height: 1.6; color: #666; white-space: pre-wrap; word-wrap: break-word; } .item .opt { margin: 4px 1px 0; font-size: 14px; line-height: 1.6; color: #666; } .item .opt.hit { color: #527aef; font-weight: 600; } .item .ans-hd { display: flex; align-items: center; gap: 5px; margin-top: 10px; padding: 10px 1px 8px; color: #222; font-size: 14px; font-weight: 500; border-top: 1px solid #f5f5f5; } .item .ans-hd svg { width: 14px; height: 14px; flex: none; } .item .ans { margin: 0 1px 12px; padding: 10px 14px; font-size: 14px; line-height: 1.6; color: #666; background: #f5f6fa; border-radius: 6px; white-space: pre-wrap; word-wrap: break-word; } .item .ans b { color: #527aef; font-weight: 600; } .empty { text-align: center; color: #9ca3af; padding: 34px 0 30px; font-size: 13px; line-height: 2; } /* 居中提示/二维码/加载 */ .center { text-align: center; padding: 14px 6px; } .center .tip { font-size: 13px; color: #586069; line-height: 1.8; margin-bottom: 8px; } .center .qr { width: 190px; height: 190px; border: 1px solid #eef0f4; border-radius: 8px; } .center .sub { font-size: 12px; color: #9ca3af; margin-top: 6px; } .center .amount { font-size: 20px; font-weight: 700; color: #527aef; margin: 4px 0; } .spin { display: inline-block; width: 18px; height: 18px; border-radius: 50%; margin: 24px auto; border: 2px solid #527aef; border-color: #527aef transparent #527aef transparent; animation: hcspin 1.2s linear infinite; } @keyframes hcspin { to { transform: rotate(360deg); } } /* 套餐 */ .plans { display: flex; gap: 8px; margin-top: 10px; } .plan { flex: 1; border: 1px solid #e3e6f0; border-radius: 8px; padding: 10px 4px; cursor: pointer; text-align: center; transition: border-color .12s, background .12s, box-shadow .12s; } .plan:hover { border-color: #527aef; background: #f0f4fe; box-shadow: 0 2px 8px rgba(82,122,239,.12); } .plan .nm { font-size: 12px; color: #586069; } .plan .pr { font-size: 17px; font-weight: 700; color: #527aef; margin-top: 2px; } /* 设置 */ .setting-row { display: flex; align-items: flex-start; gap: 8px; padding: 9px 2px; border-bottom: 1px solid #f3f4f8; cursor: pointer; } .setting-row:last-child { border-bottom: none; } .setting-row input { margin-top: 3px; accent-color: #527aef; } .setting-row .nm { font-size: 13px; color: #24292e; } .setting-row .desc { font-size: 12px; color: #9ca3af; line-height: 1.5; margin-top: 2px; } .setting-row .desc em { color: #d73a49; font-style: normal; } .account-row { display: flex; align-items: center; justify-content: space-between; margin-top: 8px; padding: 12px 2px 4px; border-top: 1px solid #f3f4f8; font-size: 13px; color: #24292e; } .account-row .uid { color: #9ca3af; font-size: 12px; margin-left: 8px; user-select: text; } .link-btn { all: unset; cursor: pointer; font-size: 13px; color: #527aef; padding: 2px 6px; border-radius: 4px; } .link-btn:hover { background: #f0f4fe; } `; const LOGO = "data:image/webp;base64,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"; const HOST_ID = "hc-search-host"; function findTopWindow() { const _self = unsafeWindow; let t = _self; if (!config.out_iframe) return t; try { while (t !== _self.top) { t = t.parent.document ? t.parent : _self.top; if (t.location.pathname === "/mycourse/studentstudy") break; } } catch (e) { t = _self; } return t; } const panel = { win: null, host: null, body: null, onAction: null, init(onAction) { this.win = findTopWindow(); this.onAction = onAction; const self = this; this.win.document.addEventListener("mousedown", function(e) { if (config.auto_close && self.host && !self.host.contains(e.target)) self.close(); }); }, show(html, reposition, mouse) { const doc = this.win.document; let host = doc.getElementById(HOST_ID); if (!host) { host = doc.createElement("div"); host.id = HOST_ID; host.style.zIndex = "2147483647"; doc.body.appendChild(host); const shadow = host.attachShadow({ mode: "open" }); const style = doc.createElement("style"); style.textContent = PANEL_CSS; shadow.appendChild(style); const wrap = doc.createElement("div"); wrap.className = "panel"; wrap.innerHTML = '
' + '" + '' + '题海 × 划词搜题' + '' + '' + '' + '
'; shadow.appendChild(wrap); this.bindShell(shadow, wrap); host._shadow = shadow; } this.host = host; const shadow = host._shadow || host.shadowRoot; this.body = shadow.querySelector("[data-ref=body]"); this.body.innerHTML = html; this.syncHeader(shadow); const locked = config.auto_close === false; if (!host.style.left && locked && lockPos.get()) { this.applyLockPos(host); } else if (reposition && !locked || !host.style.left) { this.position(host, mouse); } const wasHidden = host.style.display !== "block"; host.style.display = "block"; const wrap2 = shadow.querySelector(".panel"); if (wasHidden) { wrap2.classList.remove("in"); void wrap2.offsetWidth; } wrap2.classList.add("in"); }, bindShell(shadow, wrap) { const self = this; shadow.addEventListener("click", function(e) { const el = e.target.closest ? e.target.closest("[data-action]") : null; if (el && self.onAction) self.onAction(el.getAttribute("data-action"), el); }); shadow.addEventListener("change", function(e) { const key = e.target.getAttribute && e.target.getAttribute("data-config"); if (key) setConfig(key, e.target.checked); }); const drag = wrap.querySelector("[data-ref=drag]"); const doc = this.win.document; drag.addEventListener("mousedown", function(e) { if (e.target.closest("[data-action]")) return; e.preventDefault(); const host = self.host; const sx = e.clientX, sy = e.clientY; const ox = host.offsetLeft, oy = host.offsetTop; function move(ev) { host.style.left = ox + ev.clientX - sx + "px"; host.style.top = oy + ev.clientY - sy + "px"; } function up() { doc.removeEventListener("mousemove", move); doc.removeEventListener("mouseup", up); if (config.auto_close === false) self.saveLockPos(); } doc.addEventListener("mousemove", move); doc.addEventListener("mouseup", up); }); }, syncHeader(shadow) { shadow.querySelector(".lock").classList.toggle("on", config.auto_close === false); }, saveLockPos() { if (!this.host) return; lockPos.set({ left: this.host.offsetLeft, top: this.host.offsetTop, fixed: !!config.fixed_modal }); }, applyLockPos(host) { const p = lockPos.get(); const win = this.win; host.style.position = config.fixed_modal ? "fixed" : "absolute"; const x = Math.min(Math.max(0, p.left), Math.max(0, win.innerWidth - 60)); let y = Math.max(0, p.top); if (config.fixed_modal) y = Math.min(y, Math.max(0, win.innerHeight - 40)); host.style.left = x + "px"; host.style.top = y + "px"; }, toPanelCoords(mouse) { let x = mouse.x, y = mouse.y; try { let w = unsafeWindow; while (w !== this.win && w.frameElement) { const r = w.frameElement.getBoundingClientRect(); x += r.left; y += r.top; w = w.parent; } } catch (e) {} return { x: x, y: y }; }, position(host, mouse) { const win = this.win; const m = mouse ? this.toPanelCoords(mouse) : { x: win.innerWidth / 2 - 200, y: 80 }; const w = 400, h = 320, gap = 20; let x = m.x + gap; if (x + w > win.innerWidth) x = Math.max(8, m.x - w - gap); let y = m.y - h - gap; if (y < 0) y = m.y + gap; if (y + h > win.innerHeight) y = Math.max(8, win.innerHeight - h - gap); host.style.position = config.fixed_modal ? "fixed" : "absolute"; if (!config.fixed_modal) { x += win.pageXOffset; y += win.pageYOffset; } host.style.left = x + "px"; host.style.top = y + "px"; }, setBody(html) { if (this.body) this.body.innerHTML = html; }, bodyHtml() { return this.body ? this.body.innerHTML : ""; }, isVisible() { return !!(this.host && this.host.style.display === "block"); }, setSettingsLabel(text) { const shadow = this.host && (this.host._shadow || this.host.shadowRoot); const btn = shadow && shadow.querySelector("[data-ref=settings-btn]"); if (btn) btn.textContent = text; }, query(sel) { return this.body ? this.body.querySelector(sel) : null; }, close() { if (this.host) this.host.style.display = "none"; if (this.onAction) this.onAction("_closed"); }, toggleLock() { setConfig("auto_close", !config.auto_close); if (config.auto_close === false) this.saveLockPos(); else lockPos.clear(); const shadow = this.host && (this.host._shadow || this.host.shadowRoot); if (shadow) this.syncHeader(shadow); } }; function esc(s) { return String(s === undefined || s === null ? "" : s).replace(/[&<>"']/g, function(c) { return { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[c]; }); } const TYPE_NAMES = { 0: "单选题", 1: "多选题", 2: "填空题", 3: "判断题", 4: "简答题", 5: "名词解释", 6: "论述题", 7: "计算题", 8: "其它", 9: "分录题", 10: "资料题", 11: "连线题", 13: "排序题", 14: "完形填空", 15: "阅读理解", 18: "口语题", 19: "听力题" }; function toCN(num) { const d = [ "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" ]; if (num < 10) return d[num]; if (num < 20) return num === 10 ? "十" : "十" + d[num % 10]; return d[Math.floor(num / 10)] + "十" + (num % 10 ? d[num % 10] : ""); } const ANS_ICON = '' + ''; function searchBar(word) { return '"; } function loading() { return '
正在搜索中…
'; } function results(data) { let html = searchBar(data.question || ""); const list = data.list || []; if (!list.length) { html += '
暂时没有搜索到这道题哦
可修改题干后重试
'; return html; } for (let i = 0; i < list.length; i++) { const it = list[i]; const answers = it.answer || []; let opts = ""; for (let j = 0; j < (it.options || []).length; j++) { const o = it.options[j]; const letter = String.fromCharCode(65 + j); const hit = answers.indexOf(o) !== -1 || answers.indexOf(letter) !== -1; opts += '
' + letter + ". " + esc(o) + "
"; } html += '
' + '
' + '题目' + toCN(i + 1) + '' + '' + (TYPE_NAMES[it.type] || "其它") + "" + "
" + '
' + esc(it.question) + "
" + opts + (answers.length ? '
' + ANS_ICON + "答案
" + '
' + esc(answers.join(";")) + "
" : "") + "
"; } return html; } function manual() { return searchBar("") + '
输入题目后点击搜索
'; } function login(qrImage) { return '
' + '
微信扫码关注公众号即可登录
' + '登录二维码' + '
扫码后自动登录并继续搜题
' + "
"; } function pay(resp) { let html = '
' + esc(resp.tip || "搜题次数已用完") + "
"; if (resp.needMember) { html += '
' + '
体验 1 天
¥1
' + '
会员 30 天
¥9.9
' + '
永久会员
¥29.9
' + "
"; } else { html += ''; } return html; } function payQR(order) { return '
' + '
微信扫码支付
' + '
¥' + esc(order.amount) + "
" + '支付二维码' + '
支付成功后自动继续搜题
' + "
"; } function upgrade(resp) { return '
' + '
' + esc(resp.tip || "当前脚本版本过低,请升级") + "
" + '' + "
"; } function message(text) { return '
' + esc(text) + "
" + '
'; } const SETTING_ITEMS = [ { key: "auto_search", name: "划词后自动搜题", desc: "打开后划词直接搜题;关闭则先显示搜题图标,点击图标再搜" }, { key: "cut_search", name: "截图搜题", desc: "同时按下 T+H(题海首拼),框选题目区域 OCR 识别后搜题,解决无法复制的页面" }, { key: "remove_limit", name: "解除网站的禁止复制限制", desc: "解除部分网站禁止划词/复制的限制,如有冲突可关闭(刷新页面后生效)" }, { key: "fixed_modal", name: "基于浏览器窗口定位", desc: "搜索窗口固定于浏览器窗口,不随页面滚动" }, { key: "out_iframe", name: "寻找最外层 iframe", desc: "搜题窗口悬浮到最外层,可全窗口拖动;个别网站不显示窗口时请关闭(刷新页面后生效)" } ]; function settings(config, user) { let html = ""; for (let i = 0; i < SETTING_ITEMS.length; i++) { const it = SETTING_ITEMS[i]; html += '"; } if (user && (user.name || user.uid)) { html += '
' + '' + esc(user.name || "已登录") + (user.uid ? 'ID ' + esc(user.uid) + "" : "") + "" + '' + "
"; } else { html += '
未登录
'; } return html; } let lastWord = ""; let lastMouse = null; let pollTimer = null; let inSettings = false; let prevHtml = ""; function stopPoll() { if (pollTimer) { clearInterval(pollTimer); pollTimer = null; } } function exitSettings() { if (!inSettings) return; inSettings = false; panel.setSettingsLabel("设置"); } function initApp() { panel.init(function(action, el) { if (action === "_closed") return stopPoll(); if (action === "close") return panel.close(); if (action === "lock") return panel.toggleLock(); if (action === "open-home") return window.open("https://www.itihey.com"); if (action === "open-url") return window.open(el.getAttribute("data-url") || "https://www.itihey.com"); if (action === "settings") return openSettings(); if (action === "logout") { auth.clear(); return showLogin(); } if (action === "search") { const ta = panel.query("[data-ref=word]"); const word = ta ? ta.value.trim() : lastWord; if (word) search(word); return; } if (action === "buy") return createOrder(api.getPayUrl(el.getAttribute("data-index"))); if (action === "unlock") return createOrder(api.unlockLimit()); }); } function search(word, mouse) { if (!word) return; lastWord = word; if (mouse) lastMouse = mouse; stopPoll(); exitSettings(); panel.show(loading(), !!mouse, lastMouse); api.queryAnswer(word).then(function(res) { if (res.needUpgrade) return panel.setBody(upgrade(res)); if (res.needPay) return panel.setBody(pay(res)); panel.setBody(results(res)); }).catch(function(err) { if (err instanceof NeedLoginError) return showLogin(); panel.setBody(message(err.message)); }); } function openManual() { stopPoll(); exitSettings(); panel.show(manual(), true, lastMouse); } function openSettings() { stopPoll(); if (inSettings && panel.isVisible()) return closeSettings(); if (!inSettings) prevHtml = panel.bodyHtml(); inSettings = true; panel.show(settings(config, { name: auth.name(), uid: auth.uid() }), false); panel.setSettingsLabel("返回"); if (auth.token()) { api.profile().then(function(p) { auth.save(auth.token(), p.name || "", p.id || ""); if (inSettings) panel.setBody(settings(config, { name: auth.name(), uid: auth.uid() })); }).catch(function() {}); } } function closeSettings() { inSettings = false; panel.show(prevHtml || manual(), false); panel.setSettingsLabel("设置"); } function showLogin() { stopPoll(); exitSettings(); panel.show(loading(), false); api.loginQR().then(function(qr) { panel.setBody(login(qr.image)); pollTimer = setInterval(function() { api.loginCheck(qr.id).then(function(r) { if (r.status !== "success" || !r.token) return; stopPoll(); auth.save(r.token, ""); api.profile().then(function(p) { auth.save(r.token, p.name || "已登录", p.id || ""); }).catch(function() {}); if (lastWord) search(lastWord); else openManual(); }).catch(function() {}); }, 1500); }).catch(function(err) { panel.setBody(message(err.message)); }); } function createOrder(orderPromise) { stopPoll(); panel.setBody(loading()); orderPromise.then(function(order) { if (!order.order_no) throw new Error(order.tip || "下单失败,请稍后再试"); panel.setBody(payQR(order)); pollTimer = setInterval(function() { api.payStatus(order.order_no).then(function(r) { if (r.status === 1) { stopPoll(); if (lastWord) search(lastWord); else openManual(); } }).catch(function() {}); }, 3e3); }).catch(function(err) { if (err instanceof NeedLoginError) return showLogin(); panel.setBody(message(err.message)); }); } const ICON_ID = "hc-search-icon"; function initSelection(onSearch) { const icon = document.createElement("img"); icon.id = ICON_ID; icon.src = LOGO; icon.setAttribute("style", "all:initial;position:absolute;z-index:2147483647;display:none;width:50px;height:50px;" + "cursor:pointer;user-select:none;border-radius:50%;" + "filter:drop-shadow(0 4px 10px rgba(82,122,239,.4));" + "transition:transform .15s ease-out;"); icon.addEventListener("mouseenter", function() { icon.style.transform = "scale(1.1)"; }); icon.addEventListener("mouseleave", function() { icon.style.transform = ""; }); document.body.appendChild(icon); function hideIcon() { icon.style.display = "none"; } icon.addEventListener("mousedown", function(e) { e.preventDefault(); e.stopPropagation(); }); icon.addEventListener("click", function(e) { e.stopPropagation(); const text = window.getSelection().toString().trim(); hideIcon(); if (text) onSearch(text, { x: e.clientX, y: e.clientY }); }); let selecting = false; document.addEventListener("selectionchange", function() { selecting = true; }); document.addEventListener("mousedown", function(e) { selecting = false; if (e.target !== icon && !icon.contains(e.target)) hideIcon(); }); document.addEventListener("mouseup", function(e) { setTimeout(function() { if (!selecting) return; if (e.target === icon || icon.contains(e.target)) return; if (e.target.id === HOST_ID) return; const tag = e.target.tagName; if (tag === "INPUT" || tag === "TEXTAREA") return; const text = window.getSelection().toString().trim(); if (!text) return; selecting = false; if (config.auto_search) { onSearch(text, { x: e.clientX, y: e.clientY }); } else { icon.style.display = "block"; icon.style.left = e.pageX + "px"; icon.style.top = e.pageY + 12 + "px"; } }, 1); }); } const OVERLAY_HTML = '
' + '
' + '
请框选想要搜索的题目,Esc 取消
'; function initCutSearch(onText) { const keys = {}; let overlay = null, box = null, dragging = false, sx = 0, sy = 0; function cleanup() { dragging = false; document.removeEventListener("mousedown", down); document.removeEventListener("mousemove", move); document.removeEventListener("mouseup", up); document.removeEventListener("mouseleave", cleanup); if (overlay) { overlay.remove(); overlay = null; box = null; } } function down(e) { if (!box) return; dragging = true; sx = e.clientX; sy = e.clientY; box.style.left = sx + "px"; box.style.top = sy + "px"; box.style.width = "0px"; box.style.height = "0px"; } function move(e) { if (!dragging || !box) return; const tip = overlay.querySelector(".hc-jietu-tip"); if (tip) tip.style.display = "none"; box.style.left = Math.min(e.clientX, sx) + "px"; box.style.top = Math.min(e.clientY, sy) + "px"; box.style.width = Math.abs(e.clientX - sx) + "px"; box.style.height = Math.abs(e.clientY - sy) + "px"; } function toast(msg) { const t = document.createElement("div"); t.textContent = msg; t.setAttribute("style", "all:initial;position:fixed;left:50%;top:64px;transform:translateX(-50%);" + "z-index:2147483647;background:#000000a3;color:#fff;font-size:14px;" + "padding:10px 16px;border-radius:8px;"); document.body.appendChild(t); setTimeout(function() { t.remove(); }, 2500); } const TAINT_TAGS = { VIDEO: 1, CANVAS: 1, EMBED: 1, OBJECT: 1 }; const MEDIA_TAGS = { VIDEO: 1, CANVAS: 1, EMBED: 1, OBJECT: 1, AUDIO: 1, IMG: 1, PICTURE: 1, SVG: 1, IMAGE: 1, IFRAME: 1, FRAME: 1 }; function render(left, top, width, height, stripMedia) { return html2canvas(document.body, { x: left + window.pageXOffset, y: top + window.pageYOffset, width: width, height: height, useCORS: true, logging: false, ignoreElements: function(el) { const t = (el.tagName || "").toUpperCase(); return stripMedia ? !!MEDIA_TAGS[t] : !!TAINT_TAGS[t]; } }).then(function(canvas) { return canvas.toDataURL("image/jpeg", .8).replace("data:image/jpeg;base64,", ""); }); } function capture(left, top, width, height, mouse) { render(left, top, width, height, false).catch(function() { return render(left, top, width, height, true); }).then(function(b64) { return ocrBase64(b64).then(function(txt) { if (txt) onText(txt, mouse); else toast("未识别到文字,请重新框选"); }, function() { toast("OCR 服务请求失败,请稍后重试"); }); }).catch(function(err) { toast("页面截图失败:" + (err && err.message || "未知原因")); }); } const MSG = "hc-cut-shot", ACK = "hc-cut-ack"; let ackTimer = null; window.addEventListener("message", function(ev) { const d = ev.data; if (!d || typeof d !== "object") return; if (d.type === MSG && typeof d.left === "number" && typeof d.top === "number" && typeof d.width === "number" && typeof d.height === "number") { try { ev.source.postMessage({ type: ACK }, "*"); } catch (err) {} capture(d.left, d.top, d.width, d.height, { x: d.left + d.width / 2, y: d.top + d.height / 2 }); } else if (d.type === ACK && ackTimer) { clearTimeout(ackTimer); ackTimer = null; } }); function up(e) { if (!box || box.offsetWidth <= 0 || box.offsetHeight <= 0) { cleanup(); return; } const rect = box.getBoundingClientRect(); cleanup(); let left = rect.left, top = rect.top, frameWin = null; try { let el = document.elementFromPoint(left + rect.width / 2, top + rect.height / 2); while (el && el.tagName === "IFRAME" && el.contentDocument) { const fr = el.getBoundingClientRect(); left -= fr.left + el.clientLeft; top -= fr.top + el.clientTop; frameWin = el.contentWindow; el = el.contentDocument.elementFromPoint(left + rect.width / 2, top + rect.height / 2); } } catch (err) { frameWin = null; } if (frameWin && frameWin !== window) { frameWin.postMessage({ type: MSG, left: left, top: top, width: rect.width, height: rect.height }, "*"); ackTimer = setTimeout(function() { ackTimer = null; capture(rect.left, rect.top, rect.width, rect.height, { x: e.clientX, y: e.clientY }); }, 600); } else { capture(rect.left, rect.top, rect.width, rect.height, { x: e.clientX, y: e.clientY }); } } function keyName(e) { const m = /^Key([A-Z])$/.exec(e.code || ""); return m ? m[1] : (e.key || "").toUpperCase(); } document.addEventListener("keyup", function(e) { delete keys[keyName(e)]; }, true); window.addEventListener("blur", function() { for (const k in keys) delete keys[k]; }); document.addEventListener("keydown", function(e) { keys[keyName(e)] = true; if (config.cut_search && keys.T && keys.H && !overlay) { overlay = document.createElement("div"); overlay.innerHTML = OVERLAY_HTML; document.body.appendChild(overlay); box = overlay.querySelector(".hc-jietu-box"); document.addEventListener("mousedown", down); document.addEventListener("mousemove", move); document.addEventListener("mouseup", up); document.addEventListener("mouseleave", cleanup); } else if ((e.key === "Escape" || e.code === "Escape") && overlay) { cleanup(); } }, true); } function removeLimit() { if (location.host.indexOf("chaoxing") !== -1) { setTimeout(function() { try { unsafeWindow.UEDITOR_CONFIG.scaleEnabled = false; } catch (e) {} }, 2e3); } if (location.href.indexOf("newMooc=true") !== -1 && location.host.indexOf("chaoxing") !== -1 || location.pathname.indexOf("exam/test/reVersionPaperMarkContentNew") !== -1) { setTimeout(function() { if (document.body) document.body.removeAttribute("onselectstart"); document.documentElement.style.userSelect = "unset"; try { unsafeWindow.UE.EventBase.prototype.fireEvent = function() { return null; }; } catch (e) {} }, 2e3); } } function parseFont(buf) { const rU = o => buf[o] << 8 | buf[o + 1]; const rS = o => { const v = rU(o); return v & 32768 ? v - 65536 : v; }; const rUint = o => (buf[o] << 24 | buf[o + 1] << 16 | buf[o + 2] << 8 | buf[o + 3]) >>> 0; const num = rU(4); let p = 12; const T = {}; for (let i = 0; i < num; i++) { const tag = String.fromCharCode(buf[p], buf[p + 1], buf[p + 2], buf[p + 3]); T[tag] = { off: rUint(p + 8), len: rUint(p + 12) }; p += 16; } if (!T.glyf || !T.loca || !T.maxp || !T.head || !T.cmap) return null; const numGlyphs = rU(T.maxp.off + 4); const longLoca = rS(T.head.off + 50) !== 0; const loca = []; const lo = T.loca.off; for (let i = 0; i <= numGlyphs; i++) loca.push(longLoca ? rUint(lo + i * 4) : rU(lo + i * 2) * 2); const cm = T.cmap.off, nt = rU(cm + 2); let f4 = -1; for (let i = 0; i < nt; i++) { const off = rUint(cm + 4 + i * 8 + 4); if (rU(cm + off) === 4) { f4 = cm + off; break; } } const map = {}; if (f4 >= 0) { const segX2 = rU(f4 + 6), segC = segX2 / 2; const endO = f4 + 14, startO = endO + segX2 + 2, deltaO = startO + segX2, rangeO = deltaO + segX2; for (let s = 0; s < segC; s++) { const end = rU(endO + s * 2), start = rU(startO + s * 2), delta = rU(deltaO + s * 2), ro = rU(rangeO + s * 2); if (start === 65535) continue; for (let ch = start; ch <= end; ch++) { let g; if (ro === 0) g = ch + delta & 65535; else { const gi = rU(rangeO + s * 2 + ro + (ch - start) * 2); g = gi === 0 ? 0 : gi + delta & 65535; } if (g) map[ch] = g; } } } return { buf: buf, rU: rU, rS: rS, T: T, loca: loca, numGlyphs: numGlyphs, map: map }; } function parseGlyf(F, g) { const { buf, rU, rS, T, loca } = F; if (loca[g] === loca[g + 1]) return null; let o = T.glyf.off + loca[g]; const gl = {}; gl.noc = rS(o); o += 2; gl.xMin = rS(o); o += 2; gl.yMin = rS(o); o += 2; gl.xMax = rS(o); o += 2; gl.yMax = rS(o); o += 2; if (gl.xMin >= gl.xMax || gl.yMin >= gl.yMax) return null; if (gl.noc > 0) { gl.endPts = []; for (let i = 0; i < gl.noc; i++) { gl.endPts.push(rU(o)); o += 2; } const il = rU(o); o += 2; if (buf.length - o < il) return null; o += il; const cn = gl.endPts[gl.noc - 1] + 1; gl.flags = []; for (let i = 0; i < cn; i++) { const f = buf[o++]; gl.flags.push(f); if (f & 8) { let r = buf[o++]; for (let j = 0; j < r; j++) { gl.flags.push(f); i++; } } } gl.xs = []; for (let i = 0; i < cn; i++) { const i8 = (gl.flags[i] & 2) !== 0, sm = (gl.flags[i] & 16) !== 0; if (i8) { gl.xs.push(sm ? buf[o] : -buf[o]); o++; } else { if (sm) gl.xs.push(0); else { gl.xs.push(rS(o)); o += 2; } } } gl.ys = []; for (let i = 0; i < cn; i++) { const i8 = (gl.flags[i] & 4) !== 0, sm = (gl.flags[i] & 32) !== 0; if (i8) { gl.ys.push(sm ? buf[o] : -buf[o]); o++; } else { if (sm) gl.ys.push(0); else { gl.ys.push(rS(o)); o += 2; } } } let x = 0, y = 0; for (let i = 0; i < cn; i++) { x += gl.xs[i]; y += gl.ys[i]; gl.xs[i] = x; gl.ys[i] = y; } } else { gl.parts = []; let flags; do { flags = rU(o); o += 2; const part = { m: { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 }, p1: -1, p2: -1 }; gl.parts.push(part); part.glyphIndex = rU(o); o += 2; let a1, a2; if (flags & 1) { a1 = rS(o); o += 2; a2 = rS(o); o += 2; } else { a1 = buf[o] << 24 >> 24; o++; a2 = buf[o] << 24 >> 24; o++; } if (flags & 2) { part.m.tx = a1; part.m.ty = a2; } else { part.p1 = a1; part.p2 = a2; } const f2 = oo => rS(oo) / 16384; if (flags & 8) { part.m.a = part.m.d = f2(o); o += 2; } else if (flags & 64) { part.m.a = f2(o); o += 2; part.m.d = f2(o); o += 2; } else if (flags & 128) { part.m.a = f2(o); o += 2; part.m.b = f2(o); o += 2; part.m.c = f2(o); o += 2; part.m.d = f2(o); o += 2; } } while (flags & 32); } return gl; } const P = { M: (p, x, y) => { p.cmds.push("M"); p.crds.push(x, y); }, L: (p, x, y) => { p.cmds.push("L"); p.crds.push(x, y); }, Q: (p, a, b, c, d) => { p.cmds.push("Q"); p.crds.push(a, b, c, d); }, Z: p => { p.cmds.push("Z"); } }; function drawGlyf(F, g, path) { const gl = parseGlyf(F, g); if (!gl) return; if (gl.noc > -1) simple(gl, path); else compo(F, gl, path); } function simple(gl, p) { for (let c = 0; c < gl.noc; c++) { const i0 = c === 0 ? 0 : gl.endPts[c - 1] + 1, il = gl.endPts[c]; for (let i = i0; i <= il; i++) { const pr = i === i0 ? il : i - 1, nx = i === il ? i0 : i + 1; const on = gl.flags[i] & 1, prOn = gl.flags[pr] & 1, nxOn = gl.flags[nx] & 1; const x = gl.xs[i], y = gl.ys[i]; if (i === i0) { if (on) { if (prOn) P.M(p, gl.xs[pr], gl.ys[pr]); else { P.M(p, x, y); continue; } } else { if (prOn) P.M(p, gl.xs[pr], gl.ys[pr]); else P.M(p, Math.floor((gl.xs[pr] + x) * .5), Math.floor((gl.ys[pr] + y) * .5)); } } if (on) { if (prOn) P.L(p, x, y); } else { if (nxOn) P.Q(p, x, y, gl.xs[nx], gl.ys[nx]); else P.Q(p, x, y, Math.floor((x + gl.xs[nx]) * .5), Math.floor((y + gl.ys[nx]) * .5)); } } P.Z(p); } } function compo(F, gl, p) { for (let j = 0; j < gl.parts.length; j++) { const path = { cmds: [], crds: [] }; const prt = gl.parts[j]; drawGlyf(F, prt.glyphIndex, path); const m = prt.m; for (let i = 0; i < path.crds.length; i += 2) { const x = path.crds[i], y = path.crds[i + 1]; p.crds.push(x * m.a + y * m.b + m.tx); p.crds.push(x * m.c + y * m.d + m.ty); } for (let i = 0; i < path.cmds.length; i++) p.cmds.push(path.cmds[i]); } } function glyphToPath(F, g) { const path = { cmds: [], crds: [] }; drawGlyf(F, g, path); return { cmds: path.cmds, crds: path.crds }; } function md5(s) { function rl(n, c) { return n << c | n >>> 32 - c; } function ad(a, b) { const l = (a & 65535) + (b & 65535); const m = (a >> 16) + (b >> 16) + (l >> 16); return m << 16 | l & 65535; } function cmn(q, a, b, x, s, t) { return ad(rl(ad(ad(a, q), ad(x, t)), s), b); } function ff(a, b, c, d, x, s, t) { return cmn(b & c | ~b & d, a, b, x, s, t); } function gg(a, b, c, d, x, s, t) { return cmn(b & d | c & ~d, a, b, x, s, t); } function hh(a, b, c, d, x, s, t) { return cmn(b ^ c ^ d, a, b, x, s, t); } function ii(a, b, c, d, x, s, t) { return cmn(c ^ (b | ~d), a, b, x, s, t); } const utf8 = unescape(encodeURIComponent(s)); const n = utf8.length, blks = []; for (let i = 0; i < n * 8; i += 8) blks[i >> 5] |= (utf8.charCodeAt(i / 8) & 255) << i % 32; blks[n * 8 >> 5] |= 128 << n * 8 % 32; blks[(n * 8 + 64 >>> 9 << 4) + 14] = n * 8; let a = 1732584193, b = -271733879, c = -1732584194, d = 271733878; for (let i = 0; i < blks.length; i += 16) { const oa = a, ob = b, oc = c, od = d; a = ff(a, b, c, d, blks[i + 0] | 0, 7, -680876936); d = ff(d, a, b, c, blks[i + 1] | 0, 12, -389564586); c = ff(c, d, a, b, blks[i + 2] | 0, 17, 606105819); b = ff(b, c, d, a, blks[i + 3] | 0, 22, -1044525330); a = ff(a, b, c, d, blks[i + 4] | 0, 7, -176418897); d = ff(d, a, b, c, blks[i + 5] | 0, 12, 1200080426); c = ff(c, d, a, b, blks[i + 6] | 0, 17, -1473231341); b = ff(b, c, d, a, blks[i + 7] | 0, 22, -45705983); a = ff(a, b, c, d, blks[i + 8] | 0, 7, 1770035416); d = ff(d, a, b, c, blks[i + 9] | 0, 12, -1958414417); c = ff(c, d, a, b, blks[i + 10] | 0, 17, -42063); b = ff(b, c, d, a, blks[i + 11] | 0, 22, -1990404162); a = ff(a, b, c, d, blks[i + 12] | 0, 7, 1804603682); d = ff(d, a, b, c, blks[i + 13] | 0, 12, -40341101); c = ff(c, d, a, b, blks[i + 14] | 0, 17, -1502002290); b = ff(b, c, d, a, blks[i + 15] | 0, 22, 1236535329); a = gg(a, b, c, d, blks[i + 1] | 0, 5, -165796510); d = gg(d, a, b, c, blks[i + 6] | 0, 9, -1069501632); c = gg(c, d, a, b, blks[i + 11] | 0, 14, 643717713); b = gg(b, c, d, a, blks[i + 0] | 0, 20, -373897302); a = gg(a, b, c, d, blks[i + 5] | 0, 5, -701558691); d = gg(d, a, b, c, blks[i + 10] | 0, 9, 38016083); c = gg(c, d, a, b, blks[i + 15] | 0, 14, -660478335); b = gg(b, c, d, a, blks[i + 4] | 0, 20, -405537848); a = gg(a, b, c, d, blks[i + 9] | 0, 5, 568446438); d = gg(d, a, b, c, blks[i + 14] | 0, 9, -1019803690); c = gg(c, d, a, b, blks[i + 3] | 0, 14, -187363961); b = gg(b, c, d, a, blks[i + 8] | 0, 20, 1163531501); a = gg(a, b, c, d, blks[i + 13] | 0, 5, -1444681467); d = gg(d, a, b, c, blks[i + 2] | 0, 9, -51403784); c = gg(c, d, a, b, blks[i + 7] | 0, 14, 1735328473); b = gg(b, c, d, a, blks[i + 12] | 0, 20, -1926607734); a = hh(a, b, c, d, blks[i + 5] | 0, 4, -378558); d = hh(d, a, b, c, blks[i + 8] | 0, 11, -2022574463); c = hh(c, d, a, b, blks[i + 11] | 0, 16, 1839030562); b = hh(b, c, d, a, blks[i + 14] | 0, 23, -35309556); a = hh(a, b, c, d, blks[i + 1] | 0, 4, -1530992060); d = hh(d, a, b, c, blks[i + 4] | 0, 11, 1272893353); c = hh(c, d, a, b, blks[i + 7] | 0, 16, -155497632); b = hh(b, c, d, a, blks[i + 10] | 0, 23, -1094730640); a = hh(a, b, c, d, blks[i + 13] | 0, 4, 681279174); d = hh(d, a, b, c, blks[i + 0] | 0, 11, -358537222); c = hh(c, d, a, b, blks[i + 3] | 0, 16, -722521979); b = hh(b, c, d, a, blks[i + 6] | 0, 23, 76029189); a = hh(a, b, c, d, blks[i + 9] | 0, 4, -640364487); d = hh(d, a, b, c, blks[i + 12] | 0, 11, -421815835); c = hh(c, d, a, b, blks[i + 15] | 0, 16, 530742520); b = hh(b, c, d, a, blks[i + 2] | 0, 23, -995338651); a = ii(a, b, c, d, blks[i + 0] | 0, 6, -198630844); d = ii(d, a, b, c, blks[i + 7] | 0, 10, 1126891415); c = ii(c, d, a, b, blks[i + 14] | 0, 15, -1416354905); b = ii(b, c, d, a, blks[i + 5] | 0, 21, -57434055); a = ii(a, b, c, d, blks[i + 12] | 0, 6, 1700485571); d = ii(d, a, b, c, blks[i + 3] | 0, 10, -1894986606); c = ii(c, d, a, b, blks[i + 10] | 0, 15, -1051523); b = ii(b, c, d, a, blks[i + 1] | 0, 21, -2054922799); a = ii(a, b, c, d, blks[i + 8] | 0, 6, 1873313359); d = ii(d, a, b, c, blks[i + 15] | 0, 10, -30611744); c = ii(c, d, a, b, blks[i + 6] | 0, 15, -1560198380); b = ii(b, c, d, a, blks[i + 13] | 0, 21, 1309151649); a = ii(a, b, c, d, blks[i + 4] | 0, 6, -145523070); d = ii(d, a, b, c, blks[i + 11] | 0, 10, -1120210379); c = ii(c, d, a, b, blks[i + 2] | 0, 15, 718787259); b = ii(b, c, d, a, blks[i + 9] | 0, 21, -343485551); a = ad(a, oa); b = ad(b, ob); c = ad(c, oc); d = ad(d, od); } const x = [ a, b, c, d ]; let hex = ""; for (let i = 0; i < 16; i++) hex += (x[i >> 2] >> i % 4 * 8 & 255).toString(16).padStart(2, "0"); return hex; } function base64ToUint8Array(base64) { const data = window.atob(base64); const buffer = new Uint8Array(data.length); for (let i = 0; i < data.length; ++i) buffer[i] = data.charCodeAt(i); return buffer; } let TABLE = null; function getTable() { if (TABLE) return TABLE; try { TABLE = JSON.parse(GM_getResourceText("Table")); } catch (e) { TABLE = {}; } return TABLE; } function buildMap(base64) { const F = parseFont(base64ToUint8Array(base64)); if (!F) return null; const table = getTable(); const map = {}; for (const codeStr in F.map) { const code = +codeStr; const hash = md5(JSON.stringify(glyphToPath(F, F.map[code]))).slice(24); const real = table[hash]; if (real) map[code] = String.fromCharCode(real); } return map; } function replaceText(root, map) { const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false); const nodes = []; let n; while (n = walker.nextNode()) nodes.push(n); for (let i = 0; i < nodes.length; i++) { const t = nodes[i]; let out = "", changed = false; const s = t.nodeValue; for (let j = 0; j < s.length; j++) { const code = s.charCodeAt(j); if (map[code] !== undefined) { out += map[code]; changed = true; } else out += s[j]; } if (changed) t.nodeValue = out; } } function decryptAll(map) { const els = document.querySelectorAll(".font-cxsecret"); for (let i = 0; i < els.length; i++) { replaceText(els[i], map); els[i].classList.remove("font-cxsecret"); } } function fixChaoxingFont() { const styles = document.querySelectorAll("style"); let map = null; for (let i = 0; i < styles.length; i++) { if (styles[i].textContent.indexOf("font-cxsecret") === -1) continue; const m = styles[i].textContent.match(/base64,([\w\W]+?)'/); if (!m) continue; const sub = buildMap(m[1]); if (sub) map = Object.assign(map || {}, sub); } if (!map || !Object.keys(map).length) return; decryptAll(map); const obs = new MutationObserver(function() { decryptAll(map); }); obs.observe(document.body, { childList: true, subtree: true }); } function fixYuketang() { const intv = setInterval(function() { try { top.document.querySelector(".exam").__vue__.handleHangUpTip = function() {}; const querySelector = top.document.querySelector; top.document.querySelector = function() { if (arguments[0] === "#hc-search-host") return false; return querySelector.apply(this, arguments); }; clearInterval(intv); } catch (e) {} }, 100); } function startFontFix() { try { fixYuketang(); } catch (e) {} setTimeout(function() { try { fixChaoxingFont(); } catch (e) {} }, 1e3); } initApp(); initSelection(search); initCutSearch(search); if (config.remove_limit) { removeLimit(); startFontFix(); } GM_registerMenuCommand("文本搜题", openManual); GM_registerMenuCommand("设置", openSettings); })();