// ==UserScript== // @name 中国宝武学习系统-全能版本学习助手【多账户、多模式】 // @namespace https://learn.baowugroup.com/ // @version 8.9.71 // @description 宝武学习平台全自动挂机(AI答题、自动考试、自动调查、自动收藏点赞评论、多账号托管) // @author 令狐不太冲 // @icon https://learn.baowugroup.com/favicon.png // @license MIT // @match https://learn.baowugroup.com/* // @grant GM_setValue // @grant GM_getValue // @grant unsafeWindow // @require https://scriptcat.org/lib/8095/1.0.0/bw_learn_tool_utl_lib.js?sha384-8DUdixfmCvNg3ejsXviRkFfJm0drMFgmWTCOuEYiRa3Hgxr8W+Ct3J6BoKYtnKGp // @require https://scriptcat.org/lib/8094/1.0.0/bw_api_lib.js?sha384-hcDDeNwBTdkm5rbC0Z4vcJJbgwAPqfJrUrYSFWt9J1gS0h7fkedEMabxFST8im8s // @require https://cdn.jsdelivr.net/npm/tesseract.js@5.0.5/dist/tesseract.min.js // @run-at document-idle // ==/UserScript== (function(){ 'use strict'; var BWAPI=unsafeWindow.BWAPI,BWUTL=unsafeWindow.BWUTL; const ST={get:(k,d)=>GM_getValue(k,d),set:(k,v)=>GM_setValue(k,v)}; const S={running:ST.get('bw_running',!1),queue:ST.get('bw_queue',[]),queueIdx:ST.get('bw_queueIdx',0),accounts:ST.get('bw_accounts',[]),currentAccIdx:ST.get('bw_currentAccIdx',0),zones:{},tab:'zone',speed:ST.get('bw_speed',1),scoreInterval:ST.get('bw_scoreInterval',30),autoExam:ST.get('bw_autoExam',!0),autoSurvey:ST.get('bw_autoSurvey',!0),autoFav:ST.get('bw_autoFav',!0),autoLike:ST.get('bw_autoLike',!0),autoComment:ST.get('bw_autoComment',!0),aiApiKey:ST.get('bw_aiApiKey',''),logEl:null,studyTimer:null,chapterTimer:null,lastScoreCheck:0,retryCount:0,doneBefore:ST.get('bw_doneBefore',0),doneToday:0,ocr:null,lastScore:null,lastStudyMinutes:-1,apiStaleCount:0,surveyHandled:!1,examHandled:!1,userStopped:!1}; const $=(s,r=document)=>r.querySelector(s),$$=(s,r=document)=>[...r.querySelectorAll(s)]; const sleep=ms=>new Promise(r=>setTimeout(r,ms)); const now=()=>{const d=new Date();return `[${String(d.getHours()).padStart(2,'0')}:${String(d.getMinutes()).padStart(2,'0')}:${String(d.getSeconds()).padStart(2,'0')}]`}; const btn=(kw,scope=document)=>[...scope.querySelectorAll('button')].find(b=>b.textContent.includes(kw)&&b.offsetParent); const btnEq=(kw,scope=document)=>[...scope.querySelectorAll('button')].find(b=>b.textContent.trim()===kw&&b.offsetParent); function log(m,t='info'){const c={info:'#4fc3f7',ok:'#81c784',warn:'#ffb74d',err:'#e57373',run:'#ce93d8'};const l=document.createElement('div');l.style.cssText=`color:${c[t]||'#ccc'};font-size:12px;line-height:1.6;`;l.textContent=`${now()} ${m}`;if(S.logEl){S.logEl.appendChild(l);S.logEl.scrollTop=S.logEl.scrollHeight;while(S.logEl.children.length>300)S.logEl.removeChild(S.logEl.firstChild);}console.log(`[BW] ${m}`);} function route(){const h=location.hash;if(h.includes('/auth/login'))return'login';if(h.includes('/zoneMore'))return'zone';if(h.includes('/courseStudy'))return'study';return'home';} function getLoginName(){try{return JSON.parse(localStorage.getItem('userInfo')).loginName||null;}catch(e){return null;}} async function fetchZones(ct){return ct==='OCE'?await BWAPI.fetchPublicCourses('',1,100):await BWAPI.fetchZoneList('',1,100,ct);} async function fetchZoneCourses(z){return await BWAPI.fetchZoneCoursesDetail(z.centerCode||'C001',z.olClassNo||z.guid,z.olClassType||'ZE0');} const CSS=`#bw-helper{position:fixed;right:16px;bottom:16px;width:320px;max-height:90vh;background:#1e1e2e;border:1px solid #333;border-radius:10px;box-shadow:0 8px 32px rgba(0,0,0,.5);z-index:999999;font-family:"Microsoft YaHei",sans-serif;color:#ccc;font-size:13px;display:flex;flex-direction:column;overflow:hidden} #bw-helper .hdr{background:linear-gradient(90deg,#2d2d44,#1e1e2e);padding:10px 14px;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #333;cursor:move;user-select:none} #bw-helper .ttl{font-weight:bold;color:#89b4fa;font-size:14px} #bw-helper .ttl #bw-min-score{display:none} #bw-helper.off .ttl #bw-min-score{display:inline;font-size:11px} #bw-helper .st{font-size:12px;color:#f9e2af;margin-right:8px} #bw-helper .mn{cursor:pointer;color:#aaa;font-size:16px;padding:0 6px} #bw-helper .bd{padding:10px 14px;overflow-y:auto;flex:1} #bw-helper.off .bd{display:none} #bw-helper.off .hdr{padding:6px 10px;cursor:pointer} #bw-helper.off .ttl{font-size:12px} #bw-helper .row{display:flex;gap:6px;margin-bottom:8px;flex-wrap:wrap;align-items:center} #bw-helper .tab{padding:4px 10px;border-radius:4px;background:#313244;cursor:pointer;font-size:12px;border:1px solid #45475a} #bw-helper .tab.on{background:#89b4fa;color:#1e1e2e;font-weight:bold} #bw-helper .btn{padding:5px 10px;border-radius:4px;background:#45475a;color:#cdd6f4;border:none;cursor:pointer;font-size:12px} #bw-helper .btn:hover{background:#585b70} #bw-helper .btn.pri{background:#a6e3a1;color:#1e1e2e;font-weight:bold} #bw-helper .btn.dng{background:#f38ba8;color:#1e1e2e} #bw-helper .btn:disabled{opacity:0.4;cursor:not-allowed;pointer-events:none} #bw-helper .prog{height:6px;background:#313244;border-radius:3px;margin:4px 0;overflow:hidden} #bw-helper .prog-b{height:100%;background:#a6e3a1;width:0%;transition:width .3s} #bw-helper .prog-score{height:6px;background:#313244;border-radius:3px;margin:4px 0;overflow:hidden} #bw-helper .prog-score-b{height:100%;background:#f38ba8;width:0%;transition:width .5s} #bw-helper .prog-label{font-size:11px;color:#888;margin:2px 0} #bw-helper .cl{max-height:200px;overflow-y:auto;margin-bottom:8px;border:1px solid #45475a;border-radius:4px;padding:4px} #bw-helper .ci{padding:4px 6px;display:flex;align-items:center;gap:6px;border-bottom:1px solid #313244;font-size:12px} #bw-helper .cn{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} #bw-helper .cs{font-size:11px;white-space:nowrap;min-width:60px;text-align:right} #bw-helper .cs.done{color:#81c784}.cs.doing{color:#f9e2af}.cs.todo{color:#666} #bw-helper .log{background:#11111b;border-radius:4px;padding:6px;max-height:100px;overflow-y:auto;font-family:Consolas,monospace;font-size:11px} #bw-helper .acc-section{margin-top:8px;padding-top:8px;border-top:1px solid #333} #bw-helper .acc-header{cursor:pointer;display:flex;justify-content:space-between;align-items:center;padding:2px 0} #bw-helper .acc-header .arrow{transition:transform .3s;display:inline-block} #bw-helper .acc-section.collapsed .acc-header .arrow{transform:rotate(-90deg)} #bw-helper .acc-body{display:block;margin-top:6px} #bw-helper .acc-section.collapsed .acc-body{display:none} #bw-helper .acc-row{display:flex;gap:4px;align-items:center;margin-bottom:4px} #bw-helper .acc-row input{background:#313244;border:1px solid #45475a;color:#cdd6f4;padding:3px 6px;border-radius:3px;font-size:12px;flex:1;min-width:0} #bw-helper .acc-list{max-height:80px;overflow-y:auto;margin-top:4px} #bw-helper .acc-item{padding:3px 6px;display:flex;align-items:center;gap:6px;font-size:12px;border-bottom:1px solid #313244} #bw-helper .acc-item .edit{color:#89b4fa;cursor:pointer} #bw-helper .acc-item .del{color:#f38ba8;cursor:pointer;margin-left:auto} #bw-helper .zones-check{display:flex;gap:6px;flex-wrap:wrap;margin:4px 0;font-size:12px} #bw-helper .speed{display:flex;gap:6px;align-items:center;margin-bottom:6px} #bw-helper .speed input{width:50px;background:#313244;border:1px solid #45475a;color:#cdd6f4;padding:3px 6px;border-radius:3px;font-size:12px} #bw-helper .progress-text{font-size:12px;color:#a6e3a1;margin-bottom:4px}`; function createPanel(){ if($('#bw-helper'))return; const p=document.createElement('div');p.id='bw-helper'; p.innerHTML=`
宝武学习助手 v8.9.71 待机
当前学习账号: 未登录
公开课
学习专区
网络专题班
培训班
倍速:x检验合格:
视频进度
合格成绩 -- / --
`; document.body.appendChild(p);S.logEl=$('#bw-log'); $('#bw-mn').onclick=e=>{e.stopPropagation();p.classList.add('off');p.style.left='auto';p.style.top='auto';p.style.right='16px';p.style.bottom='16px';}; $('#bw-hdr').onclick=()=>{if(p.classList.contains('off'))p.classList.remove('off');}; $('#bw-hdr').addEventListener('mousedown',e=>{if(p.classList.contains('off'))return;let dx=e.clientX-p.offsetLeft,dy=e.clientY-p.offsetTop,dr=!0;const mv=ev=>{if(dr){p.style.left=(ev.clientX-dx)+'px';p.style.top=(ev.clientY-dy)+'px';p.style.right='auto';p.style.bottom='auto';}};const up=()=>{dr=!1;document.removeEventListener('mousemove',mv);document.removeEventListener('mouseup',up);};document.addEventListener('mousemove',mv);document.addEventListener('mouseup',up);}); $$('.tab').forEach(t=>t.onclick=()=>{$$('.tab').forEach(x=>x.classList.remove('on'));t.classList.add('on');S.tab=t.dataset.t;renderList();}); $('#bw-refresh').onclick=()=>loadAllZones(!0);$('#bw-go').onclick=startLearning;$('#bw-continue').onclick=continueLearning;$('#bw-stop').onclick=stopLearning; $('#bw-speed').onchange=()=>{S.speed=parseFloat($('#bw-speed').value)||1;ST.set('bw_speed',S.speed);log('倍速'+S.speed+'x');}; $('#bw-score-interval').onchange=()=>{S.scoreInterval=parseInt($('#bw-score-interval').value)||30;ST.set('bw_scoreInterval',S.scoreInterval);log('检验间隔'+S.scoreInterval+'秒');}; $('#bw-auto-exam').onchange=e=>{S.autoExam=e.target.checked;ST.set('bw_autoExam',S.autoExam);log('自动考试'+(S.autoExam?'开启':'关闭'));}; $('#bw-auto-survey').onchange=e=>{S.autoSurvey=e.target.checked;ST.set('bw_autoSurvey',S.autoSurvey);log('自动调查'+(S.autoSurvey?'开启':'关闭'));}; $('#bw-auto-fav').onchange=e=>{S.autoFav=e.target.checked;ST.set('bw_autoFav',S.autoFav);log('自动收藏'+(S.autoFav?'开启':'关闭'));}; $('#bw-auto-like').onchange=e=>{S.autoLike=e.target.checked;ST.set('bw_autoLike',S.autoLike);log('自动点赞'+(S.autoLike?'开启':'关闭'));}; $('#bw-auto-comment').onchange=e=>{S.autoComment=e.target.checked;ST.set('bw_autoComment',S.autoComment);log('自动评论'+(S.autoComment?'开启':'关闭'));}; $('#bw-add-acc').onclick=addAccount;$('#bw-host').onclick=startHosting; $('#bw-ai-apikey').onchange=async function(){const input=this,nv=input.value.trim();input.disabled=!0;setTimeout(()=>{input.disabled=!1;},1e4);S.aiApiKey=nv;ST.set('bw_aiApiKey',S.aiApiKey);log('AI API Key已保存,正在测试连接...','run');if(!nv){log('AI API Key已清空,关闭AI答题','warn');input.disabled=!1;return;}try{const r=await callAI('测试题目:1+1=?',['1','2','3'],'single');log(r&&r.length>0?'AI连接测试成功!答题可用':'AI连接测试失败,将使用默认答案',r&&r.length>0?'ok':'err');}catch(e){log('AI连接测试失败: '+e.message+',将使用默认答案','err');}input.disabled=!1;}; $('#bw-ai-header').onclick=()=>$('#bw-ai-section').classList.toggle('collapsed'); $('#bw-acc-header').onclick=()=>$('#bw-acc-section').classList.toggle('collapsed'); renderAccList(); } function setStatus(t,c){const e=$('#bw-st');if(e){e.textContent=t;e.style.color=c||'#f9e2af';}} function setWorking(on){setStatus(on?'工作中':'待机',on?'#a6e3a1':'#f9e2af');} function setButtonState(st){const go=$('#bw-go'),c=$('#bw-continue'),sp=$('#bw-stop'),host=$('#bw-host');if(!go||!c||!sp)return;if(st==='running'){go.disabled=!0;c.disabled=!0;sp.disabled=!1;if(host)host.disabled=!0;}else if(st==='stopped'){go.disabled=!1;c.disabled=!1;sp.disabled=!0;if(host)host.disabled=!1;}else{go.disabled=!1;c.disabled=!0;sp.disabled=!0;if(host)host.disabled=!1;}} function setProg(p){const b=$('#bw-pb');if(b)b.style.width=Math.min(100,Math.max(0,p))+'%';} function isPassed(s){if(!s||s.score==null)return!1;return s.score>=(s.passLine||60);} function setScoreProg(score,passLine){const b=$('#bw-pb-score'),t=$('#bw-score-text'),mt=$('#bw-min-score');if(!b||!t)return;if(score!=null&&passLine!=null){const pct=Math.min(100,Math.max(0,score/passLine*100));b.style.width=pct+'%';t.textContent=`${score} / ${passLine} (${Math.round(pct)}%)`;b.style.background=pct>=100?'#81c784':'#f38ba8';if(mt)mt.textContent=`(${score}/${passLine} ${Math.round(pct)}%)`;}else{b.style.width='0%';t.textContent='-- / --';if(mt)mt.textContent='';}} function setProgressText(){const e=$('#bw-prog-text');if(e)e.textContent=`当前学习账号: ${getLoginName()||'未登录'}`;} function addAccount(){const acc=$('#bw-acc').value.trim(),pwd=$('#bw-pwd').value;if(!acc||!pwd){log('请输入工号和密码','warn');return;}const zones=$$('#bw-zones-check input:checked').map(c=>c.value);let found=!1;for(let i=0;i{const d=document.createElement('div');d.className='acc-item';d.innerHTML=`${i+1}. ${a.acc}${a.zones.join('/')}编辑删除`;d.querySelector('.del').onclick=()=>{S.accounts.splice(i,1);ST.set('bw_accounts',S.accounts);renderAccList();};d.querySelector('.edit').onclick=()=>{$('#bw-acc').value=a.acc;$('#bw-pwd').value=a.pwd;$$('#bw-zones-check input').forEach(cb=>{cb.checked=a.zones.includes(cb.value);});log('编辑账号: '+a.acc);};el.appendChild(d);});const h=document.querySelector('#bw-acc-header span');if(h)h.innerHTML=`账号托管 (${S.accounts.length}个账号)`;} const TAB_CLASS={open:'OCE',zone:'ZE0',online:'ZE1',train:'TCE'}; const TAB_NAME={open:'公开课',zone:'学习专区',online:'网络专题班',train:'培训班'}; async function loadAllZones(force){log('后台API读取各专区...','run');setStatus('读取中','#89b4fa');for(const[k,ct]of Object.entries(TAB_CLASS)){if(!force&&S.zones[k]?.length)continue;try{const l=await fetchZones(ct);S.zones[k]=l;log(`${TAB_NAME[k]}: ${l.length}个`);}catch(e){log(`${TAB_NAME[k]}读取失败: ${e.message}`,'err');}}renderList();if(!S.running)setWorking(!1);log('读取完成','ok');} function renderList(){const list=S.zones[S.tab]||[],cl=$('#bw-cl');cl.innerHTML='';if(!list.length){cl.innerHTML='
暂无数据
';return;}list.forEach((item,i)=>{let st='',cls='todo';let name=item.courseName||item.olClassName||item.name||item.guid;if(item.isOpenCourse||item.courseGuid){st=item.learnStatus==='2'?'已完成':'未学习';cls=item.learnStatus==='2'?'done':'todo';}else{const total=parseInt(item.courseNum)||0,done=parseInt(item.learnNum)||0;if(total>0&&done>=total){st='已完成';cls='done';}else if(done>0){st=`学习中 ${done}/${total}`;cls='doing';}else{st='未学习';cls='todo';}}const d=document.createElement('div');d.className='ci';d.innerHTML=`${name}${st}`;cl.appendChild(d);});} async function scanZones(zoneKeys,prefix=''){let total=0,done=0;const todo=[];for(const zk of zoneKeys){for(const item of(S.zones[zk]||[])){if(item.isOpenCourse||item.courseGuid){total++;item.learnStatus==='2'?done++:todo.push(item);}else{const zn=item.courseName||item.olClassName||item.name||item.guid;log(`${prefix}扫描: ${zn}...`);try{const cs=await fetchZoneCourses(item);cs.forEach(c=>{total++;c.learnStatus==='2'?done++:todo.push({...c,zoneName:zn});});log(`${prefix} ${zn}: 共${cs.length}门,已完成${cs.filter(c=>c.learnStatus==='2').length}门`);}catch(e){log(`扫描${zn}失败`,'err');}}}}return{total,done,todo};} async function startHosting(){if(!S.accounts.length){log('请先添加账号','warn');return;}S.running=!0;ST.set('bw_running',!0);S.userStopped=!1;S.currentAccIdx=0;setWorking(!0);setButtonState('running');log(`托管开始,共${S.accounts.length}个账号`,'run');await hostNextAccount();} async function hostNextAccount(){if(!S.running||S.userStopped)return;if(S.currentAccIdx>=S.accounts.length){setWorking(!1);setButtonState('stopped');log('所有账号托管完成!','ok');ST.set('bw_running',!1);return;}const acc=S.accounts[S.currentAccIdx];log(`=== 账号 ${S.currentAccIdx+1}/${S.accounts.length}: ${acc.acc} ===`,'run');const curRoute=route();if(curRoute==='login'){log('当前已在登录页,直接登录');await doLoginWithAccount(acc);}else{const currentAcc=getLoginName();log(`当前登录账号: ${currentAcc||'未知'},目标: ${acc.acc}`);if(currentAcc&&String(currentAcc)===String(acc.acc)){log('账号一致,跳过退出登录','ok');await sleep(3000);}else{log(`账号不一致,需要切换`,'warn');await logoutAndLogin(acc);await sleep(3000);}}S.zones={};await loadAllZones(!0);const{total,done,todo}=await scanZones(acc.zones);S.totalCourses=total;S.doneBefore=done;S.doneToday=0;ST.set('bw_totalCourses',total);ST.set('bw_doneBefore',done);S.queue=todo;S.queueIdx=0;ST.set('bw_queue',S.queue);ST.set('bw_queueIdx',0);setProgressText();log(`统计: 共${total}门,已完成${done}门,待学${todo.length}门`,'ok');if(!todo.length){log('无待学课程,切换下一账号','warn');S.currentAccIdx++;ST.set('bw_currentAccIdx',S.currentAccIdx);await sleep(2000);await hostNextAccount();}else await learnNext();} async function logoutAndLogin(acc){log('退出当前账号...','run');const avatar=document.querySelector('button.outline-none');if(avatar){avatar.click();await sleep(2000);}const items=document.querySelectorAll('.el-dropdown-menu__item, [role="menuitem"], .el-dropdown-menu li');for(const it of items){if(it.textContent.includes('退出登录')&&it.offsetParent!==null){it.click();log('点了退出登录');break;}}await sleep(2000);const cfm=document.querySelectorAll('.el-message-box button, .el-dialog__footer button, .el-button--primary');for(const b of cfm){if(b.offsetParent!==null&&b.textContent.trim().match(/确定|确认|退出/)){b.click();log('确认退出弹窗: 点确定');break;}}await sleep(4000);location.hash='#/auth/login';await sleep(5000);await doLoginWithAccount(acc);} function solveMath(str){let e=str.split(/[==??]/)[0];e=e.replace(/[¥¥]/g,'+');e=e.replace(/[^\d+\-×xX*÷/]/g,'');const m=e.match(/(\d+)\s*([+\-×xX*÷/])\s*(\d+)/);if(!m)return null;const a=parseInt(m[1]),op=m[2],b=parseInt(m[3]);if(op==='+')return a+b;if(op==='-')return a-b;if(op==='×'||op==='x'||op==='X'||op==='*')return a*b;if(op==='÷'||op==='/')return b?Math.round(a/b):null;return null;} async function ocrCaptcha(){const img=document.querySelector('img.captcha-image');if(!img||!img.src)return null;const canvas=document.createElement('canvas');canvas.width=img.naturalWidth*5;canvas.height=img.naturalHeight*5;const ctx=canvas.getContext('2d');ctx.fillStyle='white';ctx.fillRect(0,0,canvas.width,canvas.height);ctx.drawImage(img,0,0,canvas.width,canvas.height);const d=ctx.getImageData(0,0,canvas.width,canvas.height);for(let i=0;i{}});await S.ocr.setParameters({tessedit_pageseg_mode:'7'});const{data}=await S.ocr.recognize(canvas.toDataURL());return(data.text||'').trim();} async function doLoginWithAccount(acc){log('登录: '+acc.acc,'run');let inputs=[];for(let i=0;i<10;i++){inputs=$$('input.el-input__inner');if(inputs.length>=3)break;await sleep(1000);}if(inputs.length<3){log('登录页输入框未加载','err');return;}inputs[0].focus();inputs[0].value=acc.acc;inputs[0].dispatchEvent(new Event('input',{bubbles:!0}));inputs[0].dispatchEvent(new Event('change',{bubbles:!0}));await sleep(300);inputs[1].focus();inputs[1].value=acc.pwd;inputs[1].dispatchEvent(new Event('input',{bubbles:!0}));inputs[1].dispatchEvent(new Event('change',{bubbles:!0}));await sleep(300);for(let attempt=1;attempt<=15;attempt++){await sleep(1000);let text='';try{text=await ocrCaptcha();}catch(e){log('OCR异常: '+e.message,'err');}log(`验证码OCR(第${attempt}次): "${text}"`);const ans=solveMath(text);if(ans!==null){const cap=$$('input.el-input__inner')[2];if(cap){cap.focus();cap.value=String(ans);cap.dispatchEvent(new Event('input',{bubbles:!0}));cap.dispatchEvent(new Event('change',{bubbles:!0}));log('填入验证码: '+ans);}await sleep(500);const bs=Array.from(document.querySelectorAll('button'));for(const b of bs){if(b.textContent.trim()==='登录'&&b.offsetParent!==null){b.click();break;}}log('点了登录,等待响应...');await sleep(4000);if(!location.hash.includes('/auth/login')){log('登录成功!','ok');return;}log('验证码错误,自动重试...','warn');await sleep(1000);}else{log('验证码识别失败,点击刷新','warn');const img=document.querySelector('img.captcha-image');if(img)img.click();await sleep(1500);}}log('验证码重试15次仍未成功','err');} async function startLearning(){const checked=$$('#bw-cl input[type=checkbox]:checked');if(!checked.length){log('请先勾选','warn');return;}setStatus('加载中','#89b4fa');const keys=[];for(const cb of checked){const i=parseInt(cb.dataset.i);const item=(S.zones[S.tab]||[])[i];if(!item)continue;if(item.isOpenCourse||item.courseGuid){keys.push({__direct:item});}else keys.push(item);} let total=0,done=0;const todo=[];for(const k of keys){if(k.__direct){total++;k.__direct.learnStatus==='2'?done++:todo.push(k.__direct);}else{const zn=k.courseName||k.olClassName||k.name||k.guid;log(`扫描: ${zn}...`);try{const cs=await fetchZoneCourses(k);cs.forEach(c=>{total++;c.learnStatus==='2'?done++:todo.push({...c,zoneName:zn});});log(` 共${cs.length}门,已完成${cs.filter(c=>c.learnStatus==='2').length}门`);}catch(e){log(`扫描失败: ${e.message}`,'err');}}} if(!todo.length){log('无未完成课程','warn');setWorking(!1);return;}todo.sort((a,b)=>(a.learnStatus==='1'?0:1)-(b.learnStatus==='1'?0:1));S.queue=todo;S.queueIdx=0;S.running=!0;S.totalCourses=total;S.doneBefore=done;S.doneToday=0;S.userStopped=!1;ST.set('bw_running',!0);ST.set('bw_queue',S.queue);ST.set('bw_queueIdx',0);ST.set('bw_totalCourses',total);ST.set('bw_doneBefore',done);setProgressText();setWorking(!0);setButtonState('running');log(`开始学习,共${total}门(已完成${done}),待学${todo.length}门`,'run');learnNext();} function stopLearning(){S.running=!1;ST.set('bw_running',!1);S.userStopped=!0;if(S.studyTimer){clearInterval(S.studyTimer);S.studyTimer=null;}if(S.chapterTimer){clearInterval(S.chapterTimer);S.chapterTimer=null;}const v=$('#xg-video video')||$('video');if(v){v.pause();log('视频已暂停','info');}setWorking(!1);setButtonState('stopped');log('已停止学习,可点"继续"从当前位置恢复','warn');} function continueLearning(){if(!S.queue||!S.queue.length){log('没有待学队列,请先点"开始学习"','warn');return;}if(S.queueIdx>=S.queue.length){log('队列已学完,请重新点"开始学习"','warn');return;}S.running=!0;ST.set('bw_running',!0);S.userStopped=!1;setWorking(!0);setButtonState('running');log(`继续学习,从第 ${S.queueIdx+1}/${S.queue.length} 门开始`,'run');learnNext();} async function learnNext(){if(!S.running||S.userStopped)return;if(S.queueIdx>=S.queue.length){const done=Math.min(S.doneBefore+S.doneToday,S.totalCourses);log(`本批次完成: ${done}/${S.totalCourses}门`,'ok');if(S.accounts.length>1&&S.currentAccIdx{});log('兜底video.play()');return!0;} function cleanupVideoOverlays(){const s=document.querySelector('.xgplayer-start');if(s)s.classList.add('hide');const o=document.querySelector('.video-overlay');if(o)o.style.display='none';} async function callAI(q,opts,type){if(!S.aiApiKey)return null;try{const prompt=`你是一个考试答题专家。请根据以下题目和选项,给出正确答案。题目类型:${type==='single'?'单选题':(type==='multiple'?'多选题':'判断题')}\n题目:${q}\n选项:\n${opts.map((o,i)=>`${i+1}. ${o}`).join('\n')}\n请只返回正确选项的编号,用逗号分隔,例如:1,2`;const r=await fetch('https://api.deepseek.com/v1/chat/completions',{method:'POST',headers:{'Content-Type':'application/json','Authorization':'Bearer '+S.aiApiKey},body:JSON.stringify({model:'deepseek-chat',messages:[{role:'system',content:'你是一个专业的考试答题助手。请只返回正确选项的编号,用逗号分隔。'},{role:'user',content:prompt}],temperature:.1,max_tokens:50})});if(!r.ok)throw new Error('HTTP '+r.status);const d=await r.json();const a=d.choices[0].message.content.trim();const nums=a.match(/\d+/g)||[];const idx=nums.map(n=>parseInt(n)-1).filter(i=>i>=0&&i0?idx:null;}catch(e){log('AI答题失败: '+e.message+',使用默认答案','warn');return null;}} function getDefaultAnswer(opts,type){if(type==='single'||type==='judge')return[0];if(type==='multiple')return opts.map((_,i)=>i);return[0];} async function doExamQuestions(){for(let retry=0;retry<10;retry++){const groups=$$('.option-group');if(!groups.length){log('没找到题目选项,第'+(retry+1)+'次重试...','warn');await sleep(5000);continue;}log(`共${groups.length}道题,开始答题...`);let ans=0;for(const g of groups){let qt='';const par=g.parentElement;if(par){const lines=par.innerText.split('\n').filter(l=>l.trim().length>0);if(lines.length>0)qt=lines[0].trim();}if(!qt)qt='考试题目';const rs=g.querySelectorAll('input[type="radio"]');if(rs.length>0){const opts=Array.from(rs).map(r=>r.parentElement.textContent.trim());const t=rs.length===2&&(rs[0].parentElement.textContent.includes('对')||rs[0].parentElement.textContent.includes('正确'))?'judge':'single';let ci=await callAI(qt,opts,t);if(!ci){ci=getDefaultAnswer(opts,t);log(`默认答: ${qt.slice(0,30)}... -> 选项${ci[0]+1}`);}else log(`AI答: ${qt.slice(0,30)}... -> 选项${ci[0]+1}`);rs[ci[0]].parentElement.click();ans++;} const cs=g.querySelectorAll('input[type="checkbox"]');if(cs.length>0){const opts=Array.from(cs).map(c=>c.parentElement.textContent.trim());let ci=await callAI(qt,opts,'multiple');if(!ci){ci=getDefaultAnswer(opts,'multiple');log(`默认多: ${qt.slice(0,30)}... -> 全选`);}else log(`AI多: ${qt.slice(0,30)}... -> 选项${ci.map(i=>i+1).join(',')}`);ci.forEach(i=>{if(!cs[i].checked)cs[i].parentElement.click();});ans++;}} log(`已答${ans}道题`);await sleep(2000);const sub=btn('我要交卷');if(!sub){log('没找到交卷按钮','warn');break;}sub.click();await sleep(2000);const cfm=btn('提交试卷');if(cfm){cfm.click();log('已提交试卷');await sleep(5000);}await sleep(2000);const ok=btnEq('好的');if(ok){log('交卷后检测到提示弹窗,点好的','warn');ok.click();await sleep(2000);}const ex=btn('退出考试');if(ex){log('交卷后检测到交卷状态提示,点退出考试','warn');ex.click();await sleep(3000);return!0;}const pt=document.body.innerText;const sm=pt.match(/得分[::]\s*(\d+\.?\d*)\s*分/);const pass=pt.match(/考试及格|考试合格|恭喜您.*及格|成绩.*合格/);const fail=pt.match(/考试不及格|未及格|成绩.*不合格|很遗憾/);if(pass||(sm&&parseFloat(sm[1])>=60)){log(`考试及格!${sm?sm[1]:''}分`,'ok');const e2=btn('退出考试');if(e2)e2.click();await sleep(3000);return!0;}else if(fail||(sm&&parseFloat(sm[1])<60)){log(`考试不及格,得分${sm?sm[1]:'?'}分,重新考`,'warn');retry++;const ag=btn('重新考试');if(ag){ag.click();await sleep(5000);}else{log('没找到重新考试按钮,尝试退出考试','warn');const e3=btn('退出考试');if(e3){e3.click();log('已点退出考试,返回课程页','warn');await sleep(3000);}else log('没找到退出考试按钮','err');break;}}else{log('没识别到成绩,可能还在加载','warn');await sleep(3000);retry++;}}return!0;} async function handleExam(){if(!S.autoExam)return!0;if(location.hash.includes('/examination')||location.hash.includes('/exam')){log('已经在考试页面,直接答题...');await doExamQuestions();return!0;}await sleep(3000);log('查找页面上的未完成考试...','run');const all=$$('div, .el-card, .card, .item');let found=!1;for(const el of all){if(!el.offsetParent)continue;const t=el.innerText||'';if(t.includes('参与状态:未参加')||t.includes('参与状态: 未参加')){if(t.includes('考试')||t.includes('开始时间')){found=!0;const eb=Array.from(el.querySelectorAll('button')).find(b=>b.textContent.includes('进入考试')||b.textContent.includes('开始考试'));if(eb&&eb.offsetParent){log('发现未完成的考试,点击进入...');eb.click();const cb=Array.from($$('button')).find(b=>b.textContent.trim()==='确定'&&b.offsetParent&&b.closest('.el-dialog, .el-message-box'));if(cb){log('点击考试弹窗的确定按钮');cb.click();}break;}}}}if(!found)log('没有发现未完成的考试,跳过','ok');log('考试完成检查完毕','info');return!0;} async function doSurveyQuestions(){let rs=[];for(let w=0;w<6;w++){await sleep(2000);rs=$$('.el-radio');if(rs.length>0)break;log(`调查题加载中,第${w+1}次等待...`,'warn');}if(!rs.length){log('调查页未找到选项,跳过','warn');return!0;}let gs=4;const fr=rs[0].closest('.el-radio-group, .el-form-item__content, .survey-item, [class*="question"], [class*="item"]');if(fr){const rr=fr.querySelectorAll('.el-radio');if(rr.length>=2)gs=rr.length;}if(rs.length%4!==0&&rs.length%3===0)gs=3;const tq=Math.floor(rs.length/gs);log(`共${tq}道调查题(每组${gs}个选项),开始填写...`);for(let i=0;ib.textContent.includes('确定')&&b.offsetParent&&b.closest('.el-message-box, .el-dialog'));if(cb){log('点击确认提交');cb.click();}await sleep(5000);log('调查已提交!','ok');}else log('没找到调查提交按钮','warn');return!0;} async function handleSurvey(){if(!S.autoSurvey)return!0;if(S.surveyHandled){log('本课程调查已处理过,跳过','info');return!0;}if(location.hash.includes('/questionnaire')||location.hash.includes('/survey')){log('已经在调查页面,直接填写...');await doSurveyQuestions();S.surveyHandled=!0;return!0;}await sleep(2000);log('查找页面上的未完成调查...','run');const all=$$('div, .el-card, .card, .item');let found=!1;for(const el of all){if(!el.offsetParent)continue;const t=el.innerText||'';if(t.includes('参与状态:未参与')||t.includes('参与状态: 未参与')){if(t.includes('调查')||t.includes('问卷')||t.includes('开始时间')){found=!0;const eb=Array.from(el.querySelectorAll('button')).find(b=>b.textContent.includes('进入调查')||b.textContent.includes('开始调查'));if(eb&&eb.offsetParent){log('发现未完成的调查,点击进入...');eb.click();S.surveyHandled=!0;break;}}}}if(!found)log('没有发现未完成的调查,跳过','ok');log('调查完成检查完毕','info');return!0;} const COMMENT_TEXTS='讲解清晰易懂,重点突出,收获很大。|课程内容扎实,逻辑严谨,学起来很顺畅。|老师讲得生动有趣,枯燥知识也变得好懂。|视频画质清晰,声音洪亮,学习体验很好。|节奏把控得当,难点讲解透彻,非常实用。|案例丰富贴近实际,帮助理解抽象概念。|知识点梳理系统,条理分明,便于记忆。|语言简洁明了,没有废话,效率很高。|互动设计巧妙,引人思考,不只是灌输。|每节课都有小结,重点复习很方便。|实操演示到位,步骤清楚,跟着做就会。|理论结合实践,讲解深入浅出,受益匪浅。|老师态度认真,答疑及时,很有责任心。|课程结构合理,由浅入深,循序渐进。|字幕准确同步,方便回看和做笔记。|内容更新及时,紧跟行业发展趋势。|讲解耐心细致,零基础也能听懂。|举例生动形象,复杂问题简单化。|视频时长适中,碎片时间也能学习。|重点难点反复强调,记忆更深刻。|课件制作精美,图文并茂,辅助效果好。|老师声音好听,语速适中,听着不累。|课程配套资料齐全,复习巩固很方便。|每章都有练习,检验学习效果很实用。|讲解风格幽默,学习过程轻松愉快。|逻辑链条完整,前后呼应,没有断层。|针对考点讲解精准,备考效率高。|实际操作环节演示清晰,上手很快。|老师经验丰富,分享很多干货技巧。|课程设计科学,符合认知学习规律。'.split('|'); function getCurrentCourseGuid(){const h=location.hash;const q=h.indexOf('?');if(q===-1)return null;const p=new URLSearchParams(h.substring(q+1));return p.get('guid');} async function autoLikeFavComment(){if(!S.autoFav&&!S.autoLike&&!S.autoComment)return;const guid=getCurrentCourseGuid();const ds=ST.get('bw_interacted_guids',[]);if(guid&&ds.includes(guid)){log('本课程已收藏/点赞/评论过,跳过','info');return;}log('开始自动收藏、点赞、评论...','run');if(S.autoFav){const fb=Array.from(document.querySelectorAll('button.el-button')).find(b=>b.textContent.includes('收藏')&&b.offsetParent);if(fb){fb.click();log('已点击课程页收藏按钮');await sleep(500);}}if(S.autoLike){const lb=document.querySelector('button.like-button');if(lb){lb.click();log('已点击课程页点赞按钮');await sleep(500);}}if(S.autoComment){const ct=Array.from($$('.tab-item button')).find(b=>b.textContent.trim().includes('交流'));if(ct)ct.click();await sleep(1000);const ta=document.querySelector('.talk-input-wrapper textarea');if(ta){const rc=COMMENT_TEXTS[Math.floor(Math.random()*COMMENT_TEXTS.length)];ta.focus();ta.value=rc;ta.dispatchEvent(new Event('input',{bubbles:!0}));await sleep(500);const sb=Array.from(document.querySelectorAll('.talk-input-wrapper button')).find(b=>b.textContent.includes('发表评论'));if(sb){sb.click();log('已发表评论');await sleep(1000);}}}if(guid){const ns=ST.get('bw_interacted_guids',[]);if(!ns.includes(guid)){ns.push(guid);ST.set('bw_interacted_guids',ns);}}log('收藏点赞评论完成','ok');} async function studyCourse(){if(S.userStopped)return;if(location.hash.includes('/questionnaire')||location.hash.includes('/survey')){log('检测到调查页面,自动填写...');await doSurveyQuestions();const c=S.queue[S.queueIdx];if(c){const g=c.courseGuid||c.guid;location.assign(`https://learn.baowugroup.com/#/courseStudy?centerCode=${c.centerCode}&guid=${g}`);}return;}if(location.hash.includes('/examination')||location.hash.includes('/exam')){log('检测到考试页面,自动答题...');await doExamQuestions();const c=S.queue[S.queueIdx];if(c){const g=c.courseGuid||c.guid;location.assign(`https://learn.baowugroup.com/#/courseStudy?centerCode=${c.centerCode}&guid=${g}`);}return;}setProgressText();await sleep(5000);const ig=ST.get('bw_invalid_guids',[]);const cg=getCurrentCourseGuid();const pt=document.body.innerText||'';if(pt.includes('班级课程不存在')||pt.includes('请求参数不正确')||(pt.includes('暂无内容')&&!document.querySelector('video'))){log('检测到课程不存在/无权限/页面空白,跳过本课程','err');if(cg&&!ig.includes(cg)){ig.push(cg);ST.set('bw_invalid_guids',ig);}S.queueIdx++;S.doneToday++;ST.set('bw_queueIdx',S.queueIdx);await sleep(2000);await learnNext();return;}await handleExam();await handleSurvey();await autoLikeFavComment();const tabs=$$('.el-tabs__item, .tab-item, [role="tab"]').filter(t=>t.offsetParent);const vt=tabs.find(t=>t.textContent.trim().includes('视频')||t.textContent.trim().includes('播放'))||tabs[0];if(vt)vt.click();await sleep(3000);let v=null;for(let i=0;i<30;i++){v=$('#xg-video video')||$('video');if(v&&v.readyState>=1&&v.duration>0)break;await sleep(1000);}if(!v||!v.duration){S.videoRetryCount=(S.videoRetryCount||0)+1;if(S.videoRetryCount>=2){log(`视频连续${S.videoRetryCount}次加载失败,判定课程无效,跳过`,'err');const guid=getCurrentCourseGuid();const inv=ST.get('bw_invalid_guids',[]);if(guid&&!inv.includes(guid)){inv.push(guid);ST.set('bw_invalid_guids',inv);}S.queueIdx++;S.doneToday++;ST.set('bw_queueIdx',S.queueIdx);await sleep(2000);await learnNext();return;}log(`视频加载失败,第${S.videoRetryCount}次重试`,'err');if(!S.userStopped)setTimeout(studyCourse,5000);return;}if(!S.userStopped){v.muted=!0;v.playbackRate=S.speed;v.play().catch(()=>{});}await sleep(1500);if(!S.userStopped)playCurrentVideo(v);await sleep(2000);const sc=await checkScore();if(sc){S.lastScore=sc;setScoreProg(sc.score,sc.passLine);log(`初始: 成绩${sc.score??'--'}/${sc.passLine||60}分 (${isPassed(sc)?'已及格':'进行中'})`);if(isPassed(sc)){log(`已及格:${sc.score}分`,'ok');S.queueIdx++;S.doneToday++;setProgressText();ST.set('bw_queueIdx',S.queueIdx);await sleep(2000);await learnNext();return;}}if(!S.userStopped)await playChapter(0);S.studyTimer=setInterval(async()=>{if(!S.running||S.userStopped){clearInterval(S.studyTimer);return;}handlePopups();watchdog();const vv=$('#xg-video video')||$('video');if(vv&&vv.duration)setProg(vv.currentTime/vv.duration*100);const n=Date.now();if(n-S.lastScoreCheck>S.scoreInterval*1000){S.lastScoreCheck=n;const s=await checkScore();if(s){S.lastScore=s;setScoreProg(s.score,s.passLine);if(isPassed(s)){log(`及格!${s.score}分/${s.passLine}分`,'ok');clearInterval(S.studyTimer);S.queueIdx++;S.doneToday++;setProgressText();ST.set('bw_queueIdx',S.queueIdx);await sleep(2000);await learnNext();}else if(s.score!=null)log(`进度: 成绩${s.score}/${s.passLine||60}分`);}}},3000);} async function playChapter(idx){if(!S.running||S.userStopped)return;const leaves=$$('.course-chapter').filter(el=>!el.classList.contains('chapter-parent'));if(!leaves.length){const v=$('#xg-video video')||$('video');if(v&&!S.userStopped){v.muted=!0;v.playbackRate=S.speed;v.play().catch(()=>{});}if(S.chapterTimer)clearInterval(S.chapterTimer);S.chapterTimer=setInterval(()=>{const vv=$('#xg-video video')||$('video');if(!vv||S.userStopped)return;if(vv.muted!==!0)vv.muted=!0;if(Math.abs(vv.playbackRate-S.speed)>.1)vv.playbackRate=S.speed;if(vv.paused&&!vv.ended)playCurrentVideo(vv);if(vv.ended||(vv.duration>0&&vv.currentTime>=vv.duration-.5)){clearInterval(S.chapterTimer);onVideoEnded();}},2000);return;}if(idx>=leaves.length){onVideoEnded();return;}const ch=leaves[idx];ch.scrollIntoView({block:'center'});ch.click();log(`小节${idx+1}/${leaves.length}: ${ch.textContent.trim().slice(0,40)}`);await sleep(3000);const v=$('#xg-video video')||$('video');if(v&&!S.userStopped){v.muted=!0;v.playbackRate=S.speed;playCurrentVideo(v);}if(S.chapterTimer)clearInterval(S.chapterTimer);S.chapterTimer=setInterval(()=>{const vv=$('#xg-video video')||$('video');if(!vv||S.userStopped)return;if(vv.muted!==!0)vv.muted=!0;if(Math.abs(vv.playbackRate-S.speed)>.1)vv.playbackRate=S.speed;if(vv.paused&&!vv.ended)playCurrentVideo(vv);if(vv.ended||(vv.duration>0&&vv.currentTime>=vv.duration-.5)){clearInterval(S.chapterTimer);log(`小节${idx+1}完毕`);if(!S.userStopped)setTimeout(()=>playChapter(idx+1),2000);}},2000);} async function onVideoEnded(){if(S.userStopped)return;log('全部小节播完,检查成绩...','run');await sleep(2000);const s=await checkScore();if(s){S.lastScore=s;setScoreProg(s.score,s.passLine);}if(isPassed(s)){log(`及格!${s.score}分`,'ok');S.queueIdx++;S.doneToday++;setProgressText();ST.set('bw_queueIdx',S.queueIdx);await sleep(2000);await learnNext();}else{S.retryCount++;log(`未及格(${s?s.score:'?'}分/${s?s.passLine:60}), 第${S.retryCount}次重播`,'warn');if(S.retryCount>=5){log('重播5次仍未及格,跳下一门','err');S.queueIdx++;ST.set('bw_queueIdx',S.queueIdx);await sleep(2000);await learnNext();}else if(!S.userStopped)setTimeout(()=>playChapter(0),3000);}} function watchdog(){if(S.userStopped)return;const v=$('#xg-video video')||$('video');if(!v)return;if(v.muted!==!0)v.muted=!0;if(Math.abs(v.playbackRate-S.speed)>.1)v.playbackRate=S.speed;if(v.paused&&!v.ended){playCurrentVideo(v);v.play().catch(()=>{});}if(!v.paused)cleanupVideoOverlays();} async function checkScore(){return await checkScoreFromDOM();} async function checkScoreFromDOM(){const b=btnEq('完成情况');if(!b)return null;b.click();await sleep(5000);const dlg=$('.el-dialog');if(!dlg)return null;const t=dlg.innerText;const pm1=t.match(/合格分数线[::]\s*(\d+)/),pm2=t.match(/及格分数[::]\s*(\d+\.?\d*)/),passLine=pm1?parseFloat(pm1[1]):(pm2?parseFloat(pm2[1]):60);const sm1=t.match(/课程成绩[::]\s*([\d.]+)\s*分/),sm2=t.match(/总分[::]\s*([\d.]+)\s*分/),sm3=t.match(/最终成绩[::]\s*([\d.]+)\s*分/),score=sm1?parseFloat(sm1[1]):(sm2?parseFloat(sm2[1]):(sm3?parseFloat(sm3[1]):null));const cl=dlg.querySelector('.el-dialog__close, [aria-label="Close"]');if(cl)cl.click();else document.body.click();await sleep(500);return{score,passLine};} function handlePopups(){$$('.el-message-box, .el-dialog, [class*="popup"], [class*="modal"]').forEach(el=>{const r=el.getBoundingClientRect();if(r.width>100&&el.offsetParent!==null){const t=el.textContent;if(t.includes('休息')||t.includes('专注学习')){if(el.dataset.handled)return;el.dataset.handled='1';log('休息弹窗,点继续','warn');for(const b of el.querySelectorAll('button')){const bt=b.textContent.trim();if(bt==='继续'||bt==='确定'||bt==='知道了'||bt==='确认'){b.click();break;}}setTimeout(()=>{delete el.dataset.handled;},5000);}if(t.includes('时间到')||t.includes('自动交卷')){const ok=Array.from(el.querySelectorAll('button')).find(b=>b.textContent.trim()==='好的'&&b.offsetParent);if(ok){log('检测到时间到自动交卷提示,点好的','warn');ok.click();}}if(t.includes('交卷状态提示')){const ex=Array.from(el.querySelectorAll('button')).find(b=>b.textContent.includes('退出考试')&&b.offsetParent);if(ex){log('检测到交卷状态提示,点退出考试','warn');ex.click();}}}});const nb=document.querySelector('.play-chapter button.el-button--primary');if(nb&&nb.offsetParent&&!nb.disabled&&nb.textContent.includes('播放下一节')){log('自动点了: 播放下一节');nb.click();return;}} async function boot(){createPanel();setProgressText();setWorking(S.running);if(S.running)setButtonState('running');else setButtonState('stopped');log('宝武学习助手 v8.9.71 启动','ok');try{const ac=new(window.AudioContext||window.webkitAudioContext)();const o=ac.createOscillator();const g=ac.createGain();g.gain.value=0;o.connect(g);g.connect(ac.destination);o.start();log('后台保活AudioContext已启动','ok');}catch(e){log('后台保活启动失败: '+e.message,'warn');}let lastLogin=!location.hash.includes('/auth/login');setInterval(()=>{handlePopups();if(S.running&&route()==='study'&&!S.userStopped){watchdog();const v=$('#xg-video video')||$('video');if(v&&v.paused&&!v.ended){v.muted=!0;v.playbackRate=S.speed;v.play().catch(()=>{});}}const nl=!location.hash.includes('/auth/login');if(nl&&!lastLogin){log('检测到登录成功,自动刷新账号和课程列表','ok');setProgressText();loadAllZones(!0);}lastLogin=nl;setProgressText();},1000); window.addEventListener('hashchange',()=>{setTimeout(async()=>{if(S.running&&!S.userStopped&&(route()==='study'||location.hash.includes('/questionnaire')||location.hash.includes('/survey')||location.hash.includes('/examination')||location.hash.includes('/exam')))await studyCourse();if(S.running&&route()==='home'&&S.queue[S.queueIdx]&&!S.userStopped){const c=S.queue[S.queueIdx];const g=c.courseGuid||c.guid;location.assign(`https://learn.baowugroup.com/#/courseStudy?centerCode=${c.centerCode}&guid=${g}`);}},3000);}); const r=route();if(location.hash.includes('/questionnaire')||location.hash.includes('/survey')){log('检测到调查页面,自动填写...');await doSurveyQuestions();return;}if(location.hash.includes('/examination')||location.hash.includes('/exam')){log('检测到考试页面,自动答题...');await doExamQuestions();return;}if(r==='login')setStatus('登录中','#f38ba8');if(!S.zones.open||S.zones.open.length===0)loadAllZones(!1);if(r==='study'&&S.running&&!S.userStopped)await studyCourse();} if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',boot);else boot(); })();