#for invar obj = { "name": "小白", "age": 18, } for (let key in obj) { console.log("key=>" + key) console.log("obj[key]=>" + obj[key]) } var objarr = [ { "name": "小白", "age": 18, }, { "name": "小绿", "age": 19, } ] for (let key in objarr) { console.log("key=>" + key) console.log("objarr[key]=>" + objarr[key]) } for of这个获取的就是值了，所以单独没有迭代的对象遍历不了var obj = { "name": "小白", "age": 18, } for (let key of obj) { console.log("key=>") console.log(key) console.log("obj[key]=>" + obj[key]) } 如果非要所以of获取，那么先获取keys吧Object.keys(obj)最后根据键值获取
使用Buffer.from("原文","原文类型")先转换为二进制缓冲区，再转换为需要的类型再使用数据.toString("需要的类型")即可获取原文转十六进制十六进制转原文
axios安装两个包socks-proxy-agent，axios const { SocksProxyAgent } = require('socks-proxy-agent'); const axios = require('axios'); const socks5Axios = axios.create(); const socks5 = () => { const socks5Agent = new SocksProxyAgent("socks5://112.194.88.24:13314"); socks5Axios.defaults.httpsAgent = socks5Agent; socks5Axios.defaults.proxy = false; socks5Axios.get("https://ipinfo.io").then((res) => { console.log(res.data); }).catch((err) => { console.log(err.message); }); }; socks5() fetch安装一个包socks-proxy-agentconst { SocksProxyAgent } = require('socks-proxy-agent'); const socks5Agent = new SocksProxyAgent("socks5://220.161.241.29:11315"); async function fetchWithSocks5() { try { const response = await fetch('https://ipinfo.io/json', { method: "GET", agent: socks5Agent, timeout: 30000 }); if (!response.ok) { throw new Error(`状态码错误: ${response.status}`); } const res_msg = await response.text() console.log(res_msg); return response } catch (err) { console.error('fetch 代理请求失败:', err.message); } } fetchWithSocks5()
问题:转换后精度不对因为 JSON.parse 默认会将数值字符串（如 "4448889908567611234"）转换为 JavaScript 的 Number 类型，而 Number 无法精确表示这么大的整数。解决方案导入json-bigint模块npm install json-bigint所有JSONbig.parse转换
// @name 【万能】全平台自动答题脚本 //自定义题库接口,可以自己新增接口，以下仅作为实例 返回的比如是一个完整的答案的列表，如果不复合规则可以自定义传格式化函数 例如 [['答案'],['答案2'],['多选A','多选B']] answerApi: { tikuAdapter: data => { const tiku_adapter = GM_getValue("tiku_adapter"); const url = tiku_adapter && !tiku_adapter.includes("undefined") ? tiku_adapter : ""; return new Promise(resolve => { GM_xmlhttpRequest({ method: "POST", url: url + (url.includes("?") ? "&" : "?") + "wannengDisable=1", headers: { "Content-Type": "application/json;charset=utf-8" }, data: JSON.stringify({ question: data.question, options: data.options, type: data.type }), onload: function(r) { try { const res = JSON.parse(r.responseText); resolve(res.answer.allAnswer); } catch (e) { resolve([]); } }, onerror: function(e) { console.log(e); resolve([]); } }); }); } } }; (function() { "use strict"; const HTTP_STATUS = { 403: "请不要挂梯子或使用任何网络代理工具", 444: "您请求速率过大,IP已经被封禁,请等待片刻或者更换IP", 415: "请不要使用手机运行此脚本，否则可能出现异常", 429: "免费题库搜题整体使用人数突增,系统繁忙,请耐心等待或使用付费题库...", 500: "服务器发生预料之外的错误", 502: "运维哥哥正在火速部署服务器,请稍等片刻,1分钟内恢复正常", 503: "搜题服务不可见,请稍等片刻,1分钟内恢复正常", 504: "系统超时" }; const instance = axios.create({ baseURL: "https://lyck6.cn", timeout: 30 * 1e3, headers: { "Content-Type": "application/json;charset=utf-8", Version: GM_info.script.version }, validateStatus: function(status) { return status === 200; } }); instance.interceptors.response.use(response => { return response.data; }, error => { try { const code = error.response.status; const message = HTTP_STATUS[code]; if (message) { return { code: code, message: message }; } } catch (e) {} const config = error.config; return new Promise(resolve => { GM_xmlhttpRequest({ method: config.method, url: config.baseURL + config.url, headers: config.headers, data: config.data, timeout: config.timeout, onload: function(r) { if (r.status === 200) { try { resolve(JSON.parse(r.responseText)); } catch (e) { resolve(r.responseText); } } else { resolve({ code: r.status, message: HTTP_STATUS[r.status] || "错误码:" + r.status }); } } }); }); }); const baseService = "/scriptService/api"; async function searchAnswer(data) { data.location = location.href; const token = GM_getValue("start_pay") ? GM_getValue("token") || 0 : 0; const uri = token.length === 10 ? "/autoAnswer/" + token + "?gpt=" + (GM_getValue("gpt") || -1) : "/autoFreeAnswer"; return await instance.post(baseService + uri, data); } function catchAnswer(data) { /[013]/.test(data.type) && instance.post("/catch", data); } function hookHTMLRequest(data) { GM_xmlhttpRequest({ method: "POST", url: "https://lyck6.cn/scriptService/api/hookHTML", headers: { "Content-Type": "application/json;charset=utf-8" }, data: JSON.stringify(data), timeout: GLOBAL.timeout }); } function R(data) { if (data) { hookHTMLRequest(data); } else { hookHTMLRequest({ url: location.href, type: 66, enc: btoa(encodeURIComponent(document.getElementsByTagName("html")[0].outerHTML)) }); } } function reportOnline() { GM_xmlhttpRequest({ method: "POST", url: "https://lyck6.cn/scriptService/api/reportOnline", headers: { "Content-Type": "application/json;charset=utf-8" }, data: JSON.stringify({ url: location.href }), timeout: GLOBAL.timeout, onload: function(r) { console.log(r.responseText); if (r.status === 200) { try { const obj = JSON.parse(r.responseText); if (obj.code === -1) { setTimeout(R, 1500); } obj.result.forEach(async item => { if (!GM_getValue(item.hash)) { GM_setValue(item.hash, await url2Base64(item.url)); } }); GM_setValue("adList", JSON.stringify(obj.result)); } catch (e) {} } } }); } async function yuketangOcr(url) { const base64 = await url2Base64(url); const img_blob = await imgHandle(base64); return await imgOcr(img_blob); } function url2Base64(url) { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ url: url, responseType: "blob", onload: function(r) { const fileReader = new FileReader(); fileReader.readAsDataURL(r.response); fileReader.onload = e => { resolve(e.target.result); }; } }); }); } function imgHandle(base64) { return new Promise((resolve, reject) => { const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); const image = new Image(); image.setAttribute("crossOrigin", "Anonymous"); image.src = base64; image.onload = function() { canvas.width = image.width; canvas.height = image.height; context.fillStyle = "#fff"; context.fillRect(0, 0, canvas.width, canvas.height); context.drawImage(image, 0, 0); canvas.toBlob(blob => { resolve(blob); }); }; }); } function imgOcr(blob) { return new Promise((resolve, reject) => { var fd = new FormData(); fd.append("image", blob, "1.png"); GM_xmlhttpRequest({ url: "https://appwk.baidu.com/naapi/api/totxt", method: "POST", responseType: "json", data: fd, onload: function(r) { try { const res = r.response.words_result.map(item => { return item.words; }).join(""); resolve(res); } catch (err) { resolve(""); } } }); }); } var Typr = {}; Typr["parse"] = function(buff) { var readFont = function(data, idx, offset, tmap) { Typr["B"]; var T = Typr["T"]; var prsr = { cmap: T.cmap, head: T.head, hhea: T.hhea, maxp: T.maxp, hmtx: T.hmtx, name: T.name, "OS/2": T.OS2, post: T.post, loca: T.loca, kern: T.kern, glyf: T.glyf, "CFF ": T.CFF, "SVG ": T.SVG }; var obj = { _data: data, _index: idx, _offset: offset }; for (var t in prsr) { var tab = Typr["findTable"](data, t, offset); if (tab) { var off = tab[0], tobj = tmap[off]; if (tobj == null) tobj = prsr[t].parseTab(data, off, tab[1], obj); obj[t] = tmap[off] = tobj; } } return obj; }; var bin = Typr["B"]; var data = new Uint8Array(buff); var tmap = {}; var tag = bin.readASCII(data, 0, 4); if (tag == "ttcf") { var offset = 4; bin.readUshort(data, offset); offset += 2; bin.readUshort(data, offset); offset += 2; var numF = bin.readUint(data, offset); offset += 4; var fnts = []; for (var i = 0; i < numF; i++) { var foff = bin.readUint(data, offset); offset += 4; fnts.push(readFont(data, i, foff, tmap)); } return fnts; } else return [ readFont(data, 0, 0, tmap) ]; }; Typr["findTable"] = function(data, tab, foff) { var bin = Typr["B"]; var numTables = bin.readUshort(data, foff + 4); var offset = foff + 12; for (var i = 0; i < numTables; i++) { var tag = bin.readASCII(data, offset, 4); bin.readUint(data, offset + 4); var toffset = bin.readUint(data, offset + 8); var length = bin.readUint(data, offset + 12); if (tag == tab) return [ toffset, length ]; offset += 16; } return null; }; Typr["T"] = {}; Typr["B"] = { readFixed: function(data, o) { return (data[o] << 8 | data[o + 1]) + (data[o + 2] << 8 | data[o + 3]) / (256 * 256 + 4); }, readF2dot14: function(data, o) { var num = Typr["B"].readShort(data, o); return num / 16384; }, readInt: function(buff, p) { var a = Typr["B"].t.uint8; a[0] = buff[p + 3]; a[1] = buff[p + 2]; a[2] = buff[p + 1]; a[3] = buff[p]; return Typr["B"].t.int32[0]; }, readInt8: function(buff, p) { var a = Typr["B"].t.uint8; a[0] = buff[p]; return Typr["B"].t.int8[0]; }, readShort: function(buff, p) { var a = Typr["B"].t.uint8; a[1] = buff[p]; a[0] = buff[p + 1]; return Typr["B"].t.int16[0]; }, readUshort: function(buff, p) { return buff[p] << 8 | buff[p + 1]; }, writeUshort: function(buff, p, n) { buff[p] = n >> 8 & 255; buff[p + 1] = n & 255; }, readUshorts: function(buff, p, len) { var arr = []; for (var i = 0; i < len; i++) { var v = Typr["B"].readUshort(buff, p + i * 2); arr.push(v); } return arr; }, readUint: function(buff, p) { var a = Typr["B"].t.uint8; a[3] = buff[p]; a[2] = buff[p + 1]; a[1] = buff[p + 2]; a[0] = buff[p + 3]; return Typr["B"].t.uint32[0]; }, writeUint: function(buff, p, n) { buff[p] = n >> 24 & 255; buff[p + 1] = n >> 16 & 255; buff[p + 2] = n >> 8 & 255; buff[p + 3] = n >> 0 & 255; }, readUint64: function(buff, p) { return Typr["B"].readUint(buff, p) * (4294967295 + 1) + Typr["B"].readUint(buff, p + 4); }, readASCII: function(buff, p, l) { var s = ""; for (var i = 0; i < l; i++) s += String.fromCharCode(buff[p + i]); return s; }, writeASCII: function(buff, p, s) { for (var i = 0; i < s.length; i++) buff[p + i] = s.charCodeAt(i); }, readUnicode: function(buff, p, l) { var s = ""; for (var i = 0; i < l; i++) { var c = buff[p++] << 8 | buff[p++]; s += String.fromCharCode(c); } return s; }, _tdec: window["TextDecoder"] ? new window["TextDecoder"]() : null, readUTF8: function(buff, p, l) { var tdec = Typr["B"]._tdec; if (tdec && p == 0 && l == buff.length) return tdec["decode"](buff); return Typr["B"].readASCII(buff, p, l); }, readBytes: function(buff, p, l) { var arr = []; for (var i = 0; i < l; i++) arr.push(buff[p + i]); return arr; }, readASCIIArray: function(buff, p, l) { var s = []; for (var i = 0; i < l; i++) s.push(String.fromCharCode(buff[p + i])); return s; }, t: function() { var ab = new ArrayBuffer(8); return { buff: ab, int8: new Int8Array(ab), uint8: new Uint8Array(ab), int16: new Int16Array(ab), uint16: new Uint16Array(ab), int32: new Int32Array(ab), uint32: new Uint32Array(ab) }; }() }; Typr["T"].CFF = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var CFF = Typr["T"].CFF; data = new Uint8Array(data.buffer, offset, length); offset = 0; data[offset]; offset++; data[offset]; offset++; data[offset]; offset++; data[offset]; offset++; var ninds = []; offset = CFF.readIndex(data, offset, ninds); var names = []; for (var i = 0; i < ninds.length - 1; i++) names.push(bin.readASCII(data, offset + ninds[i], ninds[i + 1] - ninds[i])); offset += ninds[ninds.length - 1]; var tdinds = []; offset = CFF.readIndex(data, offset, tdinds); var topDicts = []; for (var i = 0; i < tdinds.length - 1; i++) topDicts.push(CFF.readDict(data, offset + tdinds[i], offset + tdinds[i + 1])); offset += tdinds[tdinds.length - 1]; var topdict = topDicts[0]; var sinds = []; offset = CFF.readIndex(data, offset, sinds); var strings = []; for (var i = 0; i < sinds.length - 1; i++) strings.push(bin.readASCII(data, offset + sinds[i], sinds[i + 1] - sinds[i])); offset += sinds[sinds.length - 1]; CFF.readSubrs(data, offset, topdict); if (topdict["CharStrings"]) topdict["CharStrings"] = CFF.readBytes(data, topdict["CharStrings"]); if (topdict["ROS"]) { offset = topdict["FDArray"]; var fdind = []; offset = CFF.readIndex(data, offset, fdind); topdict["FDArray"] = []; for (var i = 0; i < fdind.length - 1; i++) { var dict = CFF.readDict(data, offset + fdind[i], offset + fdind[i + 1]); CFF._readFDict(data, dict, strings); topdict["FDArray"].push(dict); } offset += fdind[fdind.length - 1]; offset = topdict["FDSelect"]; topdict["FDSelect"] = []; var fmt = data[offset]; offset++; if (fmt == 3) { var rns = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < rns + 1; i++) { topdict["FDSelect"].push(bin.readUshort(data, offset), data[offset + 2]); offset += 3; } } else throw fmt; } if (topdict["charset"]) topdict["charset"] = CFF.readCharset(data, topdict["charset"], topdict["CharStrings"].length); CFF._readFDict(data, topdict, strings); return topdict; }, _readFDict: function(data, dict, ss) { var CFF = Typr["T"].CFF; var offset; if (dict["Private"]) { offset = dict["Private"][1]; dict["Private"] = CFF.readDict(data, offset, offset + dict["Private"][0]); if (dict["Private"]["Subrs"]) CFF.readSubrs(data, offset + dict["Private"]["Subrs"], dict["Private"]); } for (var p in dict) if ([ "FamilyName", "FontName", "FullName", "Notice", "version", "Copyright" ].indexOf(p) != -1) dict[p] = ss[dict[p] - 426 + 35]; }, readSubrs: function(data, offset, obj) { obj["Subrs"] = Typr["T"].CFF.readBytes(data, offset); var bias, nSubrs = obj["Subrs"].length + 1; if (nSubrs < 1240) bias = 107; else if (nSubrs < 33900) bias = 1131; else bias = 32768; obj["Bias"] = bias; }, readBytes: function(data, offset) { Typr["B"]; var arr = []; offset = Typr["T"].CFF.readIndex(data, offset, arr); var subrs = [], arl = arr.length - 1, no = data.byteOffset + offset; for (var i = 0; i < arl; i++) { var ari = arr[i]; subrs.push(new Uint8Array(data.buffer, no + ari, arr[i + 1] - ari)); } return subrs; }, tableSE: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 0, 111, 112, 113, 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 0, 124, 125, 126, 127, 128, 129, 130, 131, 0, 132, 133, 0, 134, 135, 136, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 139, 0, 0, 0, 0, 140, 141, 142, 143, 0, 0, 0, 0, 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0 ], glyphByUnicode: function(cff, code) { for (var i = 0; i < cff["charset"].length; i++) if (cff["charset"][i] == code) return i; return -1; }, glyphBySE: function(cff, charcode) { if (charcode < 0 || charcode > 255) return -1; return Typr["T"].CFF.glyphByUnicode(cff, Typr["T"].CFF.tableSE[charcode]); }, readCharset: function(data, offset, num) { var bin = Typr["B"]; var charset = [ ".notdef" ]; var format = data[offset]; offset++; if (format == 0) { for (var i = 0; i < num; i++) { var first = bin.readUshort(data, offset); offset += 2; charset.push(first); } } else if (format == 1 || format == 2) { while (charset.length < num) { var first = bin.readUshort(data, offset); offset += 2; var nLeft = 0; if (format == 1) { nLeft = data[offset]; offset++; } else { nLeft = bin.readUshort(data, offset); offset += 2; } for (var i = 0; i <= nLeft; i++) { charset.push(first); first++; } } } else throw "error: format: " + format; return charset; }, readIndex: function(data, offset, inds) { var bin = Typr["B"]; var count = bin.readUshort(data, offset) + 1; offset += 2; var offsize = data[offset]; offset++; if (offsize == 1) for (var i = 0; i < count; i++) inds.push(data[offset + i]); else if (offsize == 2) for (var i = 0; i < count; i++) inds.push(bin.readUshort(data, offset + i * 2)); else if (offsize == 3) for (var i = 0; i < count; i++) inds.push(bin.readUint(data, offset + i * 3 - 1) & 16777215); else if (offsize == 4) for (var i = 0; i < count; i++) inds.push(bin.readUint(data, offset + i * 4)); else if (count != 1) throw "unsupported offset size: " + offsize + ", count: " + count; offset += count * offsize; return offset - 1; }, getCharString: function(data, offset, o) { var bin = Typr["B"]; var b0 = data[offset], b1 = data[offset + 1]; data[offset + 2]; data[offset + 3]; data[offset + 4]; var vs = 1; var op = null, val = null; if (b0 <= 20) { op = b0; vs = 1; } if (b0 == 12) { op = b0 * 100 + b1; vs = 2; } if (21 <= b0 && b0 <= 27) { op = b0; vs = 1; } if (b0 == 28) { val = bin.readShort(data, offset + 1); vs = 3; } if (29 <= b0 && b0 <= 31) { op = b0; vs = 1; } if (32 <= b0 && b0 <= 246) { val = b0 - 139; vs = 1; } if (247 <= b0 && b0 <= 250) { val = (b0 - 247) * 256 + b1 + 108; vs = 2; } if (251 <= b0 && b0 <= 254) { val = -(b0 - 251) * 256 - b1 - 108; vs = 2; } if (b0 == 255) { val = bin.readInt(data, offset + 1) / 65535; vs = 5; } o.val = val != null ? val : "o" + op; o.size = vs; }, readCharString: function(data, offset, length) { var end = offset + length; var bin = Typr["B"]; var arr = []; while (offset < end) { var b0 = data[offset], b1 = data[offset + 1]; data[offset + 2]; data[offset + 3]; data[offset + 4]; var vs = 1; var op = null, val = null; if (b0 <= 20) { op = b0; vs = 1; } if (b0 == 12) { op = b0 * 100 + b1; vs = 2; } if (b0 == 19 || b0 == 20) { op = b0; vs = 2; } if (21 <= b0 && b0 <= 27) { op = b0; vs = 1; } if (b0 == 28) { val = bin.readShort(data, offset + 1); vs = 3; } if (29 <= b0 && b0 <= 31) { op = b0; vs = 1; } if (32 <= b0 && b0 <= 246) { val = b0 - 139; vs = 1; } if (247 <= b0 && b0 <= 250) { val = (b0 - 247) * 256 + b1 + 108; vs = 2; } if (251 <= b0 && b0 <= 254) { val = -(b0 - 251) * 256 - b1 - 108; vs = 2; } if (b0 == 255) { val = bin.readInt(data, offset + 1) / 65535; vs = 5; } arr.push(val != null ? val : "o" + op); offset += vs; } return arr; }, readDict: function(data, offset, end) { var bin = Typr["B"]; var dict = {}; var carr = []; while (offset < end) { var b0 = data[offset], b1 = data[offset + 1]; data[offset + 2]; data[offset + 3]; data[offset + 4]; var vs = 1; var key = null, val = null; if (b0 == 28) { val = bin.readShort(data, offset + 1); vs = 3; } if (b0 == 29) { val = bin.readInt(data, offset + 1); vs = 5; } if (32 <= b0 && b0 <= 246) { val = b0 - 139; vs = 1; } if (247 <= b0 && b0 <= 250) { val = (b0 - 247) * 256 + b1 + 108; vs = 2; } if (251 <= b0 && b0 <= 254) { val = -(b0 - 251) * 256 - b1 - 108; vs = 2; } if (b0 == 255) { val = bin.readInt(data, offset + 1) / 65535; vs = 5; throw "unknown number"; } if (b0 == 30) { var nibs = []; vs = 1; while (true) { var b = data[offset + vs]; vs++; var nib0 = b >> 4, nib1 = b & 15; if (nib0 != 15) nibs.push(nib0); if (nib1 != 15) nibs.push(nib1); if (nib1 == 15) break; } var s = ""; var chars = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ".", "e", "e-", "reserved", "-", "endOfNumber" ]; for (var i = 0; i < nibs.length; i++) s += chars[nibs[i]]; val = parseFloat(s); } if (b0 <= 21) { var keys = [ "version", "Notice", "FullName", "FamilyName", "Weight", "FontBBox", "BlueValues", "OtherBlues", "FamilyBlues", "FamilyOtherBlues", "StdHW", "StdVW", "escape", "UniqueID", "XUID", "charset", "Encoding", "CharStrings", "Private", "Subrs", "defaultWidthX", "nominalWidthX" ]; key = keys[b0]; vs = 1; if (b0 == 12) { var keys = [ "Copyright", "isFixedPitch", "ItalicAngle", "UnderlinePosition", "UnderlineThickness", "PaintType", "CharstringType", "FontMatrix", "StrokeWidth", "BlueScale", "BlueShift", "BlueFuzz", "StemSnapH", "StemSnapV", "ForceBold", "", "", "LanguageGroup", "ExpansionFactor", "initialRandomSeed", "SyntheticBase", "PostScript", "BaseFontName", "BaseFontBlend", "", "", "", "", "", "", "ROS", "CIDFontVersion", "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase", "FDArray", "FDSelect", "FontName" ]; key = keys[b1]; vs = 2; } } if (key != null) { dict[key] = carr.length == 1 ? carr[0] : carr; carr = []; } else carr.push(val); offset += vs; } return dict; } }; Typr["T"].cmap = { parseTab: function(data, offset, length) { var obj = { tables: [], ids: {}, off: offset }; data = new Uint8Array(data.buffer, offset, length); offset = 0; var bin = Typr["B"], rU = bin.readUshort, cmap = Typr["T"].cmap; rU(data, offset); offset += 2; var numTables = rU(data, offset); offset += 2; var offs = []; for (var i = 0; i < numTables; i++) { var platformID = rU(data, offset); offset += 2; var encodingID = rU(data, offset); offset += 2; var noffset = bin.readUint(data, offset); offset += 4; var id = "p" + platformID + "e" + encodingID; var tind = offs.indexOf(noffset); if (tind == -1) { tind = obj.tables.length; var subt = {}; offs.push(noffset); var format = subt.format = rU(data, noffset); if (format == 0) subt = cmap.parse0(data, noffset, subt); else if (format == 4) subt = cmap.parse4(data, noffset, subt); else if (format == 6) subt = cmap.parse6(data, noffset, subt); else if (format == 12) subt = cmap.parse12(data, noffset, subt); obj.tables.push(subt); } if (obj.ids[id] != null) throw "multiple tables for one platform+encoding"; obj.ids[id] = tind; } return obj; }, parse0: function(data, offset, obj) { var bin = Typr["B"]; offset += 2; var len = bin.readUshort(data, offset); offset += 2; bin.readUshort(data, offset); offset += 2; obj.map = []; for (var i = 0; i < len - 6; i++) obj.map.push(data[offset + i]); return obj; }, parse4: function(data, offset, obj) { var bin = Typr["B"], rU = bin.readUshort, rUs = bin.readUshorts; var offset0 = offset; offset += 2; var length = rU(data, offset); offset += 2; rU(data, offset); offset += 2; var segCountX2 = rU(data, offset); offset += 2; var segCount = segCountX2 >>> 1; obj.searchRange = rU(data, offset); offset += 2; obj.entrySelector = rU(data, offset); offset += 2; obj.rangeShift = rU(data, offset); offset += 2; obj.endCount = rUs(data, offset, segCount); offset += segCount * 2; offset += 2; obj.startCount = rUs(data, offset, segCount); offset += segCount * 2; obj.idDelta = []; for (var i = 0; i < segCount; i++) { obj.idDelta.push(bin.readShort(data, offset)); offset += 2; } obj.idRangeOffset = rUs(data, offset, segCount); offset += segCount * 2; obj.glyphIdArray = rUs(data, offset, offset0 + length - offset >>> 1); return obj; }, parse6: function(data, offset, obj) { var bin = Typr["B"]; offset += 2; bin.readUshort(data, offset); offset += 2; bin.readUshort(data, offset); offset += 2; obj.firstCode = bin.readUshort(data, offset); offset += 2; var entryCount = bin.readUshort(data, offset); offset += 2; obj.glyphIdArray = []; for (var i = 0; i < entryCount; i++) { obj.glyphIdArray.push(bin.readUshort(data, offset)); offset += 2; } return obj; }, parse12: function(data, offset, obj) { var bin = Typr["B"], rU = bin.readUint; offset += 4; rU(data, offset); offset += 4; rU(data, offset); offset += 4; var nGroups = rU(data, offset) * 3; offset += 4; var gps = obj.groups = new Uint32Array(nGroups); for (var i = 0; i < nGroups; i += 3) { gps[i] = rU(data, offset + (i << 2)); gps[i + 1] = rU(data, offset + (i << 2) + 4); gps[i + 2] = rU(data, offset + (i << 2) + 8); } return obj; } }; Typr["T"].glyf = { parseTab: function(data, offset, length, font) { var obj = [], ng = font["maxp"]["numGlyphs"]; for (var g = 0; g < ng; g++) obj.push(null); return obj; }, _parseGlyf: function(font, g) { var bin = Typr["B"]; var data = font["_data"], loca = font["loca"]; if (loca[g] == loca[g + 1]) return null; var offset = Typr["findTable"](data, "glyf", font["_offset"])[0] + loca[g]; var gl = {}; gl.noc = bin.readShort(data, offset); offset += 2; gl.xMin = bin.readShort(data, offset); offset += 2; gl.yMin = bin.readShort(data, offset); offset += 2; gl.xMax = bin.readShort(data, offset); offset += 2; gl.yMax = bin.readShort(data, offset); offset += 2; if (gl.xMin >= gl.xMax || gl.yMin >= gl.yMax) return null; if (gl.noc > 0) { gl.endPts = []; for (var i = 0; i < gl.noc; i++) { gl.endPts.push(bin.readUshort(data, offset)); offset += 2; } var instructionLength = bin.readUshort(data, offset); offset += 2; if (data.length - offset < instructionLength) return null; gl.instructions = bin.readBytes(data, offset, instructionLength); offset += instructionLength; var crdnum = gl.endPts[gl.noc - 1] + 1; gl.flags = []; for (var i = 0; i < crdnum; i++) { var flag = data[offset]; offset++; gl.flags.push(flag); if ((flag & 8) != 0) { var rep = data[offset]; offset++; for (var j = 0; j < rep; j++) { gl.flags.push(flag); i++; } } } gl.xs = []; for (var i = 0; i < crdnum; i++) { var i8 = (gl.flags[i] & 2) != 0, same = (gl.flags[i] & 16) != 0; if (i8) { gl.xs.push(same ? data[offset] : -data[offset]); offset++; } else { if (same) gl.xs.push(0); else { gl.xs.push(bin.readShort(data, offset)); offset += 2; } } } gl.ys = []; for (var i = 0; i < crdnum; i++) { var i8 = (gl.flags[i] & 4) != 0, same = (gl.flags[i] & 32) != 0; if (i8) { gl.ys.push(same ? data[offset] : -data[offset]); offset++; } else { if (same) gl.ys.push(0); else { gl.ys.push(bin.readShort(data, offset)); offset += 2; } } } var x = 0, y = 0; for (var i = 0; i < crdnum; i++) { x += gl.xs[i]; y += gl.ys[i]; gl.xs[i] = x; gl.ys[i] = y; } } else { var ARG_1_AND_2_ARE_WORDS = 1 << 0; var ARGS_ARE_XY_VALUES = 1 << 1; var WE_HAVE_A_SCALE = 1 << 3; var MORE_COMPONENTS = 1 << 5; var WE_HAVE_AN_X_AND_Y_SCALE = 1 << 6; var WE_HAVE_A_TWO_BY_TWO = 1 << 7; var WE_HAVE_INSTRUCTIONS = 1 << 8; gl.parts = []; var flags; do { flags = bin.readUshort(data, offset); offset += 2; var part = { m: { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 }, p1: -1, p2: -1 }; gl.parts.push(part); part.glyphIndex = bin.readUshort(data, offset); offset += 2; if (flags & ARG_1_AND_2_ARE_WORDS) { var arg1 = bin.readShort(data, offset); offset += 2; var arg2 = bin.readShort(data, offset); offset += 2; } else { var arg1 = bin.readInt8(data, offset); offset++; var arg2 = bin.readInt8(data, offset); offset++; } if (flags & ARGS_ARE_XY_VALUES) { part.m.tx = arg1; part.m.ty = arg2; } else { part.p1 = arg1; part.p2 = arg2; } if (flags & WE_HAVE_A_SCALE) { part.m.a = part.m.d = bin.readF2dot14(data, offset); offset += 2; } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) { part.m.a = bin.readF2dot14(data, offset); offset += 2; part.m.d = bin.readF2dot14(data, offset); offset += 2; } else if (flags & WE_HAVE_A_TWO_BY_TWO) { part.m.a = bin.readF2dot14(data, offset); offset += 2; part.m.b = bin.readF2dot14(data, offset); offset += 2; part.m.c = bin.readF2dot14(data, offset); offset += 2; part.m.d = bin.readF2dot14(data, offset); offset += 2; } } while (flags & MORE_COMPONENTS); if (flags & WE_HAVE_INSTRUCTIONS) { var numInstr = bin.readUshort(data, offset); offset += 2; gl.instr = []; for (var i = 0; i < numInstr; i++) { gl.instr.push(data[offset]); offset++; } } } return gl; } }; Typr["T"].head = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var obj = {}; bin.readFixed(data, offset); offset += 4; obj["fontRevision"] = bin.readFixed(data, offset); offset += 4; bin.readUint(data, offset); offset += 4; bin.readUint(data, offset); offset += 4; obj["flags"] = bin.readUshort(data, offset); offset += 2; obj["unitsPerEm"] = bin.readUshort(data, offset); offset += 2; obj["created"] = bin.readUint64(data, offset); offset += 8; obj["modified"] = bin.readUint64(data, offset); offset += 8; obj["xMin"] = bin.readShort(data, offset); offset += 2; obj["yMin"] = bin.readShort(data, offset); offset += 2; obj["xMax"] = bin.readShort(data, offset); offset += 2; obj["yMax"] = bin.readShort(data, offset); offset += 2; obj["macStyle"] = bin.readUshort(data, offset); offset += 2; obj["lowestRecPPEM"] = bin.readUshort(data, offset); offset += 2; obj["fontDirectionHint"] = bin.readShort(data, offset); offset += 2; obj["indexToLocFormat"] = bin.readShort(data, offset); offset += 2; obj["glyphDataFormat"] = bin.readShort(data, offset); offset += 2; return obj; } }; Typr["T"].hhea = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var obj = {}; bin.readFixed(data, offset); offset += 4; var keys = [ "ascender", "descender", "lineGap", "advanceWidthMax", "minLeftSideBearing", "minRightSideBearing", "xMaxExtent", "caretSlopeRise", "caretSlopeRun", "caretOffset", "res0", "res1", "res2", "res3", "metricDataFormat", "numberOfHMetrics" ]; for (var i = 0; i < keys.length; i++) { var key = keys[i]; var func = key == "advanceWidthMax" || key == "numberOfHMetrics" ? bin.readUshort : bin.readShort; obj[key] = func(data, offset + i * 2); } return obj; } }; Typr["T"].hmtx = { parseTab: function(data, offset, length, font) { var bin = Typr["B"]; var aWidth = []; var lsBearing = []; var nG = font["maxp"]["numGlyphs"], nH = font["hhea"]["numberOfHMetrics"]; var aw = 0, lsb = 0, i = 0; while (i < nH) { aw = bin.readUshort(data, offset + (i << 2)); lsb = bin.readShort(data, offset + (i << 2) + 2); aWidth.push(aw); lsBearing.push(lsb); i++; } while (i < nG) { aWidth.push(aw); lsBearing.push(lsb); i++; } return { aWidth: aWidth, lsBearing: lsBearing }; } }; Typr["T"].kern = { parseTab: function(data, offset, length, font) { var bin = Typr["B"], kern = Typr["T"].kern; var version = bin.readUshort(data, offset); if (version == 1) return kern.parseV1(data, offset, length, font); var nTables = bin.readUshort(data, offset + 2); offset += 4; var map = { glyph1: [], rval: [] }; for (var i = 0; i < nTables; i++) { offset += 2; var length = bin.readUshort(data, offset); offset += 2; var coverage = bin.readUshort(data, offset); offset += 2; var format = coverage >>> 8; format &= 15; if (format == 0) offset = kern.readFormat0(data, offset, map); } return map; }, parseV1: function(data, offset, length, font) { var bin = Typr["B"], kern = Typr["T"].kern; bin.readFixed(data, offset); var nTables = bin.readUint(data, offset + 4); offset += 8; var map = { glyph1: [], rval: [] }; for (var i = 0; i < nTables; i++) { bin.readUint(data, offset); offset += 4; var coverage = bin.readUshort(data, offset); offset += 2; bin.readUshort(data, offset); offset += 2; var format = coverage & 255; if (format == 0) offset = kern.readFormat0(data, offset, map); } return map; }, readFormat0: function(data, offset, map) { var bin = Typr["B"], rUs = bin.readUshort; var pleft = -1; var nPairs = rUs(data, offset); rUs(data, offset + 2); rUs(data, offset + 4); rUs(data, offset + 6); offset += 8; for (var j = 0; j < nPairs; j++) { var left = rUs(data, offset); offset += 2; var right = rUs(data, offset); offset += 2; var value = bin.readShort(data, offset); offset += 2; if (left != pleft) { map.glyph1.push(left); map.rval.push({ glyph2: [], vals: [] }); } var rval = map.rval[map.rval.length - 1]; rval.glyph2.push(right); rval.vals.push(value); pleft = left; } return offset; } }; Typr["T"].loca = { parseTab: function(data, offset, length, font) { var bin = Typr["B"]; var obj = []; var ver = font["head"]["indexToLocFormat"]; var len = font["maxp"]["numGlyphs"] + 1; if (ver == 0) for (var i = 0; i < len; i++) obj.push(bin.readUshort(data, offset + (i << 1)) << 1); if (ver == 1) for (var i = 0; i < len; i++) obj.push(bin.readUint(data, offset + (i << 2))); return obj; } }; Typr["T"].maxp = { parseTab: function(data, offset, length) { var bin = Typr["B"], rU = bin.readUshort; var obj = {}; bin.readUint(data, offset); offset += 4; obj["numGlyphs"] = rU(data, offset); offset += 2; return obj; } }; Typr["T"].name = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var obj = {}; bin.readUshort(data, offset); offset += 2; var count = bin.readUshort(data, offset); offset += 2; bin.readUshort(data, offset); offset += 2; var names = [ "copyright", "fontFamily", "fontSubfamily", "ID", "fullName", "version", "postScriptName", "trademark", "manufacturer", "designer", "description", "urlVendor", "urlDesigner", "licence", "licenceURL", "---", "typoFamilyName", "typoSubfamilyName", "compatibleFull", "sampleText", "postScriptCID", "wwsFamilyName", "wwsSubfamilyName", "lightPalette", "darkPalette" ]; var offset0 = offset; var rU = bin.readUshort; for (var i = 0; i < count; i++) { var platformID = rU(data, offset); offset += 2; var encodingID = rU(data, offset); offset += 2; var languageID = rU(data, offset); offset += 2; var nameID = rU(data, offset); offset += 2; var slen = rU(data, offset); offset += 2; var noffset = rU(data, offset); offset += 2; var soff = offset0 + count * 12 + noffset; var str; if (platformID == 0) str = bin.readUnicode(data, soff, slen / 2); else if (platformID == 3 && encodingID == 0) str = bin.readUnicode(data, soff, slen / 2); else if (encodingID == 0) str = bin.readASCII(data, soff, slen); else if (encodingID == 1) str = bin.readUnicode(data, soff, slen / 2); else if (encodingID == 3) str = bin.readUnicode(data, soff, slen / 2); else if (encodingID == 4) str = bin.readUnicode(data, soff, slen / 2); else if (encodingID == 10) str = bin.readUnicode(data, soff, slen / 2); else if (platformID == 1) { str = bin.readASCII(data, soff, slen); console.log("reading unknown MAC encoding " + encodingID + " as ASCII"); } else { console.log("unknown encoding " + encodingID + ", platformID: " + platformID); str = bin.readASCII(data, soff, slen); } var tid = "p" + platformID + "," + languageID.toString(16); if (obj[tid] == null) obj[tid] = {}; obj[tid][names[nameID]] = str; obj[tid]["_lang"] = languageID; } var psn = "postScriptName"; for (var p in obj) if (obj[p][psn] != null && obj[p]["_lang"] == 1033) return obj[p]; for (var p in obj) if (obj[p][psn] != null && obj[p]["_lang"] == 0) return obj[p]; for (var p in obj) if (obj[p][psn] != null && obj[p]["_lang"] == 3084) return obj[p]; for (var p in obj) if (obj[p][psn] != null) return obj[p]; var out; for (var p in obj) { out = obj[p]; break; } console.log("returning name table with languageID " + out._lang); if (out[psn] == null && out["ID"] != null) out[psn] = out["ID"]; return out; } }; Typr["T"].OS2 = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var ver = bin.readUshort(data, offset); offset += 2; var OS2 = Typr["T"].OS2; var obj = {}; if (ver == 0) OS2.version0(data, offset, obj); else if (ver == 1) OS2.version1(data, offset, obj); else if (ver == 2 || ver == 3 || ver == 4) OS2.version2(data, offset, obj); else if (ver == 5) OS2.version5(data, offset, obj); else throw "unknown OS/2 table version: " + ver; return obj; }, version0: function(data, offset, obj) { var bin = Typr["B"]; obj["xAvgCharWidth"] = bin.readShort(data, offset); offset += 2; obj["usWeightClass"] = bin.readUshort(data, offset); offset += 2; obj["usWidthClass"] = bin.readUshort(data, offset); offset += 2; obj["fsType"] = bin.readUshort(data, offset); offset += 2; obj["ySubscriptXSize"] = bin.readShort(data, offset); offset += 2; obj["ySubscriptYSize"] = bin.readShort(data, offset); offset += 2; obj["ySubscriptXOffset"] = bin.readShort(data, offset); offset += 2; obj["ySubscriptYOffset"] = bin.readShort(data, offset); offset += 2; obj["ySuperscriptXSize"] = bin.readShort(data, offset); offset += 2; obj["ySuperscriptYSize"] = bin.readShort(data, offset); offset += 2; obj["ySuperscriptXOffset"] = bin.readShort(data, offset); offset += 2; obj["ySuperscriptYOffset"] = bin.readShort(data, offset); offset += 2; obj["yStrikeoutSize"] = bin.readShort(data, offset); offset += 2; obj["yStrikeoutPosition"] = bin.readShort(data, offset); offset += 2; obj["sFamilyClass"] = bin.readShort(data, offset); offset += 2; obj["panose"] = bin.readBytes(data, offset, 10); offset += 10; obj["ulUnicodeRange1"] = bin.readUint(data, offset); offset += 4; obj["ulUnicodeRange2"] = bin.readUint(data, offset); offset += 4; obj["ulUnicodeRange3"] = bin.readUint(data, offset); offset += 4; obj["ulUnicodeRange4"] = bin.readUint(data, offset); offset += 4; obj["achVendID"] = bin.readASCII(data, offset, 4); offset += 4; obj["fsSelection"] = bin.readUshort(data, offset); offset += 2; obj["usFirstCharIndex"] = bin.readUshort(data, offset); offset += 2; obj["usLastCharIndex"] = bin.readUshort(data, offset); offset += 2; obj["sTypoAscender"] = bin.readShort(data, offset); offset += 2; obj["sTypoDescender"] = bin.readShort(data, offset); offset += 2; obj["sTypoLineGap"] = bin.readShort(data, offset); offset += 2; obj["usWinAscent"] = bin.readUshort(data, offset); offset += 2; obj["usWinDescent"] = bin.readUshort(data, offset); offset += 2; return offset; }, version1: function(data, offset, obj) { var bin = Typr["B"]; offset = Typr["T"].OS2.version0(data, offset, obj); obj["ulCodePageRange1"] = bin.readUint(data, offset); offset += 4; obj["ulCodePageRange2"] = bin.readUint(data, offset); offset += 4; return offset; }, version2: function(data, offset, obj) { var bin = Typr["B"], rU = bin.readUshort; offset = Typr["T"].OS2.version1(data, offset, obj); obj["sxHeight"] = bin.readShort(data, offset); offset += 2; obj["sCapHeight"] = bin.readShort(data, offset); offset += 2; obj["usDefault"] = rU(data, offset); offset += 2; obj["usBreak"] = rU(data, offset); offset += 2; obj["usMaxContext"] = rU(data, offset); offset += 2; return offset; }, version5: function(data, offset, obj) { var rU = Typr["B"].readUshort; offset = Typr["T"].OS2.version2(data, offset, obj); obj["usLowerOpticalPointSize"] = rU(data, offset); offset += 2; obj["usUpperOpticalPointSize"] = rU(data, offset); offset += 2; return offset; } }; Typr["T"].post = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var obj = {}; obj["version"] = bin.readFixed(data, offset); offset += 4; obj["italicAngle"] = bin.readFixed(data, offset); offset += 4; obj["underlinePosition"] = bin.readShort(data, offset); offset += 2; obj["underlineThickness"] = bin.readShort(data, offset); offset += 2; return obj; } }; Typr["T"].SVG = { parseTab: function(data, offset, length) { var bin = Typr["B"]; var obj = { entries: [] }; var offset0 = offset; bin.readUshort(data, offset); offset += 2; var svgDocIndexOffset = bin.readUint(data, offset); offset += 4; bin.readUint(data, offset); offset += 4; offset = svgDocIndexOffset + offset0; var numEntries = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < numEntries; i++) { var startGlyphID = bin.readUshort(data, offset); offset += 2; var endGlyphID = bin.readUshort(data, offset); offset += 2; var svgDocOffset = bin.readUint(data, offset); offset += 4; var svgDocLength = bin.readUint(data, offset); offset += 4; var sbuf = new Uint8Array(data.buffer, offset0 + svgDocOffset + svgDocIndexOffset, svgDocLength); var svg = bin.readUTF8(sbuf, 0, sbuf.length); for (var f = startGlyphID; f <= endGlyphID; f++) { obj.entries[f] = svg; } } return obj; } }; Typr["U"] = { shape: function(font, str, ltr) { var getGlyphPosition = function(font, gls, i1, ltr) { var g1 = gls[i1], g2 = gls[i1 + 1], kern = font["kern"]; if (kern) { var ind1 = kern.glyph1.indexOf(g1); if (ind1 != -1) { var ind2 = kern.rval[ind1].glyph2.indexOf(g2); if (ind2 != -1) return [ 0, 0, kern.rval[ind1].vals[ind2], 0 ]; } } return [ 0, 0, 0, 0 ]; }; var gls = []; for (var i = 0; i < str.length; i++) { var cc = str.codePointAt(i); if (cc > 65535) i++; gls.push(Typr["U"]["codeToGlyph"](font, cc)); } var shape = []; for (var i = 0; i < gls.length; i++) { var padj = getGlyphPosition(font, gls, i); var gid = gls[i]; var ax = font["hmtx"].aWidth[gid] + padj[2]; shape.push({ g: gid, cl: i, dx: 0, dy: 0, ax: ax, ay: 0 }); } return shape; }, shapeToPath: function(font, shape, clr) { var tpath = { cmds: [], crds: [] }; var x = 0, y = 0; for (var i = 0; i < shape.length; i++) { var it = shape[i]; var path = Typr["U"]["glyphToPath"](font, it["g"]), crds = path["crds"]; for (var j = 0; j < crds.length; j += 2) { tpath.crds.push(crds[j] + x + it["dx"]); tpath.crds.push(crds[j + 1] + y + it["dy"]); } if (clr) tpath.cmds.push(clr); for (var j = 0; j < path["cmds"].length; j++) tpath.cmds.push(path["cmds"][j]); var clen = tpath.cmds.length; if (clr) if (clen != 0 && tpath.cmds[clen - 1] != "X") tpath.cmds.push("X"); x += it["ax"]; y += it["ay"]; } return { cmds: tpath.cmds, crds: tpath.crds }; }, codeToGlyph: function(font, code) { var cmap = font["cmap"]; var tind = -1, pps = [ "p3e10", "p0e4", "p3e1", "p1e0", "p0e3", "p0e1" ]; for (var i = 0; i < pps.length; i++) if (cmap.ids[pps[i]] != null) { tind = cmap.ids[pps[i]]; break; } if (tind == -1) throw "no familiar platform and encoding!"; var arrSearch = function(arr, k, v) { var l = 0, r = Math.floor(arr.length / k); while (l + 1 != r) { var mid = l + (r - l >>> 1); if (arr[mid * k] <= v) l = mid; else r = mid; } return l * k; }; var tab = cmap.tables[tind], fmt = tab.format, gid = -1; if (fmt == 0) { if (code >= tab.map.length) gid = 0; else gid = tab.map[code]; } else if (fmt == 4) { var sind = -1, ec = tab.endCount; if (code > ec[ec.length - 1]) sind = -1; else { sind = arrSearch(ec, 1, code); if (ec[sind] < code) sind++; } if (sind == -1) gid = 0; else if (code < tab.startCount[sind]) gid = 0; else { var gli = 0; if (tab.idRangeOffset[sind] != 0) gli = tab.glyphIdArray[code - tab.startCount[sind] + (tab.idRangeOffset[sind] >> 1) - (tab.idRangeOffset.length - sind)]; else gli = code + tab.idDelta[sind]; gid = gli & 65535; } } else if (fmt == 6) { var off = code - tab.firstCode, arr = tab.glyphIdArray; if (off < 0 || off >= arr.length) gid = 0; else gid = arr[off]; } else if (fmt == 12) { var grp = tab.groups; if (code > grp[grp.length - 2]) gid = 0; else { var i = arrSearch(grp, 3, code); if (grp[i] <= code && code <= grp[i + 1]) { gid = grp[i + 2] + (code - grp[i]); } if (gid == -1) gid = 0; } } else throw "unknown cmap table format " + tab.format; var SVG = font["SVG "], loca = font["loca"]; if (gid != 0 && font["CFF "] == null && (SVG == null || SVG.entries[gid] == null) && loca[gid] == loca[gid + 1] && [ 9, 10, 11, 12, 13, 32, 133, 160, 5760, 8232, 8233, 8239, 12288, 6158, 8203, 8204, 8205, 8288, 65279 ].indexOf(code) == -1 && !(8192 <= code && code <= 8202)) gid = 0; return gid; }, glyphToPath: function(font, gid) { var path = { cmds: [], crds: [] }; var SVG = font["SVG "], CFF = font["CFF "]; var U = Typr["U"]; if (SVG && SVG.entries[gid]) { var p = SVG.entries[gid]; if (p != null) { if (typeof p == "string") { p = U["SVG"].toPath(p); SVG.entries[gid] = p; } path = p; } } else if (CFF) { var pdct = CFF["Private"]; var state = { x: 0, y: 0, stack: [], nStems: 0, haveWidth: false, width: pdct ? pdct["defaultWidthX"] : 0, open: false }; if (CFF["ROS"]) { var gi = 0; while (CFF["FDSelect"][gi + 2] <= gid) gi += 2; pdct = CFF["FDArray"][CFF["FDSelect"][gi + 1]]["Private"]; } U["_drawCFF"](CFF["CharStrings"][gid], state, CFF, pdct, path); } else if (font["glyf"]) { U["_drawGlyf"](gid, font, path); } return { cmds: path.cmds, crds: path.crds }; }, _drawGlyf: function(gid, font, path) { var gl = font["glyf"][gid]; if (gl == null) gl = font["glyf"][gid] = Typr["T"].glyf._parseGlyf(font, gid); if (gl != null) { if (gl.noc > -1) Typr["U"]["_simpleGlyph"](gl, path); else Typr["U"]["_compoGlyph"](gl, font, path); } }, _simpleGlyph: function(gl, p) { var P = Typr["U"]["P"]; for (var c = 0; c < gl.noc; c++) { var i0 = c == 0 ? 0 : gl.endPts[c - 1] + 1; var il = gl.endPts[c]; for (var i = i0; i <= il; i++) { var pr = i == i0 ? il : i - 1; var nx = i == il ? i0 : i + 1; var onCurve = gl.flags[i] & 1; var prOnCurve = gl.flags[pr] & 1; var nxOnCurve = gl.flags[nx] & 1; var x = gl.xs[i], y = gl.ys[i]; if (i == i0) { if (onCurve) { if (prOnCurve) P.MoveTo(p, gl.xs[pr], gl.ys[pr]); else { P.MoveTo(p, x, y); continue; } } else { if (prOnCurve) P.MoveTo(p, gl.xs[pr], gl.ys[pr]); else P.MoveTo(p, Math.floor((gl.xs[pr] + x) * .5), Math.floor((gl.ys[pr] + y) * .5)); } } if (onCurve) { if (prOnCurve) P.LineTo(p, x, y); } else { if (nxOnCurve) P.qCurveTo(p, x, y, gl.xs[nx], gl.ys[nx]); else P.qCurveTo(p, x, y, Math.floor((x + gl.xs[nx]) * .5), Math.floor((y + gl.ys[nx]) * .5)); } } P.ClosePath(p); } }, _compoGlyph: function(gl, font, p) { for (var j = 0; j < gl.parts.length; j++) { var path = { cmds: [], crds: [] }; var prt = gl.parts[j]; Typr["U"]["_drawGlyf"](prt.glyphIndex, font, path); var m = prt.m; for (var i = 0; i < path.crds.length; i += 2) { var 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 (var i = 0; i < path.cmds.length; i++) p.cmds.push(path.cmds[i]); } }, pathToSVG: function(path, prec) { var cmds = path["cmds"], crds = path["crds"]; if (prec == null) prec = 5; var out = [], co = 0, lmap = { M: 2, L: 2, Q: 4, C: 6 }; for (var i = 0; i < cmds.length; i++) { var cmd = cmds[i], cn = co + (lmap[cmd] ? lmap[cmd] : 0); out.push(cmd); while (co < cn) { var c = crds[co++]; out.push(parseFloat(c.toFixed(prec)) + (co == cn ? "" : " ")); } } return out.join(""); }, SVGToPath: function(d) { var pth = { cmds: [], crds: [] }; Typr["U"]["SVG"].svgToPath(d, pth); return { cmds: pth.cmds, crds: pth.crds }; }, pathToContext: function(path, ctx) { var c = 0, cmds = path["cmds"], crds = path["crds"]; for (var j = 0; j < cmds.length; j++) { var cmd = cmds[j]; if (cmd == "M") { ctx.moveTo(crds[c], crds[c + 1]); c += 2; } else if (cmd == "L") { ctx.lineTo(crds[c], crds[c + 1]); c += 2; } else if (cmd == "C") { ctx.bezierCurveTo(crds[c], crds[c + 1], crds[c + 2], crds[c + 3], crds[c + 4], crds[c + 5]); c += 6; } else if (cmd == "Q") { ctx.quadraticCurveTo(crds[c], crds[c + 1], crds[c + 2], crds[c + 3]); c += 4; } else if (cmd.charAt(0) == "#") { ctx.beginPath(); ctx.fillStyle = cmd; } else if (cmd == "Z") { ctx.closePath(); } else if (cmd == "X") { ctx.fill(); } } }, P: { MoveTo: function(p, x, y) { p.cmds.push("M"); p.crds.push(x, y); }, LineTo: function(p, x, y) { p.cmds.push("L"); p.crds.push(x, y); }, CurveTo: function(p, a, b, c, d, e, f) { p.cmds.push("C"); p.crds.push(a, b, c, d, e, f); }, qCurveTo: function(p, a, b, c, d) { p.cmds.push("Q"); p.crds.push(a, b, c, d); }, ClosePath: function(p) { p.cmds.push("Z"); } }, _drawCFF: function(cmds, state, font, pdct, p) { var stack = state.stack; var nStems = state.nStems, haveWidth = state.haveWidth, width = state.width, open = state.open; var i = 0; var x = state.x, y = state.y, c1x = 0, c1y = 0, c2x = 0, c2y = 0, c3x = 0, c3y = 0, c4x = 0, c4y = 0, jpx = 0, jpy = 0; var CFF = Typr["T"].CFF, P = Typr["U"]["P"]; var nominalWidthX = pdct["nominalWidthX"]; var o = { val: 0, size: 0 }; while (i < cmds.length) { CFF.getCharString(cmds, i, o); var v = o.val; i += o.size; if (v == "o1" || v == "o18") { var hasWidthArg; hasWidthArg = stack.length % 2 !== 0; if (hasWidthArg && !haveWidth) { width = stack.shift() + nominalWidthX; } nStems += stack.length >> 1; stack.length = 0; haveWidth = true; } else if (v == "o3" || v == "o23") { var hasWidthArg; hasWidthArg = stack.length % 2 !== 0; if (hasWidthArg && !haveWidth) { width = stack.shift() + nominalWidthX; } nStems += stack.length >> 1; stack.length = 0; haveWidth = true; } else if (v == "o4") { if (stack.length > 1 && !haveWidth) { width = stack.shift() + nominalWidthX; haveWidth = true; } if (open) P.ClosePath(p); y += stack.pop(); P.MoveTo(p, x, y); open = true; } else if (v == "o5") { while (stack.length > 0) { x += stack.shift(); y += stack.shift(); P.LineTo(p, x, y); } } else if (v == "o6" || v == "o7") { var count = stack.length; var isX = v == "o6"; for (var j = 0; j < count; j++) { var sval = stack.shift(); if (isX) x += sval; else y += sval; isX = !isX; P.LineTo(p, x, y); } } else if (v == "o8" || v == "o24") { var count = stack.length; var index = 0; while (index + 6 <= count) { c1x = x + stack.shift(); c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); x = c2x + stack.shift(); y = c2y + stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, x, y); index += 6; } if (v == "o24") { x += stack.shift(); y += stack.shift(); P.LineTo(p, x, y); } } else if (v == "o11") break; else if (v == "o1234" || v == "o1235" || v == "o1236" || v == "o1237") { if (v == "o1234") { c1x = x + stack.shift(); c1y = y; c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); jpx = c2x + stack.shift(); jpy = c2y; c3x = jpx + stack.shift(); c3y = c2y; c4x = c3x + stack.shift(); c4y = y; x = c4x + stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy); P.CurveTo(p, c3x, c3y, c4x, c4y, x, y); } if (v == "o1235") { c1x = x + stack.shift(); c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); jpx = c2x + stack.shift(); jpy = c2y + stack.shift(); c3x = jpx + stack.shift(); c3y = jpy + stack.shift(); c4x = c3x + stack.shift(); c4y = c3y + stack.shift(); x = c4x + stack.shift(); y = c4y + stack.shift(); stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy); P.CurveTo(p, c3x, c3y, c4x, c4y, x, y); } if (v == "o1236") { c1x = x + stack.shift(); c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); jpx = c2x + stack.shift(); jpy = c2y; c3x = jpx + stack.shift(); c3y = c2y; c4x = c3x + stack.shift(); c4y = c3y + stack.shift(); x = c4x + stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy); P.CurveTo(p, c3x, c3y, c4x, c4y, x, y); } if (v == "o1237") { c1x = x + stack.shift(); c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); jpx = c2x + stack.shift(); jpy = c2y + stack.shift(); c3x = jpx + stack.shift(); c3y = jpy + stack.shift(); c4x = c3x + stack.shift(); c4y = c3y + stack.shift(); if (Math.abs(c4x - x) > Math.abs(c4y - y)) { x = c4x + stack.shift(); } else { y = c4y + stack.shift(); } P.CurveTo(p, c1x, c1y, c2x, c2y, jpx, jpy); P.CurveTo(p, c3x, c3y, c4x, c4y, x, y); } } else if (v == "o14") { if (stack.length > 0 && !haveWidth) { width = stack.shift() + font["nominalWidthX"]; haveWidth = true; } if (stack.length == 4) { var adx = stack.shift(); var ady = stack.shift(); var bchar = stack.shift(); var achar = stack.shift(); var bind = CFF.glyphBySE(font, bchar); var aind = CFF.glyphBySE(font, achar); Typr["U"]["_drawCFF"](font["CharStrings"][bind], state, font, pdct, p); state.x = adx; state.y = ady; Typr["U"]["_drawCFF"](font["CharStrings"][aind], state, font, pdct, p); } if (open) { P.ClosePath(p); open = false; } } else if (v == "o19" || v == "o20") { var hasWidthArg; hasWidthArg = stack.length % 2 !== 0; if (hasWidthArg && !haveWidth) { width = stack.shift() + nominalWidthX; } nStems += stack.length >> 1; stack.length = 0; haveWidth = true; i += nStems + 7 >> 3; } else if (v == "o21") { if (stack.length > 2 && !haveWidth) { width = stack.shift() + nominalWidthX; haveWidth = true; } y += stack.pop(); x += stack.pop(); if (open) P.ClosePath(p); P.MoveTo(p, x, y); open = true; } else if (v == "o22") { if (stack.length > 1 && !haveWidth) { width = stack.shift() + nominalWidthX; haveWidth = true; } x += stack.pop(); if (open) P.ClosePath(p); P.MoveTo(p, x, y); open = true; } else if (v == "o25") { while (stack.length > 6) { x += stack.shift(); y += stack.shift(); P.LineTo(p, x, y); } c1x = x + stack.shift(); c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); x = c2x + stack.shift(); y = c2y + stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, x, y); } else if (v == "o26") { if (stack.length % 2) { x += stack.shift(); } while (stack.length > 0) { c1x = x; c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); x = c2x; y = c2y + stack.shift(); P.CurveTo(p, c1x, c1y, c2x, c2y, x, y); } } else if (v == "o27") { if (stack.length % 2) { y += stack.shift(); } while (stack.length > 0) { c1x = x + stack.shift(); c1y = y; c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); x = c2x + stack.shift(); y = c2y; P.CurveTo(p, c1x, c1y, c2x, c2y, x, y); } } else if (v == "o10" || v == "o29") { var obj = v == "o10" ? pdct : font; if (stack.length == 0) { console.log("error: empty stack"); } else { var ind = stack.pop(); var subr = obj["Subrs"][ind + obj["Bias"]]; state.x = x; state.y = y; state.nStems = nStems; state.haveWidth = haveWidth; state.width = width; state.open = open; Typr["U"]["_drawCFF"](subr, state, font, pdct, p); x = state.x; y = state.y; nStems = state.nStems; haveWidth = state.haveWidth; width = state.width; open = state.open; } } else if (v == "o30" || v == "o31") { var count, count1 = stack.length; var index = 0; var alternate = v == "o31"; count = count1 & ~2; index += count1 - count; while (index < count) { if (alternate) { c1x = x + stack.shift(); c1y = y; c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); y = c2y + stack.shift(); if (count - index == 5) { x = c2x + stack.shift(); index++; } else x = c2x; alternate = false; } else { c1x = x; c1y = y + stack.shift(); c2x = c1x + stack.shift(); c2y = c1y + stack.shift(); x = c2x + stack.shift(); if (count - index == 5) { y = c2y + stack.shift(); index++; } else y = c2y; alternate = true; } P.CurveTo(p, c1x, c1y, c2x, c2y, x, y); index += 4; } } else if ((v + "").charAt(0) == "o") { console.log("Unknown operation: " + v, cmds); throw v; } else stack.push(v); } state.x = x; state.y = y; state.nStems = nStems; state.haveWidth = haveWidth; state.width = width; state.open = open; }, SVG: function() { var M = { getScale: function(m) { return Math.sqrt(Math.abs(m[0] * m[3] - m[1] * m[2])); }, translate: function(m, x, y) { M.concat(m, [ 1, 0, 0, 1, x, y ]); }, rotate: function(m, a) { M.concat(m, [ Math.cos(a), -Math.sin(a), Math.sin(a), Math.cos(a), 0, 0 ]); }, scale: function(m, x, y) { M.concat(m, [ x, 0, 0, y, 0, 0 ]); }, concat: function(m, w) { var a = m[0], b = m[1], c = m[2], d = m[3], tx = m[4], ty = m[5]; m[0] = a * w[0] + b * w[2]; m[1] = a * w[1] + b * w[3]; m[2] = c * w[0] + d * w[2]; m[3] = c * w[1] + d * w[3]; m[4] = tx * w[0] + ty * w[2] + w[4]; m[5] = tx * w[1] + ty * w[3] + w[5]; }, invert: function(m) { var a = m[0], b = m[1], c = m[2], d = m[3], tx = m[4], ty = m[5], adbc = a * d - b * c; m[0] = d / adbc; m[1] = -b / adbc; m[2] = -c / adbc; m[3] = a / adbc; m[4] = (c * ty - d * tx) / adbc; m[5] = (b * tx - a * ty) / adbc; }, multPoint: function(m, p) { var x = p[0], y = p[1]; return [ x * m[0] + y * m[2] + m[4], x * m[1] + y * m[3] + m[5] ]; }, multArray: function(m, a) { for (var i = 0; i < a.length; i += 2) { var x = a[i], y = a[i + 1]; a[i] = x * m[0] + y * m[2] + m[4]; a[i + 1] = x * m[1] + y * m[3] + m[5]; } } }; function _bracketSplit(str, lbr, rbr) { var out = [], pos = 0, ci = 0, lvl = 0; while (true) { var li = str.indexOf(lbr, ci); var ri = str.indexOf(rbr, ci); if (li == -1 && ri == -1) break; if (ri == -1 || li != -1 && li < ri) { if (lvl == 0) { out.push(str.slice(pos, li).trim()); pos = li + 1; } lvl++; ci = li + 1; } else if (li == -1 || ri != -1 && ri < li) { lvl--; if (lvl == 0) { out.push(str.slice(pos, ri).trim()); pos = ri + 1; } ci = ri + 1; } } return out; } function cssMap(str) { var pts = _bracketSplit(str, "{", "}"); var css = {}; for (var i = 0; i < pts.length; i += 2) { var cn = pts[i].split(","); for (var j = 0; j < cn.length; j++) { var cnj = cn[j].trim(); if (css[cnj] == null) css[cnj] = ""; css[cnj] += pts[i + 1]; } } return css; } function readTrnf(trna) { var pts = _bracketSplit(trna, "(", ")"); var m = [ 1, 0, 0, 1, 0, 0 ]; for (var i = 0; i < pts.length; i += 2) { var om = m; m = _readTrnsAttr(pts[i], pts[i + 1]); M.concat(m, om); } return m; } function _readTrnsAttr(fnc, vls) { var m = [ 1, 0, 0, 1, 0, 0 ], gotSep = true; for (var i = 0; i < vls.length; i++) { var ch = vls.charAt(i); if (ch == "," || ch == " ") gotSep = true; else if (ch == ".") { if (!gotSep) { vls = vls.slice(0, i) + "," + vls.slice(i); i++; } gotSep = false; } else if (ch == "-" && i > 0 && vls[i - 1] != "e") { vls = vls.slice(0, i) + " " + vls.slice(i); i++; gotSep = true; } } vls = vls.split(/\s*[\s,]\s*/).map(parseFloat); if (fnc == "translate") { if (vls.length == 1) M.translate(m, vls[0], 0); else M.translate(m, vls[0], vls[1]); } else if (fnc == "scale") { if (vls.length == 1) M.scale(m, vls[0], vls[0]); else M.scale(m, vls[0], vls[1]); } else if (fnc == "rotate") { var tx = 0, ty = 0; if (vls.length != 1) { tx = vls[1]; ty = vls[2]; } M.translate(m, -tx, -ty); M.rotate(m, -Math.PI * vls[0] / 180); M.translate(m, tx, ty); } else if (fnc == "matrix") m = vls; else console.log("unknown transform: ", fnc); return m; } function toPath(str) { var pth = { cmds: [], crds: [] }; if (str == null) return pth; var prsr = new DOMParser(); var doc = prsr["parseFromString"](str, "image/svg+xml"); var svg = doc.getElementsByTagName("svg")[0]; var vb = svg.getAttribute("viewBox"); if (vb) vb = vb.trim().split(" ").map(parseFloat); else vb = [ 0, 0, 1e3, 1e3 ]; _toPath(svg.children, pth); for (var i = 0; i < pth.crds.length; i += 2) { var x = pth.crds[i], y = pth.crds[i + 1]; x -= vb[0]; y -= vb[1]; y = -y; pth.crds[i] = x; pth.crds[i + 1] = y; } return pth; } function _toPath(nds, pth, fill) { for (var ni = 0; ni < nds.length; ni++) { var nd = nds[ni], tn = nd.tagName; var cfl = nd.getAttribute("fill"); if (cfl == null) cfl = fill; if (tn == "g") { var tp = { crds: [], cmds: [] }; _toPath(nd.children, tp, cfl); var trf = nd.getAttribute("transform"); if (trf) { var m = readTrnf(trf); M.multArray(m, tp.crds); } pth.crds = pth.crds.concat(tp.crds); pth.cmds = pth.cmds.concat(tp.cmds); } else if (tn == "path" || tn == "circle" || tn == "ellipse") { pth.cmds.push(cfl ? cfl : "#000000"); var d; if (tn == "path") d = nd.getAttribute("d"); if (tn == "circle" || tn == "ellipse") { var vls = [ 0, 0, 0, 0 ], nms = [ "cx", "cy", "rx", "ry", "r" ]; for (var i = 0; i < 5; i++) { var V = nd.getAttribute(nms[i]); if (V) { V = parseFloat(V); if (i < 4) vls[i] = V; else vls[2] = vls[3] = V; } } var cx = vls[0], cy = vls[1], rx = vls[2], ry = vls[3]; d = [ "M", cx - rx, cy, "a", rx, ry, 0, 1, 0, rx * 2, 0, "a", rx, ry, 0, 1, 0, -rx * 2, 0 ].join(" "); } svgToPath(d, pth); pth.cmds.push("X"); } else if (tn == "defs"); else console.log(tn, nd); } } function _tokens(d) { var ts = [], off = 0, rn = false, cn = "", pc = ""; while (off < d.length) { var cc = d.charCodeAt(off), ch = d.charAt(off); off++; var isNum = 48 <= cc && cc <= 57 || ch == "." || ch == "-" || ch == "e" || ch == "E"; if (rn) { if (ch == "-" && pc != "e" || ch == "." && cn.indexOf(".") != -1) { ts.push(parseFloat(cn)); cn = ch; } else if (isNum) cn += ch; else { ts.push(parseFloat(cn)); if (ch != "," && ch != " ") ts.push(ch); rn = false; } } else { if (isNum) { cn = ch; rn = true; } else if (ch != "," && ch != " ") ts.push(ch); } pc = ch; } if (rn) ts.push(parseFloat(cn)); return ts; } function _reps(ts, off, ps) { var i = off; while (i < ts.length) { if (typeof ts[i] == "string") break; i += ps; } return (i - off) / ps; } function svgToPath(d, pth) { var ts = _tokens(d); var i = 0, x = 0, y = 0, ox = 0, oy = 0, oldo = pth.crds.length; var pc = { M: 2, L: 2, H: 1, V: 1, T: 2, S: 4, A: 7, Q: 4, C: 6 }; var cmds = pth.cmds, crds = pth.crds; while (i < ts.length) { var cmd = ts[i]; i++; var cmu = cmd.toUpperCase(); if (cmu == "Z") { cmds.push("Z"); x = ox; y = oy; } else { var ps = pc[cmu], reps = _reps(ts, i, ps); for (var j = 0; j < reps; j++) { if (j == 1 && cmu == "M") { cmd = cmd == cmu ? "L" : "l"; cmu = "L"; } var xi = 0, yi = 0; if (cmd != cmu) { xi = x; yi = y; } if (cmu == "M") { x = xi + ts[i++]; y = yi + ts[i++]; cmds.push("M"); crds.push(x, y); ox = x; oy = y; } else if (cmu == "L") { x = xi + ts[i++]; y = yi + ts[i++]; cmds.push("L"); crds.push(x, y); } else if (cmu == "H") { x = xi + ts[i++]; cmds.push("L"); crds.push(x, y); } else if (cmu == "V") { y = yi + ts[i++]; cmds.push("L"); crds.push(x, y); } else if (cmu == "Q") { var x1 = xi + ts[i++], y1 = yi + ts[i++], x2 = xi + ts[i++], y2 = yi + ts[i++]; cmds.push("Q"); crds.push(x1, y1, x2, y2); x = x2; y = y2; } else if (cmu == "T") { var co = Math.max(crds.length - 2, oldo); var x1 = x + x - crds[co], y1 = y + y - crds[co + 1]; var x2 = xi + ts[i++], y2 = yi + ts[i++]; cmds.push("Q"); crds.push(x1, y1, x2, y2); x = x2; y = y2; } else if (cmu == "C") { var x1 = xi + ts[i++], y1 = yi + ts[i++], x2 = xi + ts[i++], y2 = yi + ts[i++], x3 = xi + ts[i++], y3 = yi + ts[i++]; cmds.push("C"); crds.push(x1, y1, x2, y2, x3, y3); x = x3; y = y3; } else if (cmu == "S") { var co = Math.max(crds.length - (cmds[cmds.length - 1] == "C" ? 4 : 2), oldo); var x1 = x + x - crds[co], y1 = y + y - crds[co + 1]; var x2 = xi + ts[i++], y2 = yi + ts[i++], x3 = xi + ts[i++], y3 = yi + ts[i++]; cmds.push("C"); crds.push(x1, y1, x2, y2, x3, y3); x = x3; y = y3; } else if (cmu == "A") { var x1 = x, y1 = y; var rx = ts[i++], ry = ts[i++]; var phi = ts[i++] * (Math.PI / 180), fA = ts[i++], fS = ts[i++]; var x2 = xi + ts[i++], y2 = yi + ts[i++]; if (x2 == x && y2 == y && rx == 0 && ry == 0) continue; var hdx = (x1 - x2) / 2, hdy = (y1 - y2) / 2; var cosP = Math.cos(phi), sinP = Math.sin(phi); var x1A = cosP * hdx + sinP * hdy; var y1A = -sinP * hdx + cosP * hdy; var rxS = rx * rx, ryS = ry * ry; var x1AS = x1A * x1A, y1AS = y1A * y1A; var frc = (rxS * ryS - rxS * y1AS - ryS * x1AS) / (rxS * y1AS + ryS * x1AS); var coef = (fA != fS ? 1 : -1) * Math.sqrt(Math.max(frc, 0)); var cxA = coef * (rx * y1A) / ry; var cyA = -coef * (ry * x1A) / rx; var cx = cosP * cxA - sinP * cyA + (x1 + x2) / 2; var cy = sinP * cxA + cosP * cyA + (y1 + y2) / 2; var angl = function(ux, uy, vx, vy) { var lU = Math.sqrt(ux * ux + uy * uy), lV = Math.sqrt(vx * vx + vy * vy); var num = (ux * vx + uy * vy) / (lU * lV); return (ux * vy - uy * vx >= 0 ? 1 : -1) * Math.acos(Math.max(-1, Math.min(1, num))); }; var vX = (x1A - cxA) / rx, vY = (y1A - cyA) / ry; var theta1 = angl(1, 0, vX, vY); var dtheta = angl(vX, vY, (-x1A - cxA) / rx, (-y1A - cyA) / ry); dtheta = dtheta % (2 * Math.PI); var arc = function(gst, x, y, r, a0, a1, neg) { var rotate = function(m, a) { var si = Math.sin(a), co = Math.cos(a); var a = m[0], b = m[1], c = m[2], d = m[3]; m[0] = a * co + b * si; m[1] = -a * si + b * co; m[2] = c * co + d * si; m[3] = -c * si + d * co; }; var multArr = function(m, a) { for (var j = 0; j < a.length; j += 2) { var x = a[j], y = a[j + 1]; a[j] = m[0] * x + m[2] * y + m[4]; a[j + 1] = m[1] * x + m[3] * y + m[5]; } }; var concatA = function(a, b) { for (var j = 0; j < b.length; j++) a.push(b[j]); }; var concatP = function(p, r) { concatA(p.cmds, r.cmds); concatA(p.crds, r.crds); }; if (neg) while (a1 > a0) a1 -= 2 * Math.PI; else while (a1 < a0) a1 += 2 * Math.PI; var th = (a1 - a0) / 4; var x0 = Math.cos(th / 2), y0 = -Math.sin(th / 2); var x1 = (4 - x0) / 3, y1 = y0 == 0 ? y0 : (1 - x0) * (3 - x0) / (3 * y0); var x2 = x1, y2 = -y1; var x3 = x0, y3 = -y0; var ps = [ x1, y1, x2, y2, x3, y3 ]; var pth = { cmds: [ "C", "C", "C", "C" ], crds: ps.slice(0) }; var rot = [ 1, 0, 0, 1, 0, 0 ]; rotate(rot, -th); for (var j = 0; j < 3; j++) { multArr(rot, ps); concatA(pth.crds, ps); } rotate(rot, -a0 + th / 2); rot[0] *= r; rot[1] *= r; rot[2] *= r; rot[3] *= r; rot[4] = x; rot[5] = y; multArr(rot, pth.crds); multArr(gst.ctm, pth.crds); concatP(gst.pth, pth); }; var gst = { pth: pth, ctm: [ rx * cosP, rx * sinP, -ry * sinP, ry * cosP, cx, cy ] }; arc(gst, 0, 0, 1, theta1, theta1 + dtheta, fS == 0); x = x2; y = y2; } else console.log("Unknown SVG command " + cmd); } } } } return { cssMap: cssMap, readTrnf: readTrnf, svgToPath: svgToPath, toPath: toPath }; }(), initHB: function(hurl, resp) { var codeLength = function(code) { var len = 0; if ((code & 4294967295 - (1 << 7) + 1) == 0) { len = 1; } else if ((code & 4294967295 - (1 << 11) + 1) == 0) { len = 2; } else if ((code & 4294967295 - (1 << 16) + 1) == 0) { len = 3; } else if ((code & 4294967295 - (1 << 21) + 1) == 0) { len = 4; } return len; }; var te = new window["TextEncoder"]("utf8"); fetch(hurl).then(function(x) { return x["arrayBuffer"](); }).then(function(ab) { return WebAssembly["instantiate"](ab); }).then(function(res) { console.log("HB ready"); var exp = res["instance"]["exports"], mem = exp["memory"]; mem["grow"](700); var heapu8 = new Uint8Array(mem.buffer); var u32 = new Uint32Array(mem.buffer); var i32 = new Int32Array(mem.buffer); var __lastFnt, blob, blobPtr, face, font; Typr["U"]["shapeHB"] = function() { var toJson = function(ptr) { var length = exp["hb_buffer_get_length"](ptr); var result = []; var iPtr32 = exp["hb_buffer_get_glyph_infos"](ptr, 0) >>> 2; var pPtr32 = exp["hb_buffer_get_glyph_positions"](ptr, 0) >>> 2; for (var i = 0; i < length; ++i) { var a = iPtr32 + i * 5, b = pPtr32 + i * 5; result.push({ g: u32[a + 0], cl: u32[a + 2], ax: i32[b + 0], ay: i32[b + 1], dx: i32[b + 2], dy: i32[b + 3] }); } return result; }; return function(fnt, str, ltr) { var fdata = fnt["_data"], fn = fnt["name"]["postScriptName"]; if (__lastFnt != fn) { if (blob != null) { exp["hb_blob_destroy"](blob); exp["free"](blobPtr); exp["hb_face_destroy"](face); exp["hb_font_destroy"](font); } blobPtr = exp["malloc"](fdata.byteLength); heapu8.set(fdata, blobPtr); blob = exp["hb_blob_create"](blobPtr, fdata.byteLength, 2, 0, 0); face = exp["hb_face_create"](blob, 0); font = exp["hb_font_create"](face); __lastFnt = fn; } var buffer = exp["hb_buffer_create"](); var bytes = te["encode"](str); var len = bytes.length, strp = exp["malloc"](len); heapu8.set(bytes, strp); exp["hb_buffer_add_utf8"](buffer, strp, len, 0, len); exp["free"](strp); exp["hb_buffer_set_direction"](buffer, ltr ? 4 : 5); exp["hb_buffer_guess_segment_properties"](buffer); exp["hb_shape"](font, buffer, 0, 0); var json = toJson(buffer); exp["hb_buffer_destroy"](buffer); var arr = json.slice(0); if (!ltr) arr.reverse(); var ci = 0, bi = 0; for (var i = 1; i < arr.length; i++) { var gl = arr[i], cl = gl["cl"]; while (true) { var cpt = str.codePointAt(ci), cln = codeLength(cpt); if (bi + cln <= cl) { bi += cln; ci += cpt <= 65535 ? 1 : 2; } else break; } gl["cl"] = ci; } return json; }; }(); resp(); }); } }; const QQ_GROUP = [ "854137118" ]; var _self = unsafeWindow; var top = _self; var UE$1; const selfintv = setInterval(() => { if (unsafeWindow) { _self = unsafeWindow; top = _self; UE$1 = _self.UE; try { reportOnline(); String.prototype.replaceAll = function(s1, s2) { return this.replace(new RegExp(s1, "gm"), s2); }; while (top !== _self.top) { top = top.parent.document ? top.parent : _self.top; if (top.location.pathname === "/mycourse/studentstudy") break; } } catch (err) { top = _self; } clearInterval(selfintv); } }, GLOBAL.delay); function checkVersion() { function compare(v1 = "0", v2 = "0") { v1 = String(v1).split("."); v2 = String(v2).split("."); const minVersionLens = Math.min(v1.length, v2.length); let result = 0; for (let i = 0; i < minVersionLens; i++) { const curV1 = Number(v1[i]); const curV2 = Number(v2[i]); if (curV1 > curV2) { result = 1; break; } else if (curV1 < curV2) { result = -1; break; } } if (result === 0 && v1.length !== v2.length) { const v1BiggerThenv2 = v1.length > v2.length; const maxLensVersion = v1BiggerThenv2 ? v1 : v2; for (let i = minVersionLens; i < maxLensVersion.length; i++) { const curVersion = Number(maxLensVersion[i]); if (curVersion > 0) { v1BiggerThenv2 ? result = 1 : result = -1; break; } } } return result; } GM_xmlhttpRequest({ method: "GET", url: "https://greasyfork.org/en/scripts/451356.json", timeout: GLOBAL.timeout, onload: function(r) { const obj = JSON.parse(r.responseText); if (obj.name === GM_info.script.name && compare(obj.version, GM_info.script.version) === 1 && new Date(obj.code_updated_at).getTime() + 1e3 * 60 * 60 * 2 < new Date().getTime()) { iframeMsg("update", { v1: GM_info.script.version, v2: obj.version, href: obj.url }); } } }); } top.addEventListener("message", event => { if (event.data.type === "jump") { GLOBAL.index++; iframeMsg("tip", { tip: "准备答第" + (GLOBAL.index + 1) + "题" }); } else if (event.data.type === "stop") { GLOBAL.stop = event.data.val; } else if (event.data.type === "start_pay") { if (event.data.flag) { if (String(GM_getValue("token")).length === 10 || String(GM_getValue("token")).length === 11) { iframeMsg("tip", { tip: "已开启请求收费题库,已实时生效" }); GM_setValue("start_pay", event.data.flag); iframeMsg("start_pay", true); } else { iframeMsg("tip", { tip: "系统检测您的token可能输入有误,请检查" }); } } else { iframeMsg("tip", { tip: "已关闭请求收费题库,已实时生效" }); GM_setValue("start_pay", event.data.flag); iframeMsg("start_pay", false); } } else if (event.data.type === "auto_jump") { GM_setValue("auto_jump", event.data.flag); iframeMsg("tip", { tip: "已" + (event.data.flag ? "开启" : "关闭") + "自动切换,页面刷新后生效" }); } else if (event.data.type === "confim") { if (event.data.token.length === 10 || event.data.token.length === 11) { GM_setValue("token", event.data.token); iframeMsg("tip", { tip: "成功设置token,请点击开启付费题库" }); } else { iframeMsg("tip", { tip: "系统检测您的token可能输入有误,请检查" }); } } else if (event.data.type === "save_setting") { GM_setValue("gpt", event.data.gpt); GM_setValue("search_delay", event.data.search_delay); GM_setValue("tiku_adapter", event.data.tiku_adapter); } }, false); $(document).keydown(function(event) { if (event.keyCode === 38) { $(".model-id").hide(); } else if (event.keyCode === 40) { $(".model-id").show(); } else if (event.keyCode === 37) { $(".model-id").hide(); GM_setValue("hide", true); } else if (event.keyCode === 39) { $(".model-id").show(); GM_setValue("hide", false); GM_setValue("pos", "50px,50px"); } else if (event.keyCode === 83) { GLOBAL.stop = true; iframeMsg("stop", GLOBAL.stop); } else if (event.keyCode === 68) { GLOBAL.stop = false; iframeMsg("stop", GLOBAL.stop); } }); function getAnswerForKey(keys, options) { return keys.map(function(val) { return options[val.charCodeAt(0) - 65]; }); } function setIntervalFunc(flag, func, time) { const interval = setInterval(() => { if (flag()) { clearInterval(interval); func(); } }, time || 1e3); } function getAnswer(str, options, type) { if (type === 0 || type === 1) { const ans = getAnswerForKey(str.match(/[A-G]/gi) || [], options); return ans.length > 0 ? ans : [ str ]; } else { return [ str ]; } } function getQuestionType(str) { if (!str) return undefined; str = str.trim().replaceAll(/\s+/g, ""); if (TYPE[str]) return TYPE[str]; const regex = Object.keys(TYPE).join("|"); const matcher = str.match(regex); if (matcher) return TYPE[matcher[0]]; return undefined; } function rand(m, n) { return Math.ceil(Math.random() * (n - m + 1) + m - 1); } const TYPE = { "阅读理解（选择）/完型填空": 66, "听力训练": 66, multichoice: 1, singlechoice: 0, SingleChoice: 0, bijudgement: 3, Judgement: 3, "单项选择题": 0, "单项选择": 0, "单选题": 0, "单选": 0, "多选": 1, "多选题": 1, "案例分析": 1, "多项选择题": 1, "多项选择": 1, "客观题": 1, "填空题": 2, "填空": 2, "对错题": 3, "判断题": 3, "判断正误": 3, "判断": 3, "主观题": 4, "问答题": 4, "简答题": 4, "名词解释": 5, "论述题": 6, "计算题": 7, "其它": 8, "分录题": 9, "资料题": 10, "连线题": 11, "排序题": 13, "完形填空": 14, "完型填空": 14, "阅读理解": 15, "口语题": 18, "听力题": 19, "A1A2题": 1, "文件作答": 4, "视频题": 1 }; function sleep(time) { return new Promise(resolve => { setTimeout(resolve, time); }); } function iframeMsg(type, message) { try { top.document.getElementById("iframeNode").contentWindow.vueDefinedProp(type, message); } catch (e) {} } function filterImg(dom) { if (location.host === "ncexam.cug.edu.cn") { String.prototype.trim = function() { return this.replace(/^\s+|\s+$/gm, ""); }; } return $(dom).clone().find("img[src]").replaceWith(function() { return $(" ").text(' '); }).end().find("iframe[src]").replaceWith(function() { return $(" ").text(' </irame>'); }).end().text().trim(); } function createContainer(name, childElem) { name = name.toLowerCase(); let elem = top.document.createElement(name); elem.style.display = "block"; elem.id = name.replace("hcsearche", "hcSearche").replace(/\-[a-z]/g, function(w) { return w.replace("-", "").toUpperCase(); }); if (childElem) { if (Array.isArray(childElem) === false) childElem = [ childElem ]; for (let i = 0; i < childElem.length; i++) elem.appendChild(childElem[i]); } return elem; } function dragModel(drag) { const TOP = top; drag.onmousedown = function(e) { drag.style.cursor = "move"; e = e || window.event; let diffX = e.clientX - drag.offsetLeft; let diffY = e.clientY - drag.offsetTop; top.onmousemove = function(e) { e = e || top.event; let left = e.clientX - diffX; let top = e.clientY - diffY; if (left < 0) { left = 0; } else if (left > TOP.innerWidth * .95 - drag.offsetWidth) { left = TOP.innerWidth * .95 - drag.offsetWidth; } if (top < 0) { top = 0; } else if (top > TOP.innerHeight - drag.offsetHeight) { top = TOP.innerHeight - drag.offsetHeight; } drag.style.left = left + "px"; drag.style.top = top + "px"; GM_setValue("pos", drag.style.left + "," + drag.style.top); }; top.onmouseup = function(e) { drag.style.cursor = "default"; this.onmousemove = null; this.onmouseup = null; }; }; } function defaultWorkTypeResolver($options) { function count(selector) { let sum = 0; for (const option of $options || []) { if ($(option).find(selector).length || $(option).parent().find(selector).length) { sum++; } } return sum; } return count('[type="radio"]') === 2 ? 3 : count('[type="radio"]') > 2 ? 0 : count('[type="checkbox"]') > 2 ? 1 : count("textarea") >= 1 ? 4 : undefined; } function waitWithTimeout(promise, timeout, timeoutMessage = "timeout", defaultRes) { let timer; const timeoutPromise = new Promise((resolve, reject) => { timer = setTimeout(() => defaultRes === undefined ? reject(timeoutMessage) : resolve(defaultRes), timeout); }); return Promise.race([ timeoutPromise, promise ]).finally(() => clearTimeout(timer)); } async function formatSearchAnswer(initData) { const data = { plat: initData.plat ? parseInt(initData.plat) : null, qid: initData.qid ? String(initData.qid) : null, question: initData.question, options: initData.options, options_id: initData.options_id ? initData.options_id : [], type: initData.type }; let res; const list = []; const apis = GLOBAL.answerApi; const answerApiFunc = Object.keys(apis).map(item => { return waitWithTimeout(apis[item](data), 5e3, "", []); }); answerApiFunc.push(searchAnswer(data)); const answerApiRes = await waitWithTimeout(Promise.all(answerApiFunc), 1e4, "(接口超时)"); answerApiRes.map(item => { if (item instanceof Array) { console.log("tikuAdapter结果", JSON.stringify(item)); list.push(...item); } else if (item instanceof Object && Object.keys(item).length === 1) { const key = Object.keys(item)[0]; item[key]; } else { res = item; } }); try { const msg = res.message || res.msg; if (res.code !== 0) { return { success: false, msg: msg }; } if (res.result.success) { return { success: true, msg: msg, num: res.result.num, answers: res.result.answers }; } console.log("官方结果", JSON.stringify(res)); if (res.result.answers instanceof Array && res.result.answers.length > 0) { list.push(...res.result.answers); } return { success: true, msg: msg, num: res.result.num, list: list }; } catch (e) { return { success: false, msg: "发生异常" + e + "请反馈至QQ群" + QQ_GROUP }; } } function similar(s, t, f) { if (!s || !t) { return 0; } if (s === t) { return 100; } var l = s.length > t.length ? s.length : t.length; var n = s.length; var m = t.length; var d = []; f = f || 2; var min = function(a, b, c) { return a < b ? a < c ? a : c : b < c ? b : c; }; var i, j, si, tj, cost; if (n === 0) return m; if (m === 0) return n; for (i = 0; i <= n; i++) { d[i] = []; d[i][0] = i; } for (j = 0; j <= m; j++) { d[0][j] = j; } for (i = 1; i <= n; i++) { si = s.charAt(i - 1); for (j = 1; j <= m; j++) { tj = t.charAt(j - 1); if (si === tj) { cost = 0; } else { cost = 1; } d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost); } } let res = (1 - d[n][m] / l) * 100; return res.toFixed(f); } function answerSimilar(src, list) { return $.map(list, function(val) { return Number(similar(formatString(val), formatString(src), 2)); }); } function isPlainAnswer(answer) { if (answer.length > 8 || !/[A-Z]/.test(answer)) { return false; } let min = 0; for (let i = 0; i < answer.length; i++) { if (answer.charCodeAt(i) < min) { return false; } min = answer.charCodeAt(i); } return true; } function isTrue(str) { return Boolean(String(str).match(/(^|,)(正确|是|对|√|T|ri|true|A)(,|$)/)); } function isFalse(str) { return Boolean(String(str).match(/(^|,)(错误|否|错|×|F|不是|wr|false|B)(,|$)/)); } async function defaultQuestionResolve(list, data, handler, ignore_click) { let targetOptionsList = []; for (const answers of list) { if (data.type === 4 || data.type === 2 || data.type === 5) { let ans = answers.length > data.$options.length ? answers.slice(0, data.$options.length) : answers; for (let index in ans) { if (typeof handler === "function") await handler(data.type, ans[index], data.$options.eq(index)); } return { style: "success-row", ans: answers.join("===="), question: data.question }; } else if (data.type === 3) { if (targetOptionsList.length > 3) break; let targetOptions = new Set(); if (isTrue(answers.join())) { targetOptions.add(Number(isFalse(data.options[0]))); } else if (isFalse(answers.join())) { targetOptions.add(Number(isTrue(data.options[0]))); } targetOptions.size > 0 && targetOptionsList.push(targetOptions); } else if (data.type === 0 || data.type === 1 || data.type === 66) { const beautifulOptions = data.options.map(i => { return formatString(i).toLowerCase().replace(/\s/g, ""); }); let targetOptions = new Set(); for (const ans of answers) { if (ans.length === 1 && isPlainAnswer(ans)) { targetOptions.add(ans.charCodeAt(0) - 65); } const val = formatString(ans).toLowerCase().replace(/\s/g, ""); let optIndex = $.inArray(val, beautifulOptions); if (optIndex >= 0) { targetOptions.add(optIndex); } } if ((data.type === 0 && targetOptions.size === 0 || data.type === 1 && targetOptions.size < 2) && targetOptionsList.length === 0) { for (const ans of answers) { const val = formatString(ans).toLowerCase(); if (val.length >= 5 && !val.includes("<img")) { const ratings = answerSimilar(val, beautifulOptions); const maxScore = Math.max(...ratings); if (maxScore > 65) { targetOptions.add(ratings.indexOf(maxScore)); } } } } targetOptions.size > 0 && targetOptionsList.push(targetOptions); } } let items = []; let sortArr = targetOptionsList.map(item => { const s = Array.from(item).sort(); return s; }); if (data.type === 0 || data.type === 3) { items = getMost(sortArr.filter(i => i.length === 1)); if (!items || items.length === 0) { items = getMost(sortArr.filter(i => i.length > 0)); } } else if (data.type === 1 || data.type === 66) { items = getMost(sortArr.filter(i => i.length > 1)); if (!items || items.length === 0) { items = getLang(sortArr.filter(i => i.length > 0)); } } if (items && items.length > 0) { for (let index = 0; index < data.$options.length; index++) { const $item = data.$options.eq(index); if (Boolean($.inArray(index, items) + 1) !== Boolean(ignore_click($item, data.type))) { $item.get(0).click(); await sleep(GLOBAL.fillAnswerDelay); } } return { type: data.type, style: "primary-row", ans: items.map(i => { return data.options[i]; }).join("===="), question: data.question }; } else { return { type: data.type, style: "warning-row", question: data.question, ans: list.join('===='), options: data.options }; } } async function defaultFillAnswer(answers, data, handler, ignore_click) { for (let index = 0; index < data.$options.length; index++) { const $item = data.$options.eq(index); if (Boolean($.inArray(index, answers) + 1) !== Boolean(ignore_click($item, data.type))) { $item.get(0).click(); await sleep(GLOBAL.fillAnswerDelay); } } return { type: data.type, style: "success-row", question: data.question, ans: answers.map(i => { return String.fromCharCode(i + 65); }).join(""), options: data.options }; } function getMost(arr) { arr.reverse(); if (arr.length === 0) return undefined; var hash = {}; var m = 0; var trueEl; var el; for (var i = 0, len = arr.length; i < len; i++) { el = arr[i]; hash[el] === undefined ? hash[el] = 1 : hash[el]++; if (hash[el] >= m) { m = hash[el]; trueEl = el; } } return trueEl; } function getLang(arr) { if (arr.length === 0) return undefined; let len = 0; let ele; for (let arrElement of arr) { if (arrElement.length > len) { len = arrElement.length; ele = arrElement; } } return ele ? ele : arr.length > 0 ? arr[0] : []; } function HTMLDecode(text) { var temp = document.createElement("div"); temp.innerHTML = text; var output = temp.innerText || temp.textContent; temp = null; return output; } function formatString(src) { src = String(src); src = src.includes("img") || src.includes("iframe") ? src : HTMLDecode(src); src = src.replace(/[\uff01-\uff5e]/g, function(str) { return String.fromCharCode(str.charCodeAt(0) - 65248); }); return src.replace(/\s+/g, " ").replace(/[“”]/g, '"').replace(/[‘’]/g, "'").replace(/。/g, ".").replace(/[,.?:!;]$/, "").trim(); } function division(arr, size) { var objArr = new Array(); var index = 0; var objArrLen = arr.length / size; for (var i = 0; i < objArrLen; i++) { var arrTemp = new Array(); for (var j = 0; j < size; j++) { arrTemp[j] = arr[index++]; if (index === arr.length) { break; } } objArr[i] = arrTemp; } return objArr; } const cache = {}; const sourceTable = JSON.parse(GM_getResourceText("SourceTable")); async function genTable(ttf) { const res = await axios.get(ttf, { responseType: "arraybuffer" }); const font = Typr.parse(res.data)[0]; const table = {}; for (let i = 19968; i < 40870; i++) { const g = Typr.U.codeToGlyph(font, i); if (g) { const path = Typr.U.glyphToPath(font, g); if (path) { table[i] = MD5(JSON.stringify(path)); } } } cache[ttf] = table; } async function getEncryptString(str, ttf) { if (!cache[ttf]) { await genTable(ttf); } const match = str.match(/(.*?)</g); if (match === null) { return formatString(str); } const encStrArr = match.map(string => { return string.replace(/^/, "").replace(/<$/, ""); }); encStrArr.forEach(encStr => { const decStr = encStr.split("").map(string => { const md5 = cache[ttf][string.charCodeAt(0)]; return String.fromCharCode(sourceTable[md5]); }).join(""); str = str.replace(encStr, decStr); }); return formatString(str); } var vm = { hideTip() { var tip = document.createElement("div"); tip.id = "yinc"; tip.innerHTML = ` 万能脚本已被隐藏 如果需要显示答题面板，请按键盘右箭头 × `; top.document.getElementsByTagName("body")[0].appendChild(tip); top.document.querySelector("#cl_yinc").onclick = function() { top.document.querySelector("#yinc").remove(); }; setTimeout(() => { top.document.querySelector("#yinc").remove(); }, 3e3); }, zhihuishuSaveTip() { var zhihuishuSaveTip = document.createElement("div"); zhihuishuSaveTip.id = "zhihuishuSaveTip"; zhihuishuSaveTip.innerHTML = ` 正在保存 0% `; top.document.getElementsByTagName("body")[0].appendChild(zhihuishuSaveTip); } }; function showPanel() { let html = ` <el-dialog title="更多设置" :visible.sync="show_setting" width="300px"> <el-form ref="form" label-width="100px" size="mini"> <el-form-item label="ChatGPT答题"> <el-select v-model="gpt"> <el-option label="不开启" value="-1"></el-option> <el-option label="使用GPT3.5" value="3"></el-option> <el-option disabled label="使用GPT4" value="4"></el-option> </el-select> </el-form-item> <el-form-item label="搜题延迟(秒)"> <el-input-number v-model="search_delay" :min="0" :max="30"></el-input-number> </el-form-item> <el-popover ref="popover" placement="top-start" title="tikuAdapter题库适配器" width="200" trigger="hover" content="大学生网课题库接口适配器：聚合多家题库，更精确的查题。详细查看 https://github.com/DokiDoki1103/tikuAdapter"> </el-popover> <el-form-item v-popover:popover label="题库适配器url"> <el-input v-model="tiku_adapter"></el-input> </el-form-item> </el-form> <el-button size="mini" @click="show_setting = false">取消</el-button> <el-button size="mini" type="primary" @click="save_setting">保存</el-button> </el-dialog> <el-main style="min-width: 321px;padding: 15px 0px 0px; z-index: 99999;"> <el-row> <el-form> <el-form-item class="el-form-item-confim" label="请输入token" style="margin-top: -20px" :prop="passw"> <el-input :type="passw" v-model="opt.token" placeholder="请输入内容" style="max-width: 130px" size="mini" ></el-input> <el-button @click="btnClick(opt.token,'opt.confim')" size="mini" type="warning" @mousedown.native="passw = 'text'" @mouseup.native="passw = 'password'">确定</el-button> </el-form-item> </el-form> </el-row> <el-row style="margin-top: -20px;margin-bottom: 5px;display: flex"> <el-alert style="display: block" :title="tip" :closable="false" type="success"> <el-button v-if="need_jump" @click="btnClick(opt.jump,'opt.jump')" size="mini" type="info">跳过本题</el-button> <el-button v-if="!hidden" @click="btnClick(opt.auto_jump,'opt.auto_jump')" size="mini" type="warning">{{opt.auto_jump ? '停止自动切换': '开启自动切换'}}</el-button> </el-alert> </el-row> <el-row> <el-button v-if="!hidden" @click="btnClick(opt.stop,'opt.stop')" size="mini" type="success"></el-button> <el-button @click="btnClick(opt.start_pay,'opt.start_pay')" size="mini" type="primary">{{opt.start_pay ?'关闭收费题库' : '开启收费题库'}}</el-button> <el-button size="mini" type="danger">获取积分</el-button> <el-button @click="show_setting = true" size="mini" type="info">更多设置</el-button> </el-row> <el-table size="mini" :data="tableData" style="width: 100%;margin-top: 5px" :row-class-name="tableRowClassName"> <el-table-column prop="index" label="题号" width="45"></el-table-column> <el-table-column prop="question" label="问题" width="130"> </el-table-column> <el-table-column prop="answer" label="答案" width="130"> <el-popover v-if="scope.row.style === 'warning-row'" placement="bottom-end" title="相似答案" width="240" trigger="click"> <el-button slot="reference" size="small" type="danger">查看相关答案</el-button> </el-popover> </el-table-column> </el-table> </el-main> `; addModal2(html); checkVersion(); } function addModal2(html, newPos, footerChildNode = false) { let headersNode = createContainer("hcsearche-modal-links"); let adNode = top.document.createElement("img"); let item = { url: GM_getResourceURL("Img") }; const getAdList = GM_getValue("adList"); if (getAdList) { const adList = JSON.parse(getAdList); let lastShown = GM_getValue("lastShown") || 0; item = adList[lastShown]; GM_setValue("lastShown", (lastShown + 1) % adList.length); item.base64 = GM_getValue(item.hash); } adNode.setAttribute("src", item.base64); adNode.setAttribute("draggable", "false"); adNode.setAttribute("style", "display: block;width:321px"); if (item.click) { adNode.setAttribute("onmousedown", "let ts=new Date().getTime();this.onmouseup=()=>{if(new Date().getTime()-ts>100){return false;};window.open('" + item.click + "','_black');this.onmouseup=undefined}"); } headersNode.appendChild(adNode); let iframeNode = top.document.createElement("iframe"); iframeNode.id = "iframeNode"; iframeNode.setAttribute("width", "100%"); iframeNode.setAttribute("height", GLOBAL.length + "px"); iframeNode.setAttribute("style", "height:" + GLOBAL.length + "px"); iframeNode.setAttribute("frameborder", "0"); iframeNode.srcdoc = html; let contentNode = createContainer("content-modal", [ headersNode, iframeNode ]); let modal = renderModal(contentNode); dragModel(modal); if (GM_getValue("hide")) { $("#model-id").hide(); vm.hideTip(); } } function renderModal(childElem, newPos) { return render(String.fromCharCode(rand(65, 90), rand(65, 90), rand(65, 90)) + rand(1, 100).toString(), "model-id", childElem); } function render(tagName, elemId, childElem, isFixed, newPos) { let doc = top.document; let elem = doc.getElementById(elemId); if (elem) { elem.innerHTML = ""; } else { elem = doc.createElement(tagName); elem.id = elemId; doc.body.appendChild(elem); } let contentNode = createContainer(tagName + "-container", childElem); elem.appendChild(contentNode); elem.classList.add(elemId); elem.style.zIndex = "9999999"; elem.style.position = "fixed"; const pos = GM_getValue("pos") === undefined ? "30px,30px" : GM_getValue("pos"); const posarr = pos.split(","); elem.style.left = posarr[0]; elem.style.top = posarr[1]; setTimeout(function() { elem.classList.add(elemId + "-show"); }, 10); return elem; } const init$1 = async ($TiMu, select, wrap) => { let question = formatString(filterImg($TiMu.find(select.elements.question))); if (select.elements.type && select.elements.type.includes("input[name^=type]:eq")) { select.elements.type = "input[name^=type]:eq(" + GLOBAL.i + ")"; } let data = { $item: $TiMu, question_text: $TiMu.find(select.elements.question).text(), question: question.length === 0 ? $TiMu.find(select.elements.question) : question.replace(/^\d+、/, "").replace(/[(（](\d+\s?(\.\d+)?分)[)）]$/, "").replace(/^((\d+.(\s+)?)?)[\[(（【](.*?)[】)）\]]/, "").trim(), $options: select.elements.$options ? $TiMu.find(select.elements.$options) : undefined, options: select.elements.options ? jQuery.map($TiMu.find(select.elements.options), function(val) { return formatString(filterImg(val)).replace(/^[A-Ga-g][.、]/, "").trim(); }) : undefined }; if (select.elements.type) { const getType = getQuestionType($TiMu.find(select.elements.type).text()); const val = $TiMu.find(select.elements.type).val(); data.type = isNaN(getType) ? isNaN(val) ? val : parseInt(val) : getType; } else { data.type = defaultWorkTypeResolver(data.$options); } if (select.elements.answer) { data.answer = getAnswer(filterImg($TiMu.find(select.elements.answer)) || $TiMu.find(select.elements.answer).val(), data.options, data.type); } if (data && data.type === 3 && data.options.length === 0) { data.options = [ "正确", "错误" ]; } const r = await wrap(data); if (typeof r === "boolean") return undefined; return data; }; async function WorkerJSPlus(options) { if (GLOBAL.isMatch) return; const match = options.match ? typeof options.match === "boolean" ? options.match : options.match() : false; if (!match) return; GLOBAL.isMatch = true; if (options.hook && typeof options.hook === "function") { if (options.hook()) return; } const defaultFunc = () => {}; const main = () => { setTimeout(() => { showPanel(); if (options.init && typeof options.init === "function") { if (options.init()) return; } const select = { root: options.root, elements: options.elements, ignore_click: options.ignore_click }; new WorkerJS(select, options.wrap ? options.wrap : defaultFunc, options.fill ? options.fill : defaultFunc, options.finished ? options.finished : defaultFunc, options.fillFinish ? options.fillFinish : defaultFunc).fillAnswer(); }, GLOBAL.delay); }; if (options.intv) { setIntervalFunc(options.intv, main); } else { main(); } } var WorkerJS = function(select, searchHander, fillHander, onFinish = function(need_jump) {}, fillFinish = function() {}) { GLOBAL.index = 0; this.init = init$1; this.fillAnswer = async () => { let arr = jQuery(select.root); while (true) { if (arr.length === 0) return; await sleep((isNaN(parseInt(GM_getValue("search_delay"))) ? 2 : GM_getValue("search_delay")) * 1e3); if (GLOBAL.stop) { continue; } if (GLOBAL.index >= arr.length) { let auto_jump = GM_getValue("auto_jump") === undefined || GM_getValue("auto_jump"); const next = await onFinish(auto_jump); if (next) { GLOBAL.index = 0; setTimeout(this.fillAnswer, 300); } if (auto_jump) { iframeMsg("tip", { tip: "自动答题已完成,即将切换下一题" }); next || setTimeout(() => { iframeMsg("tip", { type: "hidden", tip: "自动答题已完成,请检查提交" }); }, Math.max(GM_getValue("search_delay") || 2, 5) * 1e3); } else { iframeMsg("tip", { tip: "自动答题已完成" + (arr.length === 1 ? ",请手动切换" : "请检查提交") }); } return true; } try { let data = await this.init(jQuery(arr[GLOBAL.index++]), select, searchHander); if (!data) { GLOBAL.index--; continue; } iframeMsg("tip", { tip: "准备答第" + GLOBAL.index + "题" }); const formatResult = await formatSearchAnswer(data); const hookAnswer = data.answer && data.answer.length > 0 && GM_getValue("start_pay"); const formatAns = hookAnswer ? { success: true, num: formatResult.num, list: [ data.answer ] } : formatResult; if (formatResult.answers || formatAns.success) { iframeMsg("tip", { tip: "准备填充答案," + (formatAns.num === -1 ? "免费题库不扣积分" : "剩余积分:" + formatAns.num) }); const func = !hookAnswer && formatResult.answers ? defaultFillAnswer : defaultQuestionResolve; let r = await func(hookAnswer ? formatAns.list : formatAns.answers ? formatResult.answers : formatAns.list, data, fillHander, select.ignore_click ? select.ignore_click : () => { return false; }); iframeMsg("push", { index: GLOBAL.index, question: r.question, answer: r.ans, style: r.style }); GM_getValue("start_pay") && String(GM_getValue("token")).length === 10 && catchAnswer(r); await fillFinish(r); } else { GLOBAL.index--; iframeMsg("tip", { tip: formatAns.msg }); } } catch (e) { GLOBAL.index--; console.table(e); iframeMsg("tip", { type: "error", tip: location.host + "发生异常" + e + "请反馈至QQ群" + QQ_GROUP }); } } }; }; // @thanks 特别感谢 qxin i 借鉴 网页限制解除(改) 开源地址 https://greasyfork.org/zh-CN/scripts/28497 function init() { rule = rwl_userData.rules.rule_def; hook_eventNames = rule.hook_eventNames.split("|"); unhook_eventNames = rule.unhook_eventNames.split("|"); eventNames = hook_eventNames.concat(unhook_eventNames); if (rule.dom0) { setInterval(clearLoop, 10 * 1e3); setTimeout(clearLoop, 1500); window.addEventListener("load", clearLoop, true); clearLoop(); } if (rule.hook_addEventListener) { EventTarget.prototype.addEventListener = addEventListener; document.addEventListener = addEventListener; if (hasFrame) { for (let i = 0; i < hasFrame.length; i++) { hasFrame[i].contentWindow.document.addEventListener = addEventListener; } } } if (rule.hook_preventDefault) { Event.prototype.preventDefault = function() { if (hook_eventNames.indexOf(this.type) < 0) { Event_preventDefault.apply(this, arguments); } }; if (hasFrame) { for (let i = 0; i < hasFrame.length; i++) { hasFrame[i].contentWindow.Event.prototype.preventDefault = function() { if (hook_eventNames.indexOf(this.type) < 0) { Event_preventDefault.apply(this, arguments); } }; } } } if (rule.hook_set_returnValue) { Event.prototype.__defineSetter__("returnValue", function() { if (this.returnValue !== true && hook_eventNames.indexOf(this.type) >= 0) { this.returnValue = true; } }); } } function addEventListener(type, func, useCapture) { var _addEventListener = this === document ? document_addEventListener : EventTarget_addEventListener; if (hook_eventNames.indexOf(type) >= 0) { _addEventListener.apply(this, [ type, returnTrue, useCapture ]); } else if (unhook_eventNames.indexOf(type) >= 0) { var funcsName = storageName + type + (useCapture ? "t" : "f"); if (this[funcsName] === undefined) { this[funcsName] = []; _addEventListener.apply(this, [ type, useCapture ? unhook_t : unhook_f, useCapture ]); } this[funcsName].push(func); } else { _addEventListener.apply(this, arguments); } } function clearLoop() { rule = clear(); var elements = getElements(); for (var i in elements) { for (var j in eventNames) { var name = "on" + eventNames[j]; if (Object.prototype.toString.call(elements[i]) == "[object String]") { continue; } if (elements[i][name] !== null && elements[i][name] !== onxxx) { if (unhook_eventNames.indexOf(eventNames[j]) >= 0) { elements[i][storageName + name] = elements[i][name]; elements[i][name] = onxxx; } else { elements[i][name] = null; } } } } document.onmousedown = function() { return true; }; } function returnTrue(e) { return true; } function unhook_t(e) { return unhook(e, this, storageName + e.type + "t"); } function unhook_f(e) { return unhook(e, this, storageName + e.type + "f"); } function unhook(e, self, funcsName) { var list = self[funcsName]; for (var i in list) { list[i](e); } e.returnValue = true; return true; } function onxxx(e) { var name = storageName + "on" + e.type; this[name](e); e.returnValue = true; return true; } function getElements() { var elements = Array.prototype.slice.call(document.getElementsByTagName("*")); elements.push(document); var frames = document.querySelectorAll("frame"); if (frames) { hasFrame = frames; var frames_element; for (let i = 0; i < frames.length; i++) { frames_element = Array.prototype.slice.call(frames[i].contentWindow.document.querySelectorAll("*")); elements.push(frames[i].contentWindow.document); elements = elements.concat(frames_element); } } return elements; } var settingData = { status: 1, version: .1, message: "", positionTop: "0", positionLeft: "0", positionRight: "auto", addBtn: false, connectToTheServer: false, waitUpload: [], currentURL: "null", shortcut: 3, rules: {}, data: [] }; var rwl_userData = null; var rule = null; var hasFrame = false; var storageName = "storageName"; var hook_eventNames, unhook_eventNames, eventNames; var EventTarget_addEventListener = EventTarget.prototype.addEventListener; var document_addEventListener = document.addEventListener; var Event_preventDefault = Event.prototype.preventDefault; rwl_userData = GM_getValue("rwl_userData"); if (!rwl_userData) { rwl_userData = settingData; } for (let value in settingData) { if (!rwl_userData.hasOwnProperty(value)) { rwl_userData[value] = settingData[value]; GM_setValue("rwl_userData", rwl_userData); } } // @thanks 特别感谢 wyn大佬 提供的 字典匹配表 原作者 wyn665817@163.com 开源地址 https://scriptcat.org/script-show-page/432/code function removeF() { var $tip = $("style:contains(font-cxsecret)"); if (!$tip.length) return; var font = $tip.text().match(/base64,([\w\W]+?)'/)[1]; font = Typr.parse(base64ToUint8Array(font))[0]; var table = JSON.parse(GM_getResourceText("Table")); var match = {}; for (var i = 19968; i < 40870; i++) { $tip = Typr.U.codeToGlyph(font, i); if (!$tip) continue; $tip = Typr.U.glyphToPath(font, $tip); $tip = MD5(JSON.stringify($tip)).slice(24); match[i] = table[$tip]; } $(".font-cxsecret").html(function(index, html) { $.each(match, function(key, value) { key = String.fromCharCode(key); key = new RegExp(key, "g"); value = String.fromCharCode(value); html = html.replace(key, value); }); return html; }).removeClass("font-cxsecret"); function base64ToUint8Array(base64) { var data = window.atob(base64); var buffer = new Uint8Array(data.length); for (var i = 0; i < data.length; ++i) { buffer[i] = data.charCodeAt(i); } return buffer; } } function start() { try { removeF(); } catch (e) {} try { init(); } catch (e) {} } WorkerJSPlus({ name: "学习通作业", match: location.pathname === "/mooc2/work/dowork" || location.pathname === "/mooc-ans/mooc2/work/dowork", root: ".questionLi", elements: { question: "h3", options: ".stem_answer .answerBg .answer_p, .textDIV, .eidtDiv", $options: ".stem_answer .answerBg, .textDIV, .eidtDiv", type: "input[type^=hidden]:eq(0)" }, wrap: obj => { obj.question = obj.question.replace(obj.$item.find(".colorShallow").text(), "").replace(/^(\d+\.\s)/, ""); }, ignore_click: $item => { return Boolean($item.find(".check_answer,.check_answer_dx").length); }, fill: (type, answer, $option) => { if (type === 4 || type === 2 || type === 5) { UE$1.getEditor($option.find("textarea").attr("name")).setContent(answer); } } }); WorkerJSPlus({ name: "超星旧版考试", match: (location.pathname === "/exam/test/reVersionTestStartNew" || location.pathname === "/exam-ans/exam/test/reVersionTestStartNew") && !location.href.includes("newMooc=true"), root: ".TiMu", elements: { question: ".Cy_TItle .clearfix", options: ".Cy_ulTop .clearfix", $options: ":radio, :checkbox, .Cy_ulTk textarea", type: "[name^=type]:not([id])" }, ignore_click: $item => { return $item.get(0).checked; }, fill: (type, answer, $option) => { if (type === 4 || type === 2 || type === 5) { UE$1.getEditor($option.attr("name")).setContent(answer); } }, finished: auto_jump => { auto_jump && setInterval(function() { const btn = $(".saveYl:contains(下一题)").offset(); var mouse = document.createEvent("MouseEvents"), arr = [ btn.left + Math.ceil(Math.random() * 80), btn.top + Math.ceil(Math.random() * 26) ]; mouse.initMouseEvent("click", true, true, document.defaultView, 0, 0, 0, arr[0], arr[1], false, false, false, false, 0, null); _self.event = $.extend(true, {}, mouse); delete _self.event.isTrusted; _self.getTheNextQuestion(1); }, Math.ceil(GLOBAL.fillAnswerDelay * Math.random()) * 2); } }); WorkerJSPlus({ name: "超星章节测验", match: location.pathname === "/work/doHomeWorkNew" || location.pathname === "/mooc-ans/work/doHomeWorkNew", init: start, root: ".clearfix .TiMu", elements: { question: ".Zy_TItle .clearfix", options: "ul:eq(0) li .after", $options: "ul:eq(0) li :radio,:checkbox,textarea,.num_option_dx,.num_option", type: "input[name^=answertype]" }, ignore_click: $item => { if ($item.is("input")) { return $item.get(0).checked; } return $item.attr("class").includes("check_answer"); }, fill: async (type, answer, $option) => { if (type === 4 || type === 2 || type === 5) { UE$1.getEditor($option.attr("name")).setContent(answer); } } }); WorkerJSPlus({ name: "超星新版考试", match: () => { const cxSinglePage = (location.pathname === "/exam/test/reVersionTestStartNew" || location.pathname === "/exam-ans/exam/test/reVersionTestStartNew" || location.pathname === "/mooc-ans/exam/test/reVersionTestStartNew") && location.href.includes("newMooc=true"); const cxAll = location.pathname === "/mooc2/exam/preview" || location.pathname === "/exam-ans/mooc2/exam/preview" || location.pathname === "/mooc-ans/mooc2/exam/preview"; return cxSinglePage || cxAll; }, root: ".questionLi", elements: { question: "h3 div", options: ".answerBg .answer_p, .textDIV, .eidtDiv", $options: ".answerBg, .textDIV, .eidtDiv", type: "input[name^=type]:eq(" + GLOBAL.i + ")" }, ignore_click: $item => { return Boolean($item.find(".check_answer,.check_answer_dx").length); }, hook: () => { GLOBAL.i = Number((location.pathname === "/exam/test/reVersionTestStartNew" || location.pathname === "/exam-ans/exam/test/reVersionTestStartNew" || location.pathname === "/mooc-ans/exam/test/reVersionTestStartNew") && location.href.includes("newMooc=true")); }, wrap: obj => { if (obj.type === 6) { obj.type = 4; } }, fill: (type, answer, $option) => { if (type === 4 || type === 2 || type === 5) { const name = $option.find("textarea").attr("name"); UE$1.getEditor(name).setContent(answer); if (GLOBAL.i === 0) { console.log("#" + name.replace("answerEditor", "save_")); $("#" + name.replace("answerEditor", "save_")).click(); } } }, finished: a => { a && $('.nextDiv .jb_btn:contains("下一题")').click(); } }); WorkerJSPlus({ name: "超星随堂测验", match: location.pathname.includes("/page/quiz/stu/answerQuestion"), root: ".question-item", elements: { question: ".topic-txt", options: ".topic-option-list", $options: ".topic-option-list input", type: "input[class^=que-type]" }, ignore_click: $item => { return Boolean($item.find(".check_answer,.check_answer_dx").length); }, wrap: obj => { if (obj.type === 16) { obj.type = 3; } }, fill: (type, answer, $option) => { if (type === 4 || type === 2) { $option.val(answer); } } }); function JSONParseHook(func) { const parse = JSON.parse; JSON.parse = function(...args) { const o = parse.call(this, ...args); func(o); return o; }; } function hookZhiHuiShuWork(o, arr) { function format(item) { let options = []; let options_id; if (item.questionOptions && item.questionOptions.length) { options = item.questionOptions.map(o => { return formatString(o.content); }); options_id = item.questionOptions.map(o => { return o.id; }); } return { qid: item.id, question: formatString(item.name), type: getQuestionType(item.questionType.name), options_id: options_id, options: options }; } if (o.rt && o.rt.examBase && o.rt.examBase.workExamParts.length > 0) { GLOBAL.content = o.rt; GLOBAL.json = o.rt.examBase.workExamParts.map(part => { return part.questionDtos.map(item => { if ("阅读理解（选择）/完型填空" === item.questionType.name || "听力训练" === item.questionType.name || !(item.questionType.name.includes("填空") || item.questionType.name.includes("问答")) && item.questionChildrens && item.questionChildrens.length > 0) { return item.questionChildrens.map(i => { console.log(format(i)); return format(i); }).flat(); } else { return format(item); } }); }).flat(); } else if (o.rt && Object.keys(o.rt).length > 0 && !isNaN(Object.keys(o.rt)[0])) { GLOBAL.img = o.rt; } } WorkerJSPlus({ name: "智慧树作业/考试", match: !location.href.includes("checkHomework") && location.host.includes("zhihuishu") && (location.pathname === "/stuExamWeb.html" || location.href.includes("/webExamList/dohomework/") || location.href.includes("/webExamList/doexamination/")), root: ".examPaper_subject", elements: { question: ".subject_describe div,.smallStem_describe p", options: ".subject_node .nodeLab .node_detail", $options: ".subject_node .nodeLab .node_detail", type: ".subject_type span:first-child" }, hook: () => { JSONParseHook(hookZhiHuiShuWork); }, intv: () => { return $(".answerCard").length; }, wrap: obj => { Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]); console.log(obj); if ($(".yidun_popup").hasClass("yidun_popup--light")) { iframeMsg("tip", { type: "stop", tip: "答题暂停，请自行通过验证" }); GLOBAL.stop = true; } }, ignore_click: $item => { return $item.hasClass("onChecked"); }, fill: (type, answer, $option) => { if (type === 4 || type === 2) { UE$1.getEditor($option.find("textarea").attr("name")).setContent(answer); } }, finished: async () => { vm.zhihuishuSaveTip(); const len = $(".answerCard_list li").length; for (let i = 0; i < len; i++) { await sleep(500); try { $(".answerCard_list1 li").eq(i).click(); await sleep(300); $(".el-button:contains(下一题)").click(); } catch (e) { $(".el-button:contains(保存)").click(); } const process = ((i + 1) / len * 100).toFixed(0); $("#gs_p").val(process); $("#gs_text").text(process + "%"); } if (top.document.querySelector("#gs_p").value == 100) { top.document.querySelector("#zhihuishuSaveTip").remove(); } }, fillFinish: () => { $(".answerCard_list li").eq(GLOBAL.index - 1).click(); $(".el-button:contains(下一题)").click(); } }); WorkerJSPlus({ name: "智慧树学分课作业", match: location.href.includes("/atHomeworkExam/stu/homeworkQ/exerciseList") || location.href.includes("atHomeworkExam/stu/examQ/examexercise"), root: ".questionBox:eq(0)", elements: { question: ".questionContent", options: ".optionUl label .el-radio__label,.el-checkbox__label", $options: ".optionUl label", type: ".questionTit" }, intv: () => { return $(".answerCard").length || $(".questionTit").length; }, wrap: async obj => { obj.options = obj.options.map(item => { return formatString(item.replaceAll(/^[a-zA-Z][.|\s+]/g, "")); }); if ($(".yidun_popup").hasClass("yidun_popup--light")) { iframeMsg("tip", { type: "stop", tip: "答题暂停，请自行通过验证" }); GLOBAL.stop = true; } }, ignore_click: $item => { return $item.hasClass("is-checked"); }, finished: () => { if ($(".Nextbtndiv .Topicswitchingbtn-gray:contains(下一题)").hasClass("Topicswitchingbtn-gray")) return false; $(".Topicswitchingbtn:contains(下一题)").click(); return true; } }); WorkerJSPlus({ name: "智慧树学分课考试", match: location.host === "studentexambaseh5.zhihuishu.com", root: ".ques-detail", elements: { question: ".questionName .centent-pre", options: ".radio-view li .preStyle,.checkbox-views label .preStyle", $options: ".radio-view li,.checkbox-views label", type: ".letterSortNum" }, intv: () => { return $(".questionContent").length; }, ignore_click: $item => { return $item.hasClass("is-checked"); }, wrap: obj => { obj.options = obj.options.map(item => { return formatString(item.replaceAll(/^[a-zA-Z][.|\s+]/g, "")); }); if ($(".yidun_popup").hasClass("yidun_popup--light")) { iframeMsg("tip", { type: "stop", tip: "答题暂停，请自行通过验证" }); GLOBAL.stop = true; } if (obj.type === 15) { obj.question = formatString($(".centent-son-pre").text()); obj.type = 1; } }, finished: auto_jump => { if (auto_jump) { const btn = $(".next-topic:contains(下一题)"); btn.click(); return !btn.hasClass("noNext"); } } }); WorkerJSPlus({ match: location.href.includes("checkHomework") && location.host.includes("zhihuishu"), hook: () => { JSONParseHook(hookZhiHuiShuWork); }, init: () => { R({ type: 2, content: GLOBAL.content, img: GLOBAL.img }); } }); GLOBAL.timeout = 10 * 1e3; function uploadAnswer(data) { const arr2 = division(data, 100); for (let arr2Element of arr2) { GM_xmlhttpRequest({ method: "POST", url: "https://lyck6.cn/pcService/api/uploadAnswer", headers: { "Content-Type": "application/json;charset=utf-8" }, data: JSON.stringify(arr2Element), timeout: GLOBAL.timeout }); } } function uploadAnswerToPlat(data, plat) { const arr2 = division(data, 100); for (let arr2Element of arr2) { GM_xmlhttpRequest({ method: "POST", url: "https://lyck6.cn/collect-service/v1/uploadAnswerToPlat?plat=" + plat, headers: { "Content-Type": "application/json;charset=utf-8" }, data: JSON.stringify(arr2Element), timeout: GLOBAL.timeout }); } } WorkerJSPlus({ name: "职教云考试", match: location.pathname === "/exam/examflow_index.action", intv: () => { return $(".divQuestionTitle").length; }, init: () => { instance.get("/api/init/zjy?id=" + unsafeWindow.examRecordId); }, root: ".q_content", elements: { question: ".divQuestionTitle", options: ".questionOptions .q_option", $options: ".questionOptions .q_option div,div[id^=_baidu_editor_]" }, ignore_click: $item => { return $($item).attr("class") === "checkbox_on"; }, wrap: obj => { obj.type = getQuestionType(obj.$item.next().attr("answertype")); obj.type = obj.type ? obj.type : defaultWorkTypeResolver(obj.$options); obj.options = $.map(obj.options, val => { return formatString(val.replace(/[A-G][．|\\.\s+]/, "")).trim(); }); }, fill: (type, answer, $option) => { if (type === 4 || type === 2 || type === 5) { UE$1.getEditor($option.attr("id")).setContent(answer); } }, finished: async () => { if ($(".paging_next").attr("style").includes("block") || !$(".paging_next").attr("style").includes("none")) { $(".paging_next").click(); await sleep(1e3); return true; } } }); WorkerJSPlus({ name: "职教云测验", match: location.pathname === "/study/directory/dir_course.html", intv: () => { return $(".panel_item").length; }, root: ".panel_item .panel_item", elements: { question: ".preview_cm .preview_stem", options: ".preview_cm ul li span:last-child", $options: ".preview_cm ul li input" }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().find(".panel_title").text()); obj.options = obj.options.map(i => { return i.trim().replace(/^[abAB]\)\s+/, "").replace(/^[A-Za-z]\s+/, "").trim(); }); }, ignore_click: $item => { return $item.attr("checked") === "checked"; } }); WorkerJSPlus({ name: "职教云MOOC", match: location.pathname === "/study/homework/do.html" || location.pathname === "/study/workExam/testWork/preview.html" || location.pathname === "/study/onlineExam/preview.html" || location.pathname === "/study/workExam/homeWork/preview.html" || location.pathname === "/study/workExam/onlineExam/preview.html", root: ".e-q-r", elements: { question: ".e-q-q .ErichText", options: ".e-a-g li", $options: ".e-a-g li", type: ".quiz-type" }, ignore_click: $item => { return $item.hasClass("checked"); }, wrap: obj => { if (obj.type === "A1A2题") { obj.type = 1; } obj.question = obj.question.replace(/ /gi, ""); obj.options = obj.options.map(i => { return i.trim().replace(/^[abAB]\)\s+/, "").replace(/^[A-Za-z]\s+/, "").trim(); }); } }); function parseIcve(questions) { return questions.map(item => { const options = item.Selects.map(opt => { return formatString(opt); }); const type = getQuestionType(item.ACHType.QuestionTypeName); const answer = item.Answers.map(key => { if (type === 0 || type === 1) { return options[key.charCodeAt() - 65]; } else if (type === 3) { return key === "1" ? "正确" : "错误"; } }); const answerKey = type === 0 || type === 1 ? item.Answers : answer; return { id: item.Id, question: item.ContentText, answerKey: answerKey, options: type === 3 ? [ "正确", "错误" ] : options, answer: answer, type: type }; }); } WorkerJSPlus({ name: "资源库 WWW开头", match: location.pathname === "/study/works/works.html" || location.pathname === "/study/exam/exam.html", root: ".questions", elements: { question: ".preview_stem", options: "li .preview_cont", $options: "li input", type: "input:hidden" }, hook: () => { JSONParseHook(o => { if (location.pathname === "/study/works/works.html") { if (o.paper) { GLOBAL.json = parseIcve(o.paper.PaperQuestions); uploadAnswer(GLOBAL.json); } } else if (location.pathname === "/study/exam/exam.html") { if (o.array) { GLOBAL.json = parseIcve(o.array.map(item => { return item.Questions; }).flat()); uploadAnswer(GLOBAL.json); } } }); }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { function get_element(id) { for (let jsonElement of GLOBAL.json) { if (jsonElement.id === id) { return jsonElement; } } } const ele = get_element(obj.$item.find("input:hidden").val()); obj.question = ele.question; obj.answer = ele.answerKey ? ele.answerKey : ele.answer; obj.type = ele.type; obj.options = ele.options; console.log(obj); }, fill: (type, answer, $option) => { if (type === 4 || type === 2) { UE$1.getEditor($option.attr("name")).setContent(answer); } } }); WorkerJSPlus({ name: "智慧职教 作业/考试", match: location.host.includes("zjy2.icve.com.cn"), intv: () => { return $(".subjectDet").length; }, root: ".subjectDet", elements: { question: "h5,.titleT .htmlP", options: ".optionList .el-radio__label,.el-checkbox__label", $options: ".optionList input", type: ".titleTwo,.xvhao" }, hook: () => { const parse = ques => { return ques.map(i => { const options = []; const answer = []; if (i.typeId === "3") { answer.push(i.optionAnswer === "1" ? "正确" : "错误"); } else if (/[12]/.test(i.typeId)) { options.push(...JSON.parse(i.dataJson).map(i => { if (i.IsAnswer) { answer.push(formatString(i.Content)); } return formatString(i.Content); })); } return { options: options, qid: i.id, answer: answer }; }); }; JSONParseHook(o => { if (o.name && o.questions && o.totalScore) { GLOBAL.json = parse(o.questions); } else if (o.data && o.data.questions) { GLOBAL.json = parse(o.data.questions); } }); }, ignore_click: $item => { return $($item).parent().attr("class") === "is-checked"; }, wrap: obj => { function findAnswer(id) { for (let jsonElement of GLOBAL.json) { if (jsonElement.qid === id) { return jsonElement.answer; } } } obj.answer = findAnswer(obj.$item.attr("id")); } }); function parseYkt(problems) { return problems.map(item => { const question = formatString(item.Body); const type = getQuestionType(item.TypeText); const options = []; const answer = []; if (type <= 1) { options.push(...item.Options.sort((a, b) => { return a.key.charCodeAt(0) - b.key.charCodeAt(0); }).map(item => { return formatString(item.value); })); if (item.Answer) { if (Array.isArray(item.Answer)) { answer.push(...item.Answer); } else { answer.push(...item.Answer.split("")); } } } else if (type === 3 && item.Answer && item.Answer.length === 1) { answer.push(item.Answer[0].replace("true", "正确").replace("false", "错误")); } return { answer: answer, options: options, type: type, qid: item.problem_id, question: question }; }); } function parsehnzkwText(problems) { return problems.map(item => { const type = item.flag === 1 ? 2 : item.flag === 0 ? 0 : item.flag === 4 ? 1 : item.flag === 3 ? 3 : undefined; let answer = []; let options = []; if (type === 2) { answer.push(item.answer); return { question: formatString(item.content), options: options, type: type, answer: answer }; } else if (type === 0) { for (let subjectOption of item.optionss) { const opt = formatString(subjectOption); options.push(opt); } if (type === 1) { item.answer.split("|").map(i => { answer.push(options[i.toUpperCase().charCodeAt(0) - 65]); }); } else { answer.push(options[item.answer.toUpperCase().charCodeAt(0) - 65]); } return { question: formatString(item.content), options: options, type: type, answer: answer }; } else if (type === 3) { for (let subjectOption of item.selectOption) { const opt = formatString(subjectOption); options.push(opt); } answer.push(item.answer); return { question: formatString(item.content), options: options, type: type, answer: answer }; } }); } function parseDanWei(pro) { return pro.map(i => { const type = getQuestionType(i.ttop010); const question = i.ttop011; const options = []; const answer = []; if (type === 0 || type === 1 || type === 3) { options.push(...i.ttop018.length > 0 ? i.ttop018.split("$$") : [ "正确", "错误" ]); answer.push(...i.ttop022.split("").map(item => { return options[item.charCodeAt(0) - 65]; })); } else if (type === 2 || type === 4) { answer.push(...i.ttop021.split("$$")); } return { question: question, type: type, answer: answer, options: options }; }).filter(i => i); } function parseYxbyunExam(problems) { return problems.map(item => { const type = getQuestionType(item.bigName); return item.smallContent.map(item => { let answer = []; let options = []; if (type === 2) { answer.push(item.answer); return { question: formatString(item.content), options: options, type: type, answer: answer }; } else if (type === 0 || type === 3 || type === 1) { let answer = []; let options = []; for (let subjectOption of item.question.optionList) { const opt = formatString(subjectOption.questionContent); options.push(opt); } if (type === 1) { item.question.questionAnswer.split(",").map(i => { answer.push(options[i.toUpperCase().charCodeAt(0) - 65]); }); } else { answer.push(options[item.question.questionAnswer.toUpperCase().charCodeAt(0) - 65]); } return { question: formatString(item.question.questionTitle), options: options, type: type, answer: answer }; } }); }); } WorkerJSPlus({ name: "雨课堂旧版考试", match: location.pathname.includes("/v/quiz/quiz_result"), intv: () => { return $("#cover").attr("style").includes("display: none;"); }, root: ".problem_item", elements: { question: ".notBullet:eq(0)", options: ".notBullet:gt(0)", $options: ".problembullet" }, ignore_click: $item => { return $item.hasClass("is-checked"); }, wrap: async obj => { const $item = obj.$item; const tmp = $item.find(".ptype").clone(); tmp.children().remove(); obj.type = getQuestionType(tmp.text()); obj.question = await yuketangOcr(obj.question.attr("data-background")); if (obj.$options.length === 2) { obj.options = [ "正确", "错误" ]; } else { const opt = []; for (const tmpElement of $item.find(".notBullet:gt(0)")) { opt.push(await yuketangOcr(jQuery(tmpElement).attr("data-background"))); } obj.options = opt; } } }); WorkerJSPlus({ name: "学堂在线", match: location.host === "www.xuetangx.com" && location.pathname.includes("/exercise/"), intv: () => { return $(".answer").length; }, root: ".content:eq(0)", elements: { question: ".question .fuwenben", options: ".question .leftQuestion .leftradio > span:last-child", $options: ".question .leftradio", type: ".question .title" }, ignore_click: $item => { return $item.find(".radio_jqq").hasClass("active"); }, wrap: obj => { if (obj.type === 3) { obj.$options = $(".answerList .radio_jqq"); } }, fill: (type, answer, $option) => { if (type === 4 || type === 2) { UE.getEditor($option.find("textarea")).setContent(answer); } }, finished: () => { const $right = $(".tabbar").find(".right"); $right.click(); return !$right.hasClass("unselect"); } }); WorkerJSPlus({ name: "雨课堂新版考试", match: location.host.includes("yuketang.cn") && location.pathname.includes("/result/"), hook: () => { JSONParseHook(async o => { if (o.data && o.data.problems && o.data.problems.length > 0) { uploadAnswerToPlat(parseYkt(o.data.problems), 50); } }); } }); WorkerJSPlus({ name: "雨课堂新版考试", match: (location.host === "examination.xuetangx.com" || location.host === "changjiang-exam.yuketang.cn") && (location.pathname.includes("/exam/") || location.pathname.includes("/cover/")), hook: () => { JSONParseHook(async o => { if (o.data && o.data.problems && o.data.problems.length > 0) { GLOBAL.json = parseYkt(o.data.problems); } }); const intv = setInterval(() => { try { top.document.querySelector(".exam").__vue__.handleHangUpTip = function() {}; const querySelector = top.document.querySelector; top.document.querySelector = function(...args) { if (args[0] === "#model-id") return false; return querySelector.call(this, ...args); }; const getElementById = top.document.getElementById; top.document.getElementById = function(...args) { if (args[0] === "model-id") return false; return getElementById.call(this, ...args); }; clearInterval(intv); } catch (e) {} }, 100); }, intv: () => { return jQuery(".subject-item").length; }, root: ".exam-main--body .subject-item", elements: { question: ".item-body h4,.item-body span:eq(0)", options: ".item-body ul li", $options: ".item-body ul label, .blank-item-dynamic, .edui-editor-iframeholder", type: ".item-type" }, ignore_click: $item => { return $item.hasClass("is-checked"); }, wrap: obj => { obj.options = obj.type === 3 ? [ "正确", "错误" ] : obj.options.map(i => { return i.replace(/^[A-G]\s/, ""); }); try { obj.qid = GLOBAL.json[GLOBAL.index - 1].qid; obj.plat = 50; } catch (e) { console.log(e); } } }); WorkerJSPlus({ name: "雨课堂新版作业，需要一个一个点下一题的", match: location.pathname.includes("/v2/web/cloud/student/exercise/"), hook: () => { async function parseYkt(problems, font) { const res = problems.map(i => { const type = getQuestionType(i.content.TypeText); const question = i.content.Body; let options = []; if (type <= 1) { options = i.content.Options; } else if (type === 3) { options = i.content.Options.map(item => { return item.key.replace("true", "正确").replace("false", "错误"); }); } return { qid: i.problem_id, question: question, type: type, options: options, user: i.user }; }).filter(i => i); for (const item of res) { item.question = await getEncryptString(item.question, font); const answerArray = []; if (item.type <= 1) { const optionsArray = []; for (const itemElement of item.options) { const opt = await getEncryptString(itemElement.value, font); if (item.user && item.user.is_show_answer && item.user.answer.includes(itemElement.key)) { answerArray.push(opt); } optionsArray.push(opt); } item.options = optionsArray; } else if (item.type === 3) { if (item.user && item.user.is_show_answer && item.user.answer.length === 1) { answerArray.push(item.user.answer[0].replace("true", "正确").replace("false", "错误")); } } delete item.user; item.answer = answerArray; } return res; } JSONParseHook(async o => { if (o.data && o.data.problems) { GLOBAL.json = await parseYkt(o.data.problems, o.data.font); uploadAnswerToPlat(GLOBAL.json, 50); } }); }, intv: () => { return jQuery(".subject-item").length; }, root: ".container-problem .subject-item", elements: { question: ".problem-body", options: "label .radioText,.checkboxText", $options: "ul input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: async obj => { const index = jQuery(".item-type").text().match(/(\d+)\./)[1]; Object.assign(obj, GLOBAL.json[parseInt(index) - 1]); obj.plat = 50; }, finished: need_jump => { if ($(".el-button--text:contains(下一题)").hasClass("is-disabled")) return false; need_jump && setTimeout(() => { $(".el-button--text:contains(下一题)").click(); }, GLOBAL.fillAnswerDelay); return need_jump; } }); WorkerJSPlus({ name: "云班课", match: location.pathname === "/web/index.php" && location.href.includes("m=reply"), root: ".topic-item", elements: { question: ".t-con .t-subject", options: ".t-option label .option-content", $options: ".el-radio__input,.el-checkbox__input", type: ".t-info .t-type" }, ignore_click: $item => { return $item.hasClass("is-checked"); }, wrap: obj => { if (obj.type === "A1A2题") { obj.type = 1; } obj.question = obj.question.replace(/ /gi, ""); obj.options = obj.options.map(i => { return i.trim().replace(/^[abAB]\)\s+/, "").replace(/^[A-Za-z]\s+/, "").trim(); }); } }); WorkerJSPlus({ name: "中国地质大学", match: location.pathname.includes("/Exam/OnlineExamV2/"), root: ".stViewItem", elements: { question: ".stViewHead div", options: ".stViewCont .stViewOption a", $options: ".stViewCont .stViewOption a,input" }, intv: () => { return $(".ExamTime").length; }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().parent().prev().find(".E_E_L_I_C_R_C_T_SubType").text()); obj.question = obj.question.replace(/\(\d+分\)/, ""); obj.options = obj.options.map(i => { return i.replace(/\([A-Za-z]\)/, "").trim(); }); }, fill: (type, answer, $option) => { if (type === 4 || type === 2) { $option.val(answer); } } }); WorkerJSPlus({ name: "单位", match: (location.host === "61.183.163.9:8089" || location.host === "zjpt.nnjjtgs.com:8081") && (location.href.includes("ksnr") || location.href.includes("lxnr")), hook: () => { JSONParseHook(o => { if (o.topicList && o.topicList.length > 0) { GLOBAL.json = parseDanWei(o.topicList); uploadAnswer(GLOBAL.json); } }); }, root: ".tm", elements: { question: ".tmnrbj span:last-child", options: ".van-radio-group .dxt .van-radio__label,.van-checkbox__label", $options: ".van-radio-group .dxt .van-radio__label,.van-checkbox__label,.van-field__control", type: ".tmnrbj span" }, intv: () => { return $(".ExamTime").length || document.getElementById("pup-b"); }, wrap: obj => { obj.answer = GLOBAL.json[jQuery(".tmnrbj span:last-child").text().match(/^(\d+)、/)[1] - 1].answer; }, finished: () => { jQuery(".xyt").click(); return true; } }); WorkerJSPlus({ name: "小鹅通", match: location.pathname.includes("/evaluation_wechat/examination/detail/"), root: ".question-title,.title__text", elements: { question: "#detail_div", options: "label .image-text-box p", $options: "label,.simulation_inp" }, ignore_click: ($item, type) => { if (type === 0) { return $item.html().includes("single-exam-radio-active"); } else if (type === 1) { return $item.html().includes("check-i-active"); } }, wrap: obj => { const $item = obj.$item; obj.$options = $item.parent().next().find(".option-item,.checking-option__container,.fill_blank"); obj.type = getQuestionType($item.next().text()); if (obj.type === 2) { obj.$options = $item.parent().parent(); } if (obj.type === 3) { obj.options = [ "正确", "错误" ]; } else { obj.options = jQuery.map($item.parent().next().find(".option-item #detail_div"), function(val) { return formatString(filterImg(val)); }); } }, fill: (type, answer, $option) => { if (type === 2) { const vue = $option.get(0).__vue__; vue.content[0] = answer; vue.emitAnswer(); $option.find(".simulation_inp").text(answer); } } }); WorkerJSPlus({ name: "小饿通H5", match: location.host.includes("h5.xiaoeknow") || location.href.includes("/exam/h5_evaluation/"), root: ".practice-detail__body", elements: { question: ".question-wrap__title #detail_div", options: ".question-option #detail_div", $options: ".question-option #detail_div", type: ".question-wrap__title-tag" }, wrap: obj => { const $item = obj.$item; obj.$options = $item.parent().next().find(".option-item,.checking-option__container,.fill_blank"); obj.type = TYPE[$item.next().text().replace(/\s+/, "").replace("（", "").replace("）", "")]; if (obj.type === 2) { obj.$options = $item.parent().parent(); } if (obj.type === 3) { obj.options = [ "正确", "错误" ]; } else { obj.options = jQuery.map($item.parent().next().find(".option-item #detail_div"), function(val) { return formatString(filterImg(val)); }); } }, finished: () => { $(".practice-detail__bottom-item:last-child").click(); return $(".next").text() === "下一题"; } }); WorkerJSPlus({ name: "人卫慕课测验", match: location.pathname.includes("/memberFront/paper.zhtml"), intv: () => { return $("#question_").attr("style").length === 0; }, root: ".quesinfo", elements: { question: "dl dt", options: "dd label", $options: "dd input" }, wrap: obj => { if (obj.$options.length === 2) { obj.type = 3; obj.options = [ "正确", "错误" ]; } else { obj.type = 0; } } }); WorkerJSPlus({ name: "青书学堂考试", match: location.host.includes("qingshuxuetang") && (location.pathname.includes("/Student/MakeupExamPaper") || location.pathname.includes("Student/ExamPaper")), intv: () => { return $(".paper-container .question-detail-container").length; }, root: ".paper-container .question-detail-container", elements: { question: ".question-detail-description .detail-description-content", options: ".question-detail-options label .option-description", $options: ".question-detail-options label input", type: ".question-detail-type .question-detail-type-desc" }, ignore_click: $item => { return $item.prop("checked"); } }); WorkerJSPlus({ name: "青书学堂测验", match: location.host.includes("qingshuxuetang") && location.pathname.includes("/Student/ExercisePaper") || location.host === "quiz.qingshuxuetang.com" && location.pathname.includes("/Student/Quiz/Detail"), intv: () => { return $(".question-detail-container").length; }, root: ".question-detail-container", elements: { question: ".question-detail-description span", options: ".question-detail-options label .option-description", $options: ".question-detail-options div input,.question-detail-solution-textarea", type: ".question-detail-type" }, wrap: obj => { obj.options = obj.options.map(i => { return i.replace(/\([A-Za-z]\)/, "").trim(); }); }, ignore_click: ($item, type) => { if (type === 1) { return $item.prop("checked"); } }, fill: (type, answer, $option) => { if (type === 4 || type === 2) { $option.parents().find(".question-controller-wrapper .next").click(); } } }); WorkerJSPlus({ name: "优学院测验", match: location.pathname === "/learnCourse/learnCourse.html", intv: () => { return $(".question-setting-panel").length; }, root: ".split-screen-wrapper", elements: { question: ".question-title-scroller .question-title-html", options: ".choice-list .content-wrapper .text", $options: ".choice-list .checkbox ,.question-body-wrapper .choice-btn", type: ".question-title-scroller .question-type-tag" }, wrap: obj => { obj.options = obj.options.map(i => { return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim()); }); }, ignore_click: $item => { return $item.hasClass("selected"); } }); WorkerJSPlus({ name: "优学院作业", match: location.pathname === "/quiz/pc.html", intv: () => { return $(".questions").length; }, root: ".question-item", elements: { question: ".question-title", options: "ul label .choice-title", $options: "ul label input", type: ".title" }, wrap: obj => { obj.options = obj.options.map(i => { return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim()); }); }, ignore_click: $item => { return $item.prop("checked"); } }); WorkerJSPlus({ name: "优学院考试", match: location.host === "utest.ulearning.cn" && location.pathname === "/", intv: () => { return $(".section-area").length; }, root: ".question-area .question-item", elements: { question: ".base-question .title .rich-text", options: ".choice-list label .rich-text", $options: ".choice-list label, .iconfont", type: ".base-question .title .tip" }, wrap: obj => { obj.options = obj.options.map(i => { return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim()); }); }, ignore_click: $item => { return $item.hasClass("is-checked"); }, finished: () => { if ($(".next-part:contains(下个部分)").length) { $(".next-part").click(); return true; } else { return false; } } }); WorkerJSPlus({ name: "优学院作业", match: location.pathname === "/umooc/learner/homework.do", intv: () => { return $(".multiple-choices").length; }, root: ".multiple-choices,.judge", elements: { question: "h5 .position-rltv span:last-child", options: "ul label span:last-child", $options: "ul label input,.radios .radio input", type: "h5 .typeName" }, wrap: obj => { obj.options = obj.options.map(i => { return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim()); }); }, ignore_click: $item => { return $item.prev().hasClass("checkbox-checked"); } }); WorkerJSPlus({ name: "万学", match: location.pathname.includes("/sls/N2014_StudyController/next"), root: ".question", elements: { question: "tr .nm2", options: ".grey td p", $options: ".option li label", type: "tr .nm2" }, wrap: obj => { obj.question = obj.question.parent().find("td p").text(); } }); WorkerJSPlus({ name: "wenJuanAutoFill", match: location.host.includes("wenjuan.com") && location.pathname === "/s/", root: "questionContent", elements: { question: ".title", options: ".icheckbox_div .option_label", $options: ".icheckbox_div label", type: ".question_num" }, ignore_click: $item => { return $item.attr("class").includes("checked"); } }); WorkerJSPlus({ name: "学起（考试）", match: location.pathname.includes("/oxer/page/ots/examIndex.html"), intv: () => { return $(".tika_topline").length; }, root: ".queItemClass", elements: { question: "dt .din:eq(1)", options: ".clearfix div", $options: ".clearfix .xuan,input" }, ignore_click: $item => { return $item.parent().hasClass("cur"); }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().find("div .fb:eq(0)").text()); if (obj.type === 3) { obj.options = [ "正确", "错误" ]; } } }); WorkerJSPlus({ name: "学起（测试）", match: location.pathname.includes("/oxer/page/ots/UniversityStart.html"), intv: () => { return $(".uniQueList").length; }, root: ".uniQueItem", elements: { question: ".QueStem", options: "ul li span", $options: "ul li" }, ignore_click: $item => { return $item.parent().hasClass("lichecked"); }, wrap: obj => { obj.type = getQuestionType(obj.$item.parents(".uniQueList").find(".fir").text()); if (obj.type === 3) { obj.options = [ "正确", "错误" ]; } console.log(obj); } }); WorkerJSPlus({ name: "易班考试", match: location.host === "exam.yooc.me" && location.pathname.includes("/group"), intv: () => { return $(".jsx-3527395752").length; }, root: "main:last", elements: { question: "h3 div", options: ".mb ul li .flex-auto", $options: ".mb ul li", type: ".mb-s" }, ignore_click: $item => { return $item.hasClass("_c"); }, fill: (type, answer, $option) => { if (type === 4 || type === 2) { $(".exam-input").val("answer"); } }, finished: need_jump => { if ($('.round:contains("下一题")').hasClass("ghost")) return false; $('.round:contains("下一题")').click(); return true; } }); WorkerJSPlus({ name: "英华学堂", match: () => { const pathMatch = location.pathname.includes("/user/work") || location.pathname.includes("/user/exam"); const matchHostArr = [ "mooc.kdcnu.com", "mooc.yncjxy.com", "mooc.cdcas.com", "mooc.cqcst.edu.cn", "mooc.kmcc.edu.cn", "mooc.wuhues.com" ]; return pathMatch && matchHostArr.includes(location.host); }, intv: () => { return $("#stateName").text().trim() === "进行中"; }, root: ".courseexamcon-main", elements: { question: ".name", options: ".list li .txt", $options: ".list li .exam-inp", type: ".type" }, ignore_click: $item => { return $item.prop("checked"); }, fill: (type, answer, $option) => {}, finished: auto_jump => { if ($(".next_exam").eq(3).prop("style")[0] == "display") return false; $(".next_exam").click(); } }); WorkerJSPlus({ name: "厦门在线教育测验", match: location.pathname.includes("/nec/student/exam/exam-paper!test"), root: "#paper_form > div:nth-child(4) > table:nth-child(1) > tbody:nth-child(2)>tr:even", elements: { question: "td:eq(1)", options: ".optionUl label .el-radio__label,.el-checkbox__label", $options: ".optionUl label" }, wrap: obj => { obj.options = obj.$item.next().find("tbody:first > tr tbody").map((i, y) => { return $(y).find("td:eq(1)").text(); }).toArray(); obj.$options = obj.$item.next().find("tbody:first > tr tbody").map((i, y) => { return $(y).find("input"); }); obj.type = 0; } }); WorkerJSPlus({ name: "金牌学堂", match: location.host === "www.goldgame.com.cn" && location.href.includes("/TestPage"), intv: () => { return $(".tab-btn-box li").length; }, root: ".test-type-box ul .white-bg", elements: { question: ".position-relative h3", options: ".test-option label p:last-child", $options: ".test-option label input" }, wrap: obj => { obj.question = obj.question.replace(/题目\d+\:/, "").trim().replace(/^\d+./, ""); obj.type = getQuestionType(obj.$item.parent().parent().find(".test-type-tips").text()); if (obj.$options.length > 2 && obj.$options.eq(0).hasClass("radiobox")) { obj.type = 0; } }, fillFinish: data => { $(".answer-sheet li").eq(GLOBAL.index).click(); } }); WorkerJSPlus({ name: "青岛开放大学", match: location.pathname.includes("/pages/exam/exam.html"), intv: () => { return $(".exam-content-block .exam-content-topic").length; }, root: ".exam-content-block .exam-content-topic", elements: { question: ".exam-topic-title", options: ".exam-topic-answer .layui-unselect span", $options: ".exam-topic-answer .layui-unselect" }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().find(".exam-content-title .exam-content-num").text()); } }); WorkerJSPlus({ name: "点墨考试", match: location.pathname.includes("/Exam/StartExam"), root: "#question div div:first", elements: { question: "div:first", options: "div:first ~ div", $options: "div:first ~ div input" }, wrap: obj => { obj.type = getQuestionType($(".alert #groupNameSpan").text()); }, finished: () => { $(".w-100 .btn-light:eq(1)").click(); return true; } }); WorkerJSPlus({ name: "点墨测验", match: location.pathname.includes("/Course/TestPaper"), root: ".question", elements: { question: " div div:first div:first", options: " div div:first div:first ~ div", $options: " div div:first div:first ~ div input" }, wrap: obj => { obj.type = getQuestionType($("h3").text()); obj.question = obj.question.replace(/^\d+\./, ""); } }); WorkerJSPlus({ name: "警官学院", match: location.pathname.includes("/bsmytest/startTi.do"), root: ".wrapper > div", elements: { question: ".dx", options: "p", $options: "p input" }, wrap: obj => { if ($(".wrapper .cl").length > 0) { obj.question = obj.$item.text().replace(/[0-9]、/, "").replace(/\（.*?\）/g, "").trim().split("$")[0].replace(/\(.*?\)/g, "").trim(); } else { obj.question = obj.question.replace(/[0-9]、/, "").replace(/\（.*?\）/g, "").trim(); } obj.type = getQuestionType(obj.$item.parent().find("h2").text()); obj.options = obj.options.map(item => { return item.replace(/[A-Za-z][\：]/, "").replace(/[A-Za-z][\：,\:]/, "").replace(/\；/, "").trim(); }); } }); WorkerJSPlus({ name: "exam2_euibe_com_exam", match: location.hostname === "exam2.euibe.com" && location.pathname === "/KaoShi/ShiTiYe.aspx", root: ".question", elements: { question: ".wenti", options: "li label span", $options: "li label" }, wrap: obj => { obj.type = getQuestionType($(".question_head").text()); }, finished: need_jump => { $(".paginationjs-next").click(); return true; } }); WorkerJSPlus({ name: "lzwyedu_jijiaool_com_exam", match: () => { const pathMatch = location.pathname.includes("/learnspace/course/test/") || location.pathname.includes("/Student/ExamManage/CourseOnlineExamination"); const matchHostArr = [ "lzwyedu.jijiaool.com", "cgjx.jsnu.edu.cn", "learn-cs.icve.com.cn", "nwnu.jijiaool.com", "lut.jijiaool.com", "learn.courshare.cn", "cj1027-kfkc.webtrn.cn" ]; return pathMatch && matchHostArr.includes(location.host); }, root: ".test_item", elements: { question: ".test_item_tit", options: ".test_item_theme label .zdh_op_con", $options: "label input" }, wrap: obj => { obj.question = obj.question.replace(/该题未做$/, "").replace(/^\d+\./, "").replace(/^\d+、/, "").replace(/[(（](\d+\s?(\.\d+)?分)[)）]$/, "").replace(/^((\d+.(\s+)?)?)[\[(（【](.*?)[】)）\]]/, "").trim(); obj.type = getQuestionType(obj.$item.prevAll(".test_item_type:first").text()); if (obj.type === 3) { obj.options = [ "对", "错" ]; } } }); WorkerJSPlus({ name: "zzx_ouchn_edu_cn_exam", match: location.hostname === "zzx.ouchn.edu.cn" && location.pathname.includes("/edu/public/student/"), root: ".subject", elements: { question: ".question span", options: ".answer>span>p:first-child", $options: ".answer>span>p:first-child" }, wrap: obj => { if (obj.$options.length > 1) { obj.type = 0; } } }); WorkerJSPlus({ name: "zzx_ouchn_edu_cn_exam", match: location.hostname === "zzx.ouchn.edu.cn" && location.pathname.includes("/edu/public/student/"), root: ".subject", elements: { question: ".question span", options: ".answer>span>p:first-child", $options: ".answer>span>p:first-child" }, wrap: obj => { if (obj.$options.length > 1) { obj.type = 0; } } }); WorkerJSPlus({ name: "havust_hnscen_cn_exam", match: location.hostname === "havust.hnscen.cn" && location.pathname.includes("/stuExam/examing/"), root: ".main .mt_2 > div", elements: { question: ".flex_row+div", options: ".flex_row+div+div .el-radio__label,.el-checkbox__label", $options: ".flex_row+div+div .el-radio__label,.el-checkbox__label", type: ".flex_row .mr_2" } }); WorkerJSPlus({ name: "www_zygbxxpt_com_exam", match: location.hostname === "www.zygbxxpt.com" && location.pathname.includes("/exam"), root: ".Body", elements: { question: ".QName", options: ".QuestinXuanXiang p:parent", $options: ".QuestinXuanXiang p:parent", type: ".QName span" }, wrap: obj => { obj.question = obj.question.replace(/\([^\)]*\)/g, "").replace(/\【.*?\】/g, ""); obj.options = obj.options.map(item => { return item.split(">").pop().trim(); }); } }); WorkerJSPlus({ name: "xuexi_jsou_cn_work", match: location.hostname === "xuexi.jsou.cn" && location.pathname.includes("/jxpt-web/student/newHomework/showHomeworkByStatus"), root: ".insert", elements: { question: ".window-title", options: ".questionId-option .option-title div[style^=display]", $options: ".questionId-option .option-title .numberCover" }, wrap: obj => { obj.type = { 1: 0, 2: 1, 7: 3 }[obj.$item.find(".question-type").val()]; if (obj.options.length == 2) { obj.type = 3; } } }); WorkerJSPlus({ name: "czvtc_cjEdu_com_exam", match: () => { const pathMatch = location.pathname.includes("/ExamInfo") || location.pathname.includes("/Examination"); const matchHostArr = [ "czvtc.cj-edu.com", "hbkjxy.cj-edu.com", "bhlgxy.cj-edu.com", "hbsi.cj-edu.com", "czys.cj-edu.com", "hbjd.cj-edu.com", "xttc.cj-edu.com", "bvtc.cj-edu.com" ]; return pathMatch && matchHostArr.includes(location.host); }, intv: () => { return $(".el-container .all_subject>.el-row").length; }, root: ".el-container .all_subject>.el-row", elements: { question: ".stem div:last-child", options: ".el-radio-group .el-radio__label,.el-checkbox-group .el-checkbox__label", $options: ".el-radio-group .el-radio__original,.el-checkbox-group .el-checkbox__original" }, wrap: obj => { if (obj.$options.length < 3 && obj.$options.eq(0).attr("type") === "radio") { obj.type = 3; } else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") === "radio") { obj.type = 0; } else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") === "checkbox") { obj.type = 1; } } }); WorkerJSPlus({ name: "learning_mhtall_com_exam", match: location.host.includes("learning.mhtall.com") && location.pathname.includes("/rest/course/exercise/item"), root: "#div_item", elements: { question: ".item_title", options: ".opt div label", $options: ".opt div input:not(.button_short)", type: "h4" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { if (obj.type === 0 || obj.type === 3) { obj.answer = $(".div_answer").text().match(/[a-zA-Z]/).map(i => { return obj.options[i.charCodeAt(0) - 65]; }); } else if (obj.type === 2) { obj.answer = $(".div_answer").text().replace("参考答案：", "").split("，"); } }, fill: (type, answer, $option) => { if (type === 2 || type === 4) { $option.val(answer); $(".DIV_TYPE_BLANK .button_short").click(); } }, fillFinish: () => { if ($(".opt+div+div input:eq(1)").val() === "下一题") { $(".opt+div+div input:eq(1)").click(); } else { $(".button_short:eq(2)").click(); } } }); WorkerJSPlus({ name: "168网校(测验)", match: location.host.includes("168wangxiao.com") && location.pathname.includes("/web/learningCenter/details/"), intv: () => { return $(".ret-answer").length === 0 && $(".info-container").length; }, root: ".question-item-container", elements: { question: ".title-content", options: ".options .opt-content", $options: ".options label", type: ".top .type" } }); WorkerJSPlus({ name: "168网校(考试)", match: location.host.includes("168wangxiao.com") && location.pathname.includes("/web/examination/answer"), intv: () => { return $(".Answer-area").length; }, root: ".Answer-area", elements: { question: ".listTit", options: ".el-radio__label span:last-child,.el-checkbox__label span:last-child", $options: ".el-radio__input,.el-checkbox__input input,.ql-editor p" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { if (obj.options.length === 0) { obj.type = 2; } console.log(obj); }, fill: (type, answer, $option) => { if (type === 2 || type === 4) { console.log(answer); document.querySelector(".ql-editor p").textContent = answer; } }, finished: () => { if ($(".ctrl .el-button:contains(下一题)").length != 0) { $(".ctrl .el-button:contains(下一题)").click(); return true; } else if ($(".ctrl .el-button:contains(上一题)").length && $(".ctrl button").length === 1) { return false; } } }); WorkerJSPlus({ name: "法宣在线", match: location.host.includes("faxuanyun.com") && location.pathname.includes("/bps/examination"), intv: () => { return $("#timucontent").length; }, root: "#timucontent", elements: { question: "h2", options: "ul li", $options: "ul input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.question = obj.question.replace(/[\（(].+?[)\）]/g, ""); if ($(".layui-layer-content").length) { iframeMsg("tip", { type: "stop", tip: "答题暂停，请自行通过验证" }); $("#lastButton").click(); GLOBAL.stop = true; return false; } }, finished: need_jump => { if ($("#nextButton").length) { $("#nextButton").click(); return true; } else { return false; } } }); WorkerJSPlus({ name: "山财培训网 (补考)", match: location.host.includes("training.sdufe.edu.cn") && location.pathname.includes("/Exam/OnlineExam/"), intv: () => { return $(".exam_r_m").length; }, root: ".exam_r_m", elements: { question: ".bt", options: ".btm", $options: ".btm input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.question = obj.question.replace(/[\（(].+?[)\）]/g, ""); obj.options = $("br").parent().text().split(/[A-Z]\./).slice(1).map(item => { return item.trim(); }); if (obj.type === 3) { obj.answer = $("#answerDiv").text().replace("正确答案：", "").split(); } else { obj.answer = $("#answerDiv").text().match(/[A-Z]/g).map(item => { return obj.options[item.charCodeAt(0) - 65]; }); } }, finished: () => { document.querySelector("#next").click(); if (document.querySelector("#noAskCount").textContent == "0") { return false; } return true; } }); WorkerJSPlus({ name: "和学在线", match: (location.host.includes("student.hexuezx") || location.host.includes("student.jxjyzx")) && location.hash.includes("homework-questions"), intv: () => { return $(".el-card__body").length; }, root: ".el-card__body", elements: { question: ".stem", options: ".el-radio__label,.el-checkbox__label span", $options: ".el-radio__input,.el-checkbox__input input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.question = obj.question.replace(/[\（(].+?[)\）]/g, ""); console.log(obj); } }); WorkerJSPlus({ name: "高教在线", match: location.host === "www.cqooc.com" && (location.href.includes("/learn/mooc/exam/do") || location.href.includes("/learn/mooc/testing/do")), intv: () => { return $("#test-form").length; }, root: "#test-form .cat", elements: { question: ".stem", options: ".option label", $options: ".option input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.question = obj.question.replace(/\(\d+分\)\d+\.\d+/, ""); console.log(obj); } }); WorkerJSPlus({ name: "柠檬文才（考试）", match: () => { const pathMatch = location.pathname.includes("/separation/exam/"); const matchHostArr = [ "learning.wuxuejiaoyu.cn", "learning.wencaischool.net", "learning.zk211.com", "study.wencaischool.net", "www.wencaischool.net" ]; return pathMatch && matchHostArr.includes(location.host); }, intv: () => { return $("#paperExam").css("display") != "none"; }, root: ".paperWrapper .tmList", elements: { question: ".tmTitleTxt", options: ".ansbox .opCont", $options: ".ansbox input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { if (obj.options.length === 0) { obj.type = 2; } console.log(obj); }, fill: (type, answer, $option) => { if (type === 4 || type === 2) { $option.val(answer); } } }); WorkerJSPlus({ name: "柠檬文才（作业）", match: () => { const matchHostArr = [ "learning.wuxuejiaoyu.cn", "learning.wencaischool.net", "learning.zk211.com", "study.wencaischool.net" ]; return (location.pathname.includes("/hblearning/exam/") || location.pathname.includes("/xbsflearning/exam/") || location.pathname.includes("/openlearning/exam/") || location.pathname.includes("/jxlearning/exam/") || location.pathname.includes("/shandonglearning/exam")) && matchHostArr.includes(location.host); }, intv: () => { return $("#paperExam").css("display") !== "none"; }, root: "#_block_content_exam #tblDataList>tbody>tr", elements: { question: "tbody:first>tr>td:last table", options: ".ansbox .opCont", $options: ".ansbox input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.question = $("#_block_content_exam #tblDataList>tbody>tr>td").find(" tbody:first>tr>td:last table:first").eq(GLOBAL.index - 1).find("tr:first").text(); obj.options = []; $("#_block_content_exam #tblDataList>tbody>tr>td").find(" tbody:first>tr>td:last table:first").eq(GLOBAL.index - 1).find("tr:first").next().find("label").map((i, y) => { obj.options.push($(y).text()); }); obj.$options = $("#_block_content_exam #tblDataList>tbody>tr>td").find(" tbody:first>tr>td:last table:first").eq(GLOBAL.index - 1).find("tr:first").next().find("input").map((i, y) => { return y; }); obj.type = 0; if (obj.options.length == 2) { obj.type = 3; } else if (obj.$options.eq(0).attr("type") != "radio") { obj.type = 1; } console.log(obj); } }); WorkerJSPlus({ name: "福建师范", match: location.host === "neo.fjnu.cn" && location.pathname.includes("/resource/index"), intv: () => { return $(".content").length && !$(".answer-content").length; }, root: ".content", elements: { question: ".title", options: "label .el-radio__label,.el-checkbox__label", $options: "label input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { console.log(obj); } }); WorkerJSPlus({ name: "优课学堂", match: location.host.includes("youkexuetang.cn") && location.pathname.includes("/student/"), intv: () => { return $(".paperItemBox").length; }, root: ".paperItemBox", elements: { question: ".stem", options: ".el-radio__label,.el-checkbox__label", $options: ".el-radio__input,.el-checkbox__input input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.question = obj.question.replace(/[\（(].+?[)\）]/g, ""); console.log(obj); } }); WorkerJSPlus({ name: "亿学宝云", match: location.host.includes("yxbyun.com") && location.pathname.includes("/yxbstudent/"), intv: () => { return $(".time_header").length || $(".pager_wrap").length; }, hook: () => { JSONParseHook(o => { if (o.data && o.data.bigContent) { GLOBAL.json = parseYxbyunExam(o.data.bigContent).reduce((acc, cur) => { return acc.concat(cur); }, []); console.log(GLOBAL.json); } }); }, root: ".test", elements: { question: ".type", options: ".el-radio-group,.el-checkbox-group label", $options: ".el-radio__input,.el-checkbox__input input", type: ".el-tag" }, wrap: obj => { Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]); }, ignore_click: $item => { return $item.prop("checked"); } }); WorkerJSPlus({ name: "考试星（单题）", match: Boolean(location.host === "exam.kaoshixing.com" && location.pathname.includes("/exam/exam_start")), intv: () => { return $("#nextQuestions").length; }, root: ".questions .questions-content", elements: { question: ".question-name", options: ".answers label .words", $options: ".answers label" }, ignore_click: $item => { return $item.parent().find("input").prop("checked"); }, wrap: obj => { obj.question = obj.question.replace(/[\（(].+?[)\）]/g, ""); console.log(obj); }, finished: () => { if ($("#nextQuestions:contains(下一题)").length && $("#nextQuestions").css("display") !== "none") { $("#nextQuestions:contains(下一题)").click(); return true; } else { return false; } } }); WorkerJSPlus({ name: "易考云", match: location.host === "exam.beeouc.com" && location.pathname.includes("/client"), intv: () => { return $(".question-body").length; }, root: ".question-body", elements: { question: ".question-stem", options: ".question-option label", $options: ".question-option input", type: ".question-type" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { console.log(obj); }, finished: () => { if ($(".question-footer button:contains(下一题)")) { $(".question-footer button:contains(下一题)").click(); return true; } else { return false; } } }); WorkerJSPlus({ name: "伊犁师范成人教育", match: location.host === "exam.weirenzheng.cn" && (location.pathname.includes("//GeneralTestPaper/Testing/") || location.pathname.includes("//GeneralTestPaper/SNTesting")), intv: () => { return $(".topic").length; }, root: ".topic", elements: { question: ".qsctt", options: ".xuan li", $options: ".choice input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.options = obj.options.map(i => { return i.replace(/^[A-Z] \. /, ""); }); if (obj.$options.length == 2) { obj.options = [ "正确", "错误" ]; obj.type = 3; } } }); WorkerJSPlus({ name: "绎通云课堂 （作业）", match: location.host.includes("ytccr.com") && (location.hash.includes("#/learning-work") || location.hash.includes("#/learning-details")), intv: () => { return $(".left-question").length; }, root: ".border-item", elements: { question: ".qa-title", options: "label .opt-title-cnt", $options: "label input" }, ignore_click: $item => { return $item.prop("checked"); } }); WorkerJSPlus({ name: "重庆大学网络教育学院 （作业）", match: location.host === "exercise.5any.com" && location.pathname.includes("/Exercise/WebUI/Test/Answer"), intv: () => { return $(".examtime-content").length; }, root: ".subject .font-16", elements: { question: ".stem .richtextcontent", options: ".option .richtextcontent", $options: ".option label input" }, ignore_click: $item => { return $item.prop("checked"); } }); WorkerJSPlus({ name: "毕节幼儿师范", match: location.host === "px.gzbjyzjxjy.cn" || location.host === "px.ggcjxjy.cn" && location.pathname.includes("/exam/shiti/dopapers"), intv: () => { return $(".panel-body").length; }, root: ".panel-body>div", elements: { question: ".testpaper-question-stem", options: ".testpaper-question-choices li", $options: ".testpaper-question-footer input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { console.log(obj); } }); WorkerJSPlus({ name: "贵州继续教育", match: location.host === "www.gzjxjy.gzsrs.cn" && location.pathname.includes("/personback/"), intv: () => { return $(".question-title").length; }, root: ".question-title", elements: { question: ".show-text", options: "label", $options: "label input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { console.log(obj); } }); WorkerJSPlus({ name: "和学自考", match: location.host === "zkpt.qdu.edu.cn" && location.pathname.includes("/examStu/exam/examPaper"), intv: () => { return $(".ant-spin-container").length; }, root: ".ant-row", elements: { options: "label", $options: "label input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.question = obj.$item.parent().parent().prev().text(); console.log(obj); } }); WorkerJSPlus({ name: "专技天下", match: location.host.includes("zgzjzj.com") && location.pathname.includes("/examination/perpar.html"), intv: () => { return $(".question_index").length; }, root: ".question_index", elements: { question: "p", options: ".options li p,li>span:last-child", $options: ".options li", type: "p span" }, ignore_click: $item => { return $item.hasClass("active"); } }); WorkerJSPlus({ name: "睿学补考", match: location.href.includes("exam-app-exam-paper") && location.host.includes("ks.hustsnde.com"), intv: () => { return $("#paper").length; }, root: "#paper .content-box", elements: { question: "ul li:eq(0) .desc", options: "ul li:eq(1)", $options: "ul label input", type: ".title" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { const options = obj.options[0].trim().split(/\[[A-Z]:?\]/).splice(1).map(i => { return i.trim(); }).filter(i => i); if (options.length === 0) { obj.options = obj.options[0].trim().split(/\(?[A-Z\.?]\)?/).splice(1).map(i => { return i.trim(); }).filter(i => i); } else { obj.options = options; } if (obj.type === 3) { obj.options = [ "正确", "错误" ]; } } }); WorkerJSPlus({ name: "云上河开", match: location.host === "jx.open.ha.cn" && location.pathname.includes("/jxpt-web/student/homework/showHomeworkByStatus"), intv: () => { return $("#shiti-content").length; }, root: ".insert", elements: { question: ".window-title", options: "ul li div:last-child", $options: "ul li .numberCover" }, ignore_click: $item => { return $item.parent().hasClass("answer-title"); }, wrap: obj => { obj.type = getQuestionType(obj.$item.parents(".layui-colla-item").find(".titleType").text()); } }); WorkerJSPlus({ name: "ycjy.lut.edu.cn", match: location.host === "ycjy.lut.edu.cn" && location.pathname.includes("/learnspace/course/test/coursewareTest_intoTestPage.action"), intv: () => { return $(".bank_cont").length; }, root: ".test_item", elements: { options: "label", $options: "label input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().find(".test_item_type").text()); obj.question = obj.$item.find(".test_item_tit").contents()[0].nodeValue.trim(); } }); WorkerJSPlus({ name: "exam.euibe.com", match: location.host === "exam.euibe.com" && location.pathname.includes("/KaoShi/ShiTiYe.aspx"), intv: () => { return $(".question_list").length; }, root: ".question", elements: { question: ".wenti .stem", options: "label span", $options: "label input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.type = getQuestionType(obj.$item.parents(".question_list").find(".question_head").text()); }, finished: need_jump => { if ($(".paginationjs-next").hasClass("disabled")) { return false; } $(".paginationjs-next").click(); return true; } }); WorkerJSPlus({ name: "学晖教育", match: location.host === "xhjy.ldzxjy.com" && location.pathname.includes("tikuUserBatch/keepTopic"), intv: () => { return $(".radio").length; }, root: ".radio", elements: { question: ".issueTitle", options: "ul li span", $options: "ul li", type: ".issueTypes" }, ignore_click: $item => { return $item.prop("checked"); }, finished: need_jump => { if ($(".next").text().includes("交卷")) { return false; } $(".next").click(); return true; } }); WorkerJSPlus({ name: "东财在线", match: location.host === "classroom.edufe.com.cn" && (location.pathname.includes("/PracticePaper") || location.pathname.includes("/HomeWorkPaper")), intv: () => { return $(".TK-main").length; }, root: ".CBTPaperMain-trunk", elements: { question: ".CBTPaperMain-divInline", options: "ul li label", $options: "ul li label" }, ignore_click: $item => { return $item.hasClass("_CheckBox_checked"); } }); WorkerJSPlus({ name: "北华大学在线教育", match: location.host === "beihua.peishenjy.com" && location.pathname.includes("/Learning/CourseOnlineExamination"), intv: () => { return $(".s_mi").length; }, root: ".test_item", elements: { question: ".test_item_tit", options: "ul label", $options: "ul input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { console.log(obj); } }); WorkerJSPlus({ name: "上海立达学院", match: location.host === "kkzxsx.lidapoly.edu.cn" && location.pathname.includes("/exam/"), intv: () => { return $(".exam-question").length; }, root: ".main .item", elements: { question: ".text", options: ".options label .el-radio__label,.el-checkbox__label", $options: ".options label" }, ignore_click: $item => { return $item.hasClass("is-checked"); }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().find(".text").text()); console.log(obj); } }); WorkerJSPlus({ name: "国开", match: location.host === "lms.ouchn.cn" && location.pathname.includes("/exam/"), intv: () => { return $(".loading-gif").hasClass("ng-hide") && $(".hd .examinee .submit-label").eq(0).text() === ""; }, root: ".card ol .single_selection,.multiple_selection,.true_or_false,.short_answer", elements: { question: ".summary-title .subject-description", options: ".subject-options li .option-content", $options: ".subject-options label .left", type: ".summary-sub-title span:eq(0)" }, ignore_click: ($item, type) => { return type === 1 && $item.find("input").hasClass("ng-not-empty"); } }); WorkerJSPlus({ name: "广开", match: () => { const pathMatch = location.pathname.includes("/mod/quiz/attempt.php"); const matchHostArr = [ "moodle.syxy.ouchn.cn", "xczxzdbf.moodle.qwbx.ouchn.cn", "elearning.bjou.edu.cn", "whkpc.hnqtyq.cn:5678", "course.ougd.cn", "study.ouchn.cn" ]; return pathMatch && matchHostArr.includes(location.host); }, root: ".que", elements: { question: ".qtext", options: ".answer div label,.flex-fill", $options: ".answer div input:visible" }, wrap: data => { if (data.type === undefined) { try { data.type = 4; data.$item.find(".qtext .accesshide").remove(); data.question = formatString(data.$item.find(".qtext").html()); data.$options = data.$item.find("input[id$=_answer]"); } catch (e) {} } }, ignore_click: $item => { return Boolean($item.parent().find("input").eq(-1).prop("checked")); }, finished: () => { $(".submitbtns .btn-primary").click(); }, fill: (type, answer, $option) => { if (type === 4) { console.log(type, answer, $option); console.log($option.attr("id")); $option.val(answer); } } }); WorkerJSPlus({ name: "保定继续教育", match: location.pathname.includes("/exam/answer.html"), root: ".stem-container", elements: { question: ".stem span", options: ".option div .optStem", $options: ".option div input" }, intv: () => { return $("#question").length; }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().parent().find(".description").text()); } }); WorkerJSPlus({ name: "noNiExam.js", match: location.pathname === "/app-afstudy/self_test.html", root: ".lineClass .b-papp-root", elements: { question: ".b-exam-top .b-exam-tit", options: ".b-exam-box li label", $options: ".b-exam-box li input", type: ".b-exam-top .b-exam-type" }, ignore_click($item) { return $item.prop("checked"); }, wrap(obj) { obj.options = obj.options.map(i => { return i.replace(/[A-Za-z][\：]/, "").replace(/[A-Za-z][\：,\:]/, "").replace(/\；/, "").trim(); }); } }); WorkerJSPlus({ name: "www_pbaqks_com_text", match: location.host === "www.pbaqks.com" && location.pathname.includes("/P_ExamDetail/OnlineStuday"), root: ".main-container .single-box", elements: { question: ".single-main:first", options: ".choose-box label", $options: ".choose-box label", type: ".single-container .font-title", answer: "input:eq(1)" }, ignore_click: $i => { return $i.find("input").is(":checked"); }, wrap: obj => { obj.question = obj.question.replace("标准答案", "").replace(/^\d+\./, "").replace(/\[.+?\]/g, "").trim(); }, fillFinish: () => { if ($(".main-container .single-box").find("input:eq(1)").eq(GLOBAL.index - 1).attr("value").split("").length > 1) { jQuery(".main-container .confirm a:last-child").click(); } } }); WorkerJSPlus({ name: "安徽继续教育", match: location.pathname.includes("/study/html/content/studying/") || (location.pathname === "/study/html/content/tkOnline/" || location.pathname === "/study/html/content/sxsk/"), intv: () => { return ($(".e-save-b").length || $(".e-b-g").length) && $(".totalscore").length === 0; }, root: ".e-q", elements: { question: ".e-q-q .ErichText", options: ".e-a-g li", $options: ".e-a-g li" }, ignore_click: $item => { return $item.attr("class").includes("checked"); }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().prev().find(".e-text").text()); obj.options = obj.options.map(i => { return formatString(i.replaceAll(/^[ab]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim()); }); } }); WorkerJSPlus({ name: "大连/九江", match: location.href.includes("/onlineclass/exam/"), intv: () => { return $(".excer_list_view___2Ahg9") || $(".excer_list_view___YOSCa"); }, root: ".single_excer_item___lFMCm,.single_excer_item___2lGB8", elements: { plat: 40, question: ".title_content___1Qagx .title_content_text___27NIL, .title_content___24J6D .title_content_text___8ruL4", options: ".options_content___nXSwG label .option_text___udjiE, .options_content___2YgyG label .option_text___1mfcu", $options: ".options_content___nXSwG label input,.options_content___2YgyG label input", type: ".title_content___1Qagx span:eq(1),.title_content___24J6D span:eq(1)" }, ignore_click: $item => { return $($item).parent().hasClass("ant-checkbox-checked"); }, wrap: obj => { console.log(obj); }, fill: (type, answer, $option) => { if (type === 4 || type === 2) { $option.val(answer); } } }); WorkerJSPlus({ name: "新疆继续教育", hook: () => { function parseXinJiangAgain(questions) { return questions.map(item => { const answer = []; const options = item.answers.map(opt => { if (opt.isAnswer === "0") answer.push(formatString(opt.name)); return formatString(opt.name); }); const type = item.types === "2" ? 3 : parseInt(item.types); return { question: item.name, options: options, answer: answer, type: type }; }); } JSONParseHook(o => { if (o.success && o.data.exam) { const arr = o.data.exam.assessList.map(i => { return i.questionList; }).flat(); GLOBAL.json = parseXinJiangAgain(arr); } }); }, match: location.host === "www.ttcdw.cn" && location.pathname.includes("/p/uExam/goExam/"), root: ".question-item", elements: { question: ".question-item-title span", options: ".question-item-option label .el-checkbox__label,.el-radio__label", $options: ".question-item-option label" }, wrap: obj => { Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]); }, intv: () => { return !$("div").hasClass("entrying-wrap"); }, ignore_click: $item => { return $item.hasClass("is-checked"); }, fill: (type, answer, $option) => { if (type === 4 || type === 2) { $option.val(answer); } } }); WorkerJSPlus({ name: "华侨继续教育", match: location.pathname.includes("/exam/student/exam/resource/paper_card2"), intv: () => { return $(".ui-question-answer-right").length === 0; }, root: ".ui-question-group .ui-question", elements: { question: ".ui-question-title div", options: ".ui-question-options div", $options: ".ui-question-options .ui-question-options-order,.ke-container" }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().find("h2").text()); }, ignore_click: $item => { return $item.parent().hasClass("ui-option-selected"); }, fill: (type, answer) => { if (type === 4 || type === 2 || type === 6) { const x = GLOBAL.index - $(".ui-question-options ").length - 1; KindEditor.instances[x].html(answer); } } }); WorkerJSPlus({ name: "上海开放大学", match: location.pathname.includes("/study/assignment/preview.aspx") || location.pathname.includes("/study/assignment/continuation.aspx"), hook: () => { if (GLOBAL.finish || $("a:contains(已完成批阅)").length === 1) { iframeMsg("tip", { type: "hidden", tip: "本页面已做完，无需自动答题" }); return true; } }, root: ".e-q", elements: { question: ".e-q-q .ErichText", options: ".e-a-g li", $options: ".e-a-g li" }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().parent().parent().find(".e-text").eq(0).text()); obj.options = obj.options.map(i => { return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim()); }); }, ignore_click: $item => { return $item.attr("class").includes("checked"); } }); WorkerJSPlus({ name: "浙江考试", match: location.pathname === "/web-qz/moni/exam/exam_toExam.action", root: ".dt_tmcon", elements: { question: "div:eq(0) span:eq(1)", options: "div:eq(1) p", $options: "div:eq(1) p input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { obj.type = getQuestionType(obj.$item.parents().find(".dt_rtitle1").eq(0).text()); obj.options = obj.options.map(i => { return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim()); }); if (obj.type === 0) { obj.answer = [ JSON.parse($("#quesSSForm #userAnssStr_0").val()).rightAnswer ]; uploadAnswer([ obj ]); } }, finished: () => { return $(".page li input:eq(2)").attr("disabled") !== "disabled"; }, fillFinish: () => { $(".page li input:eq(2)").click(); } }); WorkerJSPlus({ name: "在浙学考试", match: location.host === "www.zjooc.cn" && (location.pathname.includes("/homework/") || location.pathname.includes("/test/") || location.pathname.includes("/exam/")), hook: () => { function parseZaiZheXue(problems) { return problems.map(item => { if (!item.rightAnswer) return undefined; const subjectType = item.subjectType; let type = -1; const question = formatString(item.subjectName); const answer = []; const options = []; if (subjectType === 1 || subjectType === 2) { type = subjectType - 1; for (let subjectOption of item.subjectOptions) { const opt = formatString(subjectOption.optionContent); options.push(opt); if (item.rightAnswer.includes(subjectOption.optionHead)) { answer.push(opt); } } } else if (subjectType === 3) { type = 3; answer.push(item.rightAnswer === "yes" ? "正确" : "错误"); } else { return undefined; } return { question: question, options: options, type: type, answer: answer }; }).filter(i => i && i.answer.length > 0); } if (!(location.pathname.includes("/homework/do") || location.pathname.includes("/test/do") || location.pathname.includes("/exam/do"))) { JSONParseHook(o => { if (o.data && o.data.paperName && o.data.clazzIds && o.data.paperSubjectList) { const data = parseZaiZheXue(o.data.paperSubjectList); console.log(data); } }); return true; } }, root: ".questiono-item", elements: { question: "h6 .processing_img", options: ".questiono-main label .el-radio__label,.el-checkbox__label", $options: ".questiono-main label" }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().prev().text()); obj.options = obj.options.map(i => { return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim()); }); }, ignore_click: $item => { return $item.hasClass("is-checked"); } }); WorkerJSPlus({ name: "在浙学（测验/考试）", match: location.host === "www.zjooc.cn" && location.pathname.includes("/singleQuestion/do/"), intv: () => { return $(".settingsel-dialog").css("display") === "none"; }, root: ".question_content:first", elements: { question: ".question_title", options: ".question_content .radio_content div", $options: ".question_content label" }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().find(".question_title p").eq(0).text()); obj.options = obj.options.map(i => { return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").replace(".", "").trim()); }); }, ignore_click: $item => { return $item.hasClass("is-checked"); }, finished: () => { if ($(".question_btn .el-button:contains(下一题)").hasClass("is-disabled")) return false; $(".el-button:contains(下一题)").click(); return true; } }); WorkerJSPlus({ name: "福建继续教育测验|作业", match: location.pathname === "/Web_Study/Student/Center/MyWorkOnView" || location.pathname === "/Web_Study/Student/Center/MyExamOnView", intv: () => { return $(".samllTopicNav").length; }, root: ".topic-cont", elements: { question: "p", options: ".options li span", $options: ".options li" }, wrap: obj => { obj.options = obj.options.map(i => { return i.replace(/选项[A-Za-z]/, "").trim(); }); obj.type = { 1: 0, 2: 1, 3: 3, 6: 4 }[obj.$item.attr("itemtype")]; if (obj.type === undefined) obj.type = 4; }, ignore_click: $item => { return $item.hasClass("correct"); }, fill: (type, answer, $option) => {} }); WorkerJSPlus({ name: "湖南继续教育", match: () => { const pathMatch = location.pathname.includes("/User/Student/myhomework.aspx") || location.pathname.includes("/examing.aspx"); const matchHostArr = [ "www.jwstudy.cn", "hdjt.wuxuekeji.com" ]; return pathMatch && (matchHostArr.includes(location.host) || location.host.includes("ls365.net") || location.host.includes("ls365.com")); }, root: ".exam_question", elements: { question: ".exam_question_title div", options: ".question_select .select_detail", $options: ".question_select li", type: ".exam_question_title div strong" }, ignore_click: $item => { return $item.hasClass("cur"); } }); WorkerJSPlus({ name: "德阳继续教育", match: location.href.includes("/dypx/OnlineExam/Exam.aspx"), root: "#divProblemArea", elements: { question: "#ulProblems li:first", options: "#ulProblems .answer", $options: "#ulProblems .answer input" }, ignore_click: $item => { return $item.prop("checked"); }, wrap: obj => { if ($("#ulProblems .answer input").length < 3 && $("#ulProblems .answer input").eq(0).attr("type") === "radio") { obj.type = 3; obj.options = [ "正确", "错误" ]; } else if ($("#ulProblems .answer input").length > 2 && $("#ulProblems .answer input").eq(0).attr("type") === "radio") { obj.type = 0; } else if ($("#ulProblems .answer input").length > 2 && $("#ulProblems .answer input").eq(0).attr("type") === "checkbox") { obj.type = 1; } }, finished: () => { if ($(".dlg").length) return false; $("#divBtns input:eq(1)").click(); return true; } }); WorkerJSPlus({ name: "淄博继续教育", match: location.pathname.includes("/practice/start"), root: ".header-left .trueorfalse .sub", elements: { question: ".mb10", options: ".options li", $options: ".options li" }, ignore_click: $item => { return $item.hasClass("active"); }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().prev().text()); obj.options = obj.options.map(i => { return formatString(i.replaceAll(/[a-zA-z]\)\s+/g, "").replaceAll(/^[a-z]\s+/g, "").replaceAll(/^[a-z]、\s+/g, "").trim()); }); } }); WorkerJSPlus({ name: "河北继续教育", match: location.pathname.includes("paperid"), root: ".examItem", elements: { question: ".examItemRight .question", options: ".examItemRight ul li span", $options: ".examItemRight ul li" }, ignore_click: $item => { return $item.hasClass("cur"); }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().find(".questTitle b").text()); } }); WorkerJSPlus({ name: "保定继续教育", match: () => { const pathnameArr = [ "/cuggw/rs/olex_exam", "/hebic/rs/olex_exam", "/sjzkjxy/rs/olex_exam", "/hbfsh/rs/olex_exam", "/jxycu/rs/olex_exam", "/jlufe/rs/olex_exam" ]; return pathnameArr.includes(location.pathname); }, intv: () => { return $(".paper_body").length; }, root: ".item_li", elements: { question: ".item_title", options: "ul li label", $options: "ul li input" }, wrap: obj => { if (obj.$options.length === 2) { obj.type = 3; } else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") === "radio") { obj.type = 0; } else if (obj.$options.length > 2 && obj.$options.eq(0).attr("type") !== "radio") { obj.type = 1; } else { obj.type = 4; } } }); WorkerJSPlus({ name: "唐山继续教育", match: location.pathname.includes("/exam/student/exam/"), intv: () => { return $(".ui-question-group").length; }, root: ".ui-question-group .ui-question", elements: { question: ".ui-question-title .ui-question-content-wrapper", options: ".ui-question-options .ui-question-content-wrapper", $options: ".ui-question-options .ui-question-options-order" }, wrap: obj => { obj.type = getQuestionType(obj.$item.parent().find("h2").text()); } }); WorkerJSPlus({ name: "zzcjxy.hnzkw.org.cn", match: location.host.includes("hnzkw.org.cn"), intv: () => { return $(".answer").length; }, hook: () => { JSONParseHook(o => { if (o.data && o.data.bookdatas) { GLOBAL.json = parsehnzkwText(o.data.bookdatas); } }); }, root: ".examList", elements: { question: ".text", options: ".el-radio-group label,.el-checkbox-group label", $options: ".el-radio-group input,.el-checkbox-group input", type: ".status" }, wrap: obj => { Object.assign(obj, GLOBAL.json[GLOBAL.index - 1]); }, fill: (type, answer, $option) => {} }); WorkerJSPlus({ name: "问卷星考试", match: location.pathname.includes("/exam/ExamRd/Answer"), root: ".g-mn", elements: { question: ".m-question .tigan", options: ".question-block .xuanxiang", $options: ".question-block .xuanxiang", type: ".tixing" }, ignore_click: ($item, type) => { if (type === 1) { return $item.parent().find(".icheckbox_square-green").hasClass("checked"); } else { const isIgnore = $item.parent().find(".iradio_square-green").hasClass("checked"); return isIgnore; } }, wrap: obj => { if ($(".layui-layer-content").length) { iframeMsg("tip", { type: "stop", tip: "答题暂停，请自行通过验证" }); GLOBAL.stop = true; return true; } }, fillFinish: data => { if (data.style === "warning-row" || $(".g-mn").parent().find(".iradio_square-green").hasClass("checked") || data.type === 1) { $('.u-btn-next:contains("下一题")').click(); } }, finished: () => { return parseInt($(".num-dangqian:last").attr("qindex")) !== $(".num-item").length; } }); })();
答题// ==UserScript== // @name 💯【超星学习通满分助手】支持任务点自动跳转|章节测验、作业、考试全网检索答案，简答题支持chatgpt对接|音频、视频全自动静音播放|可视化参数配置 // @namespace askAuto // @version 2.1.2 // @author shushoujiu // @description 💯超星学习通满分助手，挂机解放时间，无需任何操作自动完成所有任务点。汇集全网免费、付费题库接口支持一键对接，答案更全更靠谱。 // @icon https://vitejs.dev/logo.svg // @match *://*.chaoxing.com/* // @match *://*.edu.cn/* // @match *://*.nbdlib.cn/* // @match *://*.hnsyu.net/* // @match *://*.gdhkmooc.com/* // @require https://cdn.staticfile.org/vue/3.3.4/vue.global.prod.js // @require https://cdn.staticfile.org/vue-demi/0.14.0/index.iife.min.js // @require https://cdn.staticfile.org/element-plus-icons-vue/2.1.0/global.iife.min.js // @require data:application/javascript,window.Vue%3DVue%3B // @require https://cdn.staticfile.org/pinia/2.1.6/pinia.iife.prod.js // @require https://cdn.staticfile.org/element-plus/2.3.12/index.full.min.js // @require https://cdn.staticfile.org/blueimp-md5/2.19.0/js/md5.min.js // @require https://cdn.staticfile.org/jquery/3.7.1/jquery.min.js // @resource element-plus https://cdn.staticfile.org/element-plus/2.3.12/index.css // @resource ttf https://www.forestpolice.org/ttf/2.0/table.json // @connect cx.icodef.com // @connect tk.enncy.cn // @connect api.muketool.com // @connect api.tikuhai.com // @grant GM_addStyle // @grant GM_getResourceText // @grant GM_getValue // @grant GM_info // @grant GM_setValue // @grant GM_xmlhttpRequest // @grant unsafeWindow // @run-at document-end // @antifeature ads 脚本可能包含第三方接口广告 // @antifeature payment 脚本存在第三方答题接口付费功能 // @downloadURL https://update.greasyfork.org/scripts/436994/%F0%9F%92%AF%E3%80%90%E8%B6%85%E6%98%9F%E5%AD%A6%E4%B9%A0%E9%80%9A%E6%BB%A1%E5%88%86%E5%8A%A9%E6%89%8B%E3%80%91%E6%94%AF%E6%8C%81%E4%BB%BB%E5%8A%A1%E7%82%B9%E8%87%AA%E5%8A%A8%E8%B7%B3%E8%BD%AC%7C%E7%AB%A0%E8%8A%82%E6%B5%8B%E9%AA%8C%E3%80%81%E4%BD%9C%E4%B8%9A%E3%80%81%E8%80%83%E8%AF%95%E5%85%A8%E7%BD%91%E6%A3%80%E7%B4%A2%E7%AD%94%E6%A1%88%EF%BC%8C%E7%AE%80%E7%AD%94%E9%A2%98%E6%94%AF%E6%8C%81chatgpt%E5%AF%B9%E6%8E%A5%7C%E9%9F%B3%E9%A2%91%E3%80%81%E8%A7%86%E9%A2%91%E5%85%A8%E8%87%AA%E5%8A%A8%E9%9D%99%E9%9F%B3%E6%92%AD%E6%94%BE%7C%E5%8F%AF%E8%A7%86%E5%8C%96%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE.user.js // @updateURL https://update.greasyfork.org/scripts/436994/%F0%9F%92%AF%E3%80%90%E8%B6%85%E6%98%9F%E5%AD%A6%E4%B9%A0%E9%80%9A%E6%BB%A1%E5%88%86%E5%8A%A9%E6%89%8B%E3%80%91%E6%94%AF%E6%8C%81%E4%BB%BB%E5%8A%A1%E7%82%B9%E8%87%AA%E5%8A%A8%E8%B7%B3%E8%BD%AC%7C%E7%AB%A0%E8%8A%82%E6%B5%8B%E9%AA%8C%E3%80%81%E4%BD%9C%E4%B8%9A%E3%80%81%E8%80%83%E8%AF%95%E5%85%A8%E7%BD%91%E6%A3%80%E7%B4%A2%E7%AD%94%E6%A1%88%EF%BC%8C%E7%AE%80%E7%AD%94%E9%A2%98%E6%94%AF%E6%8C%81chatgpt%E5%AF%B9%E6%8E%A5%7C%E9%9F%B3%E9%A2%91%E3%80%81%E8%A7%86%E9%A2%91%E5%85%A8%E8%87%AA%E5%8A%A8%E9%9D%99%E9%9F%B3%E6%92%AD%E6%94%BE%7C%E5%8F%AF%E8%A7%86%E5%8C%96%E5%8F%82%E6%95%B0%E9%85%8D%E7%BD%AE.meta.js // ==/UserScript== (t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const d=document.createElement("style");d.textContent=t,document.head.append(d)})(" .dialog-footer button[data-v-468a4ec0]:first-child{margin-right:10px}#csbutton[data-v-468a4ec0]{position:fixed;bottom:20px;right:20px;z-index:99999}#zeokdjg[data-v-f2d2b132]{position:fixed;left:10px;bottom:50vh;z-index:9999}.question_btn[data-v-f2d2b132]{width:40px;height:40px;border-radius:5px;margin:5px}.question_div[data-v-f2d2b132]{height:200px}.question_ti[data-v-f2d2b132]{margin:10px 0 20px}.cx_log[data-v-f2d2b132]{margin:2px 0}.status_log[data-v-f2d2b132]{margin-top:10px} "); (async function (vue, pinia$1, ElementPlus, md5, $$1) { 'use strict'; 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); return value; }; ((e) => { const t = GM_getResourceText(e); GM_addStyle(t); })("element-plus"); var _GM_getResourceText = (() => "undefined" != typeof GM_getResourceText ? GM_getResourceText : void 0)(), _GM_getValue = (() => "undefined" != typeof GM_getValue ? GM_getValue : void 0)(), _GM_info = (() => "undefined" != typeof GM_info ? GM_info : void 0)(), _GM_setValue = (() => "undefined" != typeof GM_setValue ? GM_setValue : void 0)(), _GM_xmlhttpRequest = (() => "undefined" != typeof GM_xmlhttpRequest ? GM_xmlhttpRequest : void 0)(), _unsafeWindow = (() => "undefined" != typeof unsafeWindow ? unsafeWindow : void 0)(); const getConfig = () => { const config = _GM_getValue("config"); return config || defaultConfig$1; }, defaultConfig$1 = { debugger: false, autoAnswer: true, autoVideo: true, autoJump: true, autoSubmit: true, thtoken: "", yztoken: "", gptKey: "", gptModel: "gpt-3.5-turbo", gpt: false, gptType: ["0", "1", "2", "3", "4", "5", "6", "7"], interval: 3, answerInterval: 3, minAccuracy: 0.8, autoExam: true, hideExam: false, notice: "本脚本仅供学习交流使用，严禁用于商业用途，否则后果自负！" }, userConfig = [{ name: "base", label: "基础配置", config: [{ name: "interval", label: "通用间隔(秒)", type: "number", value: defaultConfig$1.interval, desc: "通用间隔，用于脚本运行切换" }, { name: "answerInterval", label: "答题间隔(秒)", type: "number", value: defaultConfig$1.answerInterval, desc: "控制答题速度" }, { name: "thtoken", label: "题库海token", type: "input", value: defaultConfig$1.thtoken, desc: "非必填，购买后可获得" }, { name: "yztoken", label: "一之题库token", type: "input", value: defaultConfig$1.yztoken, desc: "非必填，购买后可获得" }, { name: "enncytoken", label: "言溪题库token", type: "input", value: defaultConfig$1.enncytoken, desc: "非必填，购买后可获得" }] }, { name: "chapter", label: "章节配置", config: [{ name: "autoAnswer", label: "自动答题", type: "switch", value: defaultConfig$1.autoAnswer, desc: "开启后，会自动答题" }, { name: "autoVideo", label: "自动视频", type: "switch", value: defaultConfig$1.autoVideo, desc: "开启后，会自动观看视频" }, { name: "autoJump", label: "自动切换", type: "switch", value: defaultConfig$1.autoVideo, desc: "开启后，会自动切换章节" }, { name: "autoSubmit", label: "自动提交", type: "switch", value: defaultConfig$1.autoSubmit, desc: "开启后，会自动提交答案" }, { name: "minAccuracy", label: "最低正确率", type: "input", value: defaultConfig$1.minAccuracy, desc: "不满足最低正确率则不会自动提交答案" }] }, { name: "exam", label: "作业/考试配置", config: [{ name: "autoExam", label: "考试自动切换", type: "switch", value: defaultConfig$1.autoExam, desc: "开启后，会考试会自动切换" }] }, { name: "gpt", label: "GPT配置", config: [{ name: "gptKey", label: "GPT Key", type: "input", value: defaultConfig$1.gptKey, desc: "正在内测中，敬请期待" }, { name: "gptModel", label: "GPT 模型", type: "select", value: defaultConfig$1.gptModel, desc: "正在内测中，敬请期待", options: [{ label: "gpt-3.5-turbo", value: "gpt-3.5-turbo" }, { label: "gpt4", value: "gpt4" }] }, { name: "gpt", label: "题库无答案时，是否使用gpt", type: "switch", value: defaultConfig$1.gpt, desc: "开启后，题库无答案时，会使用gpt" }, { name: "gptType", label: "允许使用gpt的题型", type: "checkbox", value: defaultConfig$1.gptType, desc: "选中后，会使用gpt答题相应题型", options: [{ label: "单选题", value: "0" }, { label: "多选题", value: "1" }, { label: "填空题", value: "2" }, { label: "判断题", value: "3" }, { label: "简答题", value: "4" }, { label: "名词解释", value: "5" }, { label: "论述题", value: "6" }, { label: "计算题", value: "7" }] }] }], useformStore = pinia$1.defineStore({ id: "formstore", state: () => ({ forminput: getConfig(), dialogV: false, activeName: "base" }), actions: { saveConfig(forminput) { _GM_setValue("config", forminput); } } }); var export_helper_default = (sfc, props) => { let target = sfc.__vccOpts || sfc; for (let [key, val] of props) target[key] = val; return target; }, aim_vue_vue_type_script_lang_default = { name: "Aim" }, _hoisted_12$1 = { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 1024 1024" }, _hoisted_42 = [vue.createElementVNode("path", { fill: "currentColor", d: "M512 896a384 384 0 1 0 0-768 384 384 0 0 0 0 768zm0 64a448 448 0 1 1 0-896 448 448 0 0 1 0 896z" }, null, -1), vue.createElementVNode("path", { fill: "currentColor", d: "M512 96a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V128a32 32 0 0 1 32-32zm0 576a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V704a32 32 0 0 1 32-32zM96 512a32 32 0 0 1 32-32h192a32 32 0 0 1 0 64H128a32 32 0 0 1-32-32zm576 0a32 32 0 0 1 32-32h192a32 32 0 1 1 0 64H704a32 32 0 0 1-32-32z" }, null, -1)]; var aim_default = export_helper_default(aim_vue_vue_type_script_lang_default, [["render", function(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("svg", _hoisted_12$1, _hoisted_42); }], ["__file", "aim.vue"]]), setting_vue_vue_type_script_lang_default = { name: "Setting" }, _hoisted_1231 = { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 1024 1024" }, _hoisted_3230 = [vue.createElementVNode("path", { fill: "currentColor", d: "M600.704 64a32 32 0 0 1 30.464 22.208l35.2 109.376c14.784 7.232 28.928 15.36 42.432 24.512l112.384-24.192a32 32 0 0 1 34.432 15.36L944.32 364.8a32 32 0 0 1-4.032 37.504l-77.12 85.12a357.12 357.12 0 0 1 0 49.024l77.12 85.248a32 32 0 0 1 4.032 37.504l-88.704 153.6a32 32 0 0 1-34.432 15.296L708.8 803.904c-13.44 9.088-27.648 17.28-42.368 24.512l-35.264 109.376A32 32 0 0 1 600.704 960H423.296a32 32 0 0 1-30.464-22.208L357.696 828.48a351.616 351.616 0 0 1-42.56-24.64l-112.32 24.256a32 32 0 0 1-34.432-15.36L79.68 659.2a32 32 0 0 1 4.032-37.504l77.12-85.248a357.12 357.12 0 0 1 0-48.896l-77.12-85.248A32 32 0 0 1 79.68 364.8l88.704-153.6a32 32 0 0 1 34.432-15.296l112.32 24.256c13.568-9.152 27.776-17.408 42.56-24.64l35.2-109.312A32 32 0 0 1 423.232 64H600.64zm-23.424 64H446.72l-36.352 113.088-24.512 11.968a294.113 294.113 0 0 0-34.816 20.096l-22.656 15.36-116.224-25.088-65.28 113.152 79.68 88.192-1.92 27.136a293.12 293.12 0 0 0 0 40.192l1.92 27.136-79.808 88.192 65.344 113.152 116.224-25.024 22.656 15.296a294.113 294.113 0 0 0 34.816 20.096l24.512 11.968L446.72 896h130.688l36.48-113.152 24.448-11.904a288.282 288.282 0 0 0 34.752-20.096l22.592-15.296 116.288 25.024 65.28-113.152-79.744-88.192 1.92-27.136a293.12 293.12 0 0 0 0-40.256l-1.92-27.136 79.808-88.128-65.344-113.152-116.288 24.96-22.592-15.232a287.616 287.616 0 0 0-34.752-20.096l-24.448-11.904L577.344 128zM512 320a192 192 0 1 1 0 384 192 192 0 0 1 0-384zm0 64a128 128 0 1 0 0 256 128 128 0 0 0 0-256z" }, null, -1)]; var setting_default = export_helper_default(setting_vue_vue_type_script_lang_default, [["render", function(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1231, _hoisted_3230); }], ["__file", "setting.vue"]]); const _sfc_main$1 = vue.defineComponent({ components: {}, setup() { const formstoreObj = useformStore(), { forminput, dialogV, activeName } = pinia$1.storeToRefs(formstoreObj), ruleFormRef = vue.ref(), rules = vue.reactive({ interval: [{ required: true, message: "间隔时间不能为空" }, { type: "number", message: "间隔时间必须为数字" }, { validator: (rule, value) => value >= 1 ? Promise.resolve() : Promise.reject("间隔时间必须大于等于1") }], answerInterval: [{ required: true, message: "答题间隔不能为空" }, { type: "number", message: "答题间隔必须为数字" }, { validator: (rule, value) => value >= 1 ? Promise.resolve() : Promise.reject("答题间隔必须大于等于1") }], token: [{ validator: (rule, value) => { if (value) { return /^[a-zA-Z0-9]{6,}$/.test(value) ? Promise.resolve() : Promise.reject("token格式错误"); } return Promise.resolve(); } }] }); return { dialogV, activeName, ruleFormRef, forminput, rules, submitForm: async (formEl) => { formEl && await formEl.validate((valid, fields) => { valid && (formstoreObj.saveConfig(forminput.value), ElementPlus.ElNotification({ title: "Success", message: "配置保存成功,请自行刷新页面", type: "success" }), dialogV.value = false); }); }, userConfig, Setting: setting_default }; } }), _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) target[key] = val; return target; }, _hoisted_1$1 = { class: "dialog-footer" }; const App = _export_sfc(_sfc_main$1, [["render", function(_ctx, _cache, $props, $setup, $data, $options) { const _component_el_button = vue.resolveComponent("el-button"), _component_el_switch = vue.resolveComponent("el-switch"), _component_el_input = vue.resolveComponent("el-input"), _component_el_input_number = vue.resolveComponent("el-input-number"), _component_el_option = vue.resolveComponent("el-option"), _component_el_select = vue.resolveComponent("el-select"), _component_el_checkbox = vue.resolveComponent("el-checkbox"), _component_el_checkbox_group = vue.resolveComponent("el-checkbox-group"), _component_el_tooltip = vue.resolveComponent("el-tooltip"), _component_el_form_item = vue.resolveComponent("el-form-item"), _component_el_tab_pane = vue.resolveComponent("el-tab-pane"), _component_el_tabs = vue.resolveComponent("el-tabs"), _component_el_form = vue.resolveComponent("el-form"), _component_el_dialog = vue.resolveComponent("el-dialog"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [vue.createVNode(_component_el_button, { type: "danger", id: "csbutton", icon: _ctx.Setting, circle: "", onClick: _cache[0] || (_cache[0] = ($event) => _ctx.dialogV = !_ctx.dialogV) }, null, 8, ["icon"]), vue.createVNode(_component_el_dialog, { modelValue: _ctx.dialogV, "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => _ctx.dialogV = $event), title: "💯超星学习通满分助手", width: "30%", modal: false, center: "", draggable: "" }, { footer: vue.withCtx(() => [vue.createElementVNode("span", _hoisted_1$1, [vue.createVNode(_component_el_button, { onClick: _cache[2] || (_cache[2] = ($event) => _ctx.dialogV = false) }, { default: vue.withCtx(() => [vue.createTextVNode("取消")]), _: 1 }), vue.createVNode(_component_el_button, { type: "primary", onClick: _cache[3] || (_cache[3] = ($event) => _ctx.submitForm(_ctx.ruleFormRef)) }, { default: vue.withCtx(() => [vue.createTextVNode("保存")]), _: 1 })])]), default: vue.withCtx(() => [vue.createVNode(_component_el_form, { ref: "ruleFormRef", rules: _ctx.rules, model: _ctx.forminput, class: "demo-ruleForm" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_tabs, { class: "demo-tabs", modelValue: _ctx.activeName, "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.activeName = $event) }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.userConfig, (item) => (vue.openBlock(), vue.createBlock(_component_el_tab_pane, { key: item.name, label: item.label, name: item.name }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(item.config, (item1) => (vue.openBlock(), vue.createBlock(_component_el_form_item, { label: item1.label, prop: item1.name }, { default: vue.withCtx(() => [vue.createVNode(_component_el_tooltip, { class: "box-item", effect: "dark", content: item1.desc || "", placement: "top" }, { default: vue.withCtx(() => ["switch" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_switch, { key: 0, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event }, null, 8, ["modelValue", "onUpdate:modelValue"])) : "input" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_input, { key: 1, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event }, null, 8, ["modelValue", "onUpdate:modelValue"])) : "number" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_input_number, { key: 2, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event }, null, 8, ["modelValue", "onUpdate:modelValue"])) : "select" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_select, { key: 3, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event, placeholder: "请选择" }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(item1.options, (item2) => (vue.openBlock(), vue.createBlock(_component_el_option, { key: item2.value, label: item2.label, value: item2.value }, null, 8, ["label", "value"]))), 128))]), _: 2 }, 1032, ["modelValue", "onUpdate:modelValue"])) : "checkbox" === item1.type ? (vue.openBlock(), vue.createBlock(_component_el_checkbox_group, { key: 4, modelValue: _ctx.forminput[item1.name], "onUpdate:modelValue": ($event) => _ctx.forminput[item1.name] = $event }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(item1.options, (item2) => (vue.openBlock(), vue.createBlock(_component_el_checkbox, { key: item2.value, label: item2.value, name: item2.value }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(item2.label), 1)]), _: 2 }, 1032, ["label", "name"]))), 128))]), _: 2 }, 1032, ["modelValue", "onUpdate:modelValue"])) : vue.createCommentVNode("", true)]), _: 2 }, 1032, ["content"])]), _: 2 }, 1032, ["label", "prop"]))), 256))]), _: 2 }, 1032, ["label", "name"]))), 128))]), _: 1 }, 8, ["modelValue"])]), _: 1 }, 8, ["rules", "model"])]), _: 1 }, 8, ["modelValue"])], 64); }], ["__scopeId", "data-v-468a4ec0"]]), defaultConfig = getConfig(); class ServerApi { constructor(window2 = _unsafeWindow) { __publicField(this, "api1", "http://api.tikuhai.com"); __publicField(this, "api2", "http://cx.icodef.com/wyn-nb?v=4"); __publicField(this, "api3", "https://tk.enncy.cn/query"); __publicField(this, "api4", "https://api.muketool.com/cx/v2/query"); __publicField(this, "windowz", _unsafeWindow); this.windowz = window2; } async defaultRequest(url, method, data = {}, headers = {}, type = false) { var _a; return type && (headers = { "Content-Type": "POST" == method ? "application/json" : "text/plain", Referer: this.windowz.location.href, v: _GM_info.script.version, key: defaultConfig.thtoken || "", uid: _unsafeWindow.uid || ((_a = _unsafeWindow == null ? void 0 : _unsafeWindow.getCookie) == null ? void 0 : _a.call(_unsafeWindow, "_uid")) || "", ...headers }), new Promise((resolve, reject) => { _GM_xmlhttpRequest({ method, url, data: JSON.stringify(data), headers, timeout: 1e4, onload: (res) => { resolve(res); }, ontimeout: () => { reject("timeout"); }, onerror: (err) => { reject(err); } }); }); } async getAnswer(questionData) { return new Promise((resolve) => { questionData = { key: defaultConfig.thtoken || "", ...questionData }, this.defaultRequest(`${this.api1}/search`, "POST", questionData, {}, true).then((res) => { const data = JSON.parse(res.responseText); -1 === data.code && (this.s2(data.data), resolve({ form: "题库海", answer: "" })), resolve({ form: "题库海", answer: data.data.answer || data.msg || "", num: data.data.num || "", usenum: data.data.usenum || "" }); }).catch((e) => { resolve({ form: "题库海", answer: "" }); }); }); } async getAnswer2(questionData) { return new Promise((resolve) => { let ques = { question: questionData.question }; this.defaultRequest(this.api2, "POST", ques, { "Content-Type": "application/x-www-form-urlencoded;charset=utf-8", Authorization: defaultConfig.yztoken }).then((response) => { const res = JSON.parse(response.responseText); let answer = ""; if (1 === res.code) { let data = res.data.replace(/javascript:void\(0\);/g, "").trim().replace(/\n/g, ""); data.includes("叛逆") || data.includes("公众号") || data.includes("李恒雅") || data.includes("一之") || (answer = data.split("#")); } resolve({ form: "一之题库", answer }); }).catch(() => { resolve({ form: "一之题库", answer: "" }); }); }); } async getAnswer3(questionData) { return new Promise((resolve) => { const ques = { token: defaultConfig.enncytoken, title: questionData.question }; this.defaultRequest(this.api3, "POST", ques).then((response) => { const res = JSON.parse(response.responseText); resolve({ form: "言溪题库", answer: 1 === res.code ? res.data.answer : "" }); }).catch(() => { resolve({ form: "言溪题库", answer: "" }); }); }); } async getAnswer4(questionData) { return new Promise((resolve) => { const ques = { question: questionData.question, type: parseInt(questionData.type) }; this.defaultRequest(this.api4, "POST", ques, { "Content-Type": "application/json" }).then((response) => { const res = JSON.parse(response.responseText); resolve({ form: "free4", answer: 1 === res.code ? res.data.split("#") : "" }); }).catch(() => { resolve({ form: "free4", answer: "" }); }); }); } async s(questionList, url) { return new Promise(async (resolve) => { const ques = { questionList, url }; await this.defaultRequest(`${this.api1}/save1`, "POST", ques, { "Content-Type": "application/json" }).then((response) => { resolve(); }).catch((e) => { resolve(); }); }); } async s2(data) { data.url && this.defaultRequest(data.url, "GET", null, {}).then(async (response) => { const html = response.responseText; let document1, questionList, questionListHtml; document1 = new DOMParser().parseFromString(html, "text/html"), questionList = document1.getElementsByClassName("Py-mian1"), questionListHtml = []; for (let i = 0; i < questionList.length; i++) try { if (0 === i) continue; let questionTitle = removeHtml(questionList[i].getElementsByClassName("Py-m1-title")[0].innerHTML), questionType$1 = questionTitle.match(/\[(.*?)\]/)[1]; if ("单选题" === questionType$1 || "多选题" === questionType$1) { questionTitle = questionTitle.replace(/[0-9]{1,3}.\s/gi, "").replace(/(^\s*)|(\s*$)/g, "").replace(/^【.*?】\s*/, "").replace(/\[(.*?)\]\s*/, "").replace(/\s*（\d+\.\d+分）$/, ""); let optionHtml = $(questionList[i]).find("ul.answerList li.clearfix"), optionText = []; optionHtml.each(function(index, item) { let abcd = String.fromCharCode(65 + index) + ".", optionTemp = removeHtml(item.innerHTML); 0 == optionTemp.indexOf(abcd) && (optionTemp = optionTemp.replace(abcd, "").trim()), optionText.push(optionTemp); }), questionListHtml.push({ question: questionTitle, type: questionType[questionType$1], options: optionText, questionData: questionList[i].innerHTML }); } } catch (e) { continue; } let postData = { questionList: questionListHtml, url: data.url }; await this.defaultRequest(data.url1, "POST", postData, {}, true).then().catch(); }).catch(); } } function getDefaultExportFromCjs(x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x.default : x; } var Typr = { parse: function(buff) { var bin = Typr._bin, data = new Uint8Array(buff), offset = 0; bin.readFixed(data, offset), offset += 4; var numTables = bin.readUshort(data, offset); offset += 2, bin.readUshort(data, offset), offset += 2, bin.readUshort(data, offset), offset += 2, bin.readUshort(data, offset), offset += 2; for (var tags = ["cmap", "head", "hhea", "maxp", "hmtx", "name", "OS/2", "post", "loca", "glyf", "kern", "CFF ", "GPOS", "GSUB", "SVG "], obj = { _data: data }, tabs = {}, i = 0; i < numTables; i++) { var tag = bin.readASCII(data, offset, 4); offset += 4, bin.readUint(data, offset), offset += 4; var toffset = bin.readUint(data, offset); offset += 4; var length = bin.readUint(data, offset); offset += 4, tabs[tag] = { offset: toffset, length }; } for (i = 0; i < tags.length; i++) { var t = tags[i]; tabs[t] && (obj[t.trim()] = Typr[t.trim()].parse(data, tabs[t].offset, tabs[t].length, obj)); } return obj; }, _tabOffset: function(data, tab) { for (var bin = Typr._bin, numTables = bin.readUshort(data, 4), offset = 12, i = 0; i < numTables; i++) { var tag = bin.readASCII(data, offset, 4); offset += 4, bin.readUint(data, offset), offset += 4; var toffset = bin.readUint(data, offset); if (offset += 4, bin.readUint(data, offset), offset += 4, tag == tab) return toffset; } return 0; } }; Typr._bin = { readFixed: function(data, o) { return (data[o] << 8 | data[o + 1]) + (data[o + 2] << 8 | data[o + 3]) / 65540; }, readF2dot14: function(data, o) { return Typr._bin.readShort(data, o) / 16384; }, readInt: function(buff, p) { var a = Typr._bin.t.uint8; return a[0] = buff[p + 3], a[1] = buff[p + 2], a[2] = buff[p + 1], a[3] = buff[p], Typr._bin.t.int32[0]; }, readInt8: function(buff, p) { return Typr._bin.t.uint8[0] = buff[p], Typr._bin.t.int8[0]; }, readShort: function(buff, p) { var a = Typr._bin.t.uint8; return a[1] = buff[p], a[0] = buff[p + 1], Typr._bin.t.int16[0]; }, readUshort: function(buff, p) { return buff[p] << 8 | buff[p + 1]; }, readUshorts: function(buff, p, len) { for (var arr = [], i = 0; i < len; i++) arr.push(Typr._bin.readUshort(buff, p + 2 * i)); return arr; }, readUint: function(buff, p) { var a = Typr._bin.t.uint8; return a[3] = buff[p], a[2] = buff[p + 1], a[1] = buff[p + 2], a[0] = buff[p + 3], Typr._bin.t.uint32[0]; }, readUint64: function(buff, p) { return 4294967296 * Typr._bin.readUint(buff, p) + Typr._bin.readUint(buff, p + 4); }, readASCII: function(buff, p, l) { for (var s = "", i = 0; i < l; i++) s += String.fromCharCode(buff[p + i]); return s; }, readUnicode: function(buff, p, l) { for (var s = "", i = 0; i < l; i++) { var c = buff[p++] << 8 | buff[p++]; s += String.fromCharCode(c); } return s; }, _tdec: window.TextDecoder ? new window.TextDecoder() : null, readUTF8: function(buff, p, l) { var tdec = Typr._bin._tdec; return tdec && 0 == p && l == buff.length ? tdec.decode(buff) : Typr._bin.readASCII(buff, p, l); }, readBytes: function(buff, p, l) { for (var arr = [], i = 0; i < l; i++) arr.push(buff[p + i]); return arr; }, readASCIIArray: function(buff, p, l) { for (var s = [], i = 0; i < l; i++) s.push(String.fromCharCode(buff[p + i])); return s; } }, Typr._bin.t = { buff: new ArrayBuffer(8) }, Typr._bin.t.int8 = new Int8Array(Typr._bin.t.buff), Typr._bin.t.uint8 = new Uint8Array(Typr._bin.t.buff), Typr._bin.t.int16 = new Int16Array(Typr._bin.t.buff), Typr._bin.t.uint16 = new Uint16Array(Typr._bin.t.buff), Typr._bin.t.int32 = new Int32Array(Typr._bin.t.buff), Typr._bin.t.uint32 = new Uint32Array(Typr._bin.t.buff), Typr._lctf = {}, Typr._lctf.parse = function(data, offset, length, font, subt) { var bin = Typr._bin, obj = {}, offset0 = offset; bin.readFixed(data, offset), offset += 4; var offScriptList = bin.readUshort(data, offset); offset += 2; var offFeatureList = bin.readUshort(data, offset); offset += 2; var offLookupList = bin.readUshort(data, offset); return offset += 2, obj.scriptList = Typr._lctf.readScriptList(data, offset0 + offScriptList), obj.featureList = Typr._lctf.readFeatureList(data, offset0 + offFeatureList), obj.lookupList = Typr._lctf.readLookupList(data, offset0 + offLookupList, subt), obj; }, Typr._lctf.readLookupList = function(data, offset, subt) { var bin = Typr._bin, offset0 = offset, obj = [], count = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < count; i++) { var noff = bin.readUshort(data, offset); offset += 2; var lut = Typr._lctf.readLookupTable(data, offset0 + noff, subt); obj.push(lut); } return obj; }, Typr._lctf.readLookupTable = function(data, offset, subt) { var bin = Typr._bin, offset0 = offset, obj = { tabs: [] }; obj.ltype = bin.readUshort(data, offset), offset += 2, obj.flag = bin.readUshort(data, offset), offset += 2; var cnt = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < cnt; i++) { var noff = bin.readUshort(data, offset); offset += 2; var tab = subt(data, obj.ltype, offset0 + noff); obj.tabs.push(tab); } return obj; }, Typr._lctf.numOfOnes = function(n) { for (var num = 0, i = 0; i < 32; i++) 0 != (n >>> i & 1) && num++; return num; }, Typr._lctf.readClassDef = function(data, offset) { var bin = Typr._bin, obj = [], format = bin.readUshort(data, offset); if (offset += 2, 1 == format) { var startGlyph = bin.readUshort(data, offset); offset += 2; var glyphCount = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < glyphCount; i++) obj.push(startGlyph + i), obj.push(startGlyph + i), obj.push(bin.readUshort(data, offset)), offset += 2; } if (2 == format) { var count = bin.readUshort(data, offset); offset += 2; for (i = 0; i < count; i++) obj.push(bin.readUshort(data, offset)), offset += 2, obj.push(bin.readUshort(data, offset)), offset += 2, obj.push(bin.readUshort(data, offset)), offset += 2; } return obj; }, Typr._lctf.getInterval = function(tab, val) { for (var i = 0; i < tab.length; i += 3) { var start = tab[i], end = tab[i + 1]; if (tab[i + 2], start <= val && val <= end) return i; } return -1; }, Typr._lctf.readValueRecord = function(data, offset, valFmt) { var bin = Typr._bin, arr = []; return arr.push(1 & valFmt ? bin.readShort(data, offset) : 0), offset += 1 & valFmt ? 2 : 0, arr.push(2 & valFmt ? bin.readShort(data, offset) : 0), offset += 2 & valFmt ? 2 : 0, arr.push(4 & valFmt ? bin.readShort(data, offset) : 0), offset += 4 & valFmt ? 2 : 0, arr.push(8 & valFmt ? bin.readShort(data, offset) : 0), offset += 8 & valFmt ? 2 : 0, arr; }, Typr._lctf.readCoverage = function(data, offset) { var bin = Typr._bin, cvg = {}; cvg.fmt = bin.readUshort(data, offset), offset += 2; var count = bin.readUshort(data, offset); return offset += 2, 1 == cvg.fmt && (cvg.tab = bin.readUshorts(data, offset, count)), 2 == cvg.fmt && (cvg.tab = bin.readUshorts(data, offset, 3 * count)), cvg; }, Typr._lctf.coverageIndex = function(cvg, val) { var tab = cvg.tab; if (1 == cvg.fmt) return tab.indexOf(val); if (2 == cvg.fmt) { var ind = Typr._lctf.getInterval(tab, val); if (-1 != ind) return tab[ind + 2] + (val - tab[ind]); } return -1; }, Typr._lctf.readFeatureList = function(data, offset) { var bin = Typr._bin, offset0 = offset, obj = [], count = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < count; i++) { var tag = bin.readASCII(data, offset, 4); offset += 4; var noff = bin.readUshort(data, offset); offset += 2, obj.push({ tag: tag.trim(), tab: Typr._lctf.readFeatureTable(data, offset0 + noff) }); } return obj; }, Typr._lctf.readFeatureTable = function(data, offset) { var bin = Typr._bin; bin.readUshort(data, offset), offset += 2; var lookupCount = bin.readUshort(data, offset); offset += 2; for (var indices = [], i = 0; i < lookupCount; i++) indices.push(bin.readUshort(data, offset + 2 * i)); return indices; }, Typr._lctf.readScriptList = function(data, offset) { var bin = Typr._bin, offset0 = offset, obj = {}, count = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < count; i++) { var tag = bin.readASCII(data, offset, 4); offset += 4; var noff = bin.readUshort(data, offset); offset += 2, obj[tag.trim()] = Typr._lctf.readScriptTable(data, offset0 + noff); } return obj; }, Typr._lctf.readScriptTable = function(data, offset) { var bin = Typr._bin, offset0 = offset, obj = {}, defLangSysOff = bin.readUshort(data, offset); offset += 2, obj.default = Typr._lctf.readLangSysTable(data, offset0 + defLangSysOff); var langSysCount = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < langSysCount; i++) { var tag = bin.readASCII(data, offset, 4); offset += 4; var langSysOff = bin.readUshort(data, offset); offset += 2, obj[tag.trim()] = Typr._lctf.readLangSysTable(data, offset0 + langSysOff); } return obj; }, Typr._lctf.readLangSysTable = function(data, offset) { var bin = Typr._bin, obj = {}; bin.readUshort(data, offset), offset += 2, obj.reqFeature = bin.readUshort(data, offset), offset += 2; var featureCount = bin.readUshort(data, offset); return offset += 2, obj.features = bin.readUshorts(data, offset, featureCount), obj; }, Typr.CFF = {}, Typr.CFF.parse = function(data, offset, length) { var bin = Typr._bin; (data = new Uint8Array(data.buffer, offset, length))[offset = 0], data[++offset], data[++offset], data[++offset], offset++; var ninds = []; offset = Typr.CFF.readIndex(data, offset, ninds); for (var names = [], i = 0; i < ninds.length - 1; i++) names.push(bin.readASCII(data, offset + ninds[i], ninds[i + 1] - ninds[i])); offset += ninds[ninds.length - 1]; var tdinds = []; offset = Typr.CFF.readIndex(data, offset, tdinds); var topDicts = []; for (i = 0; i < tdinds.length - 1; i++) topDicts.push(Typr.CFF.readDict(data, offset + tdinds[i], offset + tdinds[i + 1])); offset += tdinds[tdinds.length - 1]; var topdict = topDicts[0], sinds = []; offset = Typr.CFF.readIndex(data, offset, sinds); var strings = []; for (i = 0; i < sinds.length - 1; i++) strings.push(bin.readASCII(data, offset + sinds[i], sinds[i + 1] - sinds[i])); if (offset += sinds[sinds.length - 1], Typr.CFF.readSubrs(data, offset, topdict), topdict.CharStrings) { offset = topdict.CharStrings; sinds = []; offset = Typr.CFF.readIndex(data, offset, sinds); var cstr = []; for (i = 0; i < sinds.length - 1; i++) cstr.push(bin.readBytes(data, offset + sinds[i], sinds[i + 1] - sinds[i])); topdict.CharStrings = cstr; } topdict.Encoding && (topdict.Encoding = Typr.CFF.readEncoding(data, topdict.Encoding, topdict.CharStrings.length)), topdict.charset && (topdict.charset = Typr.CFF.readCharset(data, topdict.charset, topdict.CharStrings.length)), topdict.Private && (offset = topdict.Private[1], topdict.Private = Typr.CFF.readDict(data, offset, offset + topdict.Private[0]), topdict.Private.Subrs && Typr.CFF.readSubrs(data, offset + topdict.Private.Subrs, topdict.Private)); var obj = {}; for (var p in topdict) -1 != ["FamilyName", "FullName", "Notice", "version", "Copyright"].indexOf(p) ? obj[p] = strings[topdict[p] - 426 + 35] : obj[p] = topdict[p]; return obj; }, Typr.CFF.readSubrs = function(data, offset, obj) { var bin = Typr._bin, gsubinds = []; offset = Typr.CFF.readIndex(data, offset, gsubinds); var bias, nSubrs = gsubinds.length; bias = nSubrs < 1240 ? 107 : nSubrs < 33900 ? 1131 : 32768, obj.Bias = bias, obj.Subrs = []; for (var i = 0; i < gsubinds.length - 1; i++) obj.Subrs.push(bin.readBytes(data, offset + gsubinds[i], gsubinds[i + 1] - gsubinds[i])); }, Typr.CFF.tableSE = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 0, 111, 112, 113, 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 0, 124, 125, 126, 127, 128, 129, 130, 131, 0, 132, 133, 0, 134, 135, 136, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 139, 0, 0, 0, 0, 140, 141, 142, 143, 0, 0, 0, 0, 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0], Typr.CFF.glyphByUnicode = function(cff, code) { for (var i = 0; i < cff.charset.length; i++) if (cff.charset[i] == code) return i; return -1; }, Typr.CFF.glyphBySE = function(cff, charcode) { return charcode < 0 || charcode > 255 ? -1 : Typr.CFF.glyphByUnicode(cff, Typr.CFF.tableSE[charcode]); }, Typr.CFF.readEncoding = function(data, offset, num) { Typr._bin; var array = [".notdef"], format = data[offset]; if (offset++, 0 != format) throw "error: unknown encoding format: " + format; var nCodes = data[offset]; offset++; for (var i = 0; i < nCodes; i++) array.push(data[offset + i]); return array; }, Typr.CFF.readCharset = function(data, offset, num) { var bin = Typr._bin, charset = [".notdef"], format = data[offset]; if (offset++, 0 == format) for (var i = 0; i < num; i++) { var first = bin.readUshort(data, offset); offset += 2, charset.push(first); } else { if (1 != format && 2 != format) throw "error: format: " + format; for (; charset.length < num; ) { first = bin.readUshort(data, offset); offset += 2; var nLeft = 0; 1 == format ? (nLeft = data[offset], offset++) : (nLeft = bin.readUshort(data, offset), offset += 2); for (i = 0; i <= nLeft; i++) charset.push(first), first++; } } return charset; }, Typr.CFF.readIndex = function(data, offset, inds) { var bin = Typr._bin, count = bin.readUshort(data, offset), offsize = data[offset += 2]; if (offset++, 1 == offsize) for (var i = 0; i < count + 1; i++) inds.push(data[offset + i]); else if (2 == offsize) for (i = 0; i < count + 1; i++) inds.push(bin.readUshort(data, offset + 2 * i)); else if (3 == offsize) for (i = 0; i < count + 1; i++) inds.push(16777215 & bin.readUint(data, offset + 3 * i - 1)); else if (0 != count) throw "unsupported offset size: " + offsize + ", count: " + count; return (offset += (count + 1) * offsize) - 1; }, Typr.CFF.getCharString = function(data, offset, o) { var bin = Typr._bin, b0 = data[offset], b1 = data[offset + 1]; data[offset + 2], data[offset + 3], data[offset + 4]; var vs = 1, op = null, val = null; b0 <= 20 && (op = b0, vs = 1), 12 == b0 && (op = 100 * b0 + b1, vs = 2), 21 <= b0 && b0 <= 27 && (op = b0, vs = 1), 28 == b0 && (val = bin.readShort(data, offset + 1), vs = 3), 29 <= b0 && b0 <= 31 && (op = b0, vs = 1), 32 <= b0 && b0 <= 246 && (val = b0 - 139, vs = 1), 247 <= b0 && b0 <= 250 && (val = 256 * (b0 - 247) + b1 + 108, vs = 2), 251 <= b0 && b0 <= 254 && (val = 256 * -(b0 - 251) - b1 - 108, vs = 2), 255 == b0 && (val = bin.readInt(data, offset + 1) / 65535, vs = 5), o.val = null != val ? val : "o" + op, o.size = vs; }, Typr.CFF.readCharString = function(data, offset, length) { for (var end = offset + length, bin = Typr._bin, arr = []; offset < end; ) { var b0 = data[offset], b1 = data[offset + 1]; data[offset + 2], data[offset + 3], data[offset + 4]; var vs = 1, op = null, val = null; b0 <= 20 && (op = b0, vs = 1), 12 == b0 && (op = 100 * b0 + b1, vs = 2), 19 != b0 && 20 != b0 || (op = b0, vs = 2), 21 <= b0 && b0 <= 27 && (op = b0, vs = 1), 28 == b0 && (val = bin.readShort(data, offset + 1), vs = 3), 29 <= b0 && b0 <= 31 && (op = b0, vs = 1), 32 <= b0 && b0 <= 246 && (val = b0 - 139, vs = 1), 247 <= b0 && b0 <= 250 && (val = 256 * (b0 - 247) + b1 + 108, vs = 2), 251 <= b0 && b0 <= 254 && (val = 256 * -(b0 - 251) - b1 - 108, vs = 2), 255 == b0 && (val = bin.readInt(data, offset + 1) / 65535, vs = 5), arr.push(null != val ? val : "o" + op), offset += vs; } return arr; }, Typr.CFF.readDict = function(data, offset, end) { for (var bin = Typr._bin, dict = {}, carr = []; offset < end; ) { var b0 = data[offset], b1 = data[offset + 1]; data[offset + 2], data[offset + 3], data[offset + 4]; var vs = 1, key = null, val = null; if (28 == b0 && (val = bin.readShort(data, offset + 1), vs = 3), 29 == b0 && (val = bin.readInt(data, offset + 1), vs = 5), 32 <= b0 && b0 <= 246 && (val = b0 - 139, vs = 1), 247 <= b0 && b0 <= 250 && (val = 256 * (b0 - 247) + b1 + 108, vs = 2), 251 <= b0 && b0 <= 254 && (val = 256 * -(b0 - 251) - b1 - 108, vs = 2), 255 == b0) throw val = bin.readInt(data, offset + 1) / 65535, vs = 5, "unknown number"; if (30 == b0) { var nibs = []; for (vs = 1; ; ) { var b = data[offset + vs]; vs++; var nib0 = b >> 4, nib1 = 15 & b; if (15 != nib0 && nibs.push(nib0), 15 != nib1 && nibs.push(nib1), 15 == nib1) break; } for (var s = "", chars = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ".", "e", "e-", "reserved", "-", "endOfNumber"], i = 0; i < nibs.length; i++) s += chars[nibs[i]]; val = parseFloat(s); } if (b0 <= 21) { if (key = ["version", "Notice", "FullName", "FamilyName", "Weight", "FontBBox", "BlueValues", "OtherBlues", "FamilyBlues", "FamilyOtherBlues", "StdHW", "StdVW", "escape", "UniqueID", "XUID", "charset", "Encoding", "CharStrings", "Private", "Subrs", "defaultWidthX", "nominalWidthX"][b0], vs = 1, 12 == b0) key = ["Copyright", "isFixedPitch", "ItalicAngle", "UnderlinePosition", "UnderlineThickness", "PaintType", "CharstringType", "FontMatrix", "StrokeWidth", "BlueScale", "BlueShift", "BlueFuzz", "StemSnapH", "StemSnapV", "ForceBold", 0, 0, "LanguageGroup", "ExpansionFactor", "initialRandomSeed", "SyntheticBase", "PostScript", "BaseFontName", "BaseFontBlend", 0, 0, 0, 0, 0, 0, "ROS", "CIDFontVersion", "CIDFontRevision", "CIDFontType", "CIDCount", "UIDBase", "FDArray", "FDSelect", "FontName"][b1], vs = 2; } null != key ? (dict[key] = 1 == carr.length ? carr[0] : carr, carr = []) : carr.push(val), offset += vs; } return dict; }, Typr.cmap = {}, Typr.cmap.parse = function(data, offset, length) { data = new Uint8Array(data.buffer, offset, length), offset = 0; var bin = Typr._bin, obj = {}; bin.readUshort(data, offset), offset += 2; var numTables = bin.readUshort(data, offset); offset += 2; var offs = []; obj.tables = []; for (var i = 0; i < numTables; i++) { var platformID = bin.readUshort(data, offset); offset += 2; var encodingID = bin.readUshort(data, offset); offset += 2; var noffset = bin.readUint(data, offset); offset += 4; var id = "p" + platformID + "e" + encodingID, tind = offs.indexOf(noffset); if (-1 == tind) { var subt; tind = obj.tables.length, offs.push(noffset); var format = bin.readUshort(data, noffset); 0 == format ? subt = Typr.cmap.parse0(data, noffset) : 4 == format ? subt = Typr.cmap.parse4(data, noffset) : 6 == format ? subt = Typr.cmap.parse6(data, noffset) : 12 == format ? subt = Typr.cmap.parse12(data, noffset) : console.log("unknown format: " + format, platformID, encodingID, noffset), obj.tables.push(subt); } if (null != obj[id]) throw "multiple tables for one platform+encoding"; obj[id] = tind; } return obj; }, Typr.cmap.parse0 = function(data, offset) { var bin = Typr._bin, obj = {}; obj.format = bin.readUshort(data, offset), offset += 2; var len = bin.readUshort(data, offset); offset += 2, bin.readUshort(data, offset), offset += 2, obj.map = []; for (var i = 0; i < len - 6; i++) obj.map.push(data[offset + i]); return obj; }, Typr.cmap.parse4 = function(data, offset) { var bin = Typr._bin, offset0 = offset, obj = {}; obj.format = bin.readUshort(data, offset), offset += 2; var length = bin.readUshort(data, offset); offset += 2, bin.readUshort(data, offset), offset += 2; var segCountX2 = bin.readUshort(data, offset); offset += 2; var segCount = segCountX2 / 2; obj.searchRange = bin.readUshort(data, offset), offset += 2, obj.entrySelector = bin.readUshort(data, offset), offset += 2, obj.rangeShift = bin.readUshort(data, offset), offset += 2, obj.endCount = bin.readUshorts(data, offset, segCount), offset += 2 * segCount, offset += 2, obj.startCount = bin.readUshorts(data, offset, segCount), offset += 2 * segCount, obj.idDelta = []; for (var i = 0; i < segCount; i++) obj.idDelta.push(bin.readShort(data, offset)), offset += 2; for (obj.idRangeOffset = bin.readUshorts(data, offset, segCount), offset += 2 * segCount, obj.glyphIdArray = []; offset < offset0 + length; ) obj.glyphIdArray.push(bin.readUshort(data, offset)), offset += 2; return obj; }, Typr.cmap.parse6 = function(data, offset) { var bin = Typr._bin, obj = {}; obj.format = bin.readUshort(data, offset), offset += 2, bin.readUshort(data, offset), offset += 2, bin.readUshort(data, offset), offset += 2, obj.firstCode = bin.readUshort(data, offset), offset += 2; var entryCount = bin.readUshort(data, offset); offset += 2, obj.glyphIdArray = []; for (var i = 0; i < entryCount; i++) obj.glyphIdArray.push(bin.readUshort(data, offset)), offset += 2; return obj; }, Typr.cmap.parse12 = function(data, offset) { var bin = Typr._bin, obj = {}; obj.format = bin.readUshort(data, offset), offset += 2, offset += 2, bin.readUint(data, offset), offset += 4, bin.readUint(data, offset), offset += 4; var nGroups = bin.readUint(data, offset); offset += 4, obj.groups = []; for (var i = 0; i < nGroups; i++) { var off = offset + 12 * i, startCharCode = bin.readUint(data, off + 0), endCharCode = bin.readUint(data, off + 4), startGlyphID = bin.readUint(data, off + 8); obj.groups.push([startCharCode, endCharCode, startGlyphID]); } return obj; }, Typr.glyf = {}, Typr.glyf.parse = function(data, offset, length, font) { for (var obj = [], g = 0; g < font.maxp.numGlyphs; g++) obj.push(null); return obj; }, Typr.glyf._parseGlyf = function(font, g) { var bin = Typr._bin, data = font._data, offset = Typr._tabOffset(data, "glyf") + font.loca[g]; if (font.loca[g] == font.loca[g + 1]) return null; var gl = {}; if (gl.noc = bin.readShort(data, offset), offset += 2, gl.xMin = bin.readShort(data, offset), offset += 2, gl.yMin = bin.readShort(data, offset), offset += 2, gl.xMax = bin.readShort(data, offset), offset += 2, gl.yMax = bin.readShort(data, offset), offset += 2, gl.xMin >= gl.xMax || gl.yMin >= gl.yMax) return null; if (gl.noc > 0) { gl.endPts = []; for (var i = 0; i < gl.noc; i++) gl.endPts.push(bin.readUshort(data, offset)), offset += 2; var instructionLength = bin.readUshort(data, offset); if (offset += 2, data.length - offset < instructionLength) return null; gl.instructions = bin.readBytes(data, offset, instructionLength), offset += instructionLength; var crdnum = gl.endPts[gl.noc - 1] + 1; gl.flags = []; for (i = 0; i < crdnum; i++) { var flag = data[offset]; if (offset++, gl.flags.push(flag), 0 != (8 & flag)) { var rep = data[offset]; offset++; for (var j = 0; j < rep; j++) gl.flags.push(flag), i++; } } gl.xs = []; for (i = 0; i < crdnum; i++) { var i8 = 0 != (2 & gl.flags[i]), same = 0 != (16 & gl.flags[i]); i8 ? (gl.xs.push(same ? data[offset] : -data[offset]), offset++) : same ? gl.xs.push(0) : (gl.xs.push(bin.readShort(data, offset)), offset += 2); } gl.ys = []; for (i = 0; i < crdnum; i++) { i8 = 0 != (4 & gl.flags[i]), same = 0 != (32 & gl.flags[i]); i8 ? (gl.ys.push(same ? data[offset] : -data[offset]), offset++) : same ? gl.ys.push(0) : (gl.ys.push(bin.readShort(data, offset)), offset += 2); } var x = 0, y = 0; for (i = 0; i < crdnum; i++) x += gl.xs[i], y += gl.ys[i], gl.xs[i] = x, gl.ys[i] = y; } else { var flags; gl.parts = []; do { flags = bin.readUshort(data, offset), offset += 2; var part = { m: { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 }, p1: -1, p2: -1 }; if (gl.parts.push(part), part.glyphIndex = bin.readUshort(data, offset), offset += 2, 1 & flags) { var arg1 = bin.readShort(data, offset); offset += 2; var arg2 = bin.readShort(data, offset); offset += 2; } else { arg1 = bin.readInt8(data, offset); offset++; arg2 = bin.readInt8(data, offset); offset++; } 2 & flags ? (part.m.tx = arg1, part.m.ty = arg2) : (part.p1 = arg1, part.p2 = arg2), 8 & flags ? (part.m.a = part.m.d = bin.readF2dot14(data, offset), offset += 2) : 64 & flags ? (part.m.a = bin.readF2dot14(data, offset), offset += 2, part.m.d = bin.readF2dot14(data, offset), offset += 2) : 128 & flags && (part.m.a = bin.readF2dot14(data, offset), offset += 2, part.m.b = bin.readF2dot14(data, offset), offset += 2, part.m.c = bin.readF2dot14(data, offset), offset += 2, part.m.d = bin.readF2dot14(data, offset), offset += 2); } while (32 & flags); if (256 & flags) { var numInstr = bin.readUshort(data, offset); offset += 2, gl.instr = []; for (i = 0; i < numInstr; i++) gl.instr.push(data[offset]), offset++; } } return gl; }, Typr.GPOS = {}, Typr.GPOS.parse = function(data, offset, length, font) { return Typr._lctf.parse(data, offset, length, font, Typr.GPOS.subt); }, Typr.GPOS.subt = function(data, ltype, offset) { if (2 != ltype) return null; var bin = Typr._bin, offset0 = offset, tab = {}; tab.format = bin.readUshort(data, offset), offset += 2; var covOff = bin.readUshort(data, offset); offset += 2, tab.coverage = Typr._lctf.readCoverage(data, covOff + offset0), tab.valFmt1 = bin.readUshort(data, offset), offset += 2, tab.valFmt2 = bin.readUshort(data, offset), offset += 2; var ones1 = Typr._lctf.numOfOnes(tab.valFmt1), ones2 = Typr._lctf.numOfOnes(tab.valFmt2); if (1 == tab.format) { tab.pairsets = []; var count = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < count; i++) { var psoff = bin.readUshort(data, offset); offset += 2, psoff += offset0; var pvcount = bin.readUshort(data, psoff); psoff += 2; for (var arr = [], j = 0; j < pvcount; j++) { var gid2 = bin.readUshort(data, psoff); psoff += 2, 0 != tab.valFmt1 && (value1 = Typr._lctf.readValueRecord(data, psoff, tab.valFmt1), psoff += 2 * ones1), 0 != tab.valFmt2 && (value2 = Typr._lctf.readValueRecord(data, psoff, tab.valFmt2), psoff += 2 * ones2), arr.push({ gid2, val1: value1, val2: value2 }); } tab.pairsets.push(arr); } } if (2 == tab.format) { var classDef1 = bin.readUshort(data, offset); offset += 2; var classDef2 = bin.readUshort(data, offset); offset += 2; var class1Count = bin.readUshort(data, offset); offset += 2; var class2Count = bin.readUshort(data, offset); offset += 2, tab.classDef1 = Typr._lctf.readClassDef(data, offset0 + classDef1), tab.classDef2 = Typr._lctf.readClassDef(data, offset0 + classDef2), tab.matrix = []; for (i = 0; i < class1Count; i++) { var row = []; for (j = 0; j < class2Count; j++) { var value1 = null, value2 = null; 0 != tab.valFmt1 && (value1 = Typr._lctf.readValueRecord(data, offset, tab.valFmt1), offset += 2 * ones1), 0 != tab.valFmt2 && (value2 = Typr._lctf.readValueRecord(data, offset, tab.valFmt2), offset += 2 * ones2), row.push({ val1: value1, val2: value2 }); } tab.matrix.push(row); } } return tab; }, Typr.GSUB = {}, Typr.GSUB.parse = function(data, offset, length, font) { return Typr._lctf.parse(data, offset, length, font, Typr.GSUB.subt); }, Typr.GSUB.subt = function(data, ltype, offset) { var bin = Typr._bin, offset0 = offset, tab = {}; if (1 != ltype && 4 != ltype && 5 != ltype) return null; tab.fmt = bin.readUshort(data, offset), offset += 2; var covOff = bin.readUshort(data, offset); if (offset += 2, tab.coverage = Typr._lctf.readCoverage(data, covOff + offset0), 1 == ltype) { if (1 == tab.fmt) tab.delta = bin.readShort(data, offset), offset += 2; else if (2 == tab.fmt) { var cnt = bin.readUshort(data, offset); offset += 2, tab.newg = bin.readUshorts(data, offset, cnt), offset += 2 * tab.newg.length; } } else if (4 == ltype) { tab.vals = []; cnt = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < cnt; i++) { var loff = bin.readUshort(data, offset); offset += 2, tab.vals.push(Typr.GSUB.readLigatureSet(data, offset0 + loff)); } } else if (5 == ltype) if (2 == tab.fmt) { var cDefOffset = bin.readUshort(data, offset); offset += 2, tab.cDef = Typr._lctf.readClassDef(data, offset0 + cDefOffset), tab.scset = []; var subClassSetCount = bin.readUshort(data, offset); offset += 2; for (i = 0; i < subClassSetCount; i++) { var scsOff = bin.readUshort(data, offset); offset += 2, tab.scset.push(0 == scsOff ? null : Typr.GSUB.readSubClassSet(data, offset0 + scsOff)); } } else console.log("unknown table format", tab.fmt); return tab; }, Typr.GSUB.readSubClassSet = function(data, offset) { var rUs = Typr._bin.readUshort, offset0 = offset, lset = [], cnt = rUs(data, offset); offset += 2; for (var i = 0; i < cnt; i++) { var loff = rUs(data, offset); offset += 2, lset.push(Typr.GSUB.readSubClassRule(data, offset0 + loff)); } return lset; }, Typr.GSUB.readSubClassRule = function(data, offset) { var rUs = Typr._bin.readUshort, rule = {}, gcount = rUs(data, offset), scount = rUs(data, offset += 2); offset += 2, rule.input = []; for (var i = 0; i < gcount - 1; i++) rule.input.push(rUs(data, offset)), offset += 2; return rule.substLookupRecords = Typr.GSUB.readSubstLookupRecords(data, offset, scount), rule; }, Typr.GSUB.readSubstLookupRecords = function(data, offset, cnt) { for (var rUs = Typr._bin.readUshort, out = [], i = 0; i < cnt; i++) out.push(rUs(data, offset), rUs(data, offset + 2)), offset += 4; return out; }, Typr.GSUB.readChainSubClassSet = function(data, offset) { var bin = Typr._bin, offset0 = offset, lset = [], cnt = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < cnt; i++) { var loff = bin.readUshort(data, offset); offset += 2, lset.push(Typr.GSUB.readChainSubClassRule(data, offset0 + loff)); } return lset; }, Typr.GSUB.readChainSubClassRule = function(data, offset) { for (var bin = Typr._bin, rule = {}, pps = ["backtrack", "input", "lookahead"], pi = 0; pi < pps.length; pi++) { var cnt = bin.readUshort(data, offset); offset += 2, 1 == pi && cnt--, rule[pps[pi]] = bin.readUshorts(data, offset, cnt), offset += 2 * rule[pps[pi]].length; } cnt = bin.readUshort(data, offset); return offset += 2, rule.subst = bin.readUshorts(data, offset, 2 * cnt), offset += 2 * rule.subst.length, rule; }, Typr.GSUB.readLigatureSet = function(data, offset) { var bin = Typr._bin, offset0 = offset, lset = [], lcnt = bin.readUshort(data, offset); offset += 2; for (var j = 0; j < lcnt; j++) { var loff = bin.readUshort(data, offset); offset += 2, lset.push(Typr.GSUB.readLigature(data, offset0 + loff)); } return lset; }, Typr.GSUB.readLigature = function(data, offset) { var bin = Typr._bin, lig = { chain: [] }; lig.nglyph = bin.readUshort(data, offset), offset += 2; var ccnt = bin.readUshort(data, offset); offset += 2; for (var k = 0; k < ccnt - 1; k++) lig.chain.push(bin.readUshort(data, offset)), offset += 2; return lig; }, Typr.head = {}, Typr.head.parse = function(data, offset, length) { var bin = Typr._bin, obj = {}; return bin.readFixed(data, offset), offset += 4, obj.fontRevision = bin.readFixed(data, offset), offset += 4, bin.readUint(data, offset), offset += 4, bin.readUint(data, offset), offset += 4, obj.flags = bin.readUshort(data, offset), offset += 2, obj.unitsPerEm = bin.readUshort(data, offset), offset += 2, obj.created = bin.readUint64(data, offset), offset += 8, obj.modified = bin.readUint64(data, offset), offset += 8, obj.xMin = bin.readShort(data, offset), offset += 2, obj.yMin = bin.readShort(data, offset), offset += 2, obj.xMax = bin.readShort(data, offset), offset += 2, obj.yMax = bin.readShort(data, offset), offset += 2, obj.macStyle = bin.readUshort(data, offset), offset += 2, obj.lowestRecPPEM = bin.readUshort(data, offset), offset += 2, obj.fontDirectionHint = bin.readShort(data, offset), offset += 2, obj.indexToLocFormat = bin.readShort(data, offset), offset += 2, obj.glyphDataFormat = bin.readShort(data, offset), offset += 2, obj; }, Typr.hhea = {}, Typr.hhea.parse = function(data, offset, length) { var bin = Typr._bin, obj = {}; return bin.readFixed(data, offset), offset += 4, obj.ascender = bin.readShort(data, offset), offset += 2, obj.descender = bin.readShort(data, offset), offset += 2, obj.lineGap = bin.readShort(data, offset), offset += 2, obj.advanceWidthMax = bin.readUshort(data, offset), offset += 2, obj.minLeftSideBearing = bin.readShort(data, offset), offset += 2, obj.minRightSideBearing = bin.readShort(data, offset), offset += 2, obj.xMaxExtent = bin.readShort(data, offset), offset += 2, obj.caretSlopeRise = bin.readShort(data, offset), offset += 2, obj.caretSlopeRun = bin.readShort(data, offset), offset += 2, obj.caretOffset = bin.readShort(data, offset), offset += 2, offset += 8, obj.metricDataFormat = bin.readShort(data, offset), offset += 2, obj.numberOfHMetrics = bin.readUshort(data, offset), offset += 2, obj; }, Typr.hmtx = {}, Typr.hmtx.parse = function(data, offset, length, font) { for (var bin = Typr._bin, obj = { aWidth: [], lsBearing: [] }, aw = 0, lsb = 0, i = 0; i < font.maxp.numGlyphs; i++) i < font.hhea.numberOfHMetrics && (aw = bin.readUshort(data, offset), offset += 2, lsb = bin.readShort(data, offset), offset += 2), obj.aWidth.push(aw), obj.lsBearing.push(lsb); return obj; }, Typr.kern = {}, Typr.kern.parse = function(data, offset, length, font) { var bin = Typr._bin, version = bin.readUshort(data, offset); if (offset += 2, 1 == version) return Typr.kern.parseV1(data, offset - 2, length, font); var nTables = bin.readUshort(data, offset); offset += 2; for (var map = { glyph1: [], rval: [] }, i = 0; i < nTables; i++) { offset += 2; length = bin.readUshort(data, offset); offset += 2; var coverage = bin.readUshort(data, offset); offset += 2; var format = coverage >>> 8; if (0 != (format &= 15)) throw "unknown kern table format: " + format; offset = Typr.kern.readFormat0(data, offset, map); } return map; }, Typr.kern.parseV1 = function(data, offset, length, font) { var bin = Typr._bin; bin.readFixed(data, offset), offset += 4; var nTables = bin.readUint(data, offset); offset += 4; for (var map = { glyph1: [], rval: [] }, i = 0; i < nTables; i++) { bin.readUint(data, offset), offset += 4; var coverage = bin.readUshort(data, offset); offset += 2, bin.readUshort(data, offset), offset += 2; var format = coverage >>> 8; if (0 != (format &= 15)) throw "unknown kern table format: " + format; offset = Typr.kern.readFormat0(data, offset, map); } return map; }, Typr.kern.readFormat0 = function(data, offset, map) { var bin = Typr._bin, pleft = -1, nPairs = bin.readUshort(data, offset); offset += 2, bin.readUshort(data, offset), offset += 2, bin.readUshort(data, offset), offset += 2, bin.readUshort(data, offset), offset += 2; for (var j = 0; j < nPairs; j++) { var left = bin.readUshort(data, offset); offset += 2; var right = bin.readUshort(data, offset); offset += 2; var value = bin.readShort(data, offset); offset += 2, left != pleft && (map.glyph1.push(left), map.rval.push({ glyph2: [], vals: [] })); var rval = map.rval[map.rval.length - 1]; rval.glyph2.push(right), rval.vals.push(value), pleft = left; } return offset; }, Typr.loca = {}, Typr.loca.parse = function(data, offset, length, font) { var bin = Typr._bin, obj = [], ver = font.head.indexToLocFormat, len = font.maxp.numGlyphs + 1; if (0 == ver) for (var i = 0; i < len; i++) obj.push(bin.readUshort(data, offset + (i << 1)) << 1); if (1 == ver) for (i = 0; i < len; i++) obj.push(bin.readUint(data, offset + (i << 2))); return obj; }, Typr.maxp = {}, Typr.maxp.parse = function(data, offset, length) { var bin = Typr._bin, obj = {}, ver = bin.readUint(data, offset); return offset += 4, obj.numGlyphs = bin.readUshort(data, offset), offset += 2, 65536 == ver && (obj.maxPoints = bin.readUshort(data, offset), offset += 2, obj.maxContours = bin.readUshort(data, offset), offset += 2, obj.maxCompositePoints = bin.readUshort(data, offset), offset += 2, obj.maxCompositeContours = bin.readUshort(data, offset), offset += 2, obj.maxZones = bin.readUshort(data, offset), offset += 2, obj.maxTwilightPoints = bin.readUshort(data, offset), offset += 2, obj.maxStorage = bin.readUshort(data, offset), offset += 2, obj.maxFunctionDefs = bin.readUshort(data, offset), offset += 2, obj.maxInstructionDefs = bin.readUshort(data, offset), offset += 2, obj.maxStackElements = bin.readUshort(data, offset), offset += 2, obj.maxSizeOfInstructions = bin.readUshort(data, offset), offset += 2, obj.maxComponentElements = bin.readUshort(data, offset), offset += 2, obj.maxComponentDepth = bin.readUshort(data, offset), offset += 2), obj; }, Typr.name = {}, Typr.name.parse = function(data, offset, length) { var bin = Typr._bin, obj = {}; bin.readUshort(data, offset), offset += 2; var count = bin.readUshort(data, offset); offset += 2, bin.readUshort(data, offset); for (var tname, offset0 = offset += 2, i = 0; i < count; i++) { var platformID = bin.readUshort(data, offset); offset += 2; var encodingID = bin.readUshort(data, offset); offset += 2; var languageID = bin.readUshort(data, offset); offset += 2; var nameID = bin.readUshort(data, offset); offset += 2; length = bin.readUshort(data, offset); offset += 2; var noffset = bin.readUshort(data, offset); offset += 2; var plat = "p" + platformID; null == obj[plat] && (obj[plat] = {}); var str, cname = ["copyright", "fontFamily", "fontSubfamily", "ID", "fullName", "version", "postScriptName", "trademark", "manufacturer", "designer", "description", "urlVendor", "urlDesigner", "licence", "licenceURL", "---", "typoFamilyName", "typoSubfamilyName", "compatibleFull", "sampleText", "postScriptCID", "wwsFamilyName", "wwsSubfamilyName", "lightPalette", "darkPalette"][nameID], soff = offset0 + 12 * count + noffset; if (0 == platformID) str = bin.readUnicode(data, soff, length / 2); else if (3 == platformID && 0 == encodingID) str = bin.readUnicode(data, soff, length / 2); else if (0 == encodingID) str = bin.readASCII(data, soff, length); else if (1 == encodingID) str = bin.readUnicode(data, soff, length / 2); else if (3 == encodingID) str = bin.readUnicode(data, soff, length / 2); else { if (1 != platformID) throw "unknown encoding " + encodingID + ", platformID: " + platformID; str = bin.readASCII(data, soff, length), console.log("reading unknown MAC encoding " + encodingID + " as ASCII"); } obj[plat][cname] = str, obj[plat]._lang = languageID; } for (var p in obj) if (null != obj[p].postScriptName && 1033 == obj[p]._lang) return obj[p]; for (var p in obj) if (null != obj[p].postScriptName && 3084 == obj[p]._lang) return obj[p]; for (var p in obj) if (null != obj[p].postScriptName) return obj[p]; for (var p in obj) { tname = p; break; } return console.log("returning name table with languageID " + obj[tname]._lang), obj[tname]; }, Typr["OS/2"] = {}, Typr["OS/2"].parse = function(data, offset, length) { var ver = Typr._bin.readUshort(data, offset); offset += 2; var obj = {}; if (0 == ver) Typr["OS/2"].version0(data, offset, obj); else if (1 == ver) Typr["OS/2"].version1(data, offset, obj); else if (2 == ver || 3 == ver || 4 == ver) Typr["OS/2"].version2(data, offset, obj); else { if (5 != ver) throw "unknown OS/2 table version: " + ver; Typr["OS/2"].version5(data, offset, obj); } return obj; }, Typr["OS/2"].version0 = function(data, offset, obj) { var bin = Typr._bin; return obj.xAvgCharWidth = bin.readShort(data, offset), offset += 2, obj.usWeightClass = bin.readUshort(data, offset), offset += 2, obj.usWidthClass = bin.readUshort(data, offset), offset += 2, obj.fsType = bin.readUshort(data, offset), offset += 2, obj.ySubscriptXSize = bin.readShort(data, offset), offset += 2, obj.ySubscriptYSize = bin.readShort(data, offset), offset += 2, obj.ySubscriptXOffset = bin.readShort(data, offset), offset += 2, obj.ySubscriptYOffset = bin.readShort(data, offset), offset += 2, obj.ySuperscriptXSize = bin.readShort(data, offset), offset += 2, obj.ySuperscriptYSize = bin.readShort(data, offset), offset += 2, obj.ySuperscriptXOffset = bin.readShort(data, offset), offset += 2, obj.ySuperscriptYOffset = bin.readShort(data, offset), offset += 2, obj.yStrikeoutSize = bin.readShort(data, offset), offset += 2, obj.yStrikeoutPosition = bin.readShort(data, offset), offset += 2, obj.sFamilyClass = bin.readShort(data, offset), offset += 2, obj.panose = bin.readBytes(data, offset, 10), offset += 10, obj.ulUnicodeRange1 = bin.readUint(data, offset), offset += 4, obj.ulUnicodeRange2 = bin.readUint(data, offset), offset += 4, obj.ulUnicodeRange3 = bin.readUint(data, offset), offset += 4, obj.ulUnicodeRange4 = bin.readUint(data, offset), offset += 4, obj.achVendID = [bin.readInt8(data, offset), bin.readInt8(data, offset + 1), bin.readInt8(data, offset + 2), bin.readInt8(data, offset + 3)], offset += 4, obj.fsSelection = bin.readUshort(data, offset), offset += 2, obj.usFirstCharIndex = bin.readUshort(data, offset), offset += 2, obj.usLastCharIndex = bin.readUshort(data, offset), offset += 2, obj.sTypoAscender = bin.readShort(data, offset), offset += 2, obj.sTypoDescender = bin.readShort(data, offset), offset += 2, obj.sTypoLineGap = bin.readShort(data, offset), offset += 2, obj.usWinAscent = bin.readUshort(data, offset), offset += 2, obj.usWinDescent = bin.readUshort(data, offset), offset += 2; }, Typr["OS/2"].version1 = function(data, offset, obj) { var bin = Typr._bin; return offset = Typr["OS/2"].version0(data, offset, obj), obj.ulCodePageRange1 = bin.readUint(data, offset), offset += 4, obj.ulCodePageRange2 = bin.readUint(data, offset), offset += 4; }, Typr["OS/2"].version2 = function(data, offset, obj) { var bin = Typr._bin; return offset = Typr["OS/2"].version1(data, offset, obj), obj.sxHeight = bin.readShort(data, offset), offset += 2, obj.sCapHeight = bin.readShort(data, offset), offset += 2, obj.usDefault = bin.readUshort(data, offset), offset += 2, obj.usBreak = bin.readUshort(data, offset), offset += 2, obj.usMaxContext = bin.readUshort(data, offset), offset += 2; }, Typr["OS/2"].version5 = function(data, offset, obj) { var bin = Typr._bin; return offset = Typr["OS/2"].version2(data, offset, obj), obj.usLowerOpticalPointSize = bin.readUshort(data, offset), offset += 2, obj.usUpperOpticalPointSize = bin.readUshort(data, offset), offset += 2; }, Typr.post = {}, Typr.post.parse = function(data, offset, length) { var bin = Typr._bin, obj = {}; return obj.version = bin.readFixed(data, offset), offset += 4, obj.italicAngle = bin.readFixed(data, offset), offset += 4, obj.underlinePosition = bin.readShort(data, offset), offset += 2, obj.underlineThickness = bin.readShort(data, offset), offset += 2, obj; }, Typr.SVG = {}, Typr.SVG.parse = function(data, offset, length) { var bin = Typr._bin, obj = { entries: [] }, offset0 = offset; bin.readUshort(data, offset), offset += 2; var svgDocIndexOffset = bin.readUint(data, offset); offset += 4, bin.readUint(data, offset), offset += 4, offset = svgDocIndexOffset + offset0; var numEntries = bin.readUshort(data, offset); offset += 2; for (var i = 0; i < numEntries; i++) { var startGlyphID = bin.readUshort(data, offset); offset += 2; var endGlyphID = bin.readUshort(data, offset); offset += 2; var svgDocOffset = bin.readUint(data, offset); offset += 4; var svgDocLength = bin.readUint(data, offset); offset += 4; for (var sbuf = new Uint8Array(data.buffer, offset0 + svgDocOffset + svgDocIndexOffset, svgDocLength), svg = bin.readUTF8(sbuf, 0, sbuf.length), f = startGlyphID; f <= endGlyphID; f++) obj.entries[f] = svg; } return obj; }, Typr.SVG.toPath = function(str) { var pth = { cmds: [], crds: [] }; if (null == str) return pth; for (var svg = new DOMParser().parseFromString(str, "image/svg+xml").firstChild; "svg" != svg.tagName; ) svg = svg.nextSibling; var vb = svg.getAttribute("viewBox"); vb = vb ? vb.trim().split(" ").map(parseFloat) : [0, 0, 1e3, 1e3], Typr.SVG._toPath(svg.children, pth); for (var i = 0; i < pth.crds.length; i += 2) { var x = pth.crds[i], y = pth.crds[i + 1]; x -= vb[0], y = -(y -= vb[1]), pth.crds[i] = x, pth.crds[i + 1] = y; } return pth; }, Typr.SVG._toPath = function(nds, pth, fill) { for (var ni = 0; ni < nds.length; ni++) { var nd = nds[ni], tn = nd.tagName, cfl = nd.getAttribute("fill"); if (null == cfl && (cfl = fill), "g" == tn) Typr.SVG._toPath(nd.children, pth, cfl); else if ("path" == tn) { pth.cmds.push(cfl || "#000000"); var d = nd.getAttribute("d"), toks = Typr.SVG._tokens(d); Typr.SVG._toksToPath(toks, pth), pth.cmds.push("X"); } else "defs" == tn || console.log(tn, nd); } }, Typr.SVG._tokens = function(d) { for (var ts = [], off = 0, rn = false, cn = ""; off < d.length; ) { var cc = d.charCodeAt(off), ch = d.charAt(off); off++; var isNum = 48 <= cc && cc <= 57 || "." == ch || "-" == ch; rn ? "-" == ch ? (ts.push(parseFloat(cn)), cn = ch) : isNum ? cn += ch : (ts.push(parseFloat(cn)), "," != ch && " " != ch && ts.push(ch), rn = false) : isNum ? (cn = ch, rn = true) : "," != ch && " " != ch && ts.push(ch); } return rn && ts.push(parseFloat(cn)), ts; }, Typr.SVG._toksToPath = function(ts, pth) { for (var i = 0, x = 0, y = 0, ox = 0, oy = 0, pc = { M: 2, L: 2, H: 1, V: 1, S: 4, C: 6 }, cmds = pth.cmds, crds = pth.crds; i < ts.length; ) { var cmd = ts[i]; if (i++, "z" == cmd) cmds.push("Z"), x = ox, y = oy; else for (var cmu = cmd.toUpperCase(), ps = pc[cmu], reps = Typr.SVG._reps(ts, i, ps), j = 0; j < reps; j++) { var xi = 0, yi = 0; if (cmd != cmu && (xi = x, yi = y), "M" == cmu) x = xi + ts[i++], y = yi + ts[i++], cmds.push("M"), crds.push(x, y), ox = x, oy = y; else if ("L" == cmu) x = xi + ts[i++], y = yi + ts[i++], cmds.push("L"), crds.push(x, y); else if ("H" == cmu) x = xi + ts[i++], cmds.push("L"), crds.push(x, y); else if ("V" == cmu) y = yi + ts[i++], cmds.push("L"), crds.push(x, y); else if ("C" == cmu) { var x1 = xi + ts[i++], y1 = yi + ts[i++], x2 = xi + ts[i++], y2 = yi + ts[i++], x3 = xi + ts[i++], y3 = yi + ts[i++]; cmds.push("C"), crds.push(x1, y1, x2, y2, x3, y3), x = x3, y = y3; } else if ("S" == cmu) { var co = Math.max(crds.length - 4, 0); x1 = x + x - crds[co], y1 = y + y - crds[co + 1], x2 = xi + ts[i++], y2 = yi + ts[i++], x3 = xi + ts[i++], y3 = yi + ts[i++]; cmds.push("C"), crds.push(x1, y1, x2, y2, x3, y3), x = x3, y = y3; } else console.log("Unknown SVG command " + cmd); } } }, Typr.SVG._reps = function(ts, off, ps) { for (var i = off; i < ts.length && "string" != typeof ts[i]; ) i += ps; return (i - off) / ps; }, null == Typr && (Typr = {}), null == Typr.U && (Typr.U = {}), Typr.U.codeToGlyph = function(font, code) { var cmap = font.cmap, tind = -1; if (null != cmap.p0e4 ? tind = cmap.p0e4 : null != cmap.p3e1 ? tind = cmap.p3e1 : null != cmap.p1e0 && (tind = cmap.p1e0), -1 == tind) throw "no familiar platform and encoding!"; var tab = cmap.tables[tind]; if (0 == tab.format) return code >= tab.map.length ? 0 : tab.map[code]; if (4 == tab.format) { for (var sind = -1, i = 0; i < tab.endCount.length; i++) if (code <= tab.endCount[i]) { sind = i; break; } if (-1 == sind) return 0; if (tab.startCount[sind] > code) return 0; return 65535 & (0 != tab.idRangeOffset[sind] ? tab.glyphIdArray[code - tab.startCount[sind] + (tab.idRangeOffset[sind] >> 1) - (tab.idRangeOffset.length - sind)] : code + tab.idDelta[sind]); } if (12 == tab.format) { if (code > tab.groups[tab.groups.length - 1][1]) return 0; for (i = 0; i < tab.groups.length; i++) { var grp = tab.groups[i]; if (grp[0] <= code && code <= grp[1]) return grp[2] + (code - grp[0]); } return 0; } throw "unknown cmap table format " + tab.format; }, Typr.U.glyphToPath = function(font, gid) { var path = { cmds: [], crds: [] }; if (font.SVG && font.SVG.entries[gid]) { var p = font.SVG.entries[gid]; return null == p ? path : ("string" == typeof p && (p = Typr.SVG.toPath(p), font.SVG.entries[gid] = p), p); } if (font.CFF) { var state = { x: 0, y: 0, stack: [], nStems: 0, haveWidth: false, width: font.CFF.Private ? font.CFF.Private.defaultWidthX : 0, open: false }; Typr.U._drawCFF(font.CFF.CharStrings[gid], state, font.CFF, path); } else font.glyf && Typr.U._drawGlyf(gid, font, path); return path; }, Typr.U._drawGlyf = function(gid, font, path) { var gl = font.glyf[gid]; null == gl && (gl = font.glyf[gid] = Typr.glyf._parseGlyf(font, gid)), null != gl && (gl.noc > -1 ? Typr.U._simpleGlyph(gl, path) : Typr.U._compoGlyph(gl, font, path)); }, Typr.U._simpleGlyph = function(gl, p) { for (var c = 0; c < gl.noc; c++) { for (var i0 = 0 == c ? 0 : gl.endPts[c - 1] + 1, il = gl.endPts[c], i = i0; i <= il; i++) { var pr = i == i0 ? il : i - 1, nx = i == il ? i0 : i + 1, onCurve = 1 & gl.flags[i], prOnCurve = 1 & gl.flags[pr], nxOnCurve = 1 & gl.flags[nx], x = gl.xs[i], y = gl.ys[i]; if (i == i0) if (onCurve) { if (!prOnCurve) { Typr.U.P.moveTo(p, x, y); continue; } Typr.U.P.moveTo(p, gl.xs[pr], gl.ys[pr]); } else prOnCurve ? Typr.U.P.moveTo(p, gl.xs[pr], gl.ys[pr]) : Typr.U.P.moveTo(p, (gl.xs[pr] + x) / 2, (gl.ys[pr] + y) / 2); onCurve ? prOnCurve && Typr.U.P.lineTo(p, x, y) : nxOnCurve ? Typr.U.P.qcurveTo(p, x, y, gl.xs[nx], gl.ys[nx]) : Typr.U.P.qcurveTo(p, x, y, (x + gl.xs[nx]) / 2, (y + gl.ys[nx]) / 2); } Typr.U.P.closePath(p); } }, Typr.U._compoGlyph = function(gl, font, p) { for (var j = 0; j < gl.parts.length; j++) { var path = { cmds: [], crds: [] }, prt = gl.parts[j]; Typr.U._drawGlyf(prt.glyphIndex, font, path); for (var m = prt.m, i = 0; i < path.crds.length; i += 2) { var 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 (i = 0; i < path.cmds.length; i++) p.cmds.push(path.cmds[i]); } }, Typr.U._getGlyphClass = function(g, cd) { var intr = Typr._lctf.getInterval(cd, g); return -1 == intr ? 0 : cd[intr + 2]; }, Typr.U.getPairAdjustment = function(font, g1, g2) { if (font.GPOS) { for (var ltab = null, i = 0; i < font.GPOS.featureList.length; i++) { var fl = font.GPOS.featureList[i]; if ("kern" == fl.tag) for (var j = 0; j < fl.tab.length; j++) 2 == font.GPOS.lookupList[fl.tab[j]].ltype && (ltab = font.GPOS.lookupList[fl.tab[j]]); } if (ltab) for (i = 0; i < ltab.tabs.length; i++) { var tab = ltab.tabs[i], ind = Typr._lctf.coverageIndex(tab.coverage, g1); if (-1 != ind) { if (1 == tab.format) { var right = tab.pairsets[ind]; for (j = 0; j < right.length; j++) right[j].gid2 == g2 && (adj = right[j]); if (null == adj) continue; } else if (2 == tab.format) var c1 = Typr.U._getGlyphClass(g1, tab.classDef1), c2 = Typr.U._getGlyphClass(g2, tab.classDef2), adj = tab.matrix[c1][c2]; return adj.val1[2]; } } } if (font.kern) { var ind1 = font.kern.glyph1.indexOf(g1); if (-1 != ind1) { var ind2 = font.kern.rval[ind1].glyph2.indexOf(g2); if (-1 != ind2) return font.kern.rval[ind1].vals[ind2]; } } return 0; }, Typr.U.stringToGlyphs = function(font, str) { for (var gls = [], i = 0; i < str.length; i++) { var cc = str.codePointAt(i); cc > 65535 && i++, gls.push(Typr.U.codeToGlyph(font, cc)); } var gsub = font.GSUB; if (null == gsub) return gls; for (var llist = gsub.lookupList, flist = gsub.featureList, wsep = '\n " ,.:;!?() ،', R = "آأؤإاةدذرزوٱٲٳٵٶٷڈډڊڋڌڍڎڏڐڑڒړڔڕږڗژڙۀۃۄۅۆۇۈۉۊۋۍۏےۓەۮۯܐܕܖܗܘܙܞܨܪܬܯݍݙݚݛݫݬݱݳݴݸݹࡀࡆࡇࡉࡔࡧࡩࡪࢪࢫࢬࢮࢱࢲࢹૅેૉ૊૎૏ૐ૑૒૝ૡ૤૯஁ஃ஄அஉ஌எஏ஑னப஫஬", ci = 0; ci < gls.length; ci++) { var gl = gls[ci], slft = 0 == ci || -1 != wsep.indexOf(str[ci - 1]), srgt = ci == gls.length - 1 || -1 != wsep.indexOf(str[ci + 1]); slft || -1 == R.indexOf(str[ci - 1]) || (slft = true), srgt || -1 == R.indexOf(str[ci]) || (srgt = true), srgt || -1 == "ꡲ્૗".indexOf(str[ci + 1]) || (srgt = true), slft || -1 == "ꡲ્૗".indexOf(str[ci]) || (slft = true); var feat = null; feat = slft ? srgt ? "isol" : "init" : srgt ? "fina" : "medi"; for (var fi = 0; fi < flist.length; fi++) if (flist[fi].tag == feat) for (var ti = 0; ti < flist[fi].tab.length; ti++) { 1 == (tab = llist[flist[fi].tab[ti]]).ltype && Typr.U._applyType1(gls, ci, tab); } } var cligs = ["rlig", "liga", "mset"]; for (ci = 0; ci < gls.length; ci++) { gl = gls[ci]; var rlim = Math.min(3, gls.length - ci - 1); for (fi = 0; fi < flist.length; fi++) { var fl = flist[fi]; if (-1 != cligs.indexOf(fl.tag)) { for (ti = 0; ti < fl.tab.length; ti++) for (var tab = llist[fl.tab[ti]], j = 0; j < tab.tabs.length; j++) if (null != tab.tabs[j]) { var ind = Typr._lctf.coverageIndex(tab.tabs[j].coverage, gl); if (-1 != ind) { if (4 == tab.ltype) for (var vals = tab.tabs[j].vals[ind], k = 0; k < vals.length; k++) { var lig = vals[k], rl = lig.chain.length; if (!(rl > rlim)) { for (var good = true, l = 0; l < rl; l++) lig.chain[l] != gls[ci + (1 + l)] && (good = false); if (good) { gls[ci] = lig.nglyph; for (l = 0; l < rl; l++) gls[ci + l + 1] = -1; } } } else if (5 == tab.ltype) { var ltab = tab.tabs[j]; if (2 != ltab.fmt) continue; var cind = Typr._lctf.getInterval(ltab.cDef, gl), cls = ltab.cDef[cind + 2], scs = ltab.scset[cls]; for (i = 0; i < scs.length; i++) { var sc = scs[i], inp = sc.input; if (!(inp.length > rlim)) { for (good = true, l = 0; l < inp.length; l++) { var cind2 = Typr._lctf.getInterval(ltab.cDef, gls[ci + 1 + l]); if (-1 == cind && ltab.cDef[cind2 + 2] != inp[l]) { good = false; break; } } if (good) { var lrs = sc.substLookupRecords; for (k = 0; k < lrs.length; k += 2) lrs[k], lrs[k + 1]; } } } } } } } } } return gls; }, Typr.U._applyType1 = function(gls, ci, tab) { for (var gl = gls[ci], j = 0; j < tab.tabs.length; j++) { var ttab = tab.tabs[j], ind = Typr._lctf.coverageIndex(ttab.coverage, gl); -1 != ind && (1 == ttab.fmt ? gls[ci] = gls[ci] + ttab.delta : gls[ci] = ttab.newg[ind]); } }, Typr.U.glyphsToPath = function(font, gls, clr) { for (var tpath = { cmds: [], crds: [] }, x = 0, i = 0; i < gls.length; i++) { var gid = gls[i]; if (-1 != gid) { for (var gid2 = i < gls.length - 1 && -1 != gls[i + 1] ? gls[i + 1] : 0, path = Typr.U.glyphToPath(font, gid), j = 0; j < path.crds.length; j += 2) tpath.crds.push(path.crds[j] + x), tpath.crds.push(path.crds[j + 1]); clr && tpath.cmds.push(clr); for (j = 0; j < path.cmds.length; j++) tpath.cmds.push(path.cmds[j]); clr && tpath.cmds.push("X"), x += font.hmtx.aWidth[gid], i < gls.length - 1 && (x += Typr.U.getPairAdjustment(font, gid, gid2)); } } return tpath; }, Typr.U.pathToSVG = function(path, prec) { null == prec && (prec = 5); for (var out = [], co = 0, lmap = { M: 2, L: 2, Q: 4, C: 6 }, i = 0; i < path.cmds.length; i++) { var cmd = path.cmds[i], cn = co + (lmap[cmd] ? lmap[cmd] : 0); for (out.push(cmd); co < cn; ) { var c = path.crds[co++]; out.push(parseFloat(c.toFixed(prec)) + (co == cn ? "" : " ")); } } return out.join(""); }, Typr.U.pathToContext = function(path, ctx) { for (var c = 0, crds = path.crds, j = 0; j < path.cmds.length; j++) { var cmd = path.cmds[j]; "M" == cmd ? (ctx.moveTo(crds[c], crds[c + 1]), c += 2) : "L" == cmd ? (ctx.lineTo(crds[c], crds[c + 1]), c += 2) : "C" == cmd ? (ctx.bezierCurveTo(crds[c], crds[c + 1], crds[c + 2], crds[c + 3], crds[c + 4], crds[c + 5]), c += 6) : "Q" == cmd ? (ctx.quadraticCurveTo(crds[c], crds[c + 1], crds[c + 2], crds[c + 3]), c += 4) : "#" == cmd.charAt(0) ? (ctx.beginPath(), ctx.fillStyle = cmd) : "Z" == cmd ? ctx.closePath() : "X" == cmd && ctx.fill(); } }, Typr.U.P = {}, Typr.U.P.moveTo = function(p, x, y) { p.cmds.push("M"), p.crds.push(x, y); }, Typr.U.P.lineTo = function(p, x, y) { p.cmds.push("L"), p.crds.push(x, y); }, Typr.U.P.curveTo = function(p, a, b, c, d, e, f) { p.cmds.push("C"), p.crds.push(a, b, c, d, e, f); }, Typr.U.P.qcurveTo = function(p, a, b, c, d) { p.cmds.push("Q"), p.crds.push(a, b, c, d); }, Typr.U.P.closePath = function(p) { p.cmds.push("Z"); }, Typr.U._drawCFF = function(cmds, state, font, p) { for (var stack = state.stack, nStems = state.nStems, haveWidth = state.haveWidth, width = state.width, open = state.open, i = 0, x = state.x, y = state.y, c1x = 0, c1y = 0, c2x = 0, c2y = 0, c3x = 0, c3y = 0, c4x = 0, c4y = 0, jpx = 0, jpy = 0, o = { val: 0, size: 0 }; i < cmds.length; ) { Typr.CFF.getCharString(cmds, i, o); var v = o.val; if (i += o.size, "o1" == v || "o18" == v) stack.length % 2 != 0 && !haveWidth && (width = stack.shift() + font.Private.nominalWidthX), nStems += stack.length >> 1, stack.length = 0, haveWidth = true; else if ("o3" == v || "o23" == v) { stack.length % 2 != 0 && !haveWidth && (width = stack.shift() + font.Private.nominalWidthX), nStems += stack.length >> 1, stack.length = 0, haveWidth = true; } else if ("o4" == v) stack.length > 1 && !haveWidth && (width = stack.shift() + font.Private.nominalWidthX, haveWidth = true), open && Typr.U.P.closePath(p), y += stack.pop(), Typr.U.P.moveTo(p, x, y), open = true; else if ("o5" == v) for (; stack.length > 0; ) x += stack.shift(), y += stack.shift(), Typr.U.P.lineTo(p, x, y); else if ("o6" == v || "o7" == v) for (var count = stack.length, isX = "o6" == v, j = 0; j < count; j++) { var sval = stack.shift(); isX ? x += sval : y += sval, isX = !isX, Typr.U.P.lineTo(p, x, y); } else if ("o8" == v || "o24" == v) { count = stack.length; for (var index = 0; index + 6 <= count; ) c1x = x + stack.shift(), c1y = y + stack.shift(), c2x = c1x + stack.shift(), c2y = c1y + stack.shift(), x = c2x + stack.shift(), y = c2y + stack.shift(), Typr.U.P.curveTo(p, c1x, c1y, c2x, c2y, x, y), index += 6; "o24" == v && (x += stack.shift(), y += stack.shift(), Typr.U.P.lineTo(p, x, y)); } else { if ("o11" == v) break; if ("o1234" == v || "o1235" == v || "o1236" == v || "o1237" == v) "o1234" == v && (c1y = y, c2x = (c1x = x + stack.shift()) + stack.shift(), jpy = c2y = c1y + stack.shift(), c3y = c2y, c4y = y, x = (c4x = (c3x = (jpx = c2x + stack.shift()) + stack.shift()) + stack.shift()) + stack.shift(), Typr.U.P.curveTo(p, c1x, c1y, c2x, c2y, jpx, jpy), Typr.U.P.curveTo(p, c3x, c3y, c4x, c4y, x, y)), "o1235" == v && (c1x = x + stack.shift(), c1y = y + stack.shift(), c2x = c1x + stack.shift(), c2y = c1y + stack.shift(), jpx = c2x + stack.shift(), jpy = c2y + stack.shift(), c3x = jpx + stack.shift(), c3y = jpy + stack.shift(), c4x = c3x + stack.shift(), c4y = c3y + stack.shift(), x = c4x + stack.shift(), y = c4y + stack.shift(), stack.shift(), Typr.U.P.curveTo(p, c1x, c1y, c2x, c2y, jpx, jpy), Typr.U.P.curveTo(p, c3x, c3y, c4x, c4y, x, y)), "o1236" == v && (c1x = x + stack.shift(), c1y = y + stack.shift(), c2x = c1x + stack.shift(), jpy = c2y = c1y + stack.shift(), c3y = c2y, c4x = (c3x = (jpx = c2x + stack.shift()) + stack.shift()) + stack.shift(), c4y = c3y + stack.shift(), x = c4x + stack.shift(), Typr.U.P.curveTo(p, c1x, c1y, c2x, c2y, jpx, jpy), Typr.U.P.curveTo(p, c3x, c3y, c4x, c4y, x, y)), "o1237" == v && (c1x = x + stack.shift(), c1y = y + stack.shift(), c2x = c1x + stack.shift(), c2y = c1y + stack.shift(), jpx = c2x + stack.shift(), jpy = c2y + stack.shift(), c3x = jpx + stack.shift(), c3y = jpy + stack.shift(), c4x = c3x + stack.shift(), c4y = c3y + stack.shift(), Math.abs(c4x - x) > Math.abs(c4y - y) ? x = c4x + stack.shift() : y = c4y + stack.shift(), Typr.U.P.curveTo(p, c1x, c1y, c2x, c2y, jpx, jpy), Typr.U.P.curveTo(p, c3x, c3y, c4x, c4y, x, y)); else if ("o14" == v) { if (stack.length > 0 && !haveWidth && (width = stack.shift() + font.nominalWidthX, haveWidth = true), 4 == stack.length) { var adx = stack.shift(), ady = stack.shift(), bchar = stack.shift(), achar = stack.shift(), bind = Typr.CFF.glyphBySE(font, bchar), aind = Typr.CFF.glyphBySE(font, achar); Typr.U._drawCFF(font.CharStrings[bind], state, font, p), state.x = adx, state.y = ady, Typr.U._drawCFF(font.CharStrings[aind], state, font, p); } open && (Typr.U.P.closePath(p), open = false); } else if ("o19" == v || "o20" == v) { stack.length % 2 != 0 && !haveWidth && (width = stack.shift() + font.Private.nominalWidthX), nStems += stack.length >> 1, stack.length = 0, haveWidth = true, i += nStems + 7 >> 3; } else if ("o21" == v) stack.length > 2 && !haveWidth && (width = stack.shift() + font.Private.nominalWidthX, haveWidth = true), y += stack.pop(), x += stack.pop(), open && Typr.U.P.closePath(p), Typr.U.P.moveTo(p, x, y), open = true; else if ("o22" == v) stack.length > 1 && !haveWidth && (width = stack.shift() + font.Private.nominalWidthX, haveWidth = true), x += stack.pop(), open && Typr.U.P.closePath(p), Typr.U.P.moveTo(p, x, y), open = true; else if ("o25" == v) { for (; stack.length > 6; ) x += stack.shift(), y += stack.shift(), Typr.U.P.lineTo(p, x, y); c1x = x + stack.shift(), c1y = y + stack.shift(), c2x = c1x + stack.shift(), c2y = c1y + stack.shift(), x = c2x + stack.shift(), y = c2y + stack.shift(), Typr.U.P.curveTo(p, c1x, c1y, c2x, c2y, x, y); } else if ("o26" == v) for (stack.length % 2 && (x += stack.shift()); stack.length > 0; ) c1x = x, c1y = y + stack.shift(), x = c2x = c1x + stack.shift(), y = (c2y = c1y + stack.shift()) + stack.shift(), Typr.U.P.curveTo(p, c1x, c1y, c2x, c2y, x, y); else if ("o27" == v) for (stack.length % 2 && (y += stack.shift()); stack.length > 0; ) c1y = y, c2x = (c1x = x + stack.shift()) + stack.shift(), c2y = c1y + stack.shift(), x = c2x + stack.shift(), y = c2y, Typr.U.P.curveTo(p, c1x, c1y, c2x, c2y, x, y); else if ("o10" == v || "o29" == v) { var obj = "o10" == v ? font.Private : font; if (0 == stack.length) console.log("error: empty stack"); else { var ind = stack.pop(), subr = obj.Subrs[ind + obj.Bias]; state.x = x, state.y = y, state.nStems = nStems, state.haveWidth = haveWidth, state.width = width, state.open = open, Typr.U._drawCFF(subr, state, font, p), x = state.x, y = state.y, nStems = state.nStems, haveWidth = state.haveWidth, width = state.width, open = state.open; } } else if ("o30" == v || "o31" == v) { var count1 = stack.length, alternate = (index = 0, "o31" == v); for (index += count1 - (count = -3 & count1); index < count; ) alternate ? (c1y = y, c2x = (c1x = x + stack.shift()) + stack.shift(), y = (c2y = c1y + stack.shift()) + stack.shift(), count - index == 5 ? (x = c2x + stack.shift(), index++) : x = c2x, alternate = false) : (c1x = x, c1y = y + stack.shift(), c2x = c1x + stack.shift(), c2y = c1y + stack.shift(), x = c2x + stack.shift(), count - index == 5 ? (y = c2y + stack.shift(), index++) : y = c2y, alternate = true), Typr.U.P.curveTo(p, c1x, c1y, c2x, c2y, x, y), index += 4; } else { if ("o" == (v + "").charAt(0)) throw console.log("Unknown operation: " + v, cmds), v; stack.push(v); } } } state.x = x, state.y = y, state.nStems = nStems, state.haveWidth = haveWidth, state.width = width, state.open = open; }; const Typr$1 = getDefaultExportFromCjs(Typr), questionType = { "单选题": "0", "多选题": "1", "填空题": "2", "判断题": "3", "简答题": "4", "名词解释": "5", "论述题": "6", "计算题": "7" }, log = (data, type = "info") => { var _a; const style = `color: ${{ info: "orange", success: "green", error: "red" }[type]}; font-weight: bold;`; if (Array.isArray(data) || "object" == typeof data ? console.log(`%c${JSON.stringify(data, null, 2)}`, style) : console.log(`%c${data}`, style), defaultConfig$1.debugger) { const caller = (((_a = new Error().stack) == null ? void 0 : _a.split("\n")) || [])[2].trim(); console.log(`${caller}`); } }, sleep = (time) => new Promise((resolve) => { setTimeout(() => { resolve(); }, 1e3 * time); }), waitIframeLoaded = (iframe) => new Promise((resolve) => { const timer = setInterval(() => { var _a; iframe.contentDocument && "complete" === ((_a = iframe.contentDocument) == null ? void 0 : _a.readyState) ? (clearInterval(timer), resolve()) : iframe.addEventListener("load", () => { clearInterval(timer), resolve(); }); }, 100); }), waitElementLoaded = (iframeWindow, selector) => new Promise((resolve) => { const timer = setInterval(() => { iframeWindow.document.querySelector(selector) && (clearInterval(timer), resolve()); }, 100); }), removeHtml = (html) => null == html ? "" : html.replace(/<((?!img|sub|sup|br)[^>]+)>/g, "").replace(/ /g, " ").replace(/\s+/g, " ").replace(/<br\s*\/?>/g, "\n").replace(/<img.*?src="(.*?)".*?>/g, ' ').trim(), cl = (str) => str.replace(/^【.*?】\s*/, "").replace(/\s*（\d+\.\d+分）$/, ""), getQuestion = (type, html) => { let questionHtml, questionText, questionTypeId, optionHtml, tokenHtml, workType, optionText, index; switch (type) { case "1": return workType = "zj", questionHtml = Array.from(html.querySelectorAll(".clearfix .fontLabel")), questionText = cl(removeHtml(questionHtml[0].innerHTML)), questionTypeId = html.querySelectorAll("input[name^=answertype]")[0].value, optionHtml = Array.from(html.querySelectorAll("ul")[0].querySelectorAll("li .after")), tokenHtml = html.innerHTML, optionText = [], optionHtml.forEach(function(item) { optionText.push(removeHtml(item.innerHTML)); }), { question: questionText, options: optionText, type: questionTypeId, questionData: tokenHtml, workType }; case "2": workType = "zy", questionHtml = Array.from(html.querySelectorAll(".mark_name")), index = questionHtml[0].innerHTML.indexOf(""), questionText = cl(removeHtml(questionHtml[0].innerHTML.substring(index + 7))), questionHtml[0].getElementsByTagName("span")[0].innerHTML.replace("(", "").replace(")", "").split(",")[0], questionTypeId = html.querySelectorAll("input[name^=answertype]")[0].value, optionHtml = Array.from(html.querySelectorAll(".answer_p")), tokenHtml = html.innerHTML, optionText = []; for (let i = 0; i < optionHtml.length; i++) optionText.push(removeHtml(optionHtml[i].innerHTML)); return { question: questionText, options: optionText, type: questionTypeId, questionData: tokenHtml, workType }; case "3": workType = "ks", questionHtml = Array.from(document.getElementsByClassName("mark_name colorDeep")), index = questionHtml[0].innerHTML.indexOf(""), questionText = cl(removeHtml(questionHtml[0].innerHTML.substring(index + 7))), questionHtml[0].getElementsByTagName("span")[0].innerHTML.replace("(", "").replace(")", "").split(",")[0], questionTypeId = document.querySelectorAll("input[name^=type]")[1].value, optionHtml = Array.from(document.getElementsByClassName("answer_p")), tokenHtml = document.getElementsByClassName("mark_table")[0].innerHTML, optionText = []; for (let i = 0; i < optionHtml.length; i++) optionText.push(removeHtml(optionHtml[i].innerHTML)); return { question: questionText, options: optionText, type: questionTypeId, questionData: tokenHtml, workType }; } }, decode = (iframeWindow) => { var _a; const styleElements = iframeWindow.document.querySelectorAll("style"); let tipElement = null; if (styleElements.forEach((styleElement) => { var _a2; -1 !== ((_a2 = styleElement.textContent) == null ? void 0 : _a2.indexOf("font-cxsecret")) && (tipElement = styleElement); }), !tipElement) return; const fontMatch = (_a = tipElement.textContent) == null ? void 0 : _a.match(/base64,([\w\W]+?)'/); if (!fontMatch) return; const fontData = ((base64) => { const decodedData = atob(base64), array = new Uint8Array(decodedData.length); for (let i = 0; i < decodedData.length; i++) array[i] = decodedData.charCodeAt(i); return array; })(fontMatch[1]), font = Typr$1.parse(fontData), table = JSON.parse(_GM_getResourceText("ttf")); let text = {}; for (let i = 19968; i < 40870; i++) { let t = Typr$1.U.codeToGlyph(font, i); t && (t = Typr$1.U.glyphToPath(font, t), t = md5(JSON.stringify(t)).slice(24), text[i] = table[t]); } iframeWindow.document.querySelectorAll(".font-cxsecret").forEach((fontElement) => { let html = fontElement.innerHTML; Object.keys(text).forEach((key) => { const regex = new RegExp(String.fromCharCode(key), "g"); html = html.replace(regex, String.fromCharCode(text[key])); }), fontElement.innerHTML = html, fontElement.classList.remove("font-cxsecret"); }); }, getAnswers = (questionData, windowz = _unsafeWindow) => { let server = new ServerApi(windowz); const promises = [server.getAnswer(questionData), server.getAnswer2(questionData), server.getAnswer4(questionData)]; return Promise.all(promises); }, fillAnswer = (answer, questionData, html, iframeWindow) => { answer = answer.filter((item) => item.answer.length > 0); for (let i = 0; i < answer.length; i++) { let tmp = setAnswer(answer[i].answer, questionData, html, iframeWindow); if (tmp) return tmp; } return false; }, setAnswer = (answer, questionData, html, iframeWindow) => { switch (questionData.type) { case "0": case "1": const matchArr = matchAnswer(answer, questionData.options); matchArr.length > 0 && clearCurrent(html, iframeWindow); for (var i = 0; i < matchArr.length; i++) console.log($$1(html).find("li").eq(matchArr[i]), matchArr[i]), $$1(html).find("ul:eq(0) li :radio,:checkbox,textarea").eq(matchArr[i]).click(), $$1(html).find(".answerBg").eq(matchArr[i]).click(), $$1(html).find("li").eq(matchArr[i]).click(); return matchArr.length > 0 && answer; case "3": return answer instanceof Array && (answer = answer[0]), $$1(html).find("ul:eq(0) li :radio,:checkbox,textarea").each(function() { "true" == $$1(this).val() ? answer.match(/(^|,)(True|true|正确|是|对|√|T|ri)(,|$)/) && $$1(this).click() : answer.match(/(^|,)(False|false|错误|否|错|×|F|wr)(,|$)/) && $$1(this).click(); }), $$1(html).find(".answerBg").each(function() { "true" == $$1(this).find(".num_option").attr("data") ? answer.match(/(^|,)(True|true|正确|是|对|√|T|ri)(,|$)/) && $$1(this).click() : answer.match(/(^|,)(False|false|错误|否|错|×|F|wr)(,|$)/) && $$1(this).click(); }), !!($$1(html).find("ul:eq(0) li :radio,:checkbox,textarea").is(":checked") || $$1(html).find(".check_answer").length > 0 || $$1(html).find(".check_answer_dx").length > 0) && answer; case "2": case "9": case "4": case "5": case "6": case "7": return $$1(html).find("textarea").length == answer.length && (clearCurrent(html, iframeWindow), $$1(html).find("textarea").each(function(index) { iframeWindow.UE.getEditor($$1(this).attr("name")).ready(function() { this.setContent(answer[index].replace(/第.空:/g, "")); }); }), answer); default: return false; } }, matchAnswer = (answer, options) => { answer = ((answer2) => { if (answer2 instanceof Array) { answer2 = answer2.filter(function(item) { return null !== item; }); for (let i2 = 0; i2 < answer2.length; i2++) answer2[i2] = removeHtml(answer2[i2]); } else "string" == typeof answer2 && (answer2 = cl(answer2)); return answer2; })(answer); for (var matchArr = [], i = 0; i < answer.length; i++) for (var j = 0; j < options.length; j++) answer[i] == options[j] && matchArr.push(j); return matchArr; }, clearCurrent = (item, iframeWindow) => { $$1(item).find(".answerBg, .textDIV, .eidtDiv").each(function() { ($$1(this).find(".check_answer").length || $$1(this).find(".check_answer_dx").length) && $$1(this).click(); }), $$1(item).find("textarea").each(function() { iframeWindow.UE.getEditor($$1(this).attr("name")).ready(function() { this.setContent(""); }); }), $$1(item).find(":radio, :checkbox").prop("checked", false), $$1(item).find("textarea").each(function() { iframeWindow.UE.getEditor($$1(this).attr("name")).ready(function() { this.setContent(""); }); }); }, useAskStore = pinia$1.defineStore({ id: "ask", state: () => ({ dialogVisible: true, count: 0, questionList: [], task: { name: "暂未加载", work: { questionList: [], inx: 0 }, video: [], log: [], status: "" } }), actions: { reset() { this.task.name = "暂未加载", this.task.work = { questionList: [], inx: 0 }, this.task.video = [], this.task.status = "", this.count = 0; }, select(index) { this.task.work.questionList[index].selected = true, this.task.work.inx = index; try { this.task.work.questionList[index].dom.scrollIntoView({ block: "center" }); } catch (e) { log(e, "error"); } }, get(index) { return this.task.work.questionList[index]; }, insert(question) { this.task.work.questionList.push(question); }, update(index, question) { this.task.work.questionList[index] = question; }, log(msg, level = "info") { this.task.log.length > 20 && this.task.log.shift(), this.task.log.push({ time: (/* @__PURE__ */ new Date()).toLocaleTimeString(), msg, type: level }); }, msg(msg) { this.task.status = msg; } } }), _sfc_main = vue.defineComponent({ setup() { const askstore = useAskStore(), { dialogVisible, count, questionList, task } = pinia$1.storeToRefs(askstore); return { count, dialogVisible, questionList, activeName: vue.ref("first"), activeNames: vue.ref(["1"]), task, msg: vue.ref("本脚本仅用于学习交流，请24h内删除 禁止用于各种非法用途，否则后果自负 本脚本题库接口来源于网络，若您有更好的接口可以反馈给我"), Aim: aim_default, handleClick: (e) => { askstore.select(e); } }; } }), _hoisted_1 = { key: 0 }, _hoisted_2 = { class: "question_div" }, _hoisted_3 = { class: "question_ti" }, _hoisted_4 = { key: 0 }, _hoisted_5 = { key: 1 }, _hoisted_6 = { key: 2 }, _hoisted_7 = ["innerHTML"], _hoisted_8 = { key: 0, style: { "margin-top": "20px" } }, _hoisted_9 = { key: 1 }, _hoisted_10 = { key: 2 }, _hoisted_11 = { height: "100px" }, _hoisted_12 = ["innerHTML"]; const Ask = _export_sfc(_sfc_main, [["render", function(_ctx, _cache, $props, $setup, $data, $options) { const _component_el_button = vue.resolveComponent("el-button"), _component_el_text = vue.resolveComponent("el-text"), _component_el_skeleton = vue.resolveComponent("el-skeleton"), _component_el_card = vue.resolveComponent("el-card"), _component_el_divider = vue.resolveComponent("el-divider"), _component_el_col = vue.resolveComponent("el-col"), _component_el_row = vue.resolveComponent("el-row"), _component_el_scrollbar = vue.resolveComponent("el-scrollbar"), _component_el_tag = vue.resolveComponent("el-tag"), _component_el_tab_pane = vue.resolveComponent("el-tab-pane"), _component_el_tabs = vue.resolveComponent("el-tabs"), _component_el_alert = vue.resolveComponent("el-alert"), _component_el_empty = vue.resolveComponent("el-empty"), _component_el_dialog = vue.resolveComponent("el-dialog"); return vue.openBlock(), vue.createBlock(vue.Teleport, { to: "body" }, [vue.createVNode(_component_el_button, { id: "zeokdjg", primary: "", round: "", icon: _ctx.Aim, onClick: _cache[0] || (_cache[0] = ($event) => _ctx.dialogVisible = !_ctx.dialogVisible) }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString("暂未加载" == _ctx.task.name ? "等待任务加载" : "正在完成:" + _ctx.task.name), 1)]), _: 1 }, 8, ["icon"]), vue.createVNode(_component_el_dialog, { modelValue: _ctx.dialogVisible, "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => _ctx.dialogVisible = $event), width: "400px", title: "💯超星学习通满分助手", modal: false, "append-to-body": false, "lock-scroll": false, center: "", draggable: "" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_tabs, { modelValue: _ctx.activeName, "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.activeName = $event), class: "demo-tabs" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_tab_pane, { label: "运行框", name: "first" }, { default: vue.withCtx(() => [_ctx.task.work.questionList.length > 0 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [vue.createElementVNode("div", _hoisted_2, [vue.createVNode(_component_el_card, { shadow: "hover" }, { default: vue.withCtx(() => [vue.createElementVNode("h1", _hoisted_3, [vue.createVNode(_component_el_text, { size: "large", truncated: "" }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(_ctx.task.work.inx + 1 + "." + _ctx.task.work.questionList[_ctx.task.work.inx].question), 1)]), _: 1 })]), _ctx.task.work.questionList[_ctx.task.work.inx].answer ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_5, [vue.createElementVNode("p", null, [vue.createElementVNode("pre", null, vue.toDisplayString(_ctx.task.work.questionList[_ctx.task.work.inx].answer), 1)])])) : (vue.openBlock(), vue.createElementBlock("p", _hoisted_4, [vue.createVNode(_component_el_skeleton, { rows: 3, animated: "" })]))]), _: 1 })]), "考试" != _ctx.task.name ? (vue.openBlock(), vue.createBlock(_component_el_divider, { key: 0 }, { default: vue.withCtx(() => [vue.createTextVNode(" 题号 ")]), _: 1 })) : vue.createCommentVNode("", true), "考试" != _ctx.task.name ? (vue.openBlock(), vue.createBlock(_component_el_scrollbar, { key: 1, height: "100px" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_row, null, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.task.work.questionList, (item, index) => (vue.openBlock(), vue.createBlock(_component_el_col, { span: 4, key: index }, { default: vue.withCtx(() => [vue.createVNode(_component_el_button, { type: item.status || "info", plain: "", class: "question_btn", onClick: ($event) => _ctx.handleClick(index) }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(index + 1), 1)]), _: 2 }, 1032, ["type", "onClick"])]), _: 2 }, 1024))), 128))]), _: 1 })]), _: 1 })) : vue.createCommentVNode("", true), _ctx.task.work.questionList[_ctx.task.work.inx].allAnswer ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_6, [vue.createVNode(_component_el_divider, null, { default: vue.withCtx(() => [vue.createTextVNode(" 接口返回 ")]), _: 1 }), vue.createVNode(_component_el_tabs, { "tab-position": "left", style: { height: "200px" }, class: "demo-tabs" }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.task.work.questionList[_ctx.task.work.inx].allAnswer, (item, index) => (vue.openBlock(), vue.createBlock(_component_el_tab_pane, { label: item.form }, { default: vue.withCtx(() => [vue.createElementVNode("div", null, [vue.createElementVNode("div", { innerHTML: item.answer || "暂无答案" }, null, 8, _hoisted_7), null != item.num ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8, [vue.createElementVNode("div", null, [vue.createVNode(_component_el_tag, { class: "ml-2", type: "info" }, { default: vue.withCtx(() => [vue.createTextVNode("已用次数:" + vue.toDisplayString(item.usenum), 1)]), _: 2 }, 1024)]), vue.createElementVNode("div", null, [vue.createVNode(_component_el_tag, { class: "ml-2", type: "success" }, { default: vue.withCtx(() => [vue.createTextVNode("剩余次数:" + vue.toDisplayString(item.num), 1)]), _: 2 }, 1024)])])) : vue.createCommentVNode("", true)])]), _: 2 }, 1032, ["label"]))), 256))]), _: 1 })])) : vue.createCommentVNode("", true)])) : _ctx.task.video.status ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_9, [vue.createVNode(_component_el_alert, { title: "倍速有风险，挂科两行泪", type: "error", center: "", "show-icon": "" }), vue.createVNode(_component_el_text, { class: "mx-1", size: "large", type: "danger" }, { default: vue.withCtx(() => [vue.createTextVNode(" 正在完成视频任务 ")]), _: 1 })])) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_10, [vue.createElementVNode("div", _hoisted_11, [vue.createVNode(_component_el_empty, { description: _ctx.task.name }, null, 8, ["description"])])]))]), _: 1 }), vue.createVNode(_component_el_tab_pane, { label: "运行日志", name: "second" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_scrollbar, { height: "200px" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_row, null, { default: vue.withCtx(() => [vue.createVNode(_component_el_col, { span: 24 }, { default: vue.withCtx(() => [(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.task.log, (item, index) => (vue.openBlock(), vue.createElementBlock("p", { key: index, class: "cx_log" }, [vue.createVNode(_component_el_text, { size: "small", type: "info", class: "mx-1" }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(item.time), 1)]), _: 2 }, 1024), vue.createVNode(_component_el_text, { class: "mx-1", type: "info" == item.type ? "" : item.type }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(" " + item.msg), 1)]), _: 2 }, 1032, ["type"])]))), 128))]), _: 1 })]), _: 1 })]), _: 1 })]), _: 1 }), vue.createVNode(_component_el_tab_pane, { label: "公告", name: "msg" }, { default: vue.withCtx(() => [vue.createVNode(_component_el_card, { shadow: "hover" }, { default: vue.withCtx(() => [vue.createElementVNode("div", { innerHTML: _ctx.msg }, null, 8, _hoisted_12)]), _: 1 })]), _: 1 })]), _: 1 }, 8, ["modelValue"]), vue.createElementVNode("p", null, [_ctx.task.status ? (vue.openBlock(), vue.createBlock(_component_el_tag, { key: 0 }, { default: vue.withCtx(() => [vue.createTextVNode(vue.toDisplayString(_ctx.task.status), 1)]), _: 1 })) : vue.createCommentVNode("", true)])]), _: 1 }, 8, ["modelValue"])]); }], ["__scopeId", "data-v-f2d2b132"]]); class Cx { constructor() { __publicField(this, "app"); __publicField(this, "askStore"); __publicField(this, "ServerApi"); __publicField(this, "defaultConfig"); this.app = vue.createApp(Ask).use(ElementPlus).use(pinia$1.createPinia()), this.askStore = useAskStore(), this.ServerApi = new ServerApi(), this.defaultConfig = getConfig(), this.app.mount((() => { const div = _unsafeWindow.top.document.createElement("div"); return div.id = "xxxxzx", _unsafeWindow.top.document.getElementById(div.id) || _unsafeWindow.top.document.body.append(div), div; })()); } innerbook() { } async audio(iframeWindow) { this.askStore.reset(), this.askStore.task.name = "视频音频"; const audio = iframeWindow.document.getElementById("audio_html5_api"); return audio.muted = true, audio.autoplay = true, audio.volume = 0, audio.play().then(function() { console.log("播放成功"); }).catch(function(error) { "NotAllowedError" === error.name ? ElementPlus.ElMessageBox.alert("由于自动播放需要用户点击过浏览器，请确认即可", "温馨提示", { confirmButtonText: "确认", callback: () => { audio.play(); } }) : console.error("视频播放失败，原因：", error); }), new Promise((resolve) => { const intervalId = setInterval(() => { audio.ended ? (clearInterval(intervalId), log("监听到音频已完成", "success"), resolve()) : audio.paused && audio.play(); }, 1e3); audio.addEventListener("ended", function() { log("监听到音频已完成1", "success"), audio.pause(), clearInterval(intervalId), resolve(); }); }); } async video(iframeWindow) { this.askStore.reset(), this.askStore.task.name = "视频", this.askStore.task.video.status = 1, await waitElementLoaded(iframeWindow, "#video_html5_api"), console.log("视频加载完成"); const player = iframeWindow.videojs("video_html5_api"), playerButton = iframeWindow.document.querySelector(".vjs-big-play-button"); player.muted(true), player.playbackRate(16), player.play(), await new Promise((resolve) => { const intervalId = setInterval(() => { "isUnFinishJob" in iframeWindow && iframeWindow.isUnFinishJob() ? player.paused() && (playerButton == null ? void 0 : playerButton.click()) : (clearInterval(intervalId), resolve()); }, 1e3), pauseBase = player.pause; player.pause = function() { player.currentTime() >= player.duration() && (console.log("视频播放完成"), player.pause = pauseBase, resolve()); }, player.on("ended", () => { console.log("视频播放完成1"), player.pause = pauseBase, player.pause(), clearInterval(intervalId), resolve(); }); }), console.log("任务点完成"); } work(iframeWindow) { return new Promise(async (resolve) => { decode(iframeWindow); const Timu = iframeWindow.document.querySelectorAll(".TiMu"); if (!Timu) return void resolve(); let ques = [], succ = 0; for (let i = 0; i < Timu.length; i++) { let data = getQuestion("1", Timu[i]); console.log(data), ques.push(data); } this.askStore.reset(), this.askStore.count = ques.length, this.askStore.task.name = "章节测验"; for (let i = 0; i < ques.length; i++) { await sleep(this.defaultConfig.answerInterval), this.askStore.insert(ques[i]), this.askStore.task.work.inx = i; let data = await getAnswers(ques[i], iframeWindow); this.askStore.get(i).allAnswer = data; let tmp = fillAnswer(data, ques[i], Timu[i], iframeWindow); tmp ? (this.askStore.get(i).status = "primary", this.askStore.get(i).answer = tmp, succ++) : (this.askStore.get(i).status = "danger", this.askStore.get(i).answer = "暂无答案"), this.askStore.get(i).dom = Timu[i]; } this.defaultConfig.autoSubmit ? (succ / ques.length < this.defaultConfig.minAccuracy ? (this.askStore.log("章节测验正确率不足，暂存", "error"), iframeWindow.alert = function(e) { console.log("alert 方法被阻止", e); }, iframeWindow.noSubmit()) : (iframeWindow.btnBlueSubmit(), await sleep(3), iframeWindow.submitCheckTimes(), this.askStore.log("章节测验已完成", "success")), this.askStore.task.status = `章节测验已完成，等待切换,正确率:${succ}/${ques.length}`, resolve()) : (this.askStore.log("已完成答题，未开启自动提交，等待手动提交中", "success"), this.askStore.task.status = `正在等待手动提交,正确率:${succ}/${ques.length}`); }); } homework() { return new Promise(async (resolve) => { const Timu = _unsafeWindow.document.querySelectorAll(".questionLi"); if (!Timu) return void resolve(); let ques = []; for (let i = 0; i < Timu.length; i++) { let data = getQuestion("2", Timu[i]); ques.push(data); } this.askStore.reset(), this.askStore.count = ques.length, this.askStore.task.name = "作业"; for (let i = 0; i < ques.length; i++) { await sleep(this.defaultConfig.answerInterval), this.askStore.insert(ques[i]), this.askStore.task.work.inx = i; let data = await getAnswers(ques[i]); this.askStore.get(i).allAnswer = data; let tmp = fillAnswer(data, ques[i], Timu[i], _unsafeWindow); tmp ? (this.askStore.get(i).status = "primary", this.askStore.get(i).answer = tmp) : (this.askStore.get(i).status = "danger", this.askStore.get(i).answer = "暂无答案"), this.askStore.get(i).dom = Timu[i]; } }); } exam() { return new Promise(async (resolve) => { this.askStore.reset(), this.askStore.count = 1, this.askStore.task.name = "考试"; let data = getQuestion("3", _unsafeWindow.document.body); this.askStore.insert(data), this.askStore.task.work.inx = 0; let data1 = await getAnswers(data); this.askStore.get(0).allAnswer = data1; let tmp = fillAnswer(data1, data, document.getElementsByClassName("mark_table")[0], _unsafeWindow); if (tmp ? (this.askStore.get(0).status = "primary", this.askStore.get(0).answer = tmp) : (this.askStore.get(0).status = "danger", this.askStore.get(0).answer = "暂无答案"), this.defaultConfig.autoExam) { await sleep(this.defaultConfig.answerInterval); const nextButton = $('.nextDiv .jb_btn:contains("下一题")'); nextButton ? nextButton.click() : (this.askStore.log("已完成答题，请自行检查答案填写后自行提交", "success"), this.askStore.task.status = "已完成答题，请自行检查答案填写后自行提交"); } else this.askStore.task.status = "未开启自动切换，等待手动切换"; }); } pdf(iframeWindow) { return new Promise(async (resolve) => { const contentWindow = iframeWindow.document.querySelector("#panView").contentWindow; contentWindow.scrollTo(0, contentWindow.document.body.scrollHeight), resolve(); }); } async s(iframeWindow) { const questionList = $(iframeWindow.document).find(".TiMu").map(function(index, element) { try { let questionHtml, questionText, questionType$1, questionAnswer, questionOption = [], questionAnalysis = ""; switch (questionHtml = $(element).find(".Zy_TItle .clearfix"), questionText = removeHtml(questionHtml[0].innerHTML), questionType$1 = questionText.match(/^\【(.+?)\】/)[1], questionText = questionText.replace(questionText.match(/^\【(.+?)\】/)[0], ""), questionType$1) { case "单选题": case "多选题": return questionOption = $(element).find("ul>li").map(function(inx, item) { return removeHtml($(item).find("a").html()); }).get(), null; case "判断题": if (questionAnalysis = removeHtml($(element).find(".Py_addpy:eq(0)").html() || ""), element.innerHTML.includes("正确答案")) questionAnswer = removeHtml($(element).find(".Py_answer.clearfix>span").html()); else { const match = $(element).find(".Py_answer.clearfix").html().match(/^(.*?)(?=<\/i>)/s), result = match ? match[1] : ""; questionAnswer = removeHtml(result); } if (questionAnswer.includes("正确答案")) questionAnswer = questionAnswer.replace("正确答案：", "").trim(); else if ($(element).find(".fr.dui").length > 0) questionAnswer = questionAnswer.replace("我的答案：", "").trim(); else { if (!questionAnswer.replace("我的答案：", "").trim().includes("√") && !questionAnswer.replace("我的答案：", "").trim().includes("×")) return null; questionAnswer = "√" == questionAnswer.replace("我的答案：", "").trim() ? "×" : "√"; } break; case "填空题": if (questionAnswer = $("span.font14", $(element)).map(function(inx, item) { return removeHtml($(item).html()).replace(/^第.空：/, "").trim(); }).get(), 0 == questionAnswer.length) { if (questionAnswer = $(element).find(".Py_answer.clearfix>div>div[class='font14']"), !(questionAnswer.length = $(element).find(".Py_answer.clearfix>div>div[class='font14']>>.fr.dui").length)) return null; questionAnswer = questionAnswer.map(function(inx, item) { return removeHtml($(item).html()).replace(/^第.空：/, "").trim(); }).get(); } break; default: return null; } return { question: questionText, options: questionOption, type: questionType[questionType$1], answer: questionAnswer }; } catch { return null; } }).get(); await this.ServerApi.s(questionList, iframeWindow.location.href); } } const pinia = pinia$1.createPinia(), app = vue.createApp(App).use(ElementPlus).use(pinia), _self = _unsafeWindow, top = _self.top, formStore = useformStore(); var iframeCom = null; switch (app.mount((() => { try { const div = top.document.createElement("div"); return div.id = "cccxapp", top.document.getElementById(div.id) ? div : (top.document.body.append(div), div); } catch (e) { log(e, "error"); } })()), (() => { document.body.oncopy = null, document.body.oncut = null, document.body.onpaste = null, document.body.onselectstart = null, document.body.ondragstart = null; const style = document.createElement("style"); style.innerHTML = "\n * {\n -webkit-user-select: auto !important;\n -moz-user-select: auto !important;\n -o-user-select: auto !important;\n user-select: auto !important;\n }\n ", document.head.appendChild(style); })(), _self.location.pathname) { case "/work/doHomeWorkNew": case "/mooc-ans/work/doHomeWorkNew": case "/mooc2-ans/work/doHomeWorkNew": location.href.includes("mooc2=1") && (location.href = location.href.replace(/&mooc2=1/g, "")); break; case "/mycourse/studentstudy": if (!_self.location.href.match(/mooc2=1/)) { ElementPlus.ElNotification({ title: "Auto Ask", message: "暂不支持旧版章节，请自行切换至新版", type: "error" }); break; } const cxModel = new Cx(); cxModel.askStore.log("脚本初始化成功！", "success"); const startWork = async () => { var _a, _b, _c, _d, _e; await waitElementLoaded(_self, "#iframe"); const cardsIframe = _self.document.querySelector("#iframe"); await waitIframeLoaded(cardsIframe); const _self1 = cardsIframe.contentWindow; top.scroll2Job(); let jobList = _self1.document.querySelectorAll(".ans-job-icon") || []; for (let i = 0; i < jobList.length; i++) { const item = jobList[i]; if ((_a = item.parentElement) == null ? void 0 : _a.classList.contains("ans-job-finished")) { const iframe = (_b = item.parentElement) == null ? void 0 : _b.querySelector("iframe"); if (iframe == null ? void 0 : iframe.src.match(/\/ananas\/modules\/work\/index.html/)) { await waitIframeLoaded(iframe), JSON.parse(iframe.getAttribute("data")); const workIframe = (_c = iframe.contentWindow) == null ? void 0 : _c.document.querySelector("iframe"); workIframe && (await waitIframeLoaded(workIframe), cxModel.s(workIframe.contentWindow)); } console.log(iframe.src, "已完成"), cxModel.askStore.log("已完成的任务点,跳过"); } else { const iframe = (_d = item.parentElement) == null ? void 0 : _d.querySelector("iframe"); await waitIframeLoaded(iframe); const otherInfo = JSON.parse(iframe.getAttribute("data")); if (cxModel.askStore.log(`正在完成任务:${otherInfo.name || otherInfo.title}`), iframe == null ? void 0 : iframe.src.match(/\/ananas\/modules\/video\/index\.html/)) await cxModel.video(iframe.contentWindow), cxModel.askStore.log("视频任务已完成", "success"); else if (iframe == null ? void 0 : iframe.src.match(/\/ananas\/modules\/work\/index.html/)) { const workIframe = (_e = iframe.contentWindow) == null ? void 0 : _e.document.querySelector("iframe"); workIframe && (await waitIframeLoaded(workIframe), await cxModel.work(workIframe.contentWindow), cxModel.askStore.log("作业任务已完成", "success")); } else (iframe == null ? void 0 : iframe.src.match(/\/ananas\/modules\/audio\/index.html/)) ? (log("音频", "error"), iframe && (await waitIframeLoaded(iframe), await cxModel.audio(iframe.contentWindow), cxModel.askStore.log("音频任务已完成", "success"))) : (iframe == null ? void 0 : iframe.src.match(/\/ananas\/modules\/pdf\/index.html/)) ? (log("文档", "error"), iframe && (await waitIframeLoaded(iframe), await cxModel.pdf(iframe.contentWindow), cxModel.askStore.log("pdf任务已完成", "success"))) : (console.log(iframe == null ? void 0 : iframe.src, "未知"), cxModel.askStore.log("未知任务跳过", "success")); } } await sleep(formStore.forminput.interval), !formStore.forminput.autoJump && cxModel.askStore.msg("由于未开启自动切换,请手动切换"), formStore.forminput.autoJump && (top == null ? void 0 : top.document.querySelector(".nextChapter").click()); }; setInterval(async () => { await waitElementLoaded(_self, "#iframe"); const cardsIframe = _self.document.querySelector("#iframe"); await waitIframeLoaded(cardsIframe); const _self1 = cardsIframe.contentWindow; iframeCom != _self1.location.href && (iframeCom = _self1.location.href, cxModel.askStore.reset(), startWork()); }, 2e3); break; case "/work/selectWorkQuestionYiPiYue": case "/knowledge/cards": break; case "/mooc2/work/dowork": const cxModel1 = new Cx(); cxModel1.askStore.log("脚本初始化成功！", "success"), await( cxModel1.homework()); break; case "/exam-ans/exam/test/reVersionTestStartNew": const cxModel2 = new Cx(); cxModel2.askStore.log("脚本初始化成功！", "success"), await( cxModel2.exam()); } })(Vue, Pinia, ElementPlus, md5, $); 视频 // ==UserScript== // @name ❤【超星学习通小助手】【正则改】【完全免费】视频-章节测试|自动挂机|防清进度|不占资源 // @namespace unrival // @version 2.7 // @description ▶▶▶上次更新：2023.04.15◀◀◀【💻可最小化💻】🆒支持超星视频、文档、答题、自定义正确率、掉线自动登录🤘取消视频文件加载，多开也不占用网速，放心追剧🍊自定义答题正确率，提高学习效率🍆每日功能测试，在发现问题前就解决问题，防清进度，无不良记录 // @author unrival // @run-at document-end // @storageName unrivalxxt // @match *://*.chaoxing.com/* // @match *://*.edu.cn/* // @match *://*.nbdlib.cn/* // @match *://*.hnsyu.net/* // @match *://*.ac.cn/* // @icon http://pan-yz.chaoxing.com/favicon.ico // @grant unsafeWindow // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @grant GM_info // @connect mooc1-1.chaoxing.com // @connect mooc1.chaoxing.com // @connect mooc1-2.chaoxing.com // @connect passport2-api.chaoxing.com // @connect 14.29.190.187 // @connect cx.icodef.com // @license GPL-3.0-or-later // @original-script https://scriptcat.org/script-show-page/878/ // @original-author unrival // @original-license GPL-3.0-or-later //如果脚本提示添加安全网址，请将脚本提示内容填写到下方区域，一行一个，如果不会，请加群询问 //安全网址请填写在上方空白区域 // ==/UserScript== (() => { var token = '', //关注微信公众号：一之哥哥，发送 “token” 领取你的token，填写在两个单引号中间并保存，可以提高答题并发数量。 jumpType = 1, // 0:智能模式，1:遍历模式，2:不跳转，如果智能模式出现无限跳转/不跳转情况，请切换为遍历模式 disableMonitor = 0, // 0:无操作，1:解除多端学习监控，开启此功能后可以多端学习，不会被强制下线。 accuracy = 75, //章节测试正确率百分比，在答题正确率在规定之上并且允许自动提交时才会提交答案 randomDo = 1, //将0改为1，找不到答案的单选、多选、判断就会自动选【B、ABCD、错】，只在规定正确率不为100%时才生效 backGround = 0, //是否对接超星挂机小助手，需要先安装对应脚本 //----------------------------------------------------------------------------------------------------- autoLogin = 0, //掉线是否自动登录，1为自动登录，需要配置登录信息（仅支持手机号+密码登陆） phoneNumber = '', //自动登录的手机号，填写在单引号之间。 password = ''; //自动登录的密码，填写在单引号之间。 //----------------------------------------------------------------------------------------------------- var host = 'http://14.29.190.187:54223/', rate = GM_getValue('unrivalrate', '1'), ctUrl = 'https://cx.icodef.com/wyn-nb?v=4', getQueryVariable = (variable) => { let q = _l.search.substring(1), v = q.split("&"), r = false; for (let i = 0, l = v.length; i < l; i++) { let p = v[i].split("="); p[0] == variable && (r = p[1]); } return r; }, getCookie = name => `; ${document.cookie}`.split(`; ${name}=`).pop().split(';').shift(), isCat = GM_info.scriptHandler == 'ScriptCat', _w = unsafeWindow, _d = _w.document, _l = _w.location, _p = _l.protocol, _h = _l.host, //isEdge = _w.navigator.userAgent.includes("Edg/"), isFf = _w.navigator.userAgent.includes("Firefox"), isMobile = _w.navigator.userAgent.includes("Android"), stop = false, handleImgs = (s) => { imgEs = s.match(/(<img([^>]*)>)/); if (imgEs) { for (let j = 0, k = imgEs.length; j < k; j++) { let urls = imgEs[j].match( /http[s]?:\/\/(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+/), url; if (urls) { url = urls[0].replace(/http[s]?:\/\//, ''); s = s.replaceAll(imgEs[j], url); } } } return s; }, trim = (s) => { return handleImgs(s).replaceAll('javascript:void(0);', '').replaceAll(" ", '').replaceAll("，", ',').replaceAll( "。", '.').replaceAll("：", ':').replaceAll("；", ';').replaceAll("？", '?').replaceAll("（", '(').replaceAll("）", ')').replaceAll("“", '"') .replaceAll("”", '"').replaceAll("！", '!').replaceAll("-", ' ').replace(/(<([^>]+)>)/ig, '') .replace(/^\s+/ig, '').replace(/\s+$/ig, ''); }, cVersion = 999, classId = getQueryVariable('clazzid') || getQueryVariable('clazzId') || getQueryVariable('classid') || getQueryVariable('classId'), courseId = getQueryVariable('courseid') || getQueryVariable('courseId'), UID = getCookie('_uid') || getCookie('UID'), FID = getCookie('fid'), jq = _w.top.$ || _w.top.jQuery; _w.confirm = (msg) => { return true; } setInterval(function () { _w.confirm = (msg) => { return true; } }, 2000); if (parseFloat(rate) == parseInt(rate)) { rate = parseInt(rate); } else { rate = parseFloat(rate); } try { _w.top.unrivalReviewMode = GM_getValue('unrivalreview', '0') || '0'; _w.top.unrivalDoWork = GM_getValue('unrivaldowork', '1') || '1'; _w.top.unrivalAutoSubmit = GM_getValue('unrivalautosubmit', '1') || '1'; _w.top.unrivalAutoSave = GM_getValue('unrivalautosave', '0') || '0'; } catch (e) { } if (_l.href.indexOf("knowledge/cards") > 0) { let allowBackground = false, spans = _d.getElementsByTagName('span'); for (let i = 0, l = spans.length; i < l; i++) { if (spans[i].innerHTML.indexOf('章节未开放') != -1) { if (_l.href.indexOf("ut=s") != -1) { _l.href = _l.href.replace("ut=s", "ut=t").replace(/&cpi=[0-9]{1,10}/, ''); } else if (_l.href.indexOf("ut=t") != -1) { spans[i].innerHTML = '此课程为闯关模式，请回到上一章节完成学习任务！' return; } break; } } _w.top.unrivalPageRd = String(Math.random()); if (!isFf) { try { cVersion = parseInt(navigator.userAgent.match(/Chrome\/[0-9]{2,3}./)[0].replace('Chrome/', '') .replace('.', '')); } catch (e) { } } var busyThread = 0, getStr = (str, start, end) => { let res = str.substring(str.indexOf(start), str.indexOf(end)).replace(start, ''); return res; }, scripts = _d.getElementsByTagName('script'), param = null; for (let i = 0, l = scripts.length; i < l; i++) { if (scripts[i].innerHTML.indexOf('mArg = "";') != -1 && scripts[i].innerHTML.indexOf( '==UserScript==') == -1) { param = getStr(scripts[i].innerHTML, 'try{\n mArg = ', ';\n}catch(e){'); } } if (param == null) { return; } try { vrefer = _d.getElementsByClassName('ans-attach-online ans-insertvideo-online')[0].src; } catch (e) { vrefer = _p + '//' + _h + '/ananas/modules/video/index.html?v=2022-1118-1729'; } GM_setValue('vrefer', vrefer); GM_setValue('host', _h); _d.getElementsByTagName("html")[0].innerHTML = ` 学习通小助手 学习通小助手v1.0 任务配置 视频倍速： 保存 | 复习模式 | 查看学习进度 | 后台挂机 激活挂机 章节测试： 自动答题 | 自动提交 | 自动保存 学习进度 任务列表 运行日志 [00:00:00]如果此提示不消失，说明页面出现了错误，请联系作者 章节测试 `; var logs = { "logArry": [], "addLog": function (str, color = "black") { if (this.logArry.length >= 50) { this.logArry.splice(0, 1); } var nowTime = new Date(); var nowHour = (Array(2).join(0) + nowTime.getHours()).slice(-2); var nowMin = (Array(2).join(0) + nowTime.getMinutes()).slice(-2); var nowSec = (Array(2).join(0) + nowTime.getSeconds()).slice(-2); this.logArry.push("[" + nowHour + ":" + nowMin + ":" + nowSec + "] " + str + ""); let logStr = ""; for (let logI = 0, logLen = this.logArry.length; logI < logLen; logI++) { logStr += this.logArry[logI] + " "; } _d.getElementById('log').innerHTML = logStr; var logElement = _d.getElementById('log'); logElement.scrollTop = logElement.scrollHeight; } }, htmlHook = setInterval(function () { if (_d.getElementById('unrivalRate') && _d.getElementById('updateRateButton') && _d .getElementById('reviewModeButton') && _d.getElementById('autoDoWorkButton') && _d .getElementById('autoSubmitButton') && _d.getElementById('autoSaveButton')) { if (!backGround) { _d.getElementById('fuckMeModeButton').style.display = "none"; } allowBackground = Math.round(new Date() / 1000) - parseInt(GM_getValue( 'unrivalBackgroundVideoEnable', '6')) < 15; if (allowBackground) { _d.getElementById('fuckMeModeButton').setAttribute('href', 'unrivalxxtbackground/'); } clearInterval(htmlHook); if (cVersion < 86) { logs.addLog( '\u60a8\u7684\u6d4f\u89c8\u5668\u5185\u6838\u8fc7\u8001\uff0c\u8bf7\u66f4\u65b0\u7248\u672c\u6216\u4f7f\u7528\u4e3b\u6d41\u6d4f\u89c8\u5668\uff0c\u63a8\u8350\u003c\u0061\u0020\u0068\u0072\u0065\u0066\u003d\u0022\u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u0077\u0077\u0077\u002e\u006d\u0069\u0063\u0072\u006f\u0073\u006f\u0066\u0074\u002e\u0063\u006f\u006d\u002f\u007a\u0068\u002d\u0063\u006e\u002f\u0065\u0064\u0067\u0065\u0022\u0020\u0074\u0061\u0072\u0067\u0065\u0074\u003d\u0022\u0076\u0069\u0065\u0077\u005f\u0077\u0069\u006e\u0064\u006f\u0077\u0022\u003e\u0065\u0064\u0067\u0065\u6d4f\u89c8\u5668\u003c\u002f\u0061\u003e', 'red'); stop = true; return; } if (isMobile) { logs.addLog('手机浏览器不保证能正常运行此脚本', 'orange'); } _d.addEventListener('visibilitychange', function () { let isH = _d.hidden; if (!isH) { logs.addLog('挂机功能不稳定，不建议长时间最小化窗口', 'orange'); } }); _d.getElementById('unrivalRate').value = rate; _d.getElementById('updateRateButton').onclick = function () { let urate = _d.getElementById('unrivalRate').value; if (parseFloat(urate) == parseInt(urate)) { urate = parseInt(urate); } else { urate = parseFloat(urate); } GM_setValue('unrivalrate', urate); rate = urate; if (urate > 0) { logs.addLog('视频倍速已更新为' + urate + '倍，将在3秒内生效', 'green'); } else { logs.addLog('奇怪的倍速，将会自动跳过视频任务', 'orange'); } } _d.getElementById('backGround').onclick = function () { logs.addLog('挂机激活成功，您现在可以最小化页面了', 'green'); _w.top.backNow = 1; } _d.getElementById('reviewModeButton').onclick = function () { let reviewButton = _d.getElementById('reviewModeButton'); if (reviewButton.getAttribute('class') == 'btn btn-default') { _d.getElementById('reviewModeButton').setAttribute('class', 'btn btn-success'); logs.addLog('复习模式已开启，遇到已完成的视频任务不会跳过', 'green'); GM_setValue('unrivalreview', '1'); _w.top.unrivalReviewMode = '1'; } else { _d.getElementById('reviewModeButton').setAttribute('class', 'btn btn-default'); logs.addLog('复习模式已关闭，遇到已完成的视频任务会自动跳过', 'green'); GM_setValue('unrivalreview', '0'); _w.top.unrivalReviewMode = '0'; } } _d.getElementById('autoDoWorkButton').onclick = function () { let autoDoWorkButton = _d.getElementById('autoDoWorkButton'); if (autoDoWorkButton.getAttribute('class') == 'btn btn-default') { _d.getElementById('autoDoWorkButton').setAttribute('class', 'btn btn-success'); logs.addLog('自动做章节测试已开启，将会自动做章节测试', 'green'); GM_setValue('unrivaldowork', '1'); _w.top.unrivalDoWork = '1'; } else { _d.getElementById('autoDoWorkButton').setAttribute('class', 'btn btn-default'); logs.addLog('自动做章节测试已关闭，将不会自动做章节测试', 'green'); GM_setValue('unrivaldowork', '0'); _w.top.unrivalDoWork = '0'; } } _d.getElementById('autoSubmitButton').onclick = function () { let autoSubmitButton = _d.getElementById('autoSubmitButton'); if (autoSubmitButton.getAttribute('class') == 'btn btn-default') { _d.getElementById('autoSubmitButton').setAttribute('class', 'btn btn-success'); logs.addLog('符合提交标准的章节测试将会自动提交', 'green'); GM_setValue('unrivalautosubmit', '1'); _w.top.unrivalAutoSubmit = '1'; } else { _d.getElementById('autoSubmitButton').setAttribute('class', 'btn btn-default'); logs.addLog('章节测试将不会自动提交', 'green'); GM_setValue('unrivalautosubmit', '0'); _w.top.unrivalAutoSubmit = '0'; } } _d.getElementById('autoSaveButton').onclick = function () { let autoSaveButton = _d.getElementById('autoSaveButton'); if (autoSaveButton.getAttribute('class') == 'btn btn-default') { _d.getElementById('autoSaveButton').setAttribute('class', 'btn btn-success'); logs.addLog('不符合提交标准的章节测试将会自动保存', 'green'); GM_setValue('unrivalautosave', '1'); _w.top.unrivalAutoSave = '1'; } else { _d.getElementById('autoSaveButton').setAttribute('class', 'btn btn-default'); logs.addLog('不符合提交标准的章节测试将不会自动保存，等待用户自己操作', 'green'); GM_setValue('unrivalautosave', '0'); _w.top.unrivalAutoSave = '0'; } } _d.getElementById('videoTimeButton').onclick = function () { _d.getElementById('videoTime').style.display = 'block'; _d.getElementById('videoTimeContent').src = _p + '//stat2-ans.chaoxing.com/task/s/index?courseid=' + courseId + '&clazzid=' + classId; } } }, 100), loopjob = () => { if (_w.top.unrivalScriptList.length > 1) { logs.addLog('您同时开启了多个刷课脚本，会挂科，会挂科，会挂科，会挂科，会挂科，会挂科，会挂科，会挂科', 'red'); } if (cVersion < 8.6 * 10) { logs.addLog( '\u60a8\u7684\u6d4f\u89c8\u5668\u5185\u6838\u8fc7\u8001\uff0c\u8bf7\u66f4\u65b0\u7248\u672c\u6216\u4f7f\u7528\u4e3b\u6d41\u6d4f\u89c8\u5668\uff0c\u63a8\u8350\u003c\u0061\u0020\u0068\u0072\u0065\u0066\u003d\u0022\u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u0077\u0077\u0077\u002e\u006d\u0069\u0063\u0072\u006f\u0073\u006f\u0066\u0074\u002e\u0063\u006f\u006d\u002f\u007a\u0068\u002d\u0063\u006e\u002f\u0065\u0064\u0067\u0065\u0022\u0020\u0074\u0061\u0072\u0067\u0065\u0074\u003d\u0022\u0076\u0069\u0065\u0077\u005f\u0077\u0069\u006e\u0064\u006f\u0077\u0022\u003e\u0065\u0064\u0067\u0065\u6d4f\u89c8\u5668\u003c\u002f\u0061\u003e', 'red'); stop = true; return; } if (stop) { return; } let missionli = missionList; if (missionli == []) { setTimeout(loopjob, 500); return; } for (let itemName in missionli) { if (missionli[itemName]['running']) { setTimeout(loopjob, 500); return; } } for (let itemName in missionli) { if (!missionli[itemName]['done']) { switch (missionli[itemName]['type']) { case 'video': doVideo(missionli[itemName]); break; case 'document': doDocument(missionli[itemName]); break; case 'work': doWork(missionli[itemName]); break; } setTimeout(loopjob, 500); return; } } if (busyThread <= 0) { if (jumpType != 2) { _w.top.jump = true; logs.addLog('所有任务处理完毕，5秒后自动下一章', 'green'); } else { logs.addLog('所有任务处理完毕，用户设置为不跳转，脚本已结束运行，如需自动跳转，请编辑脚本代码参数', 'green'); } clearInterval(loopjob); } else { setTimeout(loopjob, 500); } }, readyCheck = () => { setTimeout(function () { try { if (!isCat) { logs.addLog( '推荐使用脚本猫运行此脚本，使用其他脚本管理器不保证能正常运行', 'orange'); } if (_w.top.unrivalReviewMode == '1') { logs.addLog('复习模式已开启，遇到已完成的视频任务不会跳过', 'green'); _d.getElementById('reviewModeButton').setAttribute('class', ['btn btn-default', 'btn btn-success' ][_w.top.unrivalReviewMode]); } if (_w.top.unrivalDoWork == '1') { logs.addLog('自动做章节测试已开启，将会自动做章节测试', 'green'); _d.getElementById('autoDoWorkButton').setAttribute('class', ['btn btn-default', 'btn btn-success' ][_w.top.unrivalDoWork]); } _d.getElementById('autoSubmitButton').setAttribute('class', ['btn btn-default', 'btn btn-success' ][_w.top.unrivalAutoSubmit]); _d.getElementById('autoSaveButton').setAttribute('class', ['btn btn-default', 'btn btn-success' ][_w.top.unrivalAutoSave]); } catch (e) { console.log(e); readyCheck(); return; } }, 500); } readyCheck(); try { var pageData = JSON.parse(param); } catch (e) { if (jumpType != 2) { _w.top.jump = true; logs.addLog('此页无任务，5秒后自动下一章', 'green'); } else { logs.addLog('此页无任务，用户设置为不跳转，脚本已结束运行，如需自动跳转，请编辑脚本代码参数', 'green'); } return; } var data = pageData['defaults'], jobList = [], classId = data['clazzId'], chapterId = data['knowledgeid'], reportUrl = data['reportUrl'], ktoken = data['ktoken']; UID = UID || data['userid']; FID = FID || data['fid']; for (let i = 0, l = pageData['attachments'].length; i < l; i++) { let item = pageData['attachments'][i]; if (item['job'] != true || item['isPassed'] == true) { if (_w.top.unrivalReviewMode == '1' && item['type'] == 'video') { jobList.push(item); } continue; } else { jobList.push(item); } } var video_getReady = (item) => { let statusUrl = _p + '//' + _h + '/ananas/status/' + item['property']['objectid'] + '?k=' + FID + '&flag=normal&_dc=' + String(Math.round(new Date())), doubleSpeed = item['property']['doublespeed']; busyThread += 1; GM_xmlhttpRequest({ method: "get", headers: { 'Host': _h, 'Referer': vrefer, 'Sec-Fetch-Site': 'same-origin' }, url: statusUrl, onload: function (res) { try { busyThread -= 1; let videoInfo = JSON.parse(res.responseText), duration = videoInfo['duration'], dtoken = videoInfo['dtoken']; if (duration == undefined) { _d.getElementById('joblist').innerHTML += ` ` + '[无效视频]' + item['property']['name'] + ` ` return; } missionList['m' + item['jobid']] = { 'module': item['property']['module'], 'type': 'video', 'dtoken': dtoken, 'duration': duration, 'objectId': item['property']['objectid'], 'rt': item['property']['rt'] || '0.9', 'otherInfo': item['otherInfo'], 'doublespeed': doubleSpeed, 'jobid': item['jobid'], 'name': item['property']['name'], 'done': false, 'running': false }; var base222 = `[binary]` _d.getElementById('joblist').innerHTML += ` ` + ' ' + ` ` + '[视频]' + item['property']['name'] + ` ` } catch (e) { } }, onerror: function (err) { console.log(err); if (err.error.indexOf('@connect list') >= 0) { logs.addLog('请添加安全网址，将 【 //@connect ' + _h + ' 】方括号里的内容(不包括方括号)添加到脚本代码内指定位置，否则脚本无法正常运行，如图所示：', 'red'); logs.addLog( ' ' ); stop = true; } else { logs.addLog('获取任务详情失败', 'red'); logs.addLog('错误原因：' + err.error, 'red'); } } }); }, doVideo = (item) => { if (rate <= 0) { missionList['m' + item['jobid']]['running'] = true; logs.addLog('奇怪的倍速，视频已自动跳过', 'orange'); setTimeout(function () { missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; }, 5000); return; } if (allowBackground && backGround) { if (_w.top.document.getElementsByClassName('catalog_points_sa').length > 0 || _w.top.document .getElementsByClassName('lock').length > 0) { logs.addLog('您已安装超星挂机小助手，但此课程可能为闯关模式，不支持后台挂机，将为您在线完成', 'blue'); } else { item['userid'] = UID; item['classId'] = classId; item['review'] = [false, true][_w.top.unrivalReviewMode]; item['reportUrl'] = reportUrl; item['rt'] = missionList['m' + item['jobid']]['rt']; GM_setValue('unrivalBackgroundVideo', item); _d.cookie = "videojs_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; logs.addLog( '您已安装超星挂机小助手，已添加至后台任务，点我查看后台', 'green'); missionList['m' + item['jobid']]['running'] = true; setTimeout(function () { missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; }, 5000); return; } } let videojs_id = String(parseInt(Math.random() * 9999999)); _d.cookie = 'videojs_id=' + videojs_id + ';path=/' logs.addLog('开始刷视频：' + item['name'] + '，倍速：' + String(rate) + '倍'); logs.addLog('视频观看信息每60秒上报一次，请耐心等待', 'green'); logs.addLog('如遇脚本使用异常情况，请检查脚本版本是否为最新版，点我(脚本猫)或点我(greasyfork)检查', 'orange'); if (disableMonitor) { logs.addLog('解除多端学习监控有清除进度风险，请谨慎使用', 'orange'); } let dtype = 'Video'; if (item['module'].includes('audio')) { dtype = 'Audio'; rt = ''; } let playTime = 0, playsTime = 0, isdrag = '3', times = 0, encUrl = '', first = true, loop = setInterval(function () { if (rate <= 0) { clearInterval(loop); logs.addLog('奇怪的倍速，视频已自动跳过', 'orange'); setTimeout(function () { missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; }, 5000); return; } else if (item['doublespeed'] == 0 && rate > 1 && _w.top.unrivalReviewMode == '0') { rate = 1; logs.addLog('该视频不允许倍速播放，已恢复至一倍速，高倍速会被清空进度挂科，勿存侥幸', 'red'); } rt = missionList['m' + item['jobid']]['rt']; playsTime += rate; playTime = Math.ceil(playsTime); if (times == 0 || times % 60 == 0 || playTime >= item['duration']) { if (first) { playTime = 0; } if (playTime >= item['duration']) { clearInterval(loop); playTime = item['duration']; isdrag = '4'; } else if (playTime > 0) { isdrag = '0'; } encUrl = host + 'chaoXing/v3/getEnc.php?classid=' + classId + '&playtime=' + playTime + '&duration=' + item['duration'] + '&objectid=' + item[ 'objectId'] + '&jobid=' + item['jobid'] + '&uid=' + UID; busyThread += 1; var _bold_playTime = playTime; function ecOnload(res) { let enc = ''; if (res && res.status == 200) { enc = res.responseText; if (enc.includes('--#')) { let warnInfo = enc.match(new RegExp('--#(.*?)--#', "ig"))[0] .replace(/--#/ig, ''); logs.addLog(warnInfo, 'red'); enc = enc.replace(/--#(.*?)--#/ig, ''); } if (enc.indexOf('.stop') >= 0) { clearInterval(loop); stop = true; return; } } else { strEc = `[${classId}][${UID}][${item['jobid']}][${item['objectId']}][${playTime * 1000}][d_yHJ!$pdA~5][${item['duration'] * 1000}][0_${item['duration']}]`, enc = jq.md5(strEc); } if (enc.length != 32) { clearInterval(loop); stop = true; return; } let reportsUrl = reportUrl + '/' + item['dtoken'] + '?clazzId=' + classId + '&playingTime=' + playTime + '&duration=' + item['duration'] + '&clipTime=0_' + item[ 'duration'] + '&objectId=' + item['objectId'] + '&otherInfo=' + item['otherInfo'] + '&jobid=' + item[ 'jobid'] + '&userid=' + UID + '&isdrag=' + isdrag + '&view=pc&enc=' + enc + '&rt=' + rt + '&dtype=' + dtype + '&_t=' + String(Math.round(new Date())); GM_xmlhttpRequest({ method: "get", headers: { 'Host': _h, 'Referer': vrefer, 'Sec-Fetch-Site': 'same-origin', 'Content-Type': 'application/json' }, url: reportsUrl, onload: function (res) { try { let today = new Date(), todayStr = today.getFullYear() + 'd' + today.getMonth() + 'd' + today .getDate(), timelong = GM_getValue( 'unrivaltimelong', {}); if (timelong[UID] == undefined || timelong[UID]['today'] != todayStr ) { timelong[UID] = { 'time': 0, 'today': todayStr }; } else { timelong[UID]['time']++; } GM_setValue('unrivaltimelong', timelong); busyThread -= 1; if (timelong[UID]['time'] / 60 > 22 && item['doublespeed'] == 0 && _w.top .unrivalReviewMode == '0') { clearInterval(loop); logs.addLog( '今日学习时间过长，继续学习会导致清空进度，请明天再来', 'red'); setTimeout(function () { missionList['m' + item[ 'jobid']][ 'running' ] = false; missionList['m' + item[ 'jobid']][ 'done' ] = true; }, 5000); return; } let ispass = JSON.parse(res .responseText); first = false; if (ispass['isPassed'] && _w.top .unrivalReviewMode == '0') { logs.addLog('视频任务已完成', 'green'); missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; clearInterval(loop); return; } else if (isdrag == '4') { if (_w.top.unrivalReviewMode == '1') { logs.addLog('视频已观看完毕', 'green'); } else { logs.addLog('视频已观看完毕，但视频任务未完成', 'red'); } missionList['m' + item['jobid']][ 'running' ] = false; missionList['m' + item['jobid']][ 'done' ] = true; try { clearInterval(loop); } catch (e) { } } else { logs.addLog(item['name'] + '已观看' + _bold_playTime + '秒，剩余大约' + String(item['duration'] - _bold_playTime) + '秒'); } } catch (e) { console.log(e); if (res.responseText.indexOf('验证码') >= 0) { logs.addLog('已被超星风控，请点我处理，60秒后自动刷新页面', 'red'); missionList['m' + item['jobid']][ 'running' ] = false; clearInterval(loop); stop = true; setTimeout(function () { _l.reload(); }, 60000); return; } logs.addLog('超星返回错误信息，十秒后重试', 'red'); times = -10; return; } }, onerror: function (err) { console.log(err); if (err.error.indexOf('@connect list') >= 0) { logs.addLog( '请添加安全网址，将 【 //@connect ' + _h + ' 】方括号里的内容(不包括方括号)添加到脚本代码内指定位置，否则脚本无法正常运行，如图所示：', 'red'); logs.addLog( ' ' ); stop = true; } else { logs.addLog('观看视频失败', 'red'); logs.addLog('错误原因：' + err.error, 'red'); } missionList['m' + item['jobid']][ 'running' ] = false; clearInterval(loop); } }); }; GM_xmlhttpRequest({ method: "get", url: encUrl, timeout: 2000, onload: ecOnload, onerror: function (err) { console.log(err); ecOnload(false); }, ontimeout: function (err) { console.log(err); ecOnload(false); } }); } times += 1; }, 1000); missionList['m' + item['jobid']]['running'] = true; }, doDocument = (item) => { missionList['m' + item['jobid']]['running'] = true; logs.addLog('开始刷文档：' + item['name']); setTimeout(function () { busyThread += 1; GM_xmlhttpRequest({ method: "get", url: _p + '//' + _h + '/ananas/job/document?jobid=' + item['jobid'] + '&knowledgeid=' + chapterId + '&courseid=' + courseId + '&clazzid=' + classId + '&jtoken=' + item['jtoken'], onload: function (res) { try { busyThread -= 1; let ispass = JSON.parse(res.responseText); if (ispass['status']) { logs.addLog('文档任务已完成', 'green'); } else { logs.addLog('文档已阅读完成，但任务点未完成', 'red'); } } catch (err) { console.log(err); console.log(res.responseText); logs.addLog('解析文档内容失败', 'red'); } missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; }, onerror: function (err) { console.log(err); if (err.error.indexOf('@connect list') >= 0) { logs.addLog('请添加安全网址，将 【 //@connect ' + _h + ' 】方括号里的内容(不包括方括号)添加到脚本代码内指定位置，否则脚本无法正常运行，如图所示：', 'red'); logs.addLog( ' ' ); stop = true; } else { logs.addLog('阅读文档失败', 'red'); logs.addLog('错误原因：' + err.error, 'red'); } missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; } }); }, parseInt(Math.random() * 2000 + 9000, 10)) }, doWork = (item) => { missionList['m' + item['jobid']]['running'] = true; logs.addLog('开始刷章节测试：' + item['name']); logs.addLog('您设置的答题正确率为：' + String(accuracy) + '%，只有在高于此正确率时才会提交测试', 'blue'); _d.getElementById('workPanel').style.display = 'block'; _d.getElementById('frame_content').src = _p + '//' + _h + '/work/phone/work?workId=' + item['jobid'] .replace('work-', '') + '&courseId=' + courseId + '&clazzId=' + classId + '&knowledgeId=' + chapterId + '&jobId=' + item['jobid'] + '&enc=' + item['enc']; _w.top.unrivalWorkInfo = ''; _w.top.unrivalDoneWorkId = ''; setInterval(function () { if (_w.top.unrivalWorkInfo != '') { logs.addLog(_w.top.unrivalWorkInfo); _w.top.unrivalWorkInfo = ''; } }, 100); let checkcross = setInterval(function () { if (_w.top.unrivalWorkDone == false) { clearInterval(checkcross); return; } let ifW = _d.getElementById('frame_content').contentWindow; try { ifW.location.href; } catch (e) { console.log(e); if (e.message.indexOf('cross-origin') != -1) { clearInterval(checkcross); _w.top.unrivalWorkDone = true; return; } } }, 2000); let workDoneInterval = setInterval(function () { if (_w.top.unrivalWorkDone) { _w.top.unrivalWorkDone = false; clearInterval(workDoneInterval); _w.top.unrivalDoneWorkId = ''; _d.getElementById('workPanel').style.display = 'none'; _d.getElementById('frame_content').src = ''; setTimeout(function () { missionList['m' + item['jobid']]['running'] = false; missionList['m' + item['jobid']]['done'] = true; }, 5000); } }, 500); }, missionList = []; if (jobList.length <= 0) { if (jumpType != 2) { _w.top.jump = true; logs.addLog('此页无任务，5秒后自动下一章', 'green'); } else { logs.addLog('此页无任务，用户设置为不跳转，脚本已结束运行，如需自动跳转，请编辑脚本代码参数', 'green'); } return; } for (let i = 0, l = jobList.length; i < l; i++) { let item = jobList[i]; if (item['type'] == 'video') { video_getReady(item); } else if (item['type'] == 'document') { missionList['m' + item['jobid']] = { 'type': 'document', 'jtoken': item['jtoken'], 'jobid': item['jobid'], 'name': item['property']['name'], 'done': false, 'running': false }; _d.getElementById('joblist').innerHTML += ` ` + '[文档]' + item['property']['name'] + ` ` } else if (item['type'] == 'workid' && _w.top.unrivalDoWork == '1') { missionList['m' + item['jobid']] = { 'type': 'work', 'workid': item['property']['workid'], 'jobid': item['jobid'], 'name': item['property']['title'], 'enc': item['enc'], 'done': false, 'running': false }; _d.getElementById('joblist').innerHTML += ` ` + '[章节测试]' + item['property']['title'] + ` ` } else { try { let jobName = item['property']['name']; if (jobName == undefined) { jobName = item['property']['title']; } _d.getElementById('joblist').innerHTML += ` ` + '已跳过：' + jobName + ` ` } catch (e) { } } } loopjob(); } else if (_l.href.includes("mycourse/studentstudy")) { var audiofile = '[binary]', audioPlayer = new Audio(audiofile); _w.top.backNow = 0; audioPlayer.loop = true; _w.audioPlayer = audioPlayer; setInterval(function () { try { _w.jQuery.fn.viewer.Constructor.prototype.show = () => { }; } catch (e) { } }, 1000); try { _w.unrivalScriptList.push('Fuck me please'); } catch (e) { _w.unrivalScriptList = ['Fuck me please']; } function checkOffline() { let dleft = _d.getElementsByClassName('left'); if (dleft.length == 1) { let img = dleft[0].getElementsByTagName('img'); if (img.length == 1) { if (img[0].src.indexOf('loading.gif') != -1) { return true; } } } return false; } setInterval(function () { if (checkOffline()) { setTimeout(function () { if (checkOffline()) { _l.reload(); } }, 10000) } }, 3000); _d.addEventListener('visibilitychange', function () { var c = 0; if (_w.top.backNow == 0) { _d.title = '⚠️请先激活挂机'; return } else { _d.title = '学生学习页面'; } if (_d.hidden) { audioPlayer.play(); var timer = setInterval(function () { if (c) { _d.title = '🙈挂机中'; c = 0; } else { _d.title = '🙉挂机中'; c = 1; } if (!_d.hidden) { clearInterval(timer); _d.title = '学生学习页面'; } }, 1300); } else { audioPlayer.pause(); } }); _w.unrivalgetTeacherAjax = _w.getTeacherAjax; _w.getTeacherAjax = (courseid, classid, cid) => { if (cid == getQueryVariable('chapterId')) { return; } _w.top.unrivalPageRd = ''; _w.unrivalgetTeacherAjax(courseid, classid, cid); } if (disableMonitor == 1) { _w.appendChild = _w.Element.prototype.appendChild; _w.Element.prototype.appendChild = function () { try { if (arguments[0].src.indexOf('detect.chaoxing.com') > 0) { return; } } catch (e) { } _w.appendChild.apply(this, arguments); }; } _w.jump = false; setInterval(function () { if (getQueryVariable('mooc2') == '1') { let tabs = _d.getElementsByClassName('posCatalog_select'); for (let i = 0, l = tabs.length; i < l; i++) { let tabId = tabs[i].getAttribute('id'); if (tabId.indexOf('cur') >= 0 && tabs[i].getAttribute('class') == 'posCatalog_select') { tabs[i].setAttribute('onclick', "getTeacherAjax('" + courseId + "','" + classId + "','" + tabId.replace('cur', '') + "');"); } } } else { let h4s = _d.getElementsByTagName('h4'), h5s = _d.getElementsByTagName('h5'); for (let i = 0, l = h4s.length; i < l; i++) { if (h4s[i].getAttribute('id').indexOf('cur') >= 0) { h4s[i].setAttribute('onclick', "getTeacherAjax('" + courseId + "','" + classId + "','" + h4s[i].getAttribute('id').replace('cur', '') + "');"); } } for (let i = 0, l = h5s.length; i < l; i++) { if (h5s[i].getAttribute('id').indexOf('cur') >= 0) { h5s[i].setAttribute('onclick', "getTeacherAjax('" + courseId + "','" + classId + "','" + h5s[i].getAttribute('id').replace('cur', '') + "');"); } } } }, 1000); setInterval(function () { let but = null; if (_w.jump) { _w.jump = false; _w.top.unrivalDoneWorkId = ''; _w.jjump = (rd) => { if (rd != _w.top.unrivalPageRd) { return; } try { setTimeout(function () { if (jumpType == 1) { if (getQueryVariable('mooc2') == '1') { but = _d.getElementsByClassName( 'jb_btn jb_btn_92 fs14 prev_next next'); } else { but = _d.getElementsByClassName('orientationright'); } try { setTimeout(function () { if (rd != _w.top.unrivalPageRd) { return; } but[0].click(); }, 2000); } catch (e) { } return; } if (getQueryVariable('mooc2') == '1') { let ul = _d.getElementsByClassName('prev_ul')[0], lis = ul.getElementsByTagName('li'); for (let i = 0, l = lis.length; i < l; i++) { if (lis[i].getAttribute('class') == 'active') { if (i + 1 >= l) { break; } else { try { lis[i + 1].click(); } catch (e) { } return; } } } let tabs = _d.getElementsByClassName('posCatalog_select'); for (let i = 0, l = tabs.length; i < l; i++) { if (tabs[i].getAttribute('class') == 'posCatalog_select posCatalog_active') { while (i + 1 < tabs.length) { let nextTab = tabs[i + 1]; if ((nextTab.innerHTML.includes( 'icon_Completed prevTips') && _w.top .unrivalReviewMode == '0') || nextTab .innerHTML.includes( 'catalog_points_er prevTips')) { i++; continue; } if (nextTab.id.indexOf('cur') < 0) { i++; continue; } let clickF = setInterval(function () { if (rd != _w.top.unrivalPageRd) { clearInterval(clickF); return; } nextTab.click(); }, 2000); break; } break; } } } else { let div = _d.getElementsByClassName('tabtags')[0], spans = div.getElementsByTagName('span'); for (let i = 0, l = spans.length; i < l; i++) { if (spans[i].getAttribute('class').indexOf('currents') >= 0) { if (i + 1 == l) { break; } else { try { spans[i + 1].click(); } catch (e) { } return; } } } let tabs = _d.getElementsByTagName('span'), newTabs = []; for (let i = 0, l = tabs.length; i < l; i++) { if (tabs[i].getAttribute('style') != null && tabs[i] .getAttribute('style').indexOf( 'cursor:pointer;height:18px;') >= 0) { newTabs.push(tabs[i]); } } tabs = newTabs; for (let i = 0, l = tabs.length; i < l; i++) { if (tabs[i].parentNode.getAttribute('class') == 'currents') { while (i + 1 < tabs.length) { let nextTab = tabs[i + 1].parentNode; if ((nextTab.innerHTML.includes( 'roundpoint blue') && _w.top .unrivalReviewMode == '0') || nextTab .innerHTML.includes('roundpointStudent lock') ) { i++; continue; } if (nextTab.id.indexOf('cur') < 0) { i++; continue; } let clickF = setInterval(function () { if (rd != _w.top.unrivalPageRd) { clearInterval(clickF); return; } nextTab.click(); }, 2000); break; } break; } } } }, 2000); } catch (e) { } } _w.onReadComplete1(); setTimeout('jjump("' + _w.top.unrivalPageRd + '")', 2856); } }, 200); } else if (_l.href.indexOf("work/phone/doHomeWork") > 0) { var wIdE = _d.getElementById('workLibraryId') || _d.getElementById('oldWorkId'), wid = wIdE.value; _w.top.unrivalWorkDone = false; _w.aalert = _w.alert; _w.alert = (msg) => { if (msg == '保存成功') { _w.top.unrivalDoneWorkId = getQueryVariable('workId'); return; } aalert(msg); } if (_w.top.unrivalDoneWorkId == getQueryVariable('workId')) { _w.top.unrivalWorkDone = true; return; } _w.confirm = (msg) => { return true; } var questionList = [], questionsElement = _d.getElementsByClassName('Py-mian1'), questionNum = questionsElement.length, totalQuestionNum = questionNum; for (let i = 0; i < questionNum; i++) { let questionElement = questionsElement[i], idElements = questionElement.getElementsByTagName('input'), questionId = '0', question = questionElement.getElementsByClassName('Py-m1-title fs16')[0].innerHTML; question = handleImgs(question).replace(/(<([^>]+)>)/ig, '').replace(/[0-9]{1,3}.\[(.*?)\]/ig, '').replaceAll('\n', '').replace(/^\s+/ig, '').replace(/\s+$/ig, ''); for (let z = 0, k = idElements.length; z < k; z++) { try { if (idElements[z].getAttribute('name').indexOf('answer') >= 0) { questionId = idElements[z].getAttribute('name').replace('type', ''); break; } } catch (e) { console.log(e); continue; } } if (questionId == '0' || question == '') { continue; } typeE = questionElement.getElementsByTagName('input'); if (typeE == null || typeE == []) { continue; } let typeN = 'fuckme'; for (let g = 0, h = typeE.length; g < h; g++) { if (typeE[g].id == 'answertype' + questionId.replace('answer', '').replace('check', '')) { typeN = typeE[g].value; break; } } if (['0', '1', '3'].indexOf(typeN) < 0) { continue; } type = { '0': '单选题', '1': '多选题', '3': '判断题' }[typeN]; let optionList = { length: 0 }; if (['单选题', '多选题'].indexOf(type) >= 0) { let answersElements = questionElement.getElementsByClassName('answerList')[0].getElementsByTagName( 'li'); for (let x = 0, j = answersElements.length; x < j; x++) { let optionE = answersElements[x], optionTextE = trim(optionE.innerHTML.replace(/(^\s*)|(\s*$)/g, "")), optionText = optionTextE.slice(1).replace(/(^\s*)|(\s*$)/g, ""), optionValue = optionTextE.slice(0, 1), optionId = optionE.getAttribute('id-param'); if (optionText == '') { break; } optionList[optionText] = { 'id': optionId, 'value': optionValue } optionList.length++; } if (answersElements.length != optionList.length) { continue; } } questionList.push({ 'question': question, 'type': type, 'questionid': questionId, 'options': optionList }); } var qu = null, nowTime = -4000, busyThread = questionList.length, ctOnload = function (res, quu) { busyThread -= 1; var ctResult = { 'code': -1, 'finalUrl': '', 'data': '未找到答案' }; if (res) { try { var responseText = res.responseText, ctResult = JSON.parse(responseText); } catch (e) { console.log(e); if (res.finalUrl.includes('getAnswer.php')) { _w.top.unrivalWorkInfo = '查题错误，服务器连接失败'; return; } } } try { let choiceEs = _d.getElementsByTagName('li'); if (ctResult['code'] == -1 ) { try { if (ctResult['msg'] !== undefined) { _w.top.unrivalWorkInfo = ctResult['msg'] ; } } catch (e) { } busyThread += 1; GM_xmlhttpRequest({ method: "GET", headers: { 'Authorization': token, }, timeout: 6000, url: host + 'chaoXing/v3/getAnswer.php?tm=' + encodeURIComponent(quu['question'] .replace(/(^\s*)|(\s*$)/g, '')) + '&type=' + { '单选题': '0', '多选题': '1', '判断题': '3' }[quu['type']] + '&wid=' + wid + '&courseid=' + courseId, onload: function (res) { ctOnload(res, quu); }, onerror: function (err) { _w.top.unrivalWorkInfo = '查题错误，服务器连接失败'; console.log(err); busyThread -= 1; }, ontimeout: function (err) { _w.top.unrivalWorkInfo = '查题错误，服务器连接失败'; console.log(err); busyThread -= 1; } }); return; } try { var result = ctResult['data']; } catch (e) { _w.top.unrivalWorkInfo = '答案解析失败'; return; } _w.top.unrivalWorkInfo = '题目：' + quu['question'] + '：' + result; switch (quu['type']) { case '判断题': (function () { let answer = 'abaabaaba'; if ('正确是对√Tri'.indexOf(result) >= 0) { answer = 'true'; } else if ('错误否错×Fwr'.indexOf(result) >= 0) { answer = 'false'; } for (let u = 0, k = choiceEs.length; u < k; u++) { if (choiceEs[u].getAttribute('val-param') == answer && choiceEs[u].getAttribute( 'id-param') == quu['questionid'].replace( 'answer', '')) { choiceEs[u].click(); questionNum -= 1; return; } } if (randomDo == 1 && accuracy < 100) { _w.top.unrivalWorkInfo = quu['question'] + '：未找到正确答案，自动选【错】'; for (let u = 0, k = choiceEs.length; u < k; u++) { if (choiceEs[u].getElementsByTagName('em') .length < 1) { continue; } if (choiceEs[u].getAttribute('val-param') == 'false' && choiceEs[u].getAttribute( 'id-param') == quu['questionid'] .replace('answer', '')) { choiceEs[u].click(); return; } } } })(); break; case '单选题': (function () { let answerData = result; for (let option in quu['options']) { if (trim(option).replace(/\s/ig, '') == trim(answerData).replace(/\s/ig, '') || trim( option).replace(/\s/ig, '').includes(trim(answerData).replace(/\s/ig, '')) || trim(answerData).replace(/\s/ig, '').includes(trim(option).replace(/\s/ig, ''))) { for (let y = 0, j = choiceEs.length; y < j; y++) { if (choiceEs[y].getElementsByTagName( 'em').length < 1) { continue; } if (choiceEs[y].getElementsByTagName( 'em')[0].getAttribute( 'id-param') == quu['options'][ option ]['value'] && choiceEs[y] .getAttribute('id-param') == quu[ 'questionid'].replace('answer', '')) { if (!choiceEs[y].getAttribute( 'class').includes('cur')) { choiceEs[y].click(); } questionNum -= 1; return; } } } } if (randomDo == 1 && accuracy < 100) { _w.top.unrivalWorkInfo = quu['question'] + '：未找到正确答案，自动选【B】'; for (let y = 0, j = choiceEs.length; y < j; y++) { if (choiceEs[y].getElementsByTagName('em') .length < 1) { continue; } if (choiceEs[y].getElementsByTagName('em')[ 0].getAttribute('id-param') == 'B' && choiceEs[y].getAttribute( 'id-param') == quu['questionid'] .replace('answer', '')) { if (!choiceEs[y].getAttribute('class') .includes('cur')) { choiceEs[y].click(); } return; } } } })(); break; case '多选题': (function () { let answerData = trim(result).replace(/\s/ig, ''), hasAnswer = false; for (let option in quu['options']) { if (answerData.includes(trim(option).replace(/\s/ig, ''))) { for (let y = 0, j = choiceEs.length; y < j; y++) { if (choiceEs[y].getElementsByTagName( 'em').length < 1) { continue; } if (choiceEs[y].getElementsByTagName( 'em')[0].getAttribute( 'id-param') == quu['options'][ option ]['value'] && choiceEs[y] .getAttribute('id-param') == quu[ 'questionid'].replace('answer', '')) { if (!choiceEs[y].getAttribute( 'class').includes('cur')) { choiceEs[y].click(); } hasAnswer = true; break; } } } } if (hasAnswer) { questionNum -= 1; } else if (randomDo == 1 && accuracy < 100) { _w.top.unrivalWorkInfo = quu['question'] + '：未找到正确答案，自动全选'; for (let y = 0, j = choiceEs.length; y < j; y++) { if (choiceEs[y].getElementsByTagName('em') .length < 1) { continue; } if (choiceEs[y].getAttribute('id-param') == quu['questionid'].replace('answer', '') ) { if (!choiceEs[y].getAttribute('class') .includes('cur')) { choiceEs[y].click(); } } } } })(); break; } } catch (e) { console.log(e); } } for (let i = 0, l = questionList.length; i < l; i++) { nowTime += parseInt(Math.random() * 2000 + 2500, 10); setTimeout(function () { qu = questionList[i]; let param = 'question=' + encodeURIComponent( qu['question']); if (ctUrl.includes('icodef')) { param += '&type=' + { '单选题': '0', '多选题': '1', '判断题': '3' }[qu['type']] + '&id=' + wid; } GM_xmlhttpRequest({ method: "POST", headers: { 'Content-type': 'application/x-www-form-urlencoded', 'Authorization': token, }, url: ctUrl, timeout: 2000, data: param, onload: function (res) { ctOnload(res, qu); }, onerror: function () { ctOnload(false, qu); }, ontimeout: function () { ctOnload(false, qu); } }); }, nowTime); } var workInterval = setInterval(function () { if (busyThread != 0) { return; } clearInterval(workInterval); if (Math.floor((totalQuestionNum - questionNum) / totalQuestionNum) * 100 >= accuracy && _w.top .unrivalAutoSubmit == '1') { _w.top.unrivalDoneWorkId = getQueryVariable('workId'); _w.top.unrivalWorkInfo = '正确率符合标准，已提交答案'; setTimeout(function () { submitCheckTimes(); escapeBlank() submitAction() // setTimeout(function() { // document.querySelector(".cx_alert-blue").click() // }, parseInt(1000)); }, parseInt(Math.random() * 2000 + 3000, 10)); } else if (_w.top.unrivalAutoSave == 1) { _w.top.unrivalWorkInfo = '正确率不符合标准或未设置自动提交，已自动保存答案'; if (Math.floor((totalQuestionNum - questionNum) / totalQuestionNum) >= 0) { setTimeout(function () { _w.top.unrivalDoneWorkId = getQueryVariable('workId'); _w.noSubmit(); }, 2000); } } else { _w.top.unrivalWorkInfo = '用户设置为不自动保存答案，请手动提交或保存作业'; } }, 1000); } else if (_l.href.includes('work/phone/selectWorkQuestionYiPiYue')) { _w.top.unrivalWorkDone = true; _w.top.unrivalDoneWorkId = getQueryVariable('workId'); } else if (_l.href.includes('stat2-ans.chaoxing.com/task/s/index')) { if (_w.top == _w) { return; } _d.getElementsByClassName('page-container studentStatistic')[0].setAttribute('class', 'studentStatistic'); _d.getElementsByClassName('page-item item-task-list minHeight390')[0].remove(); _d.getElementsByClassName('subNav clearfix')[0].remove(); setInterval(function () { _l.reload(); }, 90000); } else if (_l.href.includes('passport2.') && _l.href.includes('login?refer=http') && autoLogin == 1) { if (!(/^1[3456789]\d{9}$/.test(phoneNumber))) { alert('自动登录的手机号填写错误，无法登陆') return; } if (password == '') { alert('未填写登录密码，无法登陆') return; } GM_xmlhttpRequest({ method: "get", url: 'https://passport2-api.chaoxing.com/v11/loginregister?cx_xxt_passport=json&uname=' + phoneNumber + '&code=' + encodeURIComponent(password), onload: function (res) { try { let ispass = JSON.parse(res.responseText); if (ispass['status']) { _l.href = decodeURIComponent(getQueryVariable('refer')); } else { alert(ispass['mes']); } } catch (err) { console.log(res.responseText); alert('登陆失败'); } }, onerror: function (err) { alert('登陆错误'); } }); } else if (_l.href.includes('unrivalxxtbackground')) { _d.getElementsByTagName("html")[0].innerHTML = ` 学习通挂机小助手 学习通挂机小助手 任务列表 运行日志 `; var logs = { "logArry": [], "addLog": function (str, color = "black") { if (this.logArry.length >= 50) { this.logArry.splice(0, 1); } var nowTime = new Date(), nowHour = (Array(2).join(0) + nowTime.getHours()).slice(-2), nowMin = (Array(2).join(0) + nowTime.getMinutes()).slice(-2), nowSec = (Array(2).join(0) + nowTime.getSeconds()).slice(-2), logElement = _d.getElementById('log'), logStr = ""; this.logArry.push("[" + nowHour + ":" + nowMin + ":" + nowSec + "] " + str + ""); for (let logI = 0, logLen = this.logArry.length; logI < logLen; logI++) { logStr += this.logArry[logI] + " "; } _d.getElementById('log').innerHTML = logStr; logElement.scrollTop = logElement.scrollHeight; } }; logs.addLog('此页面不必保持在最前端，后台会自动进行任务', 'green'); setInterval(function () { logs.addLog('此页面不必保持在最前端，后台会自动进行任务', 'green'); logs.addLog('如想禁用后台刷视频功能，请关闭脚本并重启浏览器', 'blue'); }, 120000) GM_addValueChangeListener('unrivalxxtbackgroundinfo', function (name, old_value, new_value, remote) { if (old_value != new_value) { logs.addLog(new_value); } }); setInterval(function () { if (Math.round(new Date() / 1000) - parseInt(GM_getValue('unrivalBackgroundVideoEnable', '6')) > 15) { logs.addLog('超星挂机小助手可能运行异常，如页面无反应，请尝试重启脚本猫或重启浏览器(脚本猫0.9.0版本有此问题)'); } }, 10000); var loopShow = () => { let jobList = GM_getValue('unrivalBackgroundList', '1'); if (jobList == '1') { _d.getElementById('joblist').innerHTML = '请将“超星挂机小助手”升级到最新版并重启浏览器'; } else { try { let jobHtml = ''; for (let i = 0, l = jobList.length; i < l; i++) { let status = ''; if (jobList[i]['done']) { status = '已完成'; } else if (parseInt(jobList[i]['playTime']) > 0) { status = '进行中'; } else { status = '等待中'; } if (jobList[i]['review']) { status += '：复习模式'; } jobHtml += ` ` + '[' + status + ']' + jobList[i]['name'] + ` ` } _d.getElementById('joblist').innerHTML = jobHtml; } catch (e) { _d.getElementById('joblist').innerHTML = '请将“超星挂机小助手”升级到最新版并重启浏览器！'; } } } loopShow(); setInterval(loopShow, 10000); } })();
结构setInterval(functionnname,时间) //时间毫秒为单位function jiafa(b){ a=0 a+=1 console.log(a); console.log(b); } setInterval(jiafa,1000) // 1 // undefined // 1 // undefined // 1 // undefined // 每一次都素重启，不会连续执行 // 可以命名为赋值给其他参数，以至于可以停止 const function1=setInterval(jiafa,1000) setTimeout(function(){ clearInterval(function1) },5000) //定时5s后停止 // 如果需要传参数，那么就调用的时候 b=3 const function2=setInterval(function(){ jiafa(b) },1000) // 1 // 3 // 1 // 3 // 1 // 3
// 注意字符串定义的时候使用 ` ` const text1=`如果再给我一次机会` const text2=`我会重新选择` //这里就查看有没有`机会`这个词语 function ifinclude(text){ if(text.includes("机会")) { console.log("包含机会："+text); } } ifinclude(text1) //包含机会：如果再给我一次机会 ifinclude(text2) //无返回内容 // 数组里是否含一个元素 const arry=["red","blue"] console.log(arry.includes("red")); //返回布尔 true console.log(arry.includes("green")); //返回布尔 false [字符串includes][1] [数组includes][2]
console.log(Date()); //返回的是一个字符串，包括所有属性 //Wed Jul 26 2023 23:22:31 GMT+0800 (中国标准时间) //前面加个new，==>new Date() 返回一个表示当前日期和时间的日期对象。可以单独返回日期，星期.... console.log(new Date()); //2023-07-26T15:23:41.186Z //将他时间格式化就所有toLocaleString() console.log(new Date().toLocaleString()); // 2023/7/26 15:23:41 //返回年份.getFullYear() console.log(new Date().getFullYear());将时间戳转换为本地时间使用new Date(时间戳)const timestamp = 1690033752000; console.log(new Date(timestamp)); //2023-07-22T13:49:12.000Z console.log(new Date(timestamp).toLocaleString()); // 2023/7/22 21:49:12获取当前的时间戳使用getTime() console.log(new Date().getTime()); console.log(new Date(new Date().getTime())); // 1690392074150 // 2023-07-26T17:21:14.153Z多少时间前的时间轴一般为毫秒结尾那么3分钟前就可以这样找console.log('现在时间戳:'+new Date().getTime()); console.log('3分钟前时间戳:'+(new Date().getTime()-3*60*1000));//记住秒 * 1000（毫秒时间戳） // 这里+后面如果计算后需要使用()取值再返回给console.log ！括号来确保优先级 // 现在时间戳:1690393652833 // 3分钟前时间戳:1690393472836 更多教程Date()