// ==UserScript==
// @name 超星学习通小助手|多免费题库+AI答题|全自动挂机·章节测验·考试(免充值)
// @namespace cx-free-helper
// @version 1.0.0
// @description 装上点「激活挂机」就全自动跑完:视频、文档、阅读、章节测验、考试,防清进度,可最小化后台运行。①多个免费题库聚合(不挂科/万能/Muketool/lyck6/apibyte/icodef),并发查询+投票取多数;②AI兜底:题库没答案自动调AI,选择、判断、填空都能答,接口报错原文直接打在日志里,用不了能一眼看出原因;③题目解析修正:解决判断题/单选题被漏掉、题目数量对不上的问题;④提交判定修正:按真实答题比例计算,答完就会提交;提交函数取不到会自动兜底点按钮,不会假报成功;⑤多选题至少2项校验,避免只点一个也算过;⑥缓存按题目+题号区分,阅读/完型多小题不再串答案;⑦字体加密自动解密,题干自动过滤编辑器工具栏噪音;⑧完全免费,不接任何付费题库,不需要充值。
// @author C-Y-T-258
// @original-author unrival
// @original-script https://scriptcat.org/script-show-page/336
// @original-license 原脚本未声明许可证(默认保留所有权利)
// @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
// @require https://lib.baomitu.com/blueimp-md5/2.19.0/js/md5.min.js
// @resource ttf https://www.forestpolice.org/ttf/2.0/table.json
// @grant GM_getResourceText
// @connect www.forestpolice.org
// @grant unsafeWindow
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addValueChangeListener
// @grant GM_info
// @connect lyck6.cn
// @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
// @connect easylearn.baidu.com
// @connect api.muketool.com
// @connect cx.lyck6.cn
// @connect apione.apibyte.cn
// @connect tiku168.net
// @connect *
// @connect api.deepseek.com
// @license GPL-3.0-or-later
// @original-script https://greasyfork.org/zh-CN/scripts/453287
// @original-script https://scriptcat.org/zh-CN/script-show-page/379
// @original-author unrival
// @original-license GPL-3.0-or-later
//@ 如果脚本提示添加安全网址,请将脚本提示内容填写到下方区域,一行一个,如果不会,请加群询问
//@ 安全网址请填写在上方空白区域
// ==/UserScript==
(() => {
try {
window.addEventListener('error', function (e) {
console.error('[小助手] 未捕获错误:', e.message, '@' + e.lineno + ':' + e.colno);
});
window.addEventListener('unhandledrejection', function (e) {
console.error('[小助手] 未处理Promise:', e.reason && (e.reason.message || e.reason));
});
console.log('[小助手] 启动 version=' + (typeof GM_info !== 'undefined' && GM_info.script ? GM_info.script.version : '?'));
} catch (e) {}
var jumpType = 1, // 0:智能模式,1:遍历模式,2:不跳转,如果智能模式出现无限跳转/不跳转情况,请切换为遍历模式
disableMonitor = 0, // 0:无操作,1:解除多端学习监控,开启此功能后可以多端学习,不会被强制下线。
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'),//倍速
token = GM_getValue('tikutoken',"111"),//题库token
accuracy = GM_getValue('accuracy',60),//章节测试正确率百分比,在答题正确率在规定之上并且允许自动提交时才会提交答案
ctUrl = 'https://lyck6.cn/scriptService/api/autoFreeAnswer',
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(/(
]*)>)/);
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);
var tikutoken=GM_getValue("tikutoken")
if(tikutoken==null){
tikutoken=""
}
var aiUrl = GM_getValue('ai_url', 'https://api.deepseek.com/v1'),
aiKey = GM_getValue('ai_key', ''),
aiModel = GM_getValue('ai_model', 'deepseek-flash');
var srcBuguake = GM_getValue('src_buguake', 1),
srcWanneng = GM_getValue('src_wanneng', 1),
srcMuketool = GM_getValue('src_muketool', 1),
srcLyck6cx = GM_getValue('src_lyck6cx', 1),
srcApibyte = GM_getValue('src_apibyte', 1),
srcIcodef = GM_getValue('src_icodef', 0),
srcTiku168 = GM_getValue('src_tiku168', 0);
var base222 = '';
_d.getElementsByTagName("html")[0].innerHTML = `
学习通小助手
任务配置
高倍速是会清进度的,建议一倍速运行,除非是真的没时间了才调高倍数
视频倍速:
章节测试:
自动答题 |
自动提交 |
自动保存
章节测试正确率(百分比):
运行日志
[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('token').value="";
_d.getElementById('updateToken').onclick = function () {
var token = _d.getElementById('token').value;
if(token.length==16){
logs.addLog('题库 token 已更新为' +token, 'green');
GM_setValue('tikutoken', token);
}else{
logs.addLog('请检查题库 token', 'green');
}
}
_d.getElementById('updateTikuSrc').onclick = function () {
var boxes = _d.getElementsByClassName('tikuSrc');
var names = [];
for (var i = 0; i < boxes.length; i++) {
GM_setValue('src_' + boxes[i].value, boxes[i].checked ? 1 : 0);
if (boxes[i].checked) names.push(boxes[i].value);
}
logs.addLog('题库源已保存:' + (names.length ? names.join(' + ') : '未勾选任何题库'), 'green');
}
_d.getElementById('updateAiCfg').onclick = function () {
GM_setValue('ai_url', _d.getElementById('aiUrl').value.trim());
GM_setValue('ai_key', _d.getElementById('aiKey').value.trim());
GM_setValue('ai_model', _d.getElementById('aiModel').value.trim() || 'deepseek-flash');
logs.addLog('AI配置已保存', 'green');
}
_d.getElementById('accuracy').value=accuracy;
_d.getElementById('updateaccuracy').onclick = function () {
var uaccuracy = _d.getElementById('accuracy').value;
if (parseFloat(uaccuracy) == parseInt(uaccuracy)) {
uaccuracy = parseInt(uaccuracy);
} else {
uaccuracy = parseFloat(uaccuracy);
}
GM_setValue('accuracy', uaccuracy);
accuracy = uaccuracy;
if (uaccuracy >= 0 && uaccuracy<=100) {
logs.addLog('章节测试正确率已更新为'+uaccuracy+'%,将在3秒内生效', 'green');
} else {
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 () {
console.log(123)
logs.addLog('挂机激活成功,您现在可以最小化页面了', 'green');
_d.getElementById('backGround').setAttribute('class', 'btn btn-success');
_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
};
_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 % 30 == 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 += `
`
} catch (e) { }
}
}
loopjob();
} else if (_l.href.includes("mycourse/studentstudy")) {
var audiofile =
'data:audio/ogg;base64,T2dnUwACAAAAAAAAAABwRPFFAAAAAGFtEqwBHgF2b3JiaXMAAAAAAUAfAAAAAAAAUHgAAAAAAACZAU9nZ1MAAAAAAAAAAAAAcETxRQEAAAA7J4IBDP8F////////////tQN2b3JiaXMvAAAAWGlwaC5PcmcgbGliVm9yYmlzIEkgMjAxNDAxMjIgKFR1cnBha8OkcsOkamlpbikGAAAAJQAAAEVOQ09ERVI9U291bmQgU3R1ZGlvLCBsaWJWb3JiaXMgMS4zLjEbAAAAQUxCVU0gQVJUSVNUPUFkdmVudHVyZSBMYW5kFAAAAEFMQlVNPUFkdmVudHVyZSBMYW5kIQAAAEVOQ09ESU5HIEFQUExJQ0FUSU9OPVNvdW5kIFN0dWRpbxUAAABBUlRJU1Q9QWR2ZW50dXJlIExhbmQjAAAAVElUTEU9RW1wdHkgTG9vcCBGb3IgSlMgUGVyZm9ybWFuY2UBBXZvcmJpcxJCQ1YBAAABAAxSFCElGVNKYwiVUlIpBR1jUFtHHWPUOUYhZBBTiEkZpXtPKpVYSsgRUlgpRR1TTFNJlVKWKUUdYxRTSCFT1jFloXMUS4ZJCSVsTa50FkvomWOWMUYdY85aSp1j1jFFHWNSUkmhcxg6ZiVkFDpGxehifDA6laJCKL7H3lLpLYWKW4q91xpT6y2EGEtpwQhhc+211dxKasUYY4wxxsXiUyiC0JBVAAABAABABAFCQ1YBAAoAAMJQDEVRgNCQVQBABgCAABRFcRTHcRxHkiTLAkJDVgEAQAAAAgAAKI7hKJIjSZJkWZZlWZameZaouaov+64u667t6roOhIasBADIAAAYhiGH3knMkFOQSSYpVcw5CKH1DjnlFGTSUsaYYoxRzpBTDDEFMYbQKYUQ1E45pQwiCENInWTOIEs96OBi5zgQGrIiAIgCAACMQYwhxpBzDEoGIXKOScggRM45KZ2UTEoorbSWSQktldYi55yUTkompbQWUsuklNZCKwUAAAQ4AAAEWAiFhqwIAKIAABCDkFJIKcSUYk4xh5RSjinHkFLMOcWYcowx6CBUzDHIHIRIKcUYc0455iBkDCrmHIQMMgEAAAEOAAABFkKhISsCgDgBAIMkaZqlaaJoaZooeqaoqqIoqqrleabpmaaqeqKpqqaquq6pqq5seZ5peqaoqp4pqqqpqq5rqqrriqpqy6ar2rbpqrbsyrJuu7Ks256qyrapurJuqq5tu7Js664s27rkearqmabreqbpuqrr2rLqurLtmabriqor26bryrLryratyrKua6bpuqKr2q6purLtyq5tu7Ks+6br6rbqyrquyrLu27au+7KtC7vourauyq6uq7Ks67It67Zs20LJ81TVM03X9UzTdVXXtW3VdW1bM03XNV1XlkXVdWXVlXVddWVb90zTdU1XlWXTVWVZlWXddmVXl0XXtW1Vln1ddWVfl23d92VZ133TdXVblWXbV2VZ92Vd94VZt33dU1VbN11X103X1X1b131htm3fF11X11XZ1oVVlnXf1n1lmHWdMLqurqu27OuqLOu+ruvGMOu6MKy6bfyurQvDq+vGseu+rty+j2rbvvDqtjG8um4cu7Abv+37xrGpqm2brqvrpivrumzrvm/runGMrqvrqiz7uurKvm/ruvDrvi8Mo+vquirLurDasq/Lui4Mu64bw2rbwu7aunDMsi4Mt+8rx68LQ9W2heHVdaOr28ZvC8PSN3a+AACAAQcAgAATykChISsCgDgBAAYhCBVjECrGIIQQUgohpFQxBiFjDkrGHJQQSkkhlNIqxiBkjknIHJMQSmiplNBKKKWlUEpLoZTWUmotptRaDKG0FEpprZTSWmopttRSbBVjEDLnpGSOSSiltFZKaSlzTErGoKQOQiqlpNJKSa1lzknJoKPSOUippNJSSam1UEproZTWSkqxpdJKba3FGkppLaTSWkmptdRSba21WiPGIGSMQcmck1JKSamU0lrmnJQOOiqZg5JKKamVklKsmJPSQSglg4xKSaW1kkoroZTWSkqxhVJaa63VmFJLNZSSWkmpxVBKa621GlMrNYVQUgultBZKaa21VmtqLbZQQmuhpBZLKjG1FmNtrcUYSmmtpBJbKanFFluNrbVYU0s1lpJibK3V2EotOdZaa0ot1tJSjK21mFtMucVYaw0ltBZKaa2U0lpKrcXWWq2hlNZKKrGVklpsrdXYWow1lNJiKSm1kEpsrbVYW2w1ppZibLHVWFKLMcZYc0u11ZRai621WEsrNcYYa2415VIAAMCAAwBAgAlloNCQlQBAFAAAYAxjjEFoFHLMOSmNUs45JyVzDkIIKWXOQQghpc45CKW01DkHoZSUQikppRRbKCWl1losAACgwAEAIMAGTYnFAQoNWQkARAEAIMYoxRiExiClGIPQGKMUYxAqpRhzDkKlFGPOQcgYc85BKRljzkEnJYQQQimlhBBCKKWUAgAAChwAAAJs0JRYHKDQkBUBQBQAAGAMYgwxhiB0UjopEYRMSielkRJaCylllkqKJcbMWomtxNhICa2F1jJrJcbSYkatxFhiKgAA7MABAOzAQig0ZCUAkAcAQBijFGPOOWcQYsw5CCE0CDHmHIQQKsaccw5CCBVjzjkHIYTOOecghBBC55xzEEIIoYMQQgillNJBCCGEUkrpIIQQQimldBBCCKGUUgoAACpwAAAIsFFkc4KRoEJDVgIAeQAAgDFKOSclpUYpxiCkFFujFGMQUmqtYgxCSq3FWDEGIaXWYuwgpNRajLV2EFJqLcZaQ0qtxVhrziGl1mKsNdfUWoy15tx7ai3GWnPOuQAA3AUHALADG0U2JxgJKjRkJQCQBwBAIKQUY4w5h5RijDHnnENKMcaYc84pxhhzzjnnFGOMOeecc4wx55xzzjnGmHPOOeecc84556CDkDnnnHPQQeicc845CCF0zjnnHIQQCgAAKnAAAAiwUWRzgpGgQkNWAgDhAACAMZRSSimllFJKqKOUUkoppZRSAiGllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimVUkoppZRSSimllFJKKaUAIN8KBwD/BxtnWEk6KxwNLjRkJQAQDgAAGMMYhIw5JyWlhjEIpXROSkklNYxBKKVzElJKKYPQWmqlpNJSShmElGILIZWUWgqltFZrKam1lFIoKcUaS0qppdYy5ySkklpLrbaYOQelpNZaaq3FEEJKsbXWUmuxdVJSSa211lptLaSUWmstxtZibCWlllprqcXWWkyptRZbSy3G1mJLrcXYYosxxhoLAOBucACASLBxhpWks8LR4EJDVgIAIQEABDJKOeecgxBCCCFSijHnoIMQQgghREox5pyDEEIIIYSMMecghBBCCKGUkDHmHIQQQgghhFI65yCEUEoJpZRSSucchBBCCKWUUkoJIYQQQiillFJKKSGEEEoppZRSSiklhBBCKKWUUkoppYQQQiillFJKKaWUEEIopZRSSimllBJCCKGUUkoppZRSQgillFJKKaWUUkooIYRSSimllFJKCSWUUkoppZRSSikhlFJKKaWUUkoppQAAgAMHAIAAI+gko8oibDThwgMQAAAAAgACTACBAYKCUQgChBEIAAAAAAAIAPgAAEgKgIiIaOYMDhASFBYYGhweICIkAAAAAAAAAAAAAAAABE9nZ1MAAAAlAAAAAAAAcETxRQIAAADTrXQwJmt0bGlramxtbHNnb21tbXFzcGtpbmtwcW5zbnVvb2tsdHBta3BlZhbry4DtM3VQAWLUQPUmXo6f2t47/VrSXPrn8ma9e/AsTi3jqbB04Sw1zdUPa1fjBMs6ownQ4fOi7NHbj7EzW18kEcPik1/Hkf6eyyMbbw0MVludxzOcVjQa0tFB03Y3O32eBHsYvVfM2gBiF0vOUGLD1pagBBgAQIxhIGX9+b9y/2nv4/t7D9itr/186PC/E6ve0ZkxrzRb3FpXyv7J9NScZvTM1XbpHSd+Ju08SmIxLbasFJ1T6vnXiRtuqyhS3kmftQgl8tfnGzZLV/1YpYeM+Q6/cNjATi4Vt+3pAGIWvsZgLmYRoMQY9cQ8tT4w9Lvcr++VI4fNwX/fvj3rvN9EuAhnY/OP+CuO9jXMmpysCOMpwj1HBLeq35i+xyq60Nw7d6yBpaSaBDP3jOFoFN/x7/IEcapdaY2sww2nRCfm01ZD+6vEZZJ1DGIXPs6g29Iri4EYY162vvt+VKqlfzH11bP7Z33Xf6S89kRuzB/j5y/PkZOYo3S+5Jm4RvMrpEbbhLmhIaF9rVXiuUxUvHQLPVIveiyU24DGNLhIScNs9cUVfepmowzVOEnm0hDeXAdBN2IXvmTsDHEAxFgB2ooJm4floR8vJ57Y7P377PaW+GvEvSfzdnpqXFlZgjQkZUiMZPw9XnUTwquoN/oWnM29dRtD8cddNHbriDk06c9rSg4SbA2P0ctYSrAO6xeUKJTguQHVnOsW8IVKPT+hYhe+5rFe0VrKAn6M2vHJyT8nr+tDW/u+2cqlY/Lf01fq/85y7Ph7625oxu5CwuLr8dP8ROByyJ0ynbiFw360xxCM0smHfWxuwERtV8yvw+XlnjtWunqGpNh0CZd8NIE0aejlNXRk9+rTBl4XyamwBINdAqgAkWo/Lcfefr48/3H8eNduPV1ei3pQKaZwe+9mQkNnHFZ60vYOjdLfiku5C77tKvu/yWu5yLe206/LF54LvPrPlI8DEbZH5fIn6p72c5aGOumB6KazRYybsEeUAZp4GpTDDWIXvs6Yuh8xd0ACCCId96Oz1g8n5sPTPOOdzY90G8f7zNyaZ7wysba77LWDalPj0Q+3xCXGpZk3nr1GwYv8fbBzZSQfVff5/KvKVnfkizXG6Oj2tDhEbUmIexVn4W90k4QOoa7BA9SDETmTzxhiF77G0O3KBIgxyon3NVPff/3z6I/Dr+WZo+Sffmtr7bUnabprN7LWupJjOXyIqxfq2bzHeG/P+r21Lhk1zy1OGg5lEUne6kB92BzzjU/TTkYUkI9qBfop6DzmDd4UfCN/CGtO8bqvzHfi3Q5iFr7GMHJhIxdpbWNKIwHEmBirTWr/fv/4i8e7L3/dObaz+Soqwfx+/9FIvWbJicnORaLbmDyWxs3usrdwerPppjbD8MlYdOSrBJBnyG+Fv74wYPGhhxwpcpNHKqb6OmwuBIfBdT57kMINGfcpyHHhbX4KYhi+xrDd8DwPiH5MZpnvxLNDH68+7zP7j7m1Pqo1ee3Q49p8G4lVLbL5l+hK7FMPiSPL6OYwyymXkTftNF7HYlctgdsZ90F2oebPv3PJtfue942usdsE4bzeYH5hPY7WFKt8pgm7FmIXvs4gvroAEBOAel4+hCvf3/pnmcprH66dXb69vr3PjGufU9ee9FbnoBPeTYxk2siW9VPD4gf+wje4XE/VTUIgSGZOphQvYco4Mf/qcy0nHRdJ9wFSKmlsyt+tbbm0YHPO7ed5ifVhveYQm+4RTGIXvsbQB/xgtqZAjL7WhCZnHTqetn+/iZ+v21Xn/6+OW8OPkHg8fsz7dyX3h5yecQLrdpnos0RnoO89KZm/5T5CeSFao4DEhQfp+S1IdED7bPGmvL8Kbsz7wLXXx/pGHaahaxB/ya/X4jNG9gZmF0vt4Yu83igoAPwEMLFq9XQzGr3W7tFbd188TU0d5a0frZ0/M3X60sbP0TsneFsLy5OJ5ErSdOP3I20lZaasMvMl6d1Pt9FmExGTftf4zEnKoci+zzKityAgwEqmCfiVnHxoOtR1EDzKKdghXhc+ZNh4tU0AYgwW07i0dfPjQ0f+7W/X2Tnd+sBk7w6vHNo5bjHHnXUzL+yWtR/NTXmaZ0za0uNpVrVctp78reWr55Z8sfl8fXjlxnQk/a6FCCRe5aG0ejw5PqYw5ioa1vapzdtH2f04mWufu2IWvsagDxxYy0GgAsToo/WL882ntybTfjF74unM1bYH/ybTh6+GJV1cpSSHiTPLOnVoddbsfGA5iXv9sMHtqnswpu+iG3cEbKTUdfE061k1Rl8EBHEjLT287bR5LAqC//MULwTHvZxUxjJp88zWZYciYha+zmCuWpu9gxgTQDiJkz9sEqe3jtx5krA5/v+TdHd7X85+kLN7k9bJ5WVf642s9rqy6jS0vPX/O+q35dI7HPK9oVaWzId535hFksfK1DMS5dEh+6z6VKkrxF3+ylydtOjP7jt/e9Nw/Tm7Q83EKE/yAF4WPmTY/NmmPDAAgBgZL+HfX38fsrexy++SL2++llkbxs8yXvdxzz0NQ9jUPb16cfGumzvRknbtYtQjfZJfSqwcTK3dvHiSXwtnv6RTHo2zkKaMGQIMYy3peexdJ/rrkfHZIuO599bwVVbWqYYrYwliFr7OoG10t7QBMUbFw8TpA1Pre2baL5/PePvi6egSnTzrdd1oYWXdfA6BWUiIx3Ui2SOrhC/u96m/xtR5sxXiLuOwBkZgtuBljCKqwFLdqbC5iHL2dF4p6fRlCylFo0rhMTAok2kQ/LAFAWIYvmQwF010EBsgpsad/b4bU7Pf1Yfr/Xa+GG7XWqLse7eepFy273Y2Yl5qu5Ln3tVhL5lbmxjJrJ9f1sNwRveWDM/vy7Q6FbMukSjmD33JHjlvV9fs36BrTpQeyeKp5mNxSogzLV6nCGIXvs6Qi7T0tEdMAHG+YmLn/INc+v+h3f+6sqmTNn9WB28J24/T06tR2sS69cxwM5gJ1UTu/Ai8sLy/soMv6xHdOMPmP8NwM3Lu80xRO8X1nNXoxmG7f7TnYsTG1hLfPXtbriyW07e6wsace9pnYhe+zpzt2bQSwMUYrcKfil90LneuPHjsZkuaL+P4uq584t7pMO2PV1885W+NUchIEj3654qU0M92w3adIFzXHs2OxEmvoPDKARXcs8ZYMaQ9zFb3LOk0o0FwIeuMHzZYHtI9ZGhJS7JU6KRiF0vGoBffEUgA0Td8S7R8mezr+cVb4lbv5/vxaPtyb74trRzMU0+6F8s5e/29d5QMNoPbdPIyEgOReDj8jLDw8jzU0vv6/k9aJTLKj9odBdavRh3L86Pq3m2TOhkVh4jIhH4TLn39ctoU/08W6QYJYhdLzrDqoyyl6wUVIMagCXNn9er2D7t9j9hVpUWGXa+JrX8f2Kje6R1jojVJnGifyV+bj0npjj/ZO98EWoh7bKLswwfm3lJ2R3w73LHZ9Kqx3qZsn/bTQCI9b937t59x0kHCnKGXwsEQDY9IQGBZXApiF77OkAZuPG6ABBDjYshIX32ml18cSX///cvHO+fd16ZYSzz4JNH30vjK6XROfmgdE/ekGM1U2e8CtWzG8LNTdtQOXnQsw9/BHNsm/YvNe7heFyhILNy28v6Mrpy+MDJFk3pEua1ZJQ/09HpVCWIXS2SIkT9OgASEGGNMdlRtj7227Vi/i35pnp9/T1hPuC0HNqmrOJW8fMhyZl4ZJ3bUMqXpO2Pr/Vn8Moans/2xvVsmi9HF66OxZfl4eNTSYQ/m3+0LeSen6QjRplcJe96c+bCgazQz9lfYUEk6xq43j2ZeF+k9GlVGcIQKENUiqTYPvP5xM13K/OJX99bkZp/68tC4+9vWeujzdcvksKJ6op7e4uwfA525rJWXqx+Gbl59twPfke7nPYuLIdJSL5cHFou8hbxHC8KIwb7WGizRZNSnlTe40pFFa/o7DlchHmIXS0bFVwesjAYAKkDUlcejqT2Hrk18fTLr9Uuzamy99bZ1uH/UVjSRhtibu+21YLds6Yh+01l7MddlWXaMVM6e7f1ek2/i++9eMx3vj+/XHXswvGh8BaRH5p6dernxNr/HVHkoHyD648Opbr/aHxvizuSOAGIWvu6hr1IuaP+oAH7siPlh8ixN/4e+j215uD2mvO838fj16cnH6QfXV/abfffCXlt217th7Cc9eZ0fs4ksfmc7Oksnn3xdI0gFB0DFUcOzs/WzWUrBler2Top6FSwso5LFIbgTmX6Kkj1aZ+EOY2JWXIZh4002su/QeRUgRk3K/CY8uDd/6ElK/+OWyY32eHX6Rxr7XU0zle5d3E0zS05iwpoyrAhDvkjGcrnkcH4dpI6IKRPDt1L9DeLtRigRfjxx2AuDCQ4hnDVMOhfEmNXo7co2p3R1mQ2GXMaLDmIXvmRYumh6HYgxitTp6dpD/zz5Noa0R5M3r22daZ3zdHfp7X7qSXQVkJroprmsVcYp63GYVC4gGcXtY3hMkdt04/vhOfmiYycT6S84gQ+fXIbqv21+tNqrMpBsuakRd3kHwXOPTCaROGgGYldcjmG1AZEakwRQAaJ3KtF3Zsf+x7Kx/G+f2q+T7Xre//sp/G7T/R5TjHbeHfr2MZ4bZPPCCj/zmjkP1aq/jBjMsTmb4DbKj779hakKmSqWC2gpyoXi1eLsZD42o23vTstInaZWnekYvHADYhZLxnC9G0gHCSABVABhxvzn3Hwm9hObD1mM9BdHDk1fuXtzZWjtaUifrLI7ulkcrPoMi7EkwjDhdtPNttjrWG3WUiTxRZGcsI1JUkWi5ChCwmF/wqdeMo5lni5XmTU+/fjHT7GC8I72AA2Cj33dSafDvAFiF77OIDa1so0DUAEqQFxM4/bZVau5/Xz69uPbZYvtV2dNnv9JHLmb6LFunJi9Q+q4r9TpDywug2FQdhon1obW6dSy5roF6VjAMn51H/fDzOFkVIPqI+GHUXbYVF5LI2Mfx5STjc5qJIGGzrNnC0cOYhe+zrDBb04REywBALECDITunL//bdv6z6eTYB1tvdtr9puyVr680TehpqTb6Y6bivRPmaIk0dX9kdGTQ+KXK93TlVc2wMeyZy+QiLXflyi7Genmb4ltc5cjn/ztvAk7ezkHC56Ps67mIXZQZ2IXvs6gGUUrQIwxj3w+s//Vex/Yavfysc/9z93uV90nt83+4uP5xN4E3bA9fl2mi5OW0pGKtJyvUUzgp5Ry3SetNTyG91kl1Knli15bRHvk9+Ha/CaDKmcbvw410H5ZRq59wjbR3B4UKFojYhdLxlCuhw5PBYgx1N4TWV26n3b61g/77sbyz8zbp/+Wmbp3J7xl4SYYJyluGn2OvIXLuSWfkVSY2ZGQs7pfmD2mSU3yi2X09NOesxKGeh6i8niN1oMwcBd989JdBpofHyhYU4lggQcVyzvwaj+Xc2IXvu6x8fc+sOsTRD9mHzoz94ZbtUyv+m0X5GTtpF3b1tZazQhfSlP/+KS+hgxEk7CGrbkhqeW0F2RFz5p53OyxyOkyqB2tHpn9FV5Js7puV1NIMV3HWYDuXXYW1I2b5gAnWowBT2dnUwAAAEsAAAAAAABwRPFFAwAAAKvJe/AmamtuZ3lvb2lxbGt0cHZscXFsbW1rb2pqamxvamtqampvaG9ra2tiF77G4NfYCqgAUZ2Iz/LTg/TnV4bXXsw/LemNWT++vNi5Tdpu6c7Jas2Suv7zJCl9POMyHvddZRCZb+TnI5lHZDlcNjvnz9IpQ53vl/aGXP35sFMmqYYsv+slcJroYUdxnp5OcUcSP4lzYhi+znAXclFuEUQ/js14yTKR7mLcSdv/lbeHdk5P+5l3X037ou9T46StYd3oeMzdw3gYJY8UBJ6W4+EG7ZF54jBdnTioi4TjrFHMtO1lt7kr9NOv3WWOLmTR7guDlti1emYXJZ0aaPZDbwJiF77G0NrAgX8NiDHGcHLmVz9bvr7zo+8D3Xfvw49P03H64GRbsk3YysSvON6coHEN7U9xH7GHTpa0YPp8PMzbRD8Wlfj1o+nBe0XekLi2b/e0+ttMOj6CkjGPB0OKepoj9a67yK+XHEpLPAR5jmIXvsawmFCgEWMUdsdT+eed9aejv/eTCel+OTnx7GA8+ds4lNgbPOn50tAPyO8zpDnT5Y+JXyQ9H0l1SyUWdYkcHo73XcIp7RSMTTkgXmD+vKPqg3LaFjVUftV5cllGASshRns8yABiF0vuYWO33ABFwAAQUAESgK/3HT+/8/DOrW23/3m73DPzueVXn3nr3T3TK7vTVw/p7RByb/qlO6jFXnInaSx3+06utkvq+IiYoh3xRJmrYVI2lqQm2jsdZ5Hh/Vm3W8GEGg3r++JBbyK9QT5EGkI7didS8APEh+kYYhe+xrDbZNEwmRATQOzIgXdu+ny57cuP5//2Hx/X6Z7+Npayi7c3up3RqaRd1id+djvGnrRIZy9EnmQbt3H1j2NHBDGFEmopRJhwqXV40H51zzoWlzdryBNvuVC5qZAPcDRcBziO5D2mYw64rNqDYhe+zvgy60tkAJAAonpcWHvf/Vg/7fdp9/r27iu2v7qv3j2rlIuZ+nN3Mg6r2H9NfRVDZzSMdZXoUexVdDY9hL4JPN2X1afhm66Dvswywm6eJOuSuyfo3JN49BE9DRslZx85fYs0PKotUqfnmXoJYlZcjqFrkzwQYzR3ws7q6Medflt7rdLbuz6zf09n88nm/cevLpLx4CQp65fS1G4Zet92Yf5558AHzNpAo+36crks2Scs1EgIXDpKXA2P1vYDEhJyZ5jBQmnPmf1yHfA7CU003TifT1gZYhdLxnBy2Y2PhJgAYjdlSR2++L39463dgytn5mgyx27+99B7UoPR/dg9Tcrl1Uk3Tk42+bH4eveVbv8UibI+fZiwxo5F4WanuFbOmcVIt0NPEuEc8JokPWOl8zLZlnVOF61L4Zj3qdalSK81zXHaUg5iF77GsI/RMwBijE2f+fu4Xk9SD11Jc3f2pv3Ox4286oT3X5ujWflHjyA6eQ4izSDfA7+xT09JGF/LeXqn7vOzRYv4kxP0PTuNUmY9R5iTBNXh1jv4zNvMrgGhfMJ8562zFOOeY+jzDZJ4qTtiF77GMG8GGogxeuBde2Djocmn7enf5zeX097q/tm91GNM98bxV3Wy9nIn5NenDq302vUpzN5x53r1Npe8YSPXb1NfJeL6FPzVvBlPm0xfnXrScYGuroctyfFaMDwd0WV2nSVTRKsLchr9BGIXS8acGcaLdkAFKDogVsvPsFz6k/ZLm6vy0JVfp+ntn4xGT64mbG7Jy+m4vxMTY90w17i82Xk63pZj/7A68d44TyQlYa6yehxzUWw7z6JfN8mXxrOb/WYU3D7zv8BPUYDOezpIZnuPWcFMnWX2ndC/rqgFYhe+ZLih6h1AjHFCc8ql9Qd+fXp1xlcbVz/uWrZ3z/an0rWLH7NO/+ZJPY83o41XpvtYQIxJ6cRqQku/iNPNSdFzbnLC8IyoytW2hpnStUrqlWdeBGOde4tvJOHMexNWd3A25VNvcl7DZQyn1HWbCGIXS8Z4m/TN3IMBoMMAAOJkMU/eH/Twp87lV+++/7j18ysvEgePqTMSy3k2OmIc3qt2YdczHg0Tae7PLec19u4q9t9u6e7axFH7udbGyRp0t7cFtOudtbtmGTZJ0Q52LDWMHK7Baero1deDCserZEVPjcyGbhFiV1zEsO71nU1SFsQY17zmg2nzJz/c54jt3fGMT7vn+8axa2fP5HLNfFyfH7lHyZbET18sdmLC6QS1yYWdsGdUK32JJg1Cr0ZRGAm1xHNbIZm7qdvayVVw58du19x7MCkabjWN7hAX+fORvDRiF77OOKMvujWwMTFGzd8bR34l1tNYUi4fOZh19YGV5djDB9OB5Os3QVdpfm1rQNgONLxOz++9jvK1LW9a1thCjORyi6ukDzzFyOeH6L1LDVHTAhW8deDZI+1z5innRwakHMmsG5zH+5xnPJxaaFi2AmIXS8bog/3KAySACo7olTfmaX993b1t+vOP/x7Znzz88NGTzYdbPekJq5Vc2E6enHsi/QlxWE+ed89ezk+vJ9xGO4mnCc0cxT3P4ZFfHePZRd3yaasEQRb2zKkk0V90O6VaqjRJaPUExNdBjHqAYAUfYhY+xpiZZ7g3SiHGKLWSuy/ma+neH3qe9dPn04ffbNN2Z77+ffNs6RkfOB24HzSxsHhzyBSusXATd2PhMHehZYuf16AJvmMsawu95ijusWbuWVIVWIdim43hmKqHjGR4QgSpgMUp3oMm3BcAYhe+zbBIm7cUhSbGOK5VPd/y+ovP+4dHV68MP62bae5Z+v9qdbRz88W9Q+bGtAFHWnM/wPMTZUMg+ljKU5xE57MjSukp/NMDE+egMXlHKpZkOGAFj65VXhofqvp+tUUbP9yUyGl4CPe9/xsRAV4XPmSY80vBFkg6ECN+6fatj+ktf2Y9pt3qf2dSU+mN+bvbh/bGL9udFH3i5sN6MTA+fdZpZ2HTe/tZ94dzh6KzoNsxsZBCNBHx7DjXRLSWy+ECAYirTFOWNLV54GWoGA5lg/w+rTNeyFn0sAJiVlyGYUSpb2l7CWKMmqiwny695TFNytNb9zlvD13at0tY0490df7KJU6C1QkdIvHfJQWXeZHGIhmzx57cy30S+9BnY3EeYgBoxbAxpPMhMKy+cbXEviOKpeNlMlbMj+ZbOFovrMRmvnoDO2IWvs6YlD6bA3EAcIi+xJRblvT/X/v7J7HX+/CxL3bsZvz4vX66aRz+cWvMfg+/fEgYvkPsdHo7lfc6WknPy89mpuSs/WhRQUdfLus06wVhIbRACIyOkzzlfjYfyDVdRx6MfPmgj/qGEsJWjglhEGIXvsZg841MgBjjziTt4NH2yZ/5/Uv95j02lz/tXtOJLYlJRs+f7KQanovsvAXCFHI4SNgJueCncec5JnGBKCcfXjDXyN+N4uiw5eSOOSOvYH+x83VhwUXAgRhSZuHzjkfmNkkzTBJJ8AFeF8kZbGmVsQ7EGGswTn+f2NofOv7h5/MrZzbbj6U9fjBx8zxbNruXUUuHm0vpZbJ4zdlxkAT38oMu7Fp2dd4p7jUkVEmYeRGp1g4hIerlGstp6EHmg7VPvV1teS7ZpAKWnj74bNDg4GMCYhe+xmBdMyLxiDFSfUajPCP+91ry+/lkql1i65NDT85S+977lLpYy1ZGLpVitvJL6DmqhD/xS7HkNyxRzRXjyxdyyDVsbHHUY+Gnz3KJtEdT2tNyrJ+T4Ps5cXhVdApLd7Z1gB7Mk4hwUmIXvsZgvPEiCRD92IzJ8PRO3uWf3189/OTHkXTpXkn75OrrvY+nyX1NWHrWoxuO58w7oqzEt/BCwi+PYcJsnR/PRbp4hnkk8XT+ioYnFakgadInUbSHWfgdM6dzf3LOh+gSNgSHeAmYj3mNJ2IXvsYwWJ2lDjAAgAoQfZ711sGPq6sPE9XyQ1/+fhuunc5lQi2LHJbb9KTD9OnVfmy7mcTtvJ0wJEgx5XAuc9R798y3hTpt+UwqdkRDho510cr+h8Z52zI+b3Y3TgeohAPamrIoSvB1P4gH/yUtAmIXvs4wOPKIMwwx8H25aKdLrYcH0rz8/26aL7bPvPrr0Omo/+atkyF+d/tUD266biQki1epc7WKYXvBgIuxyKI+k7397btaypHbb7uJ2MKor5TDuS3Wq5Lz3kpdWZOsZcWJ3M2oQ1hy521iF77OeFVaAcQYJ4fUxPqX4QS73w9ce3zLP7+w9J/x4OedS89Sx+tGTxxLEixx6oelc/4g2SNaEstlSf+ugrnZXxftuhRXf6lkVw8mYHP7TnCPotNdZJCS9+XLxDJ7g26O4Q+0i6SqkrwNn2YYy+1hk5TeDRbEGKOzpLaHvurX9+B9Hb50cOnelV/Hfv68/my0Nopd41TGKHuNCRkK3iT/pY+LS2+Lnm8r82YIgP1TgCaJXNAl1BkhmTa6D4dKP5xBu5np3pybllg9O/CmufrkLEXs3BdiV1yGB4m31UjQYoxxtu0/T8o95dWf59hwdO1wytTzvDqbOW7f2y/tf5yfN2nmn7kgwdxSq/dvz7kOzzgewJ624Kw3+jvE/UONYW3Ba3PY5CutzqId+pISk8gdNkW+ud03M9umZRexupsdYhi+xmCb+gNEdRwR9NZjIrn0Wh7bv58e3JsRQrh8/qt7cWkYP0n3pN6pGIOb8qLjJn4qhB39Poz+o07aGv2U9v/xx0ws2mP+Qf7zVwTVyuPk00q7FjlxyiM99ieW8jLDWq8CrboBhFVvAGKXOTUM7wjAeABQAaIoukp7JfX2Zp+/z+8cfXH00lSOo94ncTVhdNZXG4v26OoOe3VLRxfBmjww4yBy99207ExIHKrX5bc4cnAz6l5OeTY2u94UNCUxCo5iT+tm4GBeT+EGSkgdzhDN8SpKlx5XAWJX3Iahsll0k+SrCaijrhlB7vw71Xcirbl5/KftWtvduDKxk/JtNQ9tNMuhiuNZ4nLUIJ2A1tlIoleXj02lu4uGnQnPnq+VS9b8Y4PV2+TKI4Ua57IFr3nkBeu1Olc4aHGXquStAy0AYhe+xvgBUW0dARUgxjZ3WW6nT58PpbMcbYfTDrd2n3SCdS0xaU6eue3uxW7rkf6rRbZ0h9CTWvXlTOZIrv691k9p2nVzC0fnQ7hLgilKNSi4XfBjuyb5gcyLt/OQtrpVEFkaRaLnsfJm+7OJ4w9IXhc+xphmbrjwlkrEGKlxrM3RrRd/7l669c+DnT/j6amPaxcpsxiGdppM+jEP08dLvBKNay0VrzVE0PEXLO8M64G73rVfsD1CUBTemmIbxgyGSn3K5nX8N0PmTJwORTsZYxileTYxBD0eu/piFr7GcJ+m1CHGmOPq1o/uL0ueva07mfohGs+v/Fkqpl2bMTG+PXlyaR1OVQ4vcveT1XXGKQl0GHGe+8xDOPNb59mSjBAu5TIfQ46/sYbWg4sNAyuxt6/bwwumjgP1K944XIU7Zq+wtxTSTWIXvsZQLjYwv4AYY6IN2T58H7XrSe3//Z/eTG5b23m6Y00c7eF4zDardWAbvINwuqDjUMNlJWcfkzCNi6c4Ct7LfKBf5U2k58tM2ffrMGAQxe+mDKMwBg2Doe8fjiHuPgaE8PaVQ7A8V0w+T2dnUwAAAHEAAAAAAABwRPFFBAAAAHza/+smcG5tbmlqa3JtbGtza3BxbnBubG9ub25saHBsbG14b25xbnBsamtiF77OsNyGdAkkgJgAoiQOW2d8ejnjhbH/4M7rXF7ueDh57ddor6rWJtYOlhNLJWf0M4wwaqlz3jSupNO1bliNtr+23uinBZVJmIthKOweF7mp37d9chq5EgMt9whLYYsNotue+rnUi98fTw0PTeoIXhc+ZPSN8MUXQAWIEdp1y9cfr6y/70nG/MCt07m27UdGhIk7l6vdWqP0JAzLvzuLYaznpA6C9uFt/70N0RiQWaETUxI55b4IeIbLii3tfLzK/E0ix1NoO3kPyaq7SUtElLFzkujlHvPHp7cPIQNiVlyOwYg7zaKgAsQE0Drt6f3H8fTkLcvb6Mw23dHerx62/BPXX4t7j0/jTetJzV88EfHTzMJc11fNmEdlY/eH0cwm9QZqdvdqeRp6kdi4URcdTSzxUSIa14PZrPZ1PrXbUBFhZk5JDEchU5IJYha+xqAvFS1LQIzRT9uL8XzNOPx9+/vw/d5Pk08eWL3U/t18s7aTmrTrmO/zqYS2fvvb+qRh6jhuysnka1AySCr/61H/SlzQyTFdBn/QWKy8kYTXJQrv+PhMtordr5exmILUY2QOq/G12Ga5+yNiGL5k6DdzMUxUgOjX+tO4XNq8nManZ8xK/+vpfynnPWdtfCjx0P027KoeeOpmGebcwD7mMrsCRp0E4SKGJoH24ASz6YsLtudqRhv88co4PI0eSVSFA++RF8wtYp0qKXbAj3F56gt2+6NiF77OcNlHMfwCYoyJlkjb6fLvQxMPXX51QxM36+3jMfYyKbaPac1k8s2tSc/Foauf/BUtUu/x9JSnp5iY+p7qp5uuzu0YBAt1D3JCLIkae5OFe0t5FV1OLofNDYtn6p66fZaexTU927IcYha+ZDgtAMQ4AIC2PDv8lkzy4HgGR19JF9P98L7Jl6eG9FltHWzV93LTMPW2+Fq1rE+1pFMaIPzc8zYMHYk3kxbX78nJOi9Mw25C2Xd6sJlo2Q5T1zCGKhed7/YNj6ez3Pj3OpNRi+ZCqQNiF77NuMVUBl4LEAcAECvks9s/H/812sw4M+2s59bnR7Z2fZn1+cqlQ518M2mIaRIWNxKx38pIxHQXmroTg4zGerqaYuq8u20e0f2HpAPctg4XfSO7o+ZkwHfe5s/T3XdeMvYS+JFEg7gOonq8jtgjcQFiF77OYPCXOOiBGGNXY3vfObjU+/D68fvL7+2J37Vz78jFp9GTk2W+c2ssHAZv1zs4R6YTL4y32Zd58OZMjQ6HX1IkXNh2iBm/OVX1uOTiN3073soFmILnvJnWdR38OVznaFdkDUYShOdXMh0DYhe+xnA/NrgGxBiznm1K3/0/3Yntd+TxRe+WazOX97WYdwy7w2K1JGoAFeTTQXIT9VKm1AtHsp/ja6rLuCEAGVtcf10X81XcqUYv7VJnajd5xXsKsQ7FelRcXgDEcSrhGafEq8Rj09rnUWgJYha+9KAbTXQg+jFVc7hZZj09/PC2F0/7Xfni4SNT9hpmdi4N3YPko93m7JVCysxgerQDdDk85+J4HUfulufGvkQzdlAndHlrBWY4i7r2gG+eTxCejP8r0OpegxKFOtjMK4XVY9DlsJU89AFiF0vGUIkom4QJEkCMHsydy2f/dw/ufz585e62vZnJWw+dpjtJpLlVyUnr2Y4vJ12eTMntzV7jw/SGjnZ8v4gg2xvxlAT9OQ8z99z0oLmcmz8LFlbhSf6xh0OH60yuwk6hjS1FH+qKwRWWgmROeDML6eIAYhe+ZLB4SCYgxhh0YrrPh6MX8vz71a1na8+MWXY+f7pVU167/GOne2ChAw+MWSzgLtAtJF04XfK+stBjuN8HDqsLU7mid95k58NYFnAZqcGZXXNWxpuGS+30yVKF8B41nn/6dLTlbCY8EARiGEvGnL92VoAKUAGixPodujXr6dToasfu6st3f7fp7/HO9xNOj9X6eTPmfbYc+mnMV0NnLCFVPJ1PPlkx9A7T+cQcG8dX+bFRXNo256U+alBRi/Ci9bCnQN60pFHS7oQQP1QkqbaBXeQfUrly5IcAYhdLxnC/2prOYTABEKMl+6FsyPVrkx+v9zzc7++55fr0wWvSnXyicduk7XJyVonshrH0G9M9K2E0t+kNyW1PzBP7Qz2yJ2PD6ndVg/eYQDJ+icNhDFj2uYT0uHrmBGaPLdz9Z92PyRcIWJipP3axHwFeFz5kWG+yid4AFSDGodptc9Wu3F6OHOo+nzH71tAv75+nf26q/J6YSjlpu7oZJtusRfK8p910iQa+Kh+MucYtNFOfbJ4zkC0EZ/dNkr34RoMLFxViN6J/HtSlc75007iFcK4fVuvnwzawOtqNAV4XvmSIzaX4BCpAjCQDlk6sZ7Ybs/8kv+j+935G/6th0jzr3z0JfUMi7k729Mj57qe1VdNR2Hq3/5IEvZWDolQyzWOal6TfTjGGoUq2x14zcodRZjrB4/nG4hGHXnBb/YUNmZd2vQNCTrvnej/hDyJiF77G8EPkrEEgxgowWWtpNs737x+ftrHvs+1r0+aB72vXpma+Hf+bk7ujeatdM3GyzM1lpL8HCY6nboF+myjDGwppOv+ZkxM/KXIbyG3JzkEypsoYM0ODWdCNJilBwHJ7RxDV27eDo+2hY7QKBWIXvsawSLoZjUSMFUCccCjN4ZNn/60+Xvp9v4+9vfVpbOODdE8+7iaMu+EqyljD3IgfYihvghBQ1s+BdRJi6m4WkAvjIKjUOpcdRXLFuhPzXJ14tDakHTscls4ibKl82CYn+N60+k0qiKNnF2IWvsYwtUWahpIqQIxzHYU05w9tW3a/sj1UszZ/d3cmDZc929MnaY5Ze9rBk8Np9/jlNSFISAxyx6fBnaOlCaNkn2h5b7mUC/XoMLVTIiWqMAVhM1gkEm0Vd9PfqzB7rCkNVeXiIIRhdRhwuyjaDmIYS86waNvIGANFjOphCInLOuvxhfzfPXzkvGevPo/reMrmPCUl5XuwbNHF12tVLM678mhJW3h7KuSMJxe/4MjoKe76aH5P+2jdcnt+P+BIHIyFPinq2cy33F68qr3a+h1sYuueYzSFh6QoqkABYha+xmit36DXTFSAGIPPzc/r97aurk+ePZv92355myfftgf7p50kqXkymZiwOdR/opOc75Wsx2XyIYx6ffpuFDPf0YSKLJD7AFgKAfqsomsdSqBhOPK4ZYmb/8YSXzCHfVtE5YeBNLXnTB+HTQokYhe+ZOjyo9OhAsQowdj9c+zh2Vcv/rFcfnj21onpH/0mpz7NtrHr7jxedPCDyDDuEeX9jjlamrfclnoT2dE8MH/qvpPo9gbf+OlantMK4YlGRq4QjgfrzKfORun1aa8ooJ5uYeQtw2HbM72jPg9iF77GMN6WeuqZoALE2NZiTr38d0a/qS82bwWJl+3tmt38z+7nO6O2ccI4N9+jtk+tk/XEF+N03HN2M5kKFX2og6NNv5W7hJ82kgc3+Hlo0rNLVOQxkxSD+9qHcvNDnIgg6HrGcsfM/y2mqRliGL7GsC2br9EOxBgxR2nofy2lfZi//vDl/v3eWd5F888QXlpn+9HbKZqPgoRfduo8+OqIVVhTWyo6/iJiwP7T/zeSYNLU3ZpoiG0UctTq25aWaYeMz16WjFmtC3C7lOavVoQ5+nCKAl4X6RmN0Sz6QI8VoAIgB+2DpR2ekX62jT7t81h32vb5kfnLYbtpjm2tadu4ur0+e6KG796NkU72xjaBuNF+VKnZTgCWbOKUsmfnt3Upylqjt+SnEOlGlLIuFC9SerMQwzLKbefXeB4T8walOI/crABiF77G0IaXUI3OJMZYZ8llmO+8vOhs/OzD13bt5cV/j6+bufflTrq9cSYM9n4VYlF4saMcgrAagv7eAaZh02FqzxdXObCNEbaswwBe7q2RMFHM94onIRhCnMjCr6Pols7k2LbLnvMtOvCHxAhiF77OMM2hmUCMUdRvm/o7pTf5Kc2n2Wu7156/XYuj5fTB3lWn51DQh+ca+vKWfJZEzhnCwJdgLg+xnCQ9ji6g4rzkGruUcPbl0zep7NCPr4EQjt6lU7iKubx3T4NyuZFT3QiVvBj+OudVvgReFz5kaMv1KwAVIEaMVt3VF6lfz9ePX5l8vBqPSs/fq1F3dubzmaP71sl4qhPd3W/rraSuxBCtXFdfCIUtvG7OvVFBpGfhMruM+Xn+4KC8Ixl8rnuPJfApfMyI+f5E8TrsnMSt7ARx5YU0Mac3YhdLxpBt0SUtbnEECWAAAHFlfO9Yh5SvfNZ/T79a/W2fT/qeTp30Tdr07Tvl5k0eTnf9/iqvxeQikt+edI7qEO7WaOhps1baNwTZTww/pPOkG2Q9adV7gVCrSqL13Sd+vNxUh7MwY3FOApT9gLTXkMiwTh04+C0BXhc+ZFicy0vGoiDG6CUnE8m/9tsufTmj/dqY8dXh49tfezGZfHou/XtHN5cOvn7l2cLfvWJvznq2naD0Byy0OG0kz47uhgmBHSwsiE5TBnny2cgpSQs670BCqn+vfFhgaz54KrLyGZNzA7Zy8cIKYldchsESMKubmBD9WKtFrBMf548v+v8zmW5v7RXjmqlGyrbE3mFz8iY5/rQtFqI19Nf4QWWK2LYo1S3/xh3DGeqU7gpeBE3Bm2quOWvd77KZEhBd5D2+dcKBcSvulXrgnQUxsD4FRAwTQ2FyVCtiF77GICtLK8FDBbQKUAFGYUif4rbjtdT8/Pb58/B2s9/0vt0Da0v/k7XE7bPpIXHSKYlhuLkk+bPnYVCfXuvttho32tuQtF+LMukdaWYygB/YVKZ0CixFNNGLmyc94TpPzoYOriZ14yDtTJlFntiVA2IXS8YwtdK6GAGxUkDU0Gm9faeXqbtTnUvtU+rmg9OXb0frlcs3j0Z5jK+uluTvTFu3XLgQbbyFMEj+JyE+zv0eLgENJS9FzZluDxhwv6aYk/4U72PKTpDD459uRLx32ISYKASV1DolZVFOpQMTYhe+ZNyZAAwAIMamt3YmfsY2Y8I+P36/dvng88/ux56bns7bYR/PnwY9WFzir1E2lhRLiPObFG/71rNoMRLy9q7Ty/caZ/20bw9NhB2JIj8Tl6RHiXz2DsJ6HY8k6RXVKFAe21mv4tPGeSg67JH0M2IXvs6YG7RKWRWbgBhjOROk+Xm+P+PnxPUtfX/nlAdvbHb7PBsm36ecdJ7Nl3ToKV2KdOnrFOU1quvRFSos9wnN3nFOQA/ncW/xzDQ9vBw59ParWKW6uQd2FUUeyEaBbJRItcawRsLc92Y5MmIWvuahbXKm2UCMau+MljRpvri0tn/r9S/f6TG/Uv+8t+iBbjW2q3XifJe+J7zRGDTdHW4pTbyRT7uLpL1KwzJPXAhri/wpirS1nTANjkL2zo5aO4WVST6dvw1GkT/dFfkmIB37F4h6pgRiF77G0PZ2OBBjrLm+NI2Zp/8eeW53/esHDyf6dJ8u/3TFbs/opyeWZTi85vb6XsdBBgfPPNs5a7v1NdAqZ+R2FehymkM9m+atn2kz3xsOwxZmdHGVEBzE5if5uu4D2M67mGykwklRvOUbBk9nZ1MAAACXAAAAAAAAcETxRQUAAADt8vzOJmZsa2tsa2tua3FtbW5xampua2xvb250anpubW9wbG9ub25ya2hxYhi+xuCHkFOTqADRb7ravTSf2US/X5/Y6GPNf9L6+671Vr9oej3dMZLfKR2NtVTQZJw/xmEENU1LsQnBPrDpOTmncGOkj01rZqE6wekhZPo1qho6GJwEKZNzArlcs40FvLlzxqwAXhfJGSdcEUAFiJG8zEx2Pr02sWZx8+Vr/3/Uh+dTl35cRVI6fePocI9oW6arPX9bz/ZGDCsvAzLWh2MN03PCwAEXhIa3Q9teXig8zppusR/5ZnM3Sq/hUxQNN6vTsNQn1Tii7qLtH6LO6VEFYha+9BA/CqmBChBjzGcH5vT1+ztvV/vduX78yYvf+5N73cvT9kmZYZEZ3d7I7M1imJoYVoIlDozLXmNOAqR+qMKnWEnPpRZ8donmQzK6upqYNoQZKR8kVy3TUH+lG/i6bko9ZYpDSNxc+ARiFz7OA459gIsOYoyi0B5VOhped1P7yoS/99v+vP/BYH+ydzrj9OeJxHWSnL2DTDFKuWc85CqJkjIn5UPgWPc9M72U5S+TjHvzXSEiSYmSxYcC+1TsTdsOj6+ptNozwzj3hyBRgKKmcIpWAGIXvmSw5Ng9oALEqEnf3+nON69MpvycmZhx/PJecvfpkG6vJsdmTztLsjssyd7WRv/anuT1wXTtLTVRmtQhwscqCntRhhs/lTuDOsl4jDodyQPbRPygqTw3CYM3OXFWro9W4SWnAzuRQrjXYGJWXMRgsJ45G1AbIFYA5qqT9/XL8/8/fbW/df+L/fCw+UB8Or8xW5o4+X7jI24bGPpUNJLJxNrKFc9cmhuleS/HdCmVu1ox2B6nncfeJqgQiteRKQNw5Mh3OlWgxc4kKhZB2P64VhfyeI4MYhi+7mFxpTcwC9GPchZt88HPVfKiku9+vPb9QJ2/8tLYOvZr/6Z0J7b2hsvDCFk3wrrbGrput8Yx54SQZWLCmncywHuH3ZtYdDqZ+Kn7fcLP53Tm752j2HWdL5w6tjyHytQRS0KciTfK9BNiF77GsBpanzQQYyR5sbPEk813l23m45k/0z3b7E5//LGaTyQvwnBrPA7ngbuZ03/lggT+ln9uVs7t+zcpeac6hOJeXbKDW/NTUgvY1DyngumnuURkcTqoB4wa3czUz3XgKCCPH0Ke9BUKfkYTGV4XPmS4G7BQU4BYAaKnJnvqYtnS27379VcPvbOmn1/7kewNzZKanF+ttR4tz2Spn5WyK5hQrCXjFmWUjzqafrvJryOptwrv2yFtdMJxqJNf368uECVRoIUSPEdrl2+fiee2MpocbGWy4NxtYhdL5mFLhMh21ogVIAHUbtfmif2nW5ZTc+vzF7aPU88eDte+0z546EolfuT5xEiVbukqhW1CN1Q6P9nQthg72SsRTI97PzuFeDNrN2Wt4RWHgJwhRCdiIUMuLEDyCs7TxEqdq+DVSa1mTwXRiRSumwFiF77GsF/2eECMsa3tJKw9r7w/e3X31X//+cGMh7Z+/fraq83fzfwzX70yGcM61mD7MS99528Su9KGSTqFTg+KzCaGSI/D0ZxjstW9e2Q073C8h1NXp75oucgtnEZMTFop3FNLNqOATrbRZyICYhZ7iaGU+kNAjHHcEnL57M+9xORXD+1/3Jnv/rv0XGnHf/e1naDXRzvZbkBf5nEu152E5SBPP3hW9DLc1D5NNxTN4srfp/ChwiaEHJeukjqKxxdXjQmTMK2AX/Noi/zxJq9mGoHq4gkFmUqRBGIYS8bgatqmASpAjEa1xKeD8W599W7L7e+tnenPt4enNvfl6PlS2ufps3/STeYh0ZtM3E1Od0jWpH7FeAQdx/WXTrxGw5FKuHDT708m+ktwR6yCLxeQR8OSdLQRBer9GMIzuZwb11/TJNYKjXkAYhdL7gdk4CW7R0y6ChCjWYjN906b8fTmPVRmd/9dS59+67+2k3Z99p//eNafmWdnnfFha+zGZBzm/iazwaLxnJ9FYNS5oKuY8Ta6bxZqbKq8lnq0h8JrMoks12IPN7/DbJ6LFK0NMHL1rIZ7xZd9ptliF77GY8EFHA4xRkHq0W76j7ff61v3M3d863x9f8aWV+fvLxtnUdd3tr19khnt4bhZdBwKB3GqYztUFHOe8Entij2aK3uIq9O0fuOZy91rFqo4V74fgFYCybl8lorhur+hr56/Ks/HFqsAYhe+xrCf3dNBrAAx12lNjNJ8sdyk6s5D4y/61E2aJ5v3Yw2p0nNWa/Za3QqJWoUWz1x6cSqs1RvVc40FFXJFTP4Q47qDyNssyBo4UpeXcx/nkDxfptGXjoZY6ovHFhpTBmjvcMz1i6ZWBGIWvs449f9oI0BLAH4MsbMkfn79+d3KfJKcnfREPDw6vDl6cuR2e2/yTi6CDH3bWf3ssYYDlnGPOjuWYkb8W3qwyzpujLlL61fcalfrVLMytunNnrPWBL2X+KTDRMJ87DYHwYmNuOK2jfM/MXwAYhe+xkjDX5r+IMaYlxr69W1p5r9t7/ek7PxOWb9q/erD4/0Hhmyk9B4d7emaHraQB6A8gSKx5vJ8q1habywNRd6lP6UavRRe12nOSB827t5LSaxdcxC/6DTRGCRLjp1L9D0hzl5XoVjJVhFiF77OYMiRN6AxABJAjPN4ZSjz5yjPNKQzT2+/O1jTns/o/X85/H7He6cheHduZOZ54S0kRSLEmbnboCOrZ42Dw0ESauBRb7PlNTZQCrNm6ZM9/0y88BYOS45SM/nsPKOPcT0omqMbFJhHFgBeFz5kuC2DkgMVIMYlTtZWm2fnKV898PqX92wmbdMm+0/+vjhkPP/ZCYfXzXepoets0ZHXhKVXR94ohIP8OU5GHZWIcM5UseN9c1OKH2UnRw2Kw57hIcXvys/2V5a6jbiIosEf/EcLXrxNluU5hxVeFskZ931uVAdIoBMjalnk55OD/tevJH59KdNr6X++JXfrqMVmNbfoumqNUkJiPbVWS/rQKQkelm9/sJ2dO44Wh1I7i2xun64pm8OZ74y20H0WakCRm2k0zUx4hf6b5ZjhtLp0diOujw5wikaX5QViF0vGMMWbURpUgBh1t+VEfHutX+L7ah28f/n+yOz1+eFb+SwbStsJU1tHp31vXz+vja0h6R4frvoXIzQ8VGrbFl0mRzLls3X1T6Y445eun3Tuplm2nvcFW8KkIR5RQZCI8AwVIc4bb9MmlKsvE2IWvsZobqEiALEiIQFo61hv7ujZuz83nX+P75gPv72fvvazt+8xi/XYnB7bU9Pd0tIZKefqsal269QYyXiRdzFGjYZG7j5I0fkcdTQJQ35zspy3yhH35vwW/2/HHXp9PaTRwkW/cTGEv5JtfYqDb8w7x73sYhe+xnDdOs0CKkCMhtZ7ztK97Fd3Ng/++2rqZb+Z8x8PPrB7OTlRW/okUydl0oYaJ2rJmxO/tQ+pO+VZZkcLPs5ibXtq4qfDH+WaDPmwwb1MG7vQSGNd6lszZVva3S7KGUpm8baFk6fqCmIWS8ZgU9epAIYC9A4FJlQA1WGJa91k7+cvfv6YaTv6mXp65030ZmbKMDWxMteNxGVtaV7qXvJZ7+S67YUkTp4k7HetZdNWbsreXkvYGHLSzxrrN4ZlZCbHld4v53FvW5tsKfFx++XBfsPqqPSOfInopQp7XO/U9+bMYhdLtqGtsAPEWAEkqP5I8+nDi807F1v/SXf5yJfanUg8IBEZy7Bm+97xrswZ6fTQ3PD17She8CNvtJIdf7HIFzQfJZHX7fvjn29758nZ/tsw3usncSmxdn7aVSYsKOXDrjKjo9RhK9LTrnO+bQpiF77OsEQ5YBIgxihxLHrn62crWb1Nvtr3q+NHrj1Ne2f3cWL9YnX6d/3iTZiI4n40WDnevgOwYfeez5AzvBrNd5qdFoRZBJ38QU1Lrt5riKXP3vIcstuF+c1mJoJ/cr/5Gj2wzE/BIRrD/RA6YldcjmHztnx1tHggKUCsAKO8lhPtxSF/a+FPJ+3GZJpPb336PE8zaTNI8vnO6aZ+iwXZjUuFhO73umTZORve1dL1nNT43vvwtztCsmpyT06CEKqiwiQmDuLIe9J8Li7vDGspmEUL9fhsw07mcXoNXhY+ZLD+4awCKkAFiMiaHzm9dzCZYjNhuzUN59YH927/SbPfgq354HTrG0on9beZ6KpUOxkvRD9YevOlUerO7qxofS7hoz02Oz5Hr8IH2vr4pPGwnW6cZVvcwy+PS8CM6izRh+cyY0kLNqrSYVYOBGIXvu5hbvgBJYkK4PvhYNiZeH6nn6Y8e/O1sD9OPnmf/ti1tYem3tmqeXz1cHdtfrKEYdPlbDnJKqCNeDk/556LdC2JlMZkUbhVxRgJfu997W0m/jV9qq7DQ59vbwL7jNdwOefGvRFEM32Uh2IYS2SwwcigARWgAkStlHETnfvmvS+eP09//O3Zpx8/np7OO4fW1icT3YnNvXmP3h46e7PqLFom6q+supJ3bixDyy1a3K2DDn9pGQiRx/LOeud0UB6E0yuIUiN2gzoT4oJ7ThXRZDJVGgmu/HmUIGJXXR7j5ybirgADAFBHbePG119nu8mpfvbtv2drv358GHfChkW3XTLq6dBN1gS1Zp+0KFva+sSza93Obkpn7rLMdWT4ruO0LpJnvk/mqPW3kEmzoHM0i20v5DozA3UYBCa0NNdpeMN4wTrzPTETYha+zjB0dgs2nsaIMS7CodvbvtA/B8vslL/3HtgbX723CjYpvyxu5u606XtenF07brw0gO9FPt4Hn6/pekDz+tNtB3kYiQeJ22fSvFzJypmsh440EzQOBvmetndwGEQO7t7EgsZxPKdG6uo7p3IFXlfQYxhAneygAsRY2W9fmZ1+693L9x+PbSYff776T3fZND69P1vrPNizt5tedV6el+nuU6Mt6x0NJal321viyoP3FMQ6RAF2bgCv/OzOLXCBrn3Yx0Ec2qM+izybHXiN3VpF1pHQw1jKc4dhkKxiF0tkMGIhTQUkgAoQhPPclXXjof9P7thcWb98JW/bYjyxrP+dp4rNybIzWs9mSufNkhzinMO74yFcNfO67/3ItRuf1YrA5mVwq7uOTWggDznr06sYztzny6xnuX+dXipCMrHY85XiqXj3WXScVM6xsb1iF77OcJtUBpEgxhjEmJA/Fz0px3Y+nLz+dHqe8t1JpNmJ81dGy+nj7nxKqf65/N+vwoI7tPKZf+56yEHHBawDZsD68iMHmvydBiF8tx1UNjmsQdqZIvzUqqvJfefGK1l6FJsYddLpJIjsGF4XPmT42vLEkYgxmjzj5ubn6Mvfrz7WwbRh+D+nfecVZrXdbV5PBqqRnph8D/0chzBlxQ4xiHdov+NJoOF9bB6tQ6gULEc5eJdZM/W9mJrecxp6aio3oTKlYg+8L1z35IFn4nUZgoEJYhhLzmCRZtEBhYZYoSFK6c2278lN+9+fd9fma92N7Rcfe2ZdDPcn+w1pk327vWUmUp5a9d2pWCuG1WSjG/MVEP72UnCvg7CAwz6b05aRtt/lv75M5PeA+J42l3oZilfVU49yG7K9nS6ks/bWes5IVQFPZ2dTAAAAvQAAAAAAAHBE8UUGAAAAFvE3iiZucGptcGpqbHBtc290bHJudHZvbmZrbnBrbXJocWxyb3Nxbm52Z2IXS+7RVZPDKqjAiVETaj3pf42rz4JZn9pO+u/urF2/87Pzr632PJ1oQyKei/Vg7pc3hR/Nw+O+xAeVKSInOAEPFz/QSrpfWZe16f4QZ2cI8X6rdK3hcZrH3bycT7q6/RmkQ+yBXSUOwyZq6EsBYha+ZNy/WQNIADGqbDVuXm75dJH856floc8fbA6mXztiy03nFOOiPeXaWjd0uuO2Wron4Twl4ZFNn3/Orv62+MtE28GreSLIgusdNS7382zvtZMCkfjzj1Y10bnidXAzy7kk8BczfQuIrSnTB2++AWIWvuZh8YAWTFsgxpjYr+SpPHv5rPthJ72dHNx6uSVdXXv/7m+zTcpOp468r+R6HnDRMDsOUmMUBU6TtgluGVGn+lRZTjd4xfQQWdTKnsWZNwntpcm9pVtA1Wvl5aetp4vcDtXqJvjOuQFiFr7u8ebmLAAVwI/zlQ/rb7dSbGut+hn/Lg8d3r75derUs2dX404+1n+key2L7S4zUh4OJ4M5ylFQPb2PBmXfi4Qer8cefLEdBTqsFPwVvtn3OqNm8n8Jk8C0oQb2z6VPspCQuxNlhHMdNl8KYhdLxqCnpUYBYoyE+HF9Yu/qs+1fPDi18+Wfx+S/Np9vjSzW54tt4rTX7rt151zt+e9iGXdiuOa8c2n3y+CTFyJ1r4duLrAtyUXbJE5HA08XMpFHtcM5Xbq31vWP6uQFTfYlUY5dMp4LwpKHwZ+bAmIXvsZw41cGH4gxlu6c7v5IPPs+lmZ3lS8nf199u9cxjvrsD+u71tSE+aYWO4XoH09UK61/XfZ1IO921jos81CUQ8uYV5I7Pkto0H5Mez+FoqF0Wd6dibU1enIYCiESC6mkuyyIPpYbEFNiF77GsGXL0IMaDzFGkjJOv/nx3Rdfv+NXetm9efZ0P+3o0MdVgjYrtLQ2buJpxXgUSkI9eME8Hk6ZtzW+mzxO7fUyqeE4Pxm0hwO7stiBDhRbBd8XSH0zICi4J1Lm8wwSdeX4iV0zlqICYha+5nGi9QH+QIyxtb1987tn/v/tbGN/ar99P+XSx74vD+p03LcrE7/7Ras4fPKWts8y3tkqXT2QMqzNiZveO1/wgi6+j0tJ4F38tCHnwiwgYF/jUzQTPT04IYOP5etoh2fjVIjfCUVcei4ZYhe+zrDIVkPtNnICYoxiHHR8dPDPK4ePXm+3/90Z/tzPaV9PvmqunWydmryklPOXNZ7j8ppCGOphuhBenOQCHKxd2IcjipzonWYr+XG718XjGZ9D74LwYusCHUkflmiI8XSzujNmf2sfbh2dSQQOE2IXvmQw0IA5O5AAYgyb4pNfbeorMeVhc/bZrNM+rxxvV6z7lkspre89QzRJ69Rub5fvEM46kGfDJnOjf03D+FCOELHN+YJ4kuqGL69dnfDIpUdkMj2P9lUyVcMeQ5YuPq8sSXkUdAcg0CaHDQZiF0v0mBbZ4lwdVIAEoAHIUTbbi4O06Z98+sJ+meztvZU4/0o7exefUvNi3bL/4MRyMxIfLaP8+FkNx7u/nlqG3Ta5po4Vem8k7gypbae+827vPCL2lPc4izQ8pdo5P23Dbh62I6I3/4TMZMtrPavcP/FAYhdL7UFl6z7qrtRBAoixSdRD7+v7avLDzWjrFjs/bLslTaV/cfjSyb1byb43ehJc8jtLn7XcK1FWAz6WNr/qViOw3siwG4lo7PHkJIpmvlsjMSZZaUyFE2tKfe4Dzrlco7HZVW74A1eOKtoWRvYBYhdLzpC9Lek0oAIkeEQjW/qd2fxnfPJjt/e37P6y63Nz3KYbVy019Zfng2dW67leO5VO3dqxLvfDQaoYmuyM++YvujVx4B4bWCbk9+UkAh9vfA53j0NfWO0RCk/PHj1bSRgfk5AjCmsHp3XFQcdax7mDPQFiF77GMK3ODrNTAMRosJF4f3D5A76td8c29p5/nc6S9kzrZ7/46hZyjKaR9i30dPyMvaRbFyPi/d6vfHt4L3MF5h/CRWzSXOlpgYt0wsC+NP7GCTV5gomq1eqtXyI/ythsZ4L5gmJ7CbOaQgViFr7GsHRdLd9BFxNAlJEc2tt+7HF946zn5K1vsrf3zvqtHhni6My8fP1E5paes515kQf7lNVt92jZbxJ5+PYpWNOBavFIRbWNkQm55I+nMLcJ0yOX4T+jMFR0FB+tUBViB3PO20zWpIEsmdswQ8TsNhFiFr5kyEq2CkAFqABRUvXdjN21208T/+x+Ml9azeXW8d7Rl4meahYZrWzO0hkTqScnGyxnQ2hWA4x5uB+yvl5DBX+c64NoeOJYeI1LugjUr2ntOWTm400QZ8JGYYs8qGc1ZBwikNKqkJZQR6uLL2IXS8boBuYitgMMACBWgK6QrLQ76a7NntX++vuJxxlHJ7q7x8527Lie+8qxTu/oh5wcTjOXoU2QJ2ym87p/r2buiei8I3k9m009UTn93hgr5ztLwk1yWDZ2uc5IIqdwJhcPs6X88ObaL1TaMqWhP0tvJ3wDYhdL5sEo933XgHUAQANEldD3jnHlbJV4er75dXL7vQfv3Lryd3LjV/LGepEPbcj2mBj7pK4bqzOmTmLlet+g5cLaU/Oe3mycL+9vx4mTvdPk9Hhjw32rJxHzRG4oykcXk3lo50Wh7MEJm4/RBD/OZquIh+whBmIXvsZw2drKAQkgxlrbuZt+7/2L/vsPjT8vKT/1eOJpnHzQOuPtYgnDk4m/iWUJq7xFUpblPIyeCeNLwv69wzGN0UY/T7hlMPch5W/mlC5cWjtBB8393hfVQolQEKWQbOsX57jdYJvTA09j5tSPBmKXRo7Bco8vFBJABYhZU/v0fljdmZwfv9ck3jma6Hz6Y+0+tGO8GK2eBB/VGhstZeMlPl/27FYdktns6TFPX5XY0/qd9nwUafVcOQ0jXyZGYrEmHqpKkGq47ag1HNixVOyrkU2C1MODoHia1bMAYha+pKL8qosxVtd63Vie7qU/dOzq9odTj7yjz4s+fQ1b0LtwOaooIAwpHNa8jErePJ7o0zfUyWe69fFUGQ8fa3tixaYJp2AMmJoFMUZn6hV+MrZCLdEP+Z4vY2EYdwQzk/PMKmpuYldchsEP3m5ATBBjxBwn9uyO+IOp29++eprYS7/936d1rVMHO+df7siduzKG4/DvkMF1EqrO07goTvxZ8z3c3BP1LhErbFeH1eIWqOGKlNQooP6aGTphdxRTYCwmXrvML3F+qYJL0flcPABiF77OEIsOHGUxoMRYAdz6zFM2Zv56dtrv6XQ+7TM66T1lK7Ok/8fTxN8fTc/cHFX+WB2N2qQV/4LJhetS8NmF5f2623/LHfkpX7ySL0iHCk9S5PSkL3FKY06uss0irdsxO5QRPiKVzJl6neUBc2IXvsZgkV9UB8QYjXHqek57ljq6snHstT+b1ktbdzcvXZmYudF7aj7QLkX/FPZ8nMbiw7+yg9u7Qw6y/D2cwuDFqHm8jQlhCjp+uXY4hJGxsB21R1Evaaxo3ffGvTfMs7KiPRW6GmEMREdRRedDCQliF77G8LSvdQpijD4/O2w5GD2c7uqX2/Zvvpz98NHjvVcG1v9pQ5qd57upJW2ZfR94MO8pusFlnDOtDO/XZRiU2mXEgqpjLmH1tuhtuJ9L1QNEnvYyYvCsxl75rVx5LA4QtgM5b4ooZWLnB14XPsbw29o0ARUgRoLFGL3b/Ur2t4anj6MtX6TZfLJ3yVqGne/Z6MGq6xNT3SjxSX6/G0/X6+jSLB7DpUeSxLquOJ6eOCgHfP7NJ74KJJTvFvbIF3NnkQoSTwV/Xw/+LmDdlm6cdzpytA/CIwJiF77GoC3hxlM+iDEBxLnOh7S3Lo72/3maPhzq101vZ701nG/+27196cw8O5Q0c+dTDaYlmKmryCLl1OE+CjFrCZ7+8vWvRAbdCNfz43y7IspDYOI9sE45F6PIVqJVwlfsPQpp/cpVaCd1vCMXolOkOAJiFr7mYTc3vlpAI8Y4kpszm9H550T48tOfl9PnT9+1FLkyOfb87nFjYj8pH4fIvlOBXVL0AkIXzmrUE2KOggbPriF3TtbUzlWbUmkOZ7FETt4Ovew8ZKG5RftqHGozkz0ONNXbXn5qEV4XvmRM96sEUgWIkdVJ3Ptv+uBnn5f2D9t/mO9fXZ+Is5M5GbbMWOtTof84dA5Pn7anIbm2tOSYBKoow5BjfdSvQV3FRai9y8c78bdTvAbMCcLgvb6ndCKn85v2rG3J4hFPYxQnmtcwWx5NgsgsdSsBYhe+ZOTZhMxQTBUgRj21Cf/tvP93o7fe75+kTXx10u+vmdLd/D6Zm4l+0ermznjkdilBdIga9Jreva9bHj7BPnMq/1KEB7RAN9JS0WtKr3YIktlETjQKZASXB6fuOghxdKqQ8kHCy9G0NKAAYhe+xugjB+aAKIAKEGPibrKZ/ac2nm2fetx6vO/42t3+g+XprfPRPDkx7sh4at+6nTyeT+y8m0+OhmpIj2XHGViVi9Ylf3lgXK9v98nqMnQseBmMFXH1wV9dL7v1OtGwzJ+01T6UhrXl9pyHK47F8z0BXhfJGfRx+AcGABCjBNqu5d7VS8f/OdtqbE3//e7a20PW023mrU4lQ7F9XsZl63o2tRNJ+vfI4thb7xiTbWfU9vx5bGIf9PxmpOsYPGS03Mh3rHVyNXwZKSL2P1v56xCvi0iYSzqPUOdP47ZtWpgDYhdLxtB/04zsDZgJAMQ4dm0nNsnvyze3vr67/+zS/pf3erZehp0t3enl53xy7fBiNzTrExK9q8OjhdX5chBXWGR0tUVPfufqVM9yN7ROn546j3A+ih5BfChLBLa6dy4ovV9Gd1gaCqUQyJM5r1IVU9exGmIXS844lcKmRA0kgBgT2jl9+ix5fUn7s+8ZR58t73pPjqaeLpd+rPaeGc+V450zYTlssc6HVLf4Ti56vS3/TrKe/k7hoOtFeXBfrkfu5fQcnm/yOnt6HovOk6Y/ZqBmH7HyHF2urMQrAeJkcZXOG20EYhe+xiDOUMEYYgWIUfbyMfnvlev/pn3t8Zbt7PQ7s3Wn9/G/v7fWkiMxO6HqZ9a15FLaPdszOP788hbs3aKl/7kATy7gvMnjZbWDH8h1jHiauSMM/j46GOTGodi2ugfSTGVktNpWoxPJG1VviAheFz5ktN2m/ktABYixwnLwTr8fTnvnwfj+y8tXjEs91yX1Vu3M0L311XK62RM6RqITV/gn8yzsQfxFLWq5k48pmnt4Jv4fzYSN9Ms4fPL2EgeEMZ2MgwY9wKvZzeOUEr4v3gGJaLZ3R8spyU+bfGIXvsYwaKnWlh0JKkAFqABteGvDy9ftU28fsussX/lOz///f7XtfE1kcn/vnlji+nRyIu8kxy21e2fnp5hiy5oZOxM+NsyD6j+f7Qwd6yQTHLjZsny4oaPj3XyebTlfOJdw4spz30uNqlaZuUTHrptDzBGZSQ1iF77GePV1ooEYo89HOWXi082n786VnrujLNtP85drbmvUzd1O9c0OgjAeLrX25QTfzXChvj3XXwKp926L4QBKC2GBkCJz3OUlZOV5mfuD6RJIKiYaDDcx4ZBRxg+p7B48+hxRuHrGT2dnUwAEFMgAAAAAAABwRPFFBwAAAOp7PcwMZmlkdnJtcWtwcWwhXhceGd1o9YWSQIlR7VqJx8+XuskHjkzYzHo9bYqovFo945OTtM+u6q/JpC8lMvdo+aBYQOznGNpML7w2HGF3HrlhyO7rmcmJYMSPIBfRxuZxPEoa9kspv8KKSmrJ1E1cFtA5wi0BYlbcZoNmiVMISYxWWckwNX9xfLPPRbj9r9utvdxy9/avrU+fzrg2c/aYk2hwtwiEfc1hi4mkQ9IUT3qOa6fXOrqCIyYnb58YY22pE/iBcf9KthrMQ6rWGbOoRxeniBzdmjsuRM8vIpMqYhi+xnBrLTE5frQuOVxs253x7M+l6xfHx3Z7dkdn/kpZ9MiefhgNP9+3pR62XRahQeR1k/NhsCfZ3mpnJTkp0kDgrkmn8npgcmtOaSnftqatd8wKw0FO55TnqyiaX2nOM6UDYmIXS84wZ/kYSVUjASTQiF0fnu4eTM3q/9+PBz7N6jveO3T7lXRT/9Fr+bjxfLK3c6kt1tEoDj6yGhdvcSKXBD+zPp4k345astarnU1Xd/COpk3d7qZjuRGGhcV2s/CS9al8T6Rw8J5tKATbDUWSiZMcd+8d2AFiF77GeFYlxiaoABUghrPVKvjl5Pnb8Zknhx6++vRa2H3yleX7wdUqr/UOZvckTe72n9RxT7aYfr0Sa3u9p36qb+sTyzBRmSOaRX6pK/fHWgPzyYvXcupTYnfDQlcPPIxH9DAhS/GYFx7x4baOoZDrjABiF77O0FN10w0AxBiDeFjrhLRbrl0Yy4frH3WmPPhFuq3WPoPFmEjzckaUO9fj1BfDHONud/zZ6SzfHirTFkfO16d0XahaGeGbuc3Niu3RWa42IeSZVkiR7zGy3ydp8JIZulhT2C1qPWOq3iMEYha+zjDLD37rdMQBACQAzBPL+sNfHtv2OXlk++z3X3yxZfbT5ev9trb1U8U+/jStBtMvgom+JZmbhlwzxY0yW2g67eMQEhJqfBoWd8Po2JuYQfi9QP4097lMQtuC45tphVquxoag8xGIOY+xcLTn7gNiF77GULRWAKoGxNh22tqPe78+/Hv0eEi/nKyV/phMbPdaje7tmYwsd+vL7szU5XILaXuSY6n2eFB3nnI8QxSGabYWGwb5USiwRquYrTdwihSDwtxGTyx9gwnTpeDyHSRzC4fkSj6+ErYwAV4X6Rn332LjRQADAEgAcWge+E675Z/4/j/bVy976mNvsPzwg9zy6Xw87z7t2/1jOdk7SCYv6WLMPdp01k5Dp93YjXKr5SYbfzwzis3VprVghmdNysqlQi5djuSZYJrDiTAW3dMsGBVJnHWRhqH1GlNiFr7GmOU2uYw9MAAAdYwd1remnLbDT9e+Pl0sTy7bfJx18tRsYbxlKKvpKV1NCZN5SO7Mk4ndft22c7KjhpHySSVRDN+XnrDzx+6nplxD+NTygEqVvfAsrlLPDdtbIY9x6g9R0qP+3kyeNa1sPgRJAWYWy8tgqI/LdQMxRnI2pn+luXzw+jDD/kmfvrIt23zcv3/8fC2ROidP/hmbtnEhp+1mLW9x2EE3T30KfG9PYZ1FkrmzhdBf6iANcV3wi0P9JqpLytqodB2bchTLoqP0/CpSvdmPyDnn1iDTCmYCjwYwuQGcMAh8wzJQOQy/NKqLAWDr4ocvJ4XBdZy4Aw==',
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;
}
try { _w.aalert(msg); } catch (__e) { console.log('[小助手] ' + msg); }
}
if (_w.top.unrivalDoneWorkId == getQueryVariable('workId')) {
_w.top.unrivalWorkDone = true;
return;
}
_w.confirm = (msg) => {
return true;
}
// ===== 字体解密(来源:ScriptCat #6859 的公开实现,Typr 路径哈希方案)=====
// ======================== ====== 字体解密(font-cxsecret) ============================
// 超星使用自定义字体加密文字,需解密后才能正确匹配答案
const decryptedDocs = new WeakSet();
function cxDecryptFont(iframeDocument) {
const doc = iframeDocument || document;
if (decryptedDocs.has(doc)) return;
const els = doc.querySelectorAll('.font-cxsecret');
if (!els.length) return;
try {
const styleEl = Array.from(doc.querySelectorAll('style')).find(s => s.textContent && s.textContent.includes('font-cxsecret'));
if (!styleEl) return;
const fontMatch = styleEl.textContent.match(/base64,([\w\W]+?)'/);
if (!fontMatch) return;
const fontArr = base64ToUint8Array(fontMatch[1]);
const font = parseTyprFont(fontArr);
if (!font) return;
const table = JSON.parse(GM_getResourceText('ttf'));
if (!table) return;
const match = {};
for (let i = 19968; i < 40870; i++) {
const gid = TyprU.codeToGlyph(font, i);
if (!gid) continue;
const path = TyprU.glyphToPath(font, gid);
if (!path) continue;
const hash = md5(JSON.stringify(path)).slice(24);
if (table[hash]) match[i] = table[hash];
}
// 文本节点替换,不改动外层DOM结构
els.forEach(el => {
const walk = document.createTreeWalker(el, 4, null, false);
let node;
while (node = walk.nextNode()) {
let txt = node.nodeValue;
for (const [key, val] of Object.entries(match)) {
txt = txt.replace(new RegExp(String.fromCharCode(Number(key)), 'g'), String.fromCharCode(val));
}
node.nodeValue = txt;
}
el.classList.remove('font-cxsecret');
});
decryptedDocs.add(doc);
console.log('🔤 字体解密完成','#4caf50');
} catch(e) { console.log('字体解密失败:', e); }
}
function base64ToUint8Array(base64) {
const data = atob(base64);
const buf = new Uint8Array(data.length);
for (let i = 0; i < data.length; i++) buf[i] = data.charCodeAt(i);
return buf;
}
// 精简版 Typr 字体解析器(仅用于 font-cxsecret 解密)
var TyprU = {};
TyprU.codeToGlyph = function(font, code) {
const cmap = font.cmap;
if (!cmap) return 0;
const tabs = ['p3e10','p0e4','p3e1','p1e0'];
for (const key of tabs) {
const idx = cmap[key];
if (idx === undefined) continue;
const tab = cmap.tables[idx];
if (!tab) continue;
if (tab.format === 4) {
for (let i = 0; i < tab.endCount.length; i++) {
if (code <= tab.endCount[i]) {
if (code < tab.startCount[i]) break;
if (tab.idRangeOffset[i] !== 0) {
const offset = tab.idRangeOffset[i] >> 1;
const base = i - tab.idRangeOffset.length + offset;
if (base + code - tab.startCount[i] < tab.glyphIdArray.length)
return tab.glyphIdArray[code - tab.startCount[i] + base];
} else {
return (code + tab.idDelta[i]) & 0xFFFF;
}
}
}
} else if (tab.format === 12 && tab.groups) {
for (const g of tab.groups) {
if (g[0] <= code && code <= g[1]) return g[2] + (code - g[0]);
}
}
}
return 0;
};
var TyprP = { 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'); } };
TyprU.glyphToPath = function(font, gid) {
const path = { cmds: [], crds: [] };
if (!font.glyf) return path;
const loca = font.loca, data = font._data, glyfOff = font._glyfOff;
if (!loca || !data) return path;
const off = glyfOff + loca[gid];
if (loca[gid] === loca[gid+1]) return path;
try {
const bin = TyprB;
const noc = bin.readShort(data, off);
if (noc > 0) {
let o = off + 10;
const endPts = bin.readUshorts(data, o, noc); o += noc * 2;
const insLen = bin.readUshort(data, o); o += 2 + insLen;
const ptCount = endPts[noc - 1] + 1;
const flags = [];
for (let i = 0; i < ptCount; i++) {
const f = data[o++];
flags.push(f);
if (f & 8) { const r = data[o++]; for (let j = 0; j < r; j++) { flags.push(f); i++; } }
}
const xs = [], ys = [];
let x = 0, y = 0;
for (let i = 0; i < ptCount; i++) {
const f = flags[i], i8 = !!(f & 2), same = !!(f & 16);
if (i8) { x += same ? data[o] : -data[o]; o++; } else { x += same ? 0 : bin.readShort(data, o); o += same ? 0 : 2; }
xs.push(x);
}
for (let i = 0; i < ptCount; i++) {
const f = flags[i], i8 = !!(f & 4), same = !!(f & 32);
if (i8) { y += same ? data[o] : -data[o]; o++; } else { y += same ? 0 : bin.readShort(data, o); o += same ? 0 : 2; }
ys.push(y);
}
for (let c = 0; c < noc; c++) {
const i0 = c === 0 ? 0 : endPts[c-1] + 1, il = endPts[c];
for (let i = i0; i <= il; i++) {
const pr = i === i0 ? il : i - 1, nx = i === il ? i0 : i + 1;
const on = !!(flags[i] & 1), prOn = !!(flags[pr] & 1), nxOn = !!(flags[nx] & 1);
if (i === i0) {
if (on) { if (prOn) TyprP.moveTo(path, xs[pr], ys[pr]); else TyprP.moveTo(path, xs[i], ys[i]); }
else TyprP.moveTo(path, prOn ? xs[pr] : (xs[pr]+xs[i])/2, prOn ? ys[pr] : (ys[pr]+ys[i])/2);
}
if (on) { if (prOn) TyprP.lineTo(path, xs[i], ys[i]); }
else { if (nxOn) TyprP.qcurveTo(path, xs[i], ys[i], xs[nx], ys[nx]); else TyprP.qcurveTo(path, xs[i], ys[i], (xs[i]+xs[nx])/2, (ys[i]+ys[nx])/2); }
}
TyprP.closePath(path);
}
}
} catch(e) { /* ignore parse errors */ }
return path;
};
var TyprB = {
readShort: function(d,o) { const v = new DataView(d.buffer, d.byteOffset, d.byteLength); return v.getInt16(o); },
readUshort: function(d,o) { const v = new DataView(d.buffer, d.byteOffset, d.byteLength); return v.getUint16(o); },
readUshorts: function(d,o,l) { const r = []; for (let i = 0; i < l; i++) r.push(TyprB.readUshort(d, o + i*2)); return r; },
readUint: function(d,o) { const v = new DataView(d.buffer, d.byteOffset, d.byteLength); return v.getUint32(o); },
readASCII: function(d,o,l) { let s = ''; for (let i = 0; i < l; i++) s += String.fromCharCode(d[o+i]); return s; },
readFixed: function(d,o) { return (d[o]<<8|d[o+1]) + (d[o+2]<<8|d[o+3]) / (256*256+4); }
};
function parseTyprFont(data) {
try {
const bin = TyprB;
const tag = bin.readASCII(data, 0, 4);
if (tag !== 'OTTO' && tag !== 'true' && tag !== '\x00\x01\x00\x00' && tag !== 'ttcf') {
// 尝试解析
}
const numTables = bin.readUshort(data, 4);
const font = { _data: data, _offset: 0 };
const tabs = {};
let off = 12;
for (let i = 0; i < numTables; i++) {
const tag = bin.readASCII(data, off, 4); off += 4;
bin.readUint(data, off); off += 4;
const toff = bin.readUint(data, off); off += 4;
const len = bin.readUint(data, off); off += 4;
tabs[tag] = { offset: toff, length: len };
}
if (tabs.cmap) font.cmap = parseCmap(data, tabs.cmap.offset, tabs.cmap.length);
if (tabs.loca) font.loca = parseLoca(data, tabs.loca.offset, tabs.loca.length, font);
if (tabs.glyf) { font.glyf = []; font._glyfOff = tabs.glyf.offset; }
if (tabs.head) font.head = { indexToLocFormat: bin.readShort(data, tabs.head.offset + 50) };
if (tabs.maxp) font.maxp = { numGlyphs: bin.readUshort(data, tabs.maxp.offset + 4) };
if (tabs.hmtx) font.hmtx = { aWidth: [] };
return font;
} catch(e) { return null; }
}
function parseCmap(data, offset) {
const bin = TyprB;
const numTables = bin.readUshort(data, offset + 2);
const cmap = { tables: [] };
let off = offset + 4;
const map = {};
for (let i = 0; i < numTables; i++) {
const pid = bin.readUshort(data, off); off += 2;
const eid = bin.readUshort(data, off); off += 2;
const subOff = bin.readUint(data, off); off += 4;
const key = 'p' + pid + 'e' + eid;
const idx = cmap.tables.length;
const fmt = bin.readUshort(data, offset + subOff);
let subt;
if (fmt === 4) subt = parseCmap4(data, offset + subOff);
else if (fmt === 12) subt = parseCmap12(data, offset + subOff);
else continue;
cmap.tables.push(subt);
map[key] = idx;
}
Object.assign(cmap, map);
return cmap;
}
function parseCmap4(data, offset) {
const bin = TyprB;
const segCount = bin.readUshort(data, offset + 6) >> 1;
let o = offset + 14;
const endCount = bin.readUshorts(data, o, segCount); o += segCount * 2 + 2;
const startCount = bin.readUshorts(data, o, segCount); o += segCount * 2;
const idDelta = []; for (let i = 0; i < segCount; i++) { idDelta.push(bin.readShort(data, o)); o += 2; }
const idRangeOffset = bin.readUshorts(data, o, segCount); o += segCount * 2;
const glyphIdArray = []; while (o < offset + 1024) { try { glyphIdArray.push(bin.readUshort(data, o)); o += 2; } catch(e) { break; } }
return { format: 4, endCount, startCount, idDelta, idRangeOffset, glyphIdArray };
}
function parseCmap12(data, offset) {
const bin = TyprB;
const nGroups = bin.readUint(data, offset + 12);
const groups = [];
let o = offset + 16;
for (let i = 0; i < nGroups; i++) {
groups.push([bin.readUint(data, o), bin.readUint(data, o + 4), bin.readUint(data, o + 8)]);
o += 12;
}
return { format: 12, groups };
}
function parseLoca(data, offset, length, font) {
const headOff = font._offset + (font._headOff || 0);
const ver = font.head ? font.head.indexToLocFormat : 0;
const num = font.maxp ? font.maxp.numGlyphs : 0;
const loca = [];
if (ver === 0) for (let i = 0; i <= num && i * 2 + offset < data.length; i++) loca.push(TyprB.readUshort(data, offset + i * 2) << 1);
else for (let i = 0; i <= num && i * 4 + offset < data.length; i++) loca.push(TyprB.readUint(data, offset + i * 4));
return loca;
}
var questionList = [],
questionsElement = _d.getElementsByClassName('Py-mian1'),
questionNum = questionsElement.length,
totalQuestionNum = questionNum;
// 4.11:字体加密的题干先解密,否则查到的是乱码
try { cxDecryptFont(_d); } catch (e) { console.warn('[小助手] 字体解密失败:', e && e.message); }
for (let i = 0; i < questionNum; i++) {
console.log('[小助手] 解析第' + (i + 1) + '/' + questionNum + '块开始');
let questionElement = questionsElement[i],
idElements = questionElement.getElementsByTagName('input'),
questionId = '0';
// 4.11:UEditor 等富文本编辑器的工具栏/下拉会被当成题干文字读进去
//(实测会读到 "Plain TextBashC/C++C" 这类噪音),读题前先摘掉
try {
var __noises = questionElement.querySelectorAll(
'.edui-editor, .edui-editor-iframeholder, .edui-toolbar, [id^="ueditor-"]');
for (var __nz = __noises.length - 1; __nz >= 0; __nz--) {
if (__noises[__nz].parentNode) __noises[__nz].parentNode.removeChild(__noises[__nz]);
}
} catch (__nzerr) { }
var __titleEl = questionElement.getElementsByClassName('Py-m1-title fs16')[0];
if (!__titleEl) { console.warn('[小助手] 第' + (i + 1) + '块缺少题干,跳过'); continue; }
let question = __titleEl.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;
}
}
// 先看这道题是不是填空/简答:有 answer 命名的输入框就算
var __blankEls = [];
var __inputs = questionElement.querySelectorAll('textarea, input[type="text"], input:not([type])');
for (var __bi = 0; __bi < __inputs.length; __bi++) {
var __nm = __inputs[__bi].getAttribute('name') || '';
if (__nm.indexOf('answer') >= 0 || __nm.indexOf('Answer') >= 0) __blankEls.push(__inputs[__bi]);
}
if (__blankEls.length > 0 && ['0', '1', '3'].indexOf(typeN) < 0) {
// 填空 / 简答
var __tnb = parseInt(typeN);
questionList.push({
'question': question,
'type': '填空题',
'kind': 'blank',
'typeNum': isNaN(__tnb) ? 4 : __tnb,
'questionid': questionId,
'blanks': __blankEls
});
} else {
// 按「选项组」拆题:阅读/完型(66) 的多小题、以及普通单选/多选都走这里
var __groups = questionElement.getElementsByClassName('answerList');
console.log('[小助手] 第' + (i + 1) + '块 answerList=' + __groups.length + ' ul=' + questionElement.getElementsByTagName('ul').length);
if (!__groups.length) __groups = questionElement.getElementsByTagName('ul');
var __pushed = 0;
for (var __gi = 0; __gi < __groups.length; __gi++) {
var __parsed = null;
console.log('[小助手] 第' + (i + 1) + '块 准备 parseOptionGroup, group=' + (__groups[__gi] && __groups[__gi].className));
try { __parsed = parseOptionGroup(__groups[__gi]); } catch (e) { console.warn('[小助手] parseOptionGroup 异常', e && e.message); continue; }
if (!__parsed || !__parsed.options || !__parsed.lis) continue;
if (!__parsed) continue;
var __gtn = 0;
try {
__gtn = (typeN === '0' || typeN === '1' || typeN === '3')
? parseInt(typeN)
: inferGroupType(__groups[__gi], __parsed.options);
} catch (__e3) {
console.error('[小助手] 第' + (i + 1) + '块 推断题型失败:', __e3 && __e3.message);
continue;
}
try {
questionList.push({
'question': question,
'type': groupTypeName(__gtn),
'kind': 'choice',
'questionid': questionId,
'gidx': __gi, // 4.10.4:同题块内第几组选项,用于区分阅读/完型多小题
'typeNum': __gtn,
'options': __parsed.options,
'lis': __parsed.lis
});
} catch (__e4) {
console.error('[小助手] 第' + (i + 1) + '块 入队失败:', (__e4 && __e4.message), (__e4 && __e4.stack));
continue;
}
__pushed++;
console.log('[小助手] 第' + (i + 1) + '块 已入队, 共' + questionList.length + '题');
}
// 没有选项组的判断题
if (!__pushed && (typeN === '3' || inferJudgeByValParam(questionElement))) {
var __jlis = [];
var __all = questionElement.getElementsByTagName('li');
for (var __ji = 0; __ji < __all.length; __ji++) {
if (__all[__ji].getAttribute('val-param')) __jlis.push(__all[__ji]);
}
questionList.push({
'question': question,
'type': '判断题',
'kind': 'choice',
'questionid': questionId,
'typeNum': 3,
'options': { length: 0 },
'lis': __jlis
});
}
}
}
try {
console.log('[小助手] 解析完成:' + questionList.length + '/' + questionsElement.length + ' 题 -> ' +
questionList.map(function (q) {
return (q['kind'] === 'blank' ? '填空' : q['type']) +
(q['lis'] ? ('/' + q['lis'].length + '项') : '');
}).join(' | '));
} catch (e) { console.warn('[小助手] 解析日志异常', e); }
var qu = null,
nowTime = -4000,
busyThread = questionList.length,
answeredCount = 0, // 4.10.4:已答小题数,与 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'] ;
_w.top.unrivalWorkInfo = '题目:' + quu['question'] + ':未搜索到答案';
}
} 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;
}
else if(ctResult['code'] == -2){
_w.top.unrivalWorkInfo = ctResult['msg'];
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);
}
}
// ===== 移植自万能脚本的匹配工具 =====
function HTMLDecode(text) {
var temp = _d.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 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)(,|$)/));
}
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, m = t.length, 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);
cost = si === tj ? 0 : 1;
d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
}
}
return ((1 - d[n][m] / l) * 100).toFixed(f);
}
function answerSimilar(src, list) {
return list.map(val => Number(similar(formatString(val), formatString(src), 2)));
}
function getMost(arr) {
arr.reverse();
if (arr.length === 0) return undefined;
var hash = {}, max = 0, trueEl, 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] >= max) { max = hash[el]; trueEl = el; }
}
return trueEl;
}
function getLang(arr) {
if (arr.length === 0) return undefined;
let len = 0, ele;
for (let arrElement of arr) {
if (arrElement.length > len) { len = arrElement.length; ele = arrElement; }
}
return ele ? ele : arr.length > 0 ? arr[0] : [];
}
// ===== 答案解析(修复版)=====
// 官方题库 /scriptService/api/autoFreeAnswer 返回的是「选项下标」数组:
// 单选 [0] / 多选 [0,2] / 判断 [0] 或 [1](也兼容返回 "正确"/"错误" 的旧格式)。
// 旧版移植代码只认字母和原文,下标一律被判成「未找到答案」,这里改成按下标优先解析。
function normalizeAnswerList(raw) {
if (raw === undefined || raw === null) return [];
if (!Array.isArray(raw)) return [[String(raw)]];
if (raw.length && Array.isArray(raw[0])) {
return raw.map(function (a) { return a.map(String); });
}
return [raw.map(String)];
}
// 选项文本清洗:小助手用 slice(1) 去字母,可能残留 "."、"、" 之类前导标点
function cleanOptText(s) {
var t = formatString(String(s));
t = t.replace(/^\s*(正确答案|参考答案|答案)\s*[::]?\s*/i, '');
t = t.replace(/^[A-Fa-f]\s*[\.、.\)\])】::\-—]\s*/, '');
t = t.replace(/^[\s\.、.\)\])】::\-—]+/, '');
return t.trim();
}
function cleanOpt(s) {
return cleanOptText(s).toLowerCase().replace(/\s/g, '');
}
// 一个 token 可能是 "A#B" / "富强 和谐" / "富强、和谐" / "正确答案:A",
// 拆成多个候选片段逐一匹配,解决多选答案「一串文本对不上单个选项」的问题
function expandAnswerTokens(ans) {
var out = [ans];
var parts = String(ans).split(/[#||;;、,,\/\n]+/);
if (parts.length > 1) out = out.concat(parts);
var more = [];
out.forEach(function (x) {
var t = String(x).trim();
if (t && /\s/.test(t)) {
t.split(/\s+/).forEach(function (y) { if (y) more.push(y); });
}
});
var letters = [];
out.concat(more).forEach(function (x) {
var t = String(x).trim();
if (/^[A-Fa-f]{2,6}$/.test(t)) {
t.split('').forEach(function (y) { letters.push(y); });
}
});
return out.concat(more).concat(letters);
}
function resolveAnswer(list, qu) {
var optionKeys = Object.keys(qu['options']).filter(function (k) { return k !== 'length'; });
var type = { '单选题': 0, '多选题': 1, '判断题': 3 }[qu['type']];
var groups = normalizeAnswerList(list);
var targetOptionsList = [];
var beautifulOptions = optionKeys.map(cleanOpt);
var lastAnswers = [];
for (var g = 0; g < groups.length; g++) {
var answers = groups[g];
if (!answers.length) continue;
lastAnswers = answers;
if (type === 3) {
if (targetOptionsList.length > 3) break;
var judge = new Set();
for (var a1 = 0; a1 < answers.length; a1++) {
var s1 = answers[a1].trim();
if (/^[01]$/.test(s1)) judge.add(Number(s1));
else if (isTrue(s1)) judge.add(0);
else if (isFalse(s1)) judge.add(1);
}
if (judge.size > 0) targetOptionsList.push(judge);
continue;
}
if (type !== 0 && type !== 1) continue;
var target = new Set();
for (var a2 = 0; a2 < answers.length; a2++) {
var tries = expandAnswerTokens(answers[a2]);
for (var t2 = 0; t2 < tries.length; t2++) {
var ans = String(tries[t2]).trim();
if (!ans) continue;
if (/^\d+$/.test(ans) && Number(ans) < optionKeys.length) {
target.add(Number(ans));
continue;
}
if (ans.length === 1 && isPlainAnswer(ans)) {
target.add(ans.toUpperCase().charCodeAt(0) - 65);
}
var val = cleanOpt(ans);
if (/^[a-f]$/.test(val)) {
target.add(val.charCodeAt(0) - 97);
} else if (/^[a-f]{2,6}$/.test(val)) {
val.split('').forEach(function (ch) { target.add(ch.charCodeAt(0) - 97); });
}
var optIndex = beautifulOptions.indexOf(val);
if (optIndex >= 0) target.add(optIndex);
}
}
var needFuzzy = (type === 0 && target.size === 0) || (type === 1 && target.size < 2);
if (!needFuzzy || targetOptionsList.length > 0) {
if (target.size > 0) targetOptionsList.push(target);
continue;
}
for (var a3 = 0; a3 < answers.length; a3++) {
var val3 = cleanOpt(answers[a3]);
if (val3.length >= 5 && val3.indexOf("
65) target.add(ratings.indexOf(maxScore));
}
}
if (target.size > 0) targetOptionsList.push(target);
}
if (type === 3) {
var zero = 0, one = 0;
targetOptionsList.forEach(function (set) {
if (set.has(0)) zero++;
if (set.has(1)) one++;
});
if (zero === 0 && one === 0) return [];
return [zero >= one ? 0 : 1];
}
var sorted = targetOptionsList.map(function (item) {
return Array.from(item).sort(function (a, b) { return a - b; });
});
if (type === 0) {
var items = getMost(sorted.filter(function (i) { return i.length === 1; }));
if (!items || items.length === 0) {
items = getMost(sorted.filter(function (i) { return i.length > 0; }));
}
if (items && items.length > 1) {
// 单选:一段话里对上了多个选项时,只保留最相似的那个,避免把单选点成多选
var srcText = cleanOpt(lastAnswers.join(' '));
var bestIdx = items[0], bestScore = -1;
items.forEach(function (idx) {
var sc = Number(similar(srcText, beautifulOptions[idx], 2));
if (sc > bestScore) { bestScore = sc; bestIdx = idx; }
});
items = [bestIdx];
}
return items || [];
}
if (type === 1) {
var items2 = getMost(sorted.filter(function (i) { return i.length > 1; }));
if (!items2 || items2.length === 0) {
items2 = getLang(sorted.filter(function (i) { return i.length > 0; }));
}
return items2 || [];
}
return [];
}
// ===== 按小助手页面结构点击选项 =====
var TYPE_NAME = { 0: '单选题', 1: '多选题', 3: '判断题' };
// 函数声明会被提升,保证前面解析题目时也能安全取到题型名
function groupTypeName(n) {
n = parseInt(n);
if (n === 1) return '多选题';
if (n === 3) return '判断题';
return '单选题';
}
// 解析一组选项:返回 { options: {文本:{id,value},length}, lis: [li元素] }
function parseOptionGroup(groupEl) {
var lis = groupEl.getElementsByTagName('li');
var arr = [];
var optionList = { length: 0 };
for (var x = 0; x < lis.length; x++) {
var textE = trim(String(lis[x].innerHTML || '').replace(/(^\s*)|(\s*$)/g, ''));
if (!textE) break;
var plain = textE.replace(/<[^>]+>/g, '').trim();
var m = /^([A-Ga-g])[\.、\s::]\s*([\s\S]*)$/.exec(plain);
var value = m ? m[1] : '';
var text = m ? m[2].trim() : plain;
if (!text) break;
optionList[text] = { id: lis[x].getAttribute('id-param'), value: value };
optionList.length++;
arr.push(lis[x]);
}
if (!arr.length || arr.length !== lis.length) return null;
return { options: optionList, lis: arr };
}
function inferGroupType(groupEl, optionList) {
var boxes = groupEl.querySelectorAll ? groupEl.querySelectorAll('input[type="checkbox"]').length : 0;
var radios = groupEl.querySelectorAll ? groupEl.querySelectorAll('input[type="radio"]').length : 0;
if (boxes > 0) return 1;
if (radios === 2) return 3;
if (!radios && inferJudgeByValParam(groupEl)) return 3;
return 0;
}
function inferJudgeByValParam(el) {
var lis = el.getElementsByTagName('li');
var t = 0, f = 0;
for (var i = 0; i < lis.length; i++) {
var vp = lis[i].getAttribute('val-param');
if (vp === 'true') t++;
if (vp === 'false') f++;
}
return t > 0 && f > 0;
}
function isSelected(el) {
if (!el) return false;
if (el.checked === true) return true;
return (el.getAttribute('class') || '').indexOf('cur') >= 0;
}
// 有绑定元素就按元素点,否则退回旧的「按 qid+字母找 li」
function clickOptions(qu, items) {
var type = { '单选题': 0, '多选题': 1, '判断题': 3 }[qu['type']];
var lis = qu['lis'];
var qid = qu['qid'] !== undefined ? String(qu['qid']) : qu['questionid'].replace('answer', '');
var choiceEs = _d.getElementsByTagName('li');
var satisfied = 0;
var wantMap = {};
items.forEach(function (i) { wantMap[i] = true; });
if (lis && lis.length) {
for (var i = 0; i < lis.length; i++) {
var el = lis[i];
var selected = isSelected(el);
if (wantMap[i] && !selected) {
el.click();
selected = isSelected(el);
} else if (!wantMap[i] && selected && type === 1) {
el.click();
selected = isSelected(el);
}
if (wantMap[i] && selected) satisfied++;
}
return satisfied;
}
// —— 旧路径(没有绑定元素时)——
if (type === 3) {
var ordered = [];
for (var y = 0; y < choiceEs.length; y++) {
if (choiceEs[y].getAttribute('id-param') == qid) ordered.push(choiceEs[y]);
}
var target = null;
var v = items[0];
if (typeof v === 'number') target = ordered[v] || null;
if (target) {
if (!isSelected(target)) target.click();
if (isSelected(target)) satisfied = 1;
}
return satisfied;
}
var optionKeys = Object.keys(qu['options']).filter(function (k) { return k !== 'length'; });
for (var oi = 0; oi < optionKeys.length; oi++) {
var value = qu['options'][optionKeys[oi]]['value'];
for (var y2 = 0; y2 < choiceEs.length; y2++) {
var ems = choiceEs[y2].getElementsByTagName('em');
if (ems.length < 1) continue;
if (ems[0].getAttribute('id-param') != value) continue;
if (choiceEs[y2].getAttribute('id-param') != qid) continue;
var sel = isSelected(choiceEs[y2]);
if (wantMap[oi] && !sel) {
choiceEs[y2].click();
sel = isSelected(choiceEs[y2]);
} else if (!wantMap[oi] && sel && type === 1) {
choiceEs[y2].click();
sel = isSelected(choiceEs[y2]);
}
if (wantMap[oi] && sel) satisfied++;
break;
}
}
return satisfied;
}
function verifyChoice(qu, items) {
var lis = qu['lis'];
var type = { '单选题': 0, '多选题': 1, '判断题': 3 }[qu['type']];
var qid = qu['qid'] !== undefined ? String(qu['qid']) : qu['questionid'].replace('answer', '');
var choiceEs = _d.getElementsByTagName('li');
if (lis && lis.length) {
for (var i = 0; i < items.length; i++) {
var idx = items[i];
if (idx < 0 || idx >= lis.length) return false;
if (!isSelected(lis[idx])) return false;
}
return items.length > 0;
}
if (type === 3) {
var ordered = [];
for (var y = 0; y < choiceEs.length; y++) {
if (choiceEs[y].getAttribute('id-param') == qid) ordered.push(choiceEs[y]);
}
var idx2 = items[0];
return typeof idx2 === 'number' && isSelected(ordered[idx2]);
}
var optionKeys = Object.keys(qu['options']).filter(function (k) { return k !== 'length'; });
for (var j = 0; j < items.length; j++) {
var oi = items[j];
if (oi < 0 || oi >= optionKeys.length) return false;
var value = qu['options'][optionKeys[oi]]['value'];
var hit = false;
for (var y2 = 0; y2 < choiceEs.length; y2++) {
var ems = choiceEs[y2].getElementsByTagName('em');
if (ems.length < 1) continue;
if (ems[0].getAttribute('id-param') != value) continue;
if (choiceEs[y2].getAttribute('id-param') != qid) continue;
hit = isSelected(choiceEs[y2]);
break;
}
if (!hit) return false;
}
return items.length > 0;
}
// 填空:按 ==== 或 | 拆答案,依次写进输入框(已有内容的框不覆盖)
function fillBlanks(qu, text) {
var els = qu['blanks'] || [];
var rawText = String(text === undefined || text === null ? '' : text).trim();
if (!els.length || !rawText) return 0;
var parts = rawText.split(/\s*====\s*|[||]/).map(function (x) { return x.trim(); }).filter(function (x) { return !!x; });
if (!parts.length) return 0;
var filled = 0;
for (var i = 0; i < els.length; i++) {
var el = els[i];
if (!el || el.disabled || el.readOnly) continue;
if (el.value && String(el.value).trim()) { filled++; continue; }
var v = parts[i] !== undefined ? parts[i] : (parts.length === 1 ? parts[0] : '');
if (!v) continue;
el.value = v;
try {
el.dispatchEvent(new Event('input', { bubbles: true }));
el.dispatchEvent(new Event('change', { bubbles: true }));
} catch (e) {
try {
var ev = _d.createEvent('HTMLEvents');
ev.initEvent('input', true, true);
el.dispatchEvent(ev);
} catch (e2) {}
}
filled++;
}
return filled;
}
// 填空答案:票数优先,平票取更长的那条
function pickBlank(cands) {
var map = {}, best = null;
for (var i = 0; i < cands.length; i++) {
var t = cands[i].tokens;
var s = Object.prototype.toString.call(t) === '[object Array]'
? t.map(function (x) { return String(x).trim(); }).filter(function (x) { return !!x; }).join('====')
: String(t === undefined || t === null ? '' : t).trim();
if (!s) continue;
if (!map[s]) map[s] = { text: s, votes: 0, src: [] };
map[s].votes++;
map[s].src.push(cands[i].name);
if (!best || map[s].votes > best.votes ||
(map[s].votes === best.votes && s.length > best.text.length)) best = map[s];
}
return best;
}
// ===== 纯免费聚合引擎 =====
// 五个免登录、免付费源:不挂科 / 万能免费 / Muketool / lyck6接口 / apibyte
// 另有 icodef(公众号免费领 token)、万能备用节点,默认关闭。
var TIKU_SOURCES = [
{ id: 'buguake', name: '不挂科', enable: true, timeout: 6000 },
{ id: 'wanneng', name: '万能免费', enable: true, timeout: 7000 },
{ id: 'muketool', name: 'Muketool', enable: true, timeout: 3000 },
{ id: 'lyck6cx', name: 'lyck6接口', enable: true, timeout: 3000 },
{ id: 'apibyte', name: 'apibyte', enable: true, timeout: 4000 },
{ id: 'icodef', name: 'icodef', enable: false, timeout: 5000 },
{ id: 'tiku168', name: '万能备用', enable: false, timeout: 6000 }
];
function srcOn(id, def) {
var v = GM_getValue('src_' + id);
if (v === undefined || v === null || v === '') return def;
return v == 1 || v === true;
}
function xhr(o) {
return new Promise(function (resolve, reject) {
GM_xmlhttpRequest({
method: o.method || 'GET',
url: o.url,
headers: o.headers || {},
data: o.data,
timeout: o.timeout || 8000,
onload: function (r) {
if (r.status >= 200 && r.status < 300) { resolve(r); return; }
reject(new Error('HTTP ' + r.status));
},
onerror: function () { reject(new Error('网络错误')); },
ontimeout: function () { reject(new Error('超时')); }
});
});
}
// ===== 本地缓存:同一道题只查一次 =====
var CACHE_KEY = 'qb_cache_v1';
function loadCache() {
try {
var raw = GM_getValue(CACHE_KEY, '');
return raw ? JSON.parse(raw) : {};
} catch (e) { return {}; }
}
var CACHE_TTL = 7 * 24 * 3600 * 1000;
function cacheGet(k) {
var v = loadCache()[k];
if (!v) return null;
if (Object.prototype.toString.call(v) === '[object Array]') {
return v.length ? v : null; // 旧格式(数组)
}
if (v.t && (Date.now() - v.t) > CACHE_TTL) return null; // 过期
return (v.items && v.items.length) ? v.items : null;
}
function cachePut(k, items) {
if (!items || !items.length) return;
var c = loadCache();
c[k] = { t: Date.now(), items: items };
var keys = Object.keys(c);
if (keys.length > 400) delete c[keys[0]];
try { GM_setValue(CACHE_KEY, JSON.stringify(c)); } catch (e) {}
}
// ===== 答案解析工具 =====
function stripAnswerPrefix(s) {
return String(s).replace(/^\s*(正确答案|参考答案|答案)\s*[::]?\s*/i, '').trim();
}
// 兼容 JSON / 纯文本 / "A" / "AB" / "A,B" / 长句 等返回
function parseSimpleBank(text) {
if (!text) return [];
var t = String(text).trim();
if (!t || t === 'null' || t === 'undefined' || t.charAt(0) === '<') return [];
var out = [];
try {
var j = JSON.parse(t);
if (typeof j === 'string') { out.push(j); }
var keys = ['answer', 'Answer', 'answers', 'data', 'result', 'msg', 'content',
'answerStr', 'correctAnswer', 'correct', 'option'];
for (var i = 0; i < keys.length; i++) {
var v = j[keys[i]];
if (typeof v === 'string' && v.trim()) { out.push(v); break; }
if (Object.prototype.toString.call(v) === '[object Array]') {
v.forEach(function (x) {
if (typeof x === 'string') out.push(x);
else if (x && typeof x === 'object') {
var s = x.answer || x.option || x.content || x.name || x.value || '';
if (s) out.push(String(s));
}
});
break;
}
}
if (!out.length) {
var deep = (function scan(o, d) {
if (d > 3 || !o || typeof o !== 'object') return null;
for (var k in o) {
var val = o[k];
if (typeof val === 'string' && val.trim() && val.length < 120) return val;
var r = scan(val, d + 1);
if (r) return r;
}
return null;
})(j, 0);
if (deep) out.push(deep);
}
} catch (e) {
out.push(t);
}
var res = [];
for (var n = 0; n < out.length; n++) {
var s = stripAnswerPrefix(out[n]);
if (!s || s.length > 120) continue;
if (/^[A-Fa-f][A-Fa-f,,\|;;、\s]*$/.test(s)) {
var parts = s.split(/[,,\|;;、\s]+/).filter(function (x) { return !!x; });
if (parts.length === 1 && /^[A-Fa-f]{2,6}$/.test(parts[0])) {
parts = parts[0].split('');
}
parts.forEach(function (x) { res.push(x.toUpperCase()); });
} else {
s.split(/[||]/).forEach(function (x) {
x = x.trim();
if (x) res.push(x);
});
}
}
return res;
}
function simpleBank(buildUrl) {
return function (ctx) {
return xhr({
url: buildUrl(ctx.question),
timeout: ctx.timeout,
headers: { 'Accept': 'application/json,text/plain,*/*' }
}).then(function (r) {
var toks = parseSimpleBank(r.responseText);
if (!toks.length) throw new Error('无答案');
return toks;
});
};
}
// ===== 万能官方题库(lyck6 / tiku168 同接口,返回选项下标)=====
function wannengLike(host) {
return function (ctx) {
return xhr({
method: 'POST',
url: host + '/scriptService/api/autoFreeAnswer',
headers: {
'Content-Type': 'application/json;charset=utf-8',
'Version': '5.4.2'
},
data: JSON.stringify({
question: ctx.question,
options: ctx.options,
type: ctx.type,
location: location.href
}),
timeout: ctx.timeout
}).then(function (r) {
var j = JSON.parse(r.responseText);
if (!j || j.code !== 0 || !j.result) {
throw new Error((j && (j.message || j.msg)) || '接口异常');
}
var ans = j.result.answers || [];
if (!ans.length) throw new Error('无答案');
return ans;
});
};
}
// ===== 百度不挂科:解密移植自 tikuAdapter/internal/search/buguake.go =====
var BUGUAKE_KEY = '34cab29ef956d78afd';
function buguakeDecrypt(t, r) {
var e = BUGUAKE_KEY + r;
var bin = atob(t);
var x = new Uint8Array(bin.length);
for (var i = 0; i < bin.length; i++) {
x[i] = bin.charCodeAt(i) ^ e.charCodeAt(i % e.length);
}
var s = '';
for (var p = 0; p < x.length - 1; p++) {
s += String.fromCharCode(x[p] ^ x[p + 1]);
p++;
}
try {
s = decodeURIComponent(s.replace(/\+/g, '%20'));
} catch (err) {
s = s.replace(/\+/g, ' ');
}
return s;
}
function bdText(node) {
if (node === null || node === undefined) return '';
if (typeof node === 'string') return node;
if (Object.prototype.toString.call(node) === '[object Array]') {
return node.map(bdText).join('');
}
if (typeof node === 'object') {
if (typeof node.c === 'string') return node.c;
if (node.c) return bdText(node.c);
}
return '';
}
function buguakeQuery(ctx) {
var url = 'https://easylearn.baidu.com/edu-web-go/bgk/searchlist?query=' +
encodeURIComponent(ctx.question) + '&rn=10&pn=0';
return xhr({ url: url, timeout: ctx.timeout }).then(function (r) {
var j = JSON.parse(r.responseText);
var list = (j.data && j.data.list) || [];
var best = null;
for (var i = 0; i < list.length; i++) {
var dec;
try {
dec = JSON.parse(buguakeDecrypt(list[i].bdjson, list[i].actk));
} catch (e) { continue; }
var stem = (((dec.que_stem || [])[0] || {}).c || [])[0];
if (!stem || !stem.c) continue;
var score = Number(similar(formatString(ctx.question), formatString(stem.c), 2));
if (score < 75) continue;
if (best && best.score >= score) continue;
var opt = ((((dec.que_options || [])[0] || {}).ret || [])[0] || {}).c;
var tokens = [];
if (opt && opt.length) {
tokens = opt.map(function (o) { return bdText(o); });
} else {
tokens = [bdText((dec.que_answer || [])[0])];
}
tokens = tokens.filter(function (x) { return x && String(x).trim(); });
if (!tokens.length) continue;
best = { score: score, tokens: tokens };
}
if (!best) throw new Error('无答案');
return best.tokens;
});
}
// ===== apibyte:每天 50 次免费额度,自己计数 =====
var APIBYTE_LIMIT = 50;
function apibyteQuotaOk() {
var today = new Date(Date.now() + 8 * 3600 * 1000).toISOString().slice(0, 10);
if (GM_getValue('qb_apibyte_date') !== today) {
GM_setValue('qb_apibyte_date', today);
GM_setValue('qb_apibyte_count', 0);
return true;
}
return (Number(GM_getValue('qb_apibyte_count')) || 0) < APIBYTE_LIMIT;
}
function apibyteIncr() {
GM_setValue('qb_apibyte_count', (Number(GM_getValue('qb_apibyte_count')) || 0) + 1);
}
function apibyteQuery(ctx) {
if (!apibyteQuotaOk()) return Promise.reject(new Error('今日额度用完'));
return xhr({
url: 'https://apione.apibyte.cn/edusearch?question=' + encodeURIComponent(ctx.question) +
'&platform=chaoxing',
timeout: ctx.timeout
}).then(function (r) {
apibyteIncr();
var toks = parseSimpleBank(r.responseText);
if (!toks.length) throw new Error('无答案');
return toks;
}, function (e) {
apibyteIncr();
throw e;
});
}
// ===== icodef(可选,需免费 token)=====
function icodefQuery(ctx) {
var token = GM_getValue('tikutoken', '') || '';
if (!token) return Promise.reject(new Error('未配置Token'));
return xhr({
method: 'POST',
url: 'https://cx.icodef.com/wyn-nb?v=4',
headers: {
'Content-type': 'application/x-www-form-urlencoded',
'Authorization': token
},
data: 'question=' + encodeURIComponent(ctx.question),
timeout: ctx.timeout
}).then(function (r) {
var j = JSON.parse(r.responseText);
if (!j || j.code !== 1 || !j.data) throw new Error((j && (j.msg || j.data)) || '无答案');
return String(j.data).split('#');
});
}
// ===== AI 兜底(OpenAI 兼容)=====
// 4.11:15 秒超时 + 单次重试;兼容流式(SSE);按题型给不同指令;填空/简答同样可用
function aiAnswer(qu, optionTexts, typeNum) {
var url = String(GM_getValue('ai_url', 'https://api.deepseek.com/v1') || '').replace(/\/+$/, '');
var key = String(GM_getValue('ai_key', '') || '');
var model = String(GM_getValue('ai_model', 'deepseek-flash') || 'deepseek-flash');
if (!url || !key) return Promise.reject(new Error('未配置AI'));
if (!/\/chat\/completions$/.test(url)) url += '/chat/completions';
var isBlank = !(typeNum === 0 || typeNum === 1 || typeNum === 3);
var rule = typeNum === 0 ? '只输出一个选项字母(A/B/C/D)'
: typeNum === 1 ? '输出全部正确选项的字母,连续无分隔,例如 ACD'
: typeNum === 3 ? '只输出"正确"或"错误"'
: '直接给出答案原文;多个空用 | 分隔';
var body = '【题型】' + (isBlank ? '填空/简答'
: typeNum === 1 ? '多选题' : typeNum === 3 ? '判断题' : '单选题') +
'\n【题目】' + String(qu['question'] || '').replace(/<[^>]+>/g, '').trim();
if (optionTexts && optionTexts.length) {
body += '\n【选项】\n' + optionTexts.map(function (t, i) {
return String.fromCharCode(65 + i) + '. ' + t;
}).join('\n');
}
body += '\n要求:' + rule + '。只给答案,不要解释。';
function once() {
return new Promise(function (resolve, reject) {
GM_xmlhttpRequest({
method: 'POST',
url: url,
headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + key },
data: JSON.stringify({
model: model,
temperature: 0.1,
max_tokens: 512,
messages: [
{ role: 'system', content: '你是网课答题助手,严格按要求只输出答案本身,不加解释。' },
{ role: 'user', content: body }
]
}),
timeout: 15000,
onload: function (r) {
var status = r.status;
var raw = String(r.responseText || '').trim();
// 非 200:把状态码 + 接口原文一起抛出去,用户一眼能看出是 key 错、余额不足还是限流
if (status && (status < 200 || status >= 300)) {
var em = '';
try {
var ej = JSON.parse(raw);
em = ((ej.error || {}).message) || ej.message || '';
} catch (e3) { }
return reject(new Error('AI HTTP ' + status + (em ? ':' + em : ':' + raw.slice(0, 160))));
}
var txt = '';
try {
var j = JSON.parse(raw);
txt = (((j.choices || [])[0] || {}).message || {}).content || '';
} catch (e) {
// 流式(SSE):拼接 data: 行里的 delta.content
if (raw.indexOf('data:') >= 0) {
raw.split('\n').forEach(function (ln) {
ln = ln.trim();
if (ln.indexOf('data:') !== 0 || ln === 'data: [DONE]') return;
try {
var c = JSON.parse(ln.slice(5).trim());
var d = (((c.choices || [])[0] || {}).delta || {}).content;
if (d) txt += d;
} catch (e2) { }
});
}
}
txt = String(txt).trim();
if (!txt) return reject(new Error('AI返回为空,原始响应:' + raw.slice(0, 160)));
resolve(txt);
},
onerror: function (e) {
reject(new Error('AI网络错误' + (e && e.error ? ':' + e.error : '')));
},
ontimeout: function () { reject(new Error('AI超时(15s)请检查接口地址或网络')); }
});
});
}
function parse(txt) {
if (typeNum === 3) {
if (/正确|对|√|true/i.test(txt)) return ['正确'];
if (/错误|错|×|false/i.test(txt)) return ['错误'];
throw new Error('AI答案无法解析');
}
if (isBlank) {
return [txt.replace(/^【?答案】?[::]?\s*/, '').trim()];
}
var m = txt.match(/[A-Ha-h]/g);
if (m && m.length) {
var out = [];
m.forEach(function (c) {
c = c.toUpperCase();
if (out.indexOf(c) < 0) out.push(c);
});
if (out.length) return out;
}
throw new Error('AI答案无法解析');
}
// 失败重试一次(间隔 1.2s),两次都失败才抛
return once().catch(function () {
return new Promise(function (res) { setTimeout(res, 1200); }).then(once);
}).then(parse);
}
var PROVIDERS = {
buguake: buguakeQuery,
wanneng: wannengLike('https://lyck6.cn'),
muketool: simpleBank(function (q) { return 'https://api.muketool.com?question=' + encodeURIComponent(q); }),
lyck6cx: simpleBank(function (q) { return 'http://cx.lyck6.cn/api/api.php?question=' + encodeURIComponent(q); }),
apibyte: apibyteQuery,
icodef: icodefQuery,
tiku168: wannengLike('https://tiku168.net')
};
// 并发查所有启用源:全部返回 / 两源一致 / 8 秒到点,三者任一即收
function queryAllSources(ctx, qu) {
var srcs = TIKU_SOURCES.filter(function (s) { return srcOn(s.id, s.enable); });
return new Promise(function (resolve) {
if (!srcs.length) { resolve([]); return; }
var results = [], left = srcs.length, done = false;
var timer = setTimeout(finishNow, 8000);
var graceTimer = null;
function finishNow() {
if (done) return;
done = true;
clearTimeout(timer);
if (graceTimer) clearTimeout(graceTimer);
resolve(results);
}
function settle(name, items) {
results.push({ name: name, items: items });
var tally = {};
for (var i = 0; i < results.length; i++) {
var k = results[i].items.join(',');
tally[k] = (tally[k] || 0) + 1;
if (tally[k] >= 2) { finishNow(); return; }
}
// 已经有答案了:再给其他源 1.8 秒,凑不到第二票就先用这个
if (!graceTimer) graceTimer = setTimeout(finishNow, 1800);
}
srcs.forEach(function (s) {
var p;
try {
p = PROVIDERS[s.id]({
question: ctx.question,
options: ctx.options,
type: ctx.type,
timeout: s.timeout
});
} catch (e) {
p = Promise.reject(e);
}
p.then(function (tokens) {
var items = resolveAnswer(tokens, qu);
if (items && items.length) settle(s.name, items);
}, function (e) {
console.warn('[题库]', s.name, e && e.message);
}).then(function () {
left--;
if (left === 0) finishNow();
});
});
});
}
function voteAnswers(list) {
var map = {}, best = null;
for (var i = 0; i < list.length; i++) {
var key = list[i].items.join(',');
if (!map[key]) map[key] = { items: list[i].items, votes: 0, src: [] };
map[key].votes++;
map[key].src.push(list[i].name);
if (!best || map[key].votes > best.votes) best = map[key];
}
return best;
}
// 填空/简答用的原始查询:不做选项解析,只把各源的文本答案收回来
function queryAllRawSources(ctx) {
var srcs = TIKU_SOURCES.filter(function (s) { return srcOn(s.id, s.enable); });
return new Promise(function (resolve) {
if (!srcs.length) { resolve([]); return; }
var results = [], left = srcs.length, done = false;
var timer = setTimeout(finishNow, 8000);
var graceTimer = null;
function finishNow() {
if (done) return;
done = true;
clearTimeout(timer);
if (graceTimer) clearTimeout(graceTimer);
resolve(results);
}
function settle(name, tokens) {
results.push({ name: name, tokens: tokens });
var tally = {};
for (var i = 0; i < results.length; i++) {
var t = results[i].tokens;
var k = Object.prototype.toString.call(t) === '[object Array]' ? t.join('====') : String(t);
tally[k] = (tally[k] || 0) + 1;
if (tally[k] >= 2) { finishNow(); return; }
}
if (!graceTimer) graceTimer = setTimeout(finishNow, 1800);
}
srcs.forEach(function (s) {
var p;
try {
p = PROVIDERS[s.id]({
question: ctx.question,
options: ctx.options || [],
type: ctx.type || 4,
timeout: s.timeout
});
} catch (e) {
p = Promise.reject(e);
}
p.then(function (tokens) {
var empty = !tokens || (Object.prototype.toString.call(tokens) === '[object Array]' && !tokens.length);
if (!empty) settle(s.name, tokens);
}, function (e) {
console.warn('[题库]', s.name, e && e.message);
}).then(function () {
left--;
if (left === 0) finishNow();
});
});
});
}
// ===== 逐题查询 =====
for (let i = 0, l = questionList.length; i < l; i++) {
nowTime += parseInt(Math.random() * 3000 + 3500, 10);
setTimeout(function () {
let __done = false;
try {
let qu = questionList[i];
console.log('[小助手] 第' + (i + 1) + '题 开始:' + (qu['kind'] === 'blank' ? '填空' : qu['type']) + ' ' + String(qu['question']).slice(0, 40));
// ---------- 填空 / 简答 ----------
if (qu['kind'] === 'blank') {
// 4.10.4:缓存键加 questionid,避免不同题同题干串答案
let bk = 'B|' + (qu['questionid'] || '') + '|' + qu['question'];
function blankFinish(tip, txt, src) {
__done = true;
busyThread -= 1;
_w.top.unrivalWorkInfo = qu['question'] + ':' +
(txt ? ('【' + txt + '】(' + src + ')') : tip);
}
let cachedB = cacheGet(bk);
if (cachedB && cachedB.length && fillBlanks(qu, cachedB[0]) > 0) {
answeredCount += 1;
blankFinish('', cachedB[0], '本地缓存');
return;
}
let runBlank = function (attempt) {
queryAllRawSources({
question: qu['question'],
options: [],
type: qu['typeNum'] || 4
}).then(function (cands) {
let best = pickBlank(cands);
if (!best) {
if (attempt < 1) { setTimeout(function () { runBlank(1); }, 1500); return; }
// 4.11:填空/简答也走 AI 兜底(以前只有选择题有)
aiAnswer(qu, [], qu['typeNum'] || 4).then(function (tokens) {
let txt = (tokens && tokens[0]) ? String(tokens[0]).trim() : '';
let n2 = txt ? fillBlanks(qu, txt) : 0;
if (n2 > 0) {
answeredCount += 1;
cachePut(bk, [txt]);
blankFinish('', txt, 'AI');
} else {
blankFinish('AI 没写出答案', null);
}
}).catch(function (e) {
console.warn('[小助手] 填空 AI 兜底失败:', e && e.message);
blankFinish('各免费题库均未搜到(AI:' + (e && e.message) + ')', null);
});
return;
}
let n = fillBlanks(qu, best.text);
if (n > 0) {
answeredCount += 1;
cachePut(bk, [best.text]);
blankFinish('', best.text, best.src.join('/'));
} else {
blankFinish('搜到答案但没写进输入框', null);
}
}).catch(function () {
if (attempt < 1) { setTimeout(function () { runBlank(1); }, 1500); return; }
blankFinish('查题异常', null);
});
};
runBlank(0);
return;
}
// ---------- 选择 / 判断 ----------
let optionKeys = Object.keys(qu['options']).filter(k => k !== 'length');
let typeNum = (qu['typeNum'] !== undefined) ? qu['typeNum'] : { '单选题': 0, '多选题': 1, '判断题': 3 }[qu['type']];
let options = optionKeys.map(cleanOptText);
if (typeNum === 3 && options.length === 0) options = ['正确', '错误'];
function finish(tip, win) {
__done = true;
busyThread -= 1;
if (win && win.items && win.items.length) {
let ansText = typeNum === 3
? (win.items[0] === 0 ? '正确' : '错误')
: win.items.map(function (k) { return optionKeys[k]; }).join(' ');
let tag = win.src.length > 1
? ('(' + win.src.length + '源一致:' + win.src.join('/') + ')')
: ('(' + win.src[0] + (win.votes < 2 ? ',低置信' : '') + ')');
_w.top.unrivalWorkInfo = qu['question'] + ':' + ansText + tag;
console.log('[小助手] 第' + (i + 1) + '题 完成:' + ansText + tag);
} else {
_w.top.unrivalWorkInfo = qu['question'] + ':' + tip;
console.warn('[小助手] 第' + (i + 1) + '题 失败:' + tip);
}
}
// 1) 命中本地缓存(7 天内)
// 4.10.4:缓存键 = 题型|questionid|组序号|题干,避免阅读/完型多小题共用块题干互相串答案
let ck = typeNum + '|' + (qu['questionid'] || '') + '|' +
(qu['gidx'] !== undefined ? qu['gidx'] : 0) + '|' + qu['question'];
let cached = cacheGet(ck);
if (cached && clickOptions(qu, cached) > 0 && verifyChoice(qu, cached)) {
answeredCount += 1;
finish('', { items: cached, src: ['本地缓存'], votes: 2 });
return;
}
// 2) 并发查所有免费源,全空时重试一次
let runChoice = function (attempt) {
queryAllSources({
question: qu['question'],
options: options,
type: typeNum
}, qu).then(function (cands) {
let win = voteAnswers(cands);
// 4.10.4:多选题只解析出 1 个选项,历史上几乎必错(resolveAnswer 的
// getLang 兜底会返回单元素)。判为不可信,走 AI 兜底而不是「点一个就算过」。
if (win && typeNum === 1 && (!win.items || win.items.length < 2)) {
console.warn('[小助手] 第' + (i + 1) + '题 多选只解出 ' +
(win.items ? win.items.length : 0) + ' 项,判为不可信,转 AI 兜底');
win = null;
}
if (!win) {
aiAnswer(qu, optionKeys, typeNum).then(function (tokens) {
let aiItems = resolveAnswer(tokens, qu);
if (!aiItems || !aiItems.length) throw new Error('AI答案对不上选项');
// 4.10.4:多选同样要求至少 2 项,避免「只点一个也算过」
if (typeNum === 1 && aiItems.length < 2) throw new Error('AI多选答案少于2项');
let n = clickOptions(qu, aiItems);
if (n > 0 && verifyChoice(qu, aiItems)) {
answeredCount += 1;
cachePut(ck, aiItems);
console.log('[小助手] 第' + (i + 1) + '题 AI命中: ' + tokens.join(''));
finish('', { items: aiItems, src: ['AI'], votes: 1 });
} else {
finish('AI答案没能点中');
}
}).catch(function (e) {
console.warn('[小助手] 第' + (i + 1) + '题 AI兜底失败:', e && e.message);
if (attempt < 1) { setTimeout(function () { runChoice(1); }, 1500); return; }
finish('各免费题库均未搜到');
});
return;
}
let clicked = clickOptions(qu, win.items);
if (clicked > 0 && verifyChoice(qu, win.items)) {
answeredCount += 1;
cachePut(ck, win.items);
finish('', win);
} else if (clicked > 0) {
finish('点了但没生效(可能被页面重置)');
} else {
finish('匹配到答案但未点中选项');
}
}).catch(function () {
if (attempt < 1) { setTimeout(function () { runChoice(1); }, 1500); return; }
finish('查题异常');
});
};
runChoice(0);
} catch (e) {
console.error('[小助手] 答题异常', (e && e.stack) || e);
if (!__done) { try { busyThread -= 1; } catch (e2) {} }
try { _w.top.unrivalWorkInfo = '答题异常:' + (e && e.message); } catch (e3) {}
}
}, nowTime);
}
// 看门狗已移除(它引用了不存在的 GLOBAL,会每 20 秒抛一次 ReferenceError)
var workInterval = setInterval(function () {
if (busyThread != 0) {
return;
}
clearInterval(workInterval);
// 4.10.3 修了 Math.floor 的位置;4.10.4 再修口径与边界:
// a) 分母必须是「解析出来的小题数」,不能用题块数(阅读/完型一块多小题会导致 pct>100%)
// b) 题目数为 0 时不能返回 100%(会把空卷当达标直接提交)
// c) accuracy 可能是空串/NaN/越界,强制成数字并夹在 0-100
var __totalQ = questionList.length;
var __answeredNum = answeredCount;
var __accuracyNum = Number(accuracy);
// 空串/null 会被 Number() 变成 0(=阈值0=永远提交),越界值同理,一律回落到 60
if (accuracy === '' || accuracy === null || accuracy === undefined ||
!isFinite(__accuracyNum) || __accuracyNum < 0 || __accuracyNum > 100) {
__accuracyNum = 60;
}
__accuracyNum = Math.max(0, Math.min(100, __accuracyNum));
var __answeredPct = __totalQ > 0
? Math.floor(__answeredNum / __totalQ * 100) : 0;
console.log('[小助手] 已答 ' + __answeredNum + '/' + __totalQ + ' 小题 = ' +
__answeredPct + '%,提交阈值 ' + __accuracyNum + '%,自动提交=' +
_w.top.unrivalAutoSubmit + ',自动保存=' + _w.top.unrivalAutoSave);
if (__totalQ > 0 && __answeredPct >= __accuracyNum && _w.top
.unrivalAutoSubmit == '1') {
// 4.10.4:不再提交前就写 DoneWorkId(原来一写,下次进入就会被判定已完成而不再重试)
_w.top.unrivalWorkInfo = '已答 ' + __answeredNum + '/' + __totalQ + ',正在提交…';
setTimeout(function () {
// 4.10.4:
// a) 去掉 eval(沙箱里必失败、raw 下与 _w 等价,属无效代码)
// b) 探测顺序改成 _w(作业 iframe 自己的窗口)优先,再退到 _w.top
// c) 只有「一个都没调用成功」才点按钮兜底,避免函数已提交又点一次 → 重复提交
// d) 有函数抛错时不再打印「已调用页面提交函数提交」这种假成功日志
var __submitFns = ['submitCheckTimes', 'escapeBlank', 'submitAction'];
var __missing = [], __okCount = 0, __callErr = 0;
__submitFns.forEach(function (__fn) {
var __f = null;
try { if (typeof _w[__fn] === 'function') __f = _w[__fn]; } catch (__e) { }
if (typeof __f !== 'function') {
try { if (typeof _w.top[__fn] === 'function') __f = _w.top[__fn]; } catch (__e) { }
}
if (typeof __f !== 'function') { __missing.push(__fn); return; }
try { __f(); __okCount += 1; } catch (__e) {
__callErr += 1;
console.error('[小助手] 调用 ' + __fn + ' 抛错:', __e && __e.message);
}
});
// 实测本页真实提交入口是 submitData()(按钮 onclick=submitData();)。
// 仅当没有 submitAction 时才用它,避免「已提交又提交一次」。
if (__okCount > 0 && __missing.indexOf('submitAction') >= 0) {
var __sd = null;
try { if (typeof _w.submitData === 'function') __sd = _w.submitData; } catch (__e) { }
if (!__sd) {
try { if (typeof _w.top.submitData === 'function') __sd = _w.top.submitData; } catch (__e) { }
}
if (__sd) {
try { __sd(); __okCount += 1; console.log('[小助手] 已调用 submitData 提交'); }
catch (__e) { console.error('[小助手] submitData 抛错:', __e && __e.message); }
}
}
if (__okCount === 0) {
console.error('[小助手] 提交函数一个都没取到:', __missing.join(', '));
// 只找「提交」类按钮,绝不退回点「保存」
// 实测本页:button.btn-ok-bottom[onclick="submitData();"],文字「提交」
var __sel = '.btn-ok-bottom, #btnBlueSubmit, .btnBlue, #submitBtn, .completeBtn,' +
' button[onclick*="submit"], a[onclick*="submit"],' +
' button[onclick*="Submit"], a[onclick*="Submit"]';
var __btn = null;
try { __btn = _d.querySelector(__sel); } catch (__e) { }
if (!__btn) {
try { __btn = _w.top.document.querySelector(__sel); } catch (__e) { }
}
if (__btn) {
__btn.click();
_w.top.unrivalDoneWorkId = getQueryVariable('workId');
_w.top.unrivalWorkInfo = '已点击提交按钮(兜底),请确认页面结果';
console.log('[小助手] 已点击提交按钮兜底');
} else {
_w.top.unrivalWorkInfo = '提交失败:页面没有提交函数也没有提交按钮,请手动提交';
console.error('[小助手] 也找不到提交按钮,请手动提交');
}
} else if (__callErr > 0) {
_w.top.unrivalWorkInfo = '提交函数调用有异常(' + __callErr + ' 个),请检查页面是否已提交';
console.error('[小助手] 提交函数调用异常 ' + __callErr + ' 个');
} else {
_w.top.unrivalDoneWorkId = getQueryVariable('workId');
_w.top.unrivalWorkInfo = '已调用页面提交函数提交';
console.log('[小助手] 已调用页面提交函数提交');
}
// 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 = '正确率不符合标准或未设置自动提交,已自动保存答案';
setTimeout(function () {
// 4.10.4:noSubmit 也是页面函数,原来裸调未做存在性检查
var __noSub = null;
try { if (typeof _w.noSubmit === 'function') __noSub = _w.noSubmit; } catch (__e) { }
if (!__noSub) {
try { if (typeof _w.top.noSubmit === 'function') __noSub = _w.top.noSubmit; } catch (__e) { }
}
if (__noSub) {
try {
__noSub();
_w.top.unrivalDoneWorkId = getQueryVariable('workId');
console.log('[小助手] 已调用 noSubmit 保存');
} catch (__e) {
console.error('[小助手] noSubmit 抛错:', __e && __e.message);
}
} else {
console.error('[小助手] 页面没有 noSubmit,尝试点保存按钮');
// 实测本页:button.btn-save[onclick="noSubmit();"],文字「保存」
var __saveSel = '.btn-save, a[onclick*="save"], button[onclick*="save"],' +
' #saveBtn, .btnSave, a[onclick*="Save"]';
var __sb = null;
try { __sb = _d.querySelector(__saveSel); } catch (__e) { }
if (!__sb) {
try { __sb = _w.top.document.querySelector(__saveSel); } catch (__e) { }
}
if (__sb) { __sb.click(); console.log('[小助手] 已点击保存按钮兜底'); }
else console.error('[小助手] 保存也失败,请手动保存');
}
}, 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);
}
})();