---
# System prepended metadata

title: 上課
tags: [javascript, script]

---

# 上課

## 1. 十倍速＆自動點掉下個課程
``` javascript
// 十倍速
setInterval(() => {
    let player = document.getElementById("aplayer");
    if (player && player.playbackRate !== 10.0) {
        player.playbackRate = 10.0;
    }
}, 1000); // 每秒檢查一次

// 自動點
window.confirm = function() {
  console.log("偵測到 confirm，已自動點擊 '確定'");
  return true;
};
```
![image](https://hackmd.io/_uploads/r120ngPmkl.png)


## 2. 測驗答題 - 半自動版

#### 1. 複製題目丟給chatGPT
``` javascript
 = = = = = = = = = = = =
      [題目貼在這裡]
 = = = = = = = = = = = =
幫我作答以上題目 答案化為這種形式

// 是非題的答案索引（0 = 對，1 = 錯）
const ynAnswers = [x,x];

// 單選題的答案索引
const singleAnswers = [x,x];

// 複選題的答案索引
const doubleAnswers = [
  [x,x],
  [x],
];
 ```
![image](https://hackmd.io/_uploads/r1Jt8bG1lx.png)

#### 2. 得到的回應 與下面組合 貼在 console 裡面
``` javascript
 = = = = = = = = = = = = = = = =
     [ 得到的回應貼在這裡 ]
 = = = = = = = = = = = = = = = =
     
// 點是非題
ynAnswers.forEach((ans, i) => {
  const id = `ctl00_ContentPlaceHolder1_gvYN_ctl${String(i + 2).padStart(2, '0')}_rbYorN_${ans}`;
  const el = document.getElementById(id);
  if (el) el.click();
});

// 點單選題
singleAnswers.forEach((ans, i) => {
  const id = `ctl00_ContentPlaceHolder1_gvSingle_ctl${String(i + 2).padStart(2, '0')}_rbSingle_${ans}`;
  const el = document.getElementById(id);
  if (el) el.click();
});

// 點複選題
doubleAnswers.forEach((answers, i) => {
  answers.forEach(ans => {
    const id = `ctl00_ContentPlaceHolder1_gvDouble_ctl${String(i + 2).padStart(2, '0')}_rbDouble_${ans}`;
    const el = document.getElementById(id);
    if (el) el.click();
  });
});
```

![image](https://hackmd.io/_uploads/rygIObMJlg.png)

## 2. 測驗答題 - 完全自動版 
###### (試題 → Gemini → 回傳後直接自動勾選)
###### 填入 Gemini API Key 貼在 console

``` javascript
(async()=>{window.alert=function(){};const GEMINI_API_KEY="<< 填入 Gemini API Key >>";const GEMINI_MODEL="gemini-2.5-flash-lite";const LOG=(...a)=>console.log("[TKM]",...a);const WARN=(...a)=>console.warn("[TKM]",...a);const ERR=(...a)=>console.error("[TKM]",...a);const byId=(id)=>document.getElementById(id);const tidy=(s)=>(s||"").replace(/\s+/g," ").trim();const stripLeadingNo=(s)=>(s||"").replace(/^\s*\d+\.\s*/,"");function getDirectBodyRows(table){if(!table?.tBodies?.[0])return[];const rows=Array.from(table.tBodies[0].rows);return rows.filter((tr,idx)=>idx>0&&tr.cells?.length>=3);}function extractGrid(id,typeName){const table=byId(id);if(!table){WARN("找不到表格",`#${id}（將略過 ${typeName}）`);return[];}const rows=getDirectBodyRows(table);return rows.map((tr)=>{const tds=tr.cells;const rawNo=tidy(tds[0]?.textContent||"");const number=(rawNo.match(/\d+/)||[""])[0];const question=stripLeadingNo(tidy(tds[1]?.textContent||""));const options=Array.from(tds[2]?.querySelectorAll("label")||[]).map((l)=>tidy(l.textContent));return{type:typeName,number,question,options};});}const TABLE_IDS={yn:"ctl00_ContentPlaceHolder1_gvYN",single:"ctl00_ContentPlaceHolder1_gvSingle",multi:"ctl00_ContentPlaceHolder1_gvDouble",};const yn=extractGrid(TABLE_IDS.yn,"是非題");const single=extractGrid(TABLE_IDS.single,"單選題");const multi=extractGrid(TABLE_IDS.multi,"複選題");const allQuestions=[...yn,...single,...multi];LOG(`總題數: ${allQuestions.length}（是非: ${yn.length}、單選: ${single.length}、複選: ${multi.length}）`);if(!allQuestions.length)return ERR("抓不到任何題目。");const prompt=`你是一個考試助手，請根據題目與選項產生答案 JSON。請務必「只輸出純 JSON」，不要有任何說明、不要有 Markdown \` \` \` 區塊、不要有註解。格式：[{"type":"單選題|複選題|是非題","number":"題號（純數字）","question": "題目文字","options": ["選項1", "選項2", ...],"answer": "若為是非/單選→字串；複選→字串陣列。是非題請用「對」或「錯」。"}題目如下：${JSON.stringify(allQuestions, null, 2)}`.trim();async function askGeminiForAnswers(text){const model=typeof GEMINI_MODEL==="string"?GEMINI_MODEL:"gemini-2.5-flash";const base=model==="gemini-2.5-flash-lite"?"https://generativelanguage.googleapis.com/v1beta":"https://generativelanguage.googleapis.com/v1";const url=`${base}/models/${encodeURIComponent(model)}:generateContent`;const ac=new AbortController();const to=setTimeout(()=>ac.abort(),60_000);let res;try{res=await fetch(url,{method:"POST",headers:{"Content-Type":"application/json","X-goog-api-key":GEMINI_API_KEY,},signal:ac.signal,body:JSON.stringify({contents:[{role:"user",parts:[{text}]}],}),});}finally{clearTimeout(to);}if(!res.ok){const t=await res.text().catch(()=>"");throw new Error(`Gemini API 失敗 ${res.status}: ${t}`);}const data=await res.json();let out=data?.candidates?.[0]?.content?.parts?.[0]?.text??data?.candidates?.[0]?.content?.parts?.[0]?.inline_data?.data??"";if(typeof out!=="string")out=JSON.stringify(out);out=out.replace(/```json/gi, "").replace(/```/g,"").trim();let jsonText=out;if(!/^\s*[\[{]/.test(out)){const m=out.match(/([\[{][\s\S]*[\]}])/);if(m)jsonText=m[1];}try{const parsed=JSON.parse(jsonText);if(!Array.isArray(parsed))throw new Error("回覆不是陣列");return parsed;}catch(e){ERR("JSON.parse 失敗，原始回覆：",out);throw new Error("Gemini 回覆非有效 JSON。");}}function findRowByNumber(tableId,number){const table=byId(tableId);if(!table)return null;const rows=getDirectBodyRows(table);return rows.find((tr)=>(tr.cells?.[0]?.textContent||"").includes(`${number}.`))||null;}function clickOptionByExactLabel(cell,targetText){const labels=Array.from(cell?.querySelectorAll("label")||[]);const tNorm=tidy(targetText);const found=labels.find((l)=>tidy(l.textContent)===tNorm);if(!found)return false;const input=found.control||found.previousElementSibling;if(input&&(input.type==="radio"||input.type==="checkbox")){input.click();return true;}return false;}function autofillAnswer(item){const{type,number,answer}=item;if(type==="是非題"){const row=findRowByNumber(TABLE_IDS.yn,number);if(!row)return{ok:false,reason:"找不到是非題列"};const cell=row.cells[2];const ans=String(answer??"").trim();const target=(ans==="對"||ans.toLowerCase()==="true")?"對":"錯";const ok=clickOptionByExactLabel(cell,target);return{ok,reason:ok?"":`無法匹配選項：${target}`};}if(type==="單選題"){const row=findRowByNumber(TABLE_IDS.single,number);if(!row)return{ok:false,reason:"找不到單選題列（頁面可能沒有單選區）"};const cell=row.cells[2];if(typeof answer!=="string")return{ok:false,reason:"單選題答案應為字串"};const ok=clickOptionByExactLabel(cell,answer);return{ok,reason:ok?"":`無法匹配選項：${answer}`};}if(type==="複選題"){const row=findRowByNumber(TABLE_IDS.multi,number);if(!row)return{ok:false,reason:"找不到複選題列（頁面可能沒有複選區）"};const cell=row.cells[2];const arr=Array.isArray(answer)?answer:(answer==null?[]:[answer]);const miss=[];for(const a of arr){const ok=clickOptionByExactLabel(cell,String(a));if(!ok)miss.push(a);}return{ok:miss.length===0,reason:miss.length?`未匹配：${miss.join("、")}`:""};}return{ok:false,reason:"未知題型"};}function autofillAll(answers){let ok=0,fail=0;const fails=[];for(const a of answers){const r=autofillAnswer(a);if(r.ok)ok++;else{fail++;fails.push({number:a.number,type:a.type,reason:r.reason,question:a.question,answer:a.answer});}}LOG(`自動填答完成：成功 ${ok} 題、失敗 ${fail} 題`);if(fails.length){console.table(fails);WARN("有未匹配成功的題目，已列在上表，請檢查題幹與選項字串是否完全一致。");}}try{if(!GEMINI_API_KEY||/<<\s*填入/i.test(GEMINI_API_KEY)){return WARN("請先把 GEMINI_API_KEY 換成你的金鑰再執行。");}LOG("送出至 Gemini 產生答案…");const answers=await askGeminiForAnswers(prompt);const cnt={yn:answers.filter(a=>a.type==="是非題").length,single:answers.filter(a=>a.type==="單選題").length,multi:answers.filter(a=>a.type==="複選題").length,};LOG("Gemini 回傳題數：",cnt,"（頁面實際 → 是非:",yn.length,"單選:",single.length,"複選:",multi.length,")");window._tkmQuestions=allQuestions;window._tkmAnswers=answers;autofillAll(answers);}catch(e){ERR("流程失敗：",e);}})()
```

``` cmd
:: cmd 連線 VPN
rasdial.exe vpn user passwd
timeout /t 3600
rasdial.exe vpn /DISCONNECT
```

## 3. 評比

### 1. 滿分版
``` javascript
var ids = [    
    "ctl00_ContentPlaceHolder1_gvCompete_ctl02_rblCompete_0",
    "ctl00_ContentPlaceHolder1_gvCompete_ctl03_rblCompete_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl01_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl02_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl03_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl04_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl05_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl06_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl07_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl08_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl09_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl10_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl11_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl12_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl13_rbSa_0",
    "ctl00_ContentPlaceHolder1_gvSa_ctl14_rbSa_0"
];

ids.forEach(function(id) {
    var element = document.getElementById(id);
    if (element) {
        element.click(); // 模擬點擊操作
    }
});
```

###  2.隨機版
``` javascript
// 評比
let score1 = Math.random() < 0.5 ? "0" : "1"; // 0: 10分, 1: 9分
document.getElementById("ctl00_ContentPlaceHolder1_gvCompete_ctl02_rblCompete_" + score1).checked = true;
let score2 = Math.random() < 0.5 ? "0" : "1"; // 0: 10分, 1: 9分
document.getElementById("ctl00_ContentPlaceHolder1_gvCompete_ctl03_rblCompete_" + score2).checked = true;

// 滿意度
for (let i = 2; i <= 14; i++) {
    const index = Math.random() < 0.5 ? 0 : 1; // 0 = 非常同意, 1 = 同意
    const id = `ctl00_ContentPlaceHolder1_gvSa_ctl${i.toString().padStart(2, '0')}_rbSa_${index}`;
    const el = document.getElementById(id);
    if (el) el.checked = true;
}

```
![image](https://hackmd.io/_uploads/ByqcWeDlWg.png)


