您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
学在浙大/智云课堂 辅助脚本 by memset0
当前为
// ==UserScript== // @name 学在浙大/智云课堂 辅助脚本 // @description 学在浙大/智云课堂 辅助脚本 by memset0 // @namespace https://github.com/memset0/Learning-at-ZJU-Helper // @homepage https://github.com/memset0/Learning-at-ZJU-Helper // @supportURL https://github.com/memset0/Learning-at-ZJU-Helper/issues // @match *://classroom.zju.edu.cn/* // @match *://onlineroom.cmc.zju.edu.cn/* // @match *://livingroom.cmc.zju.edu.cn/* // @match *://interactivemeta.cmc.zju.edu.cn/* // @match *://courses.zju.edu.cn/* // @match **://pintia.cn/* // @grant unsafeWindow // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @grant GM_removeValueChangeListener // @grant GM_getResourceText // @resource jszip.min.js https://jsd.cdn.zzko.cn/gh/memset0/Learning-at-ZJU-Helper@latest/lib/jszip.min.js // @encoding utf-8 // @run-at document-start // @version 1.3.0 // @author memset0 // @license MIT // ==/UserScript== (() => { var e = { 271: (e, t, n) => { "use strict"; n.d(t, { A: () => s }); var r = n(601), o = n.n(r), i = n(314), a = n.n(i)()(o()); a.push([e.id, ".mem-pta-btn{border:none;border-radius:4px}", ""]); const s = a }, 443: (e, t, n) => { "use strict"; n.d(t, { A: () => s }); var r = n(601), o = n.n(r), i = n(314), a = n.n(i)()(o()); a.push([e.id, ".mem-bvp-btn{position:relative;margin-right:10px;order:-1;color:#fff;font-size:12px}.mem-bvt-fullscreen .app-wrap{overflow:hidden!important}.mem-bvt-fullscreen .player-wrapper{position:fixed!important;top:0;left:0;z-index:114514!important;width:100%!important;height:100%!important}", ""]); const s = a }, 297: (e, t, n) => { "use strict"; n.d(t, { A: () => s }); var r = n(601), o = n.n(r), i = n(314), a = n.n(i)()(o()); a.push([e.id, ".mem-btn{border:none;display:flex;margin-left:16px;cursor:pointer;height:32px;line-height:32px;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;border-radius:4px;background-color:#f0f1f3;font-size:14px;color:#144aea;text-align:center;position:relative;padding:0 6px}@media screen and (max-width:1679px){.mem-btn{margin-left:11.42856px;height:22.85712px;line-height:22.85712px;font-size:9.99999px}}@media screen and (min-width:1680px) and (max-width:1919px){.mem-btn{margin-left:14px;height:28px;line-height:28px;font-size:12.25px}}", ""]); const s = a }, 254: (e, t, n) => { "use strict"; n.d(t, { A: () => s }); var r = n(601), o = n.n(r), i = n(314), a = n.n(i)()(o()); a.push([e.id, ".footer.gtm-category.ng-scope,__nothing__{display:none!important}", ""]); const s = a }, 844: (e, t, n) => { "use strict"; n.d(t, { A: () => s }); var r = n(601), o = n.n(r), i = n(314), a = n.n(i)()(o()); a.push([e.id, ".custom-footer,.feedback-wrapper,.hot-recommend-wrapper,.menu-content>.first-menu:nth-child(4),.menu-content>.first-menu:nth-child(5),__nothing__{display:none!important}__nothing__{opacity:0!important;pointer-events:none;cursor:default}.living-page-wrapper{padding-bottom:20.040129px}.course-filter-searchAll-custom{border-left:none!important;border-right:none!important}.collect>.collect_span,.collect>.good_span,.operate_wrap>.collect_span,.operate_wrap>.good_span{display:none!important}.side_tab_wrap .side_tab{background:#f9f9f9!important;transform:none!important;color:#a0a0a0!important}.side_tab_wrap .side_tab span{transform:none!important}.side_tab_wrap .side_tab.active span{color:#144aea!important;font-weight:700!important}.relative-info-gap,.relative-info-right{display:none}.relative-info-left{width:100%!important}", ""]); const s = a }, 314: e => { "use strict"; e.exports = function(e) { var t = []; return t.toString = function() { return this.map((function(t) { var n = "", r = void 0 !== t[5]; return t[4] && (n += "@supports (".concat(t[4], ") {")), t[2] && (n += "@media ".concat(t[2], " {")), r && (n += "@layer".concat(t[5].length > 0 ? " ".concat(t[5]) : "", " {")), n += e(t), r && (n += "}"), t[2] && (n += "}"), t[4] && (n += "}"), n })).join("") }, t.i = function(e, n, r, o, i) { "string" == typeof e && (e = [ [null, e, void 0] ]); var a = {}; if (r) for (var s = 0; s < this.length; s++) { var c = this[s][0]; null != c && (a[c] = !0) } for (var l = 0; l < e.length; l++) { var u = [].concat(e[l]); r && a[u[0]] || (void 0 !== i && (void 0 === u[5] || (u[1] = "@layer".concat(u[5].length > 0 ? " ".concat(u[5]) : "", " {").concat(u[1], "}")), u[5] = i), n && (u[2] ? (u[1] = "@media ".concat(u[2], " {").concat(u[1], "}"), u[2] = n) : u[2] = n), o && (u[4] ? (u[1] = "@supports (".concat(u[4], ") {").concat(u[1], "}"), u[4] = o) : u[4] = "".concat(o)), t.push(u)) } }, t } }, 601: e => { "use strict"; e.exports = function(e) { return e[1] } }, 213: function(e, t, n) { var r, o; void 0 === (o = "function" == typeof(r = function() { "use strict"; function t(e, t, n) { var r = new XMLHttpRequest; r.open("GET", e), r.responseType = "blob", r.onload = function() { s(r.response, t, n) }, r.onerror = function() { console.error("could not download file") }, r.send() } function r(e) { var t = new XMLHttpRequest; t.open("HEAD", e, !1); try { t.send() } catch (e) {} return 200 <= t.status && 299 >= t.status } function o(e) { try { e.dispatchEvent(new MouseEvent("click")) } catch (n) { var t = document.createEvent("MouseEvents"); t.initMouseEvent("click", !0, !0, window, 0, 0, 0, 80, 20, !1, !1, !1, !1, 0, null), e.dispatchEvent(t) } } var i = "object" == typeof window && window.window === window ? window : "object" == typeof self && self.self === self ? self : "object" == typeof n.g && n.g.global === n.g ? n.g : void 0, a = i.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent), s = i.saveAs || ("object" != typeof window || window !== i ? function() {} : "download" in HTMLAnchorElement.prototype && !a ? function(e, n, a) { var s = i.URL || i.webkitURL, c = document.createElement("a"); n = n || e.name || "download", c.download = n, c.rel = "noopener", "string" == typeof e ? (c.href = e, c.origin === location.origin ? o(c) : r(c.href) ? t(e, n, a) : o(c, c.target = "_blank")) : (c.href = s.createObjectURL(e), setTimeout((function() { s.revokeObjectURL(c.href) }), 4e4), setTimeout((function() { o(c) }), 0)) } : "msSaveOrOpenBlob" in navigator ? function(e, n, i) { if (n = n || e.name || "download", "string" != typeof e) navigator.msSaveOrOpenBlob(function(e, t) { return void 0 === t ? t = { autoBom: !1 } : "object" != typeof t && (console.warn("Deprecated: Expected third argument to be a object"), t = { autoBom: !t }), t.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type) ? new Blob(["\ufeff", e], { type: e.type }) : e }(e, i), n); else if (r(e)) t(e, n, i); else { var a = document.createElement("a"); a.href = e, a.target = "_blank", setTimeout((function() { o(a) })) } } : function(e, n, r, o) { if ((o = o || open("", "_blank")) && (o.document.title = o.document.body.innerText = "downloading..."), "string" == typeof e) return t(e, n, r); var s = "application/octet-stream" === e.type, c = /constructor/i.test(i.HTMLElement) || i.safari, l = /CriOS\/[\d]+/.test(navigator.userAgent); if ((l || s && c || a) && "undefined" != typeof FileReader) { var u = new FileReader; u.onloadend = function() { var e = u.result; e = l ? e : e.replace(/^data:[^;]*;/, "data:attachment/file;"), o ? o.location.href = e : location = e, o = null }, u.readAsDataURL(e) } else { var d = i.URL || i.webkitURL, p = d.createObjectURL(e); o ? o.location = p : location.href = p, o = null, setTimeout((function() { d.revokeObjectURL(p) }), 4e4) } }); i.saveAs = s.saveAs = s, e.exports = s }) ? r.apply(t, []) : r) || (e.exports = o) }, 102: (e, t, n) => { "use strict"; n.r(t), n.d(t, { default: () => y }); var r = n(72), o = n.n(r), i = n(825), a = n.n(i), s = n(659), c = n.n(s), l = n(56), u = n.n(l), d = n(540), p = n.n(d), f = n(113), m = n.n(f), g = n(271), h = {}; h.styleTagTransform = m(), h.setAttributes = u(), h.insert = c().bind(null, "head"), h.domAPI = a(), h.insertStyleElement = p(), o()(g.A, h); const y = g.A && g.A.locals ? g.A.locals : void 0 }, 734: (e, t, n) => { "use strict"; n.r(t), n.d(t, { default: () => y }); var r = n(72), o = n.n(r), i = n(825), a = n.n(i), s = n(659), c = n.n(s), l = n(56), u = n.n(l), d = n(540), p = n.n(d), f = n(113), m = n.n(f), g = n(443), h = {}; h.styleTagTransform = m(), h.setAttributes = u(), h.insert = c().bind(null, "head"), h.domAPI = a(), h.insertStyleElement = p(), o()(g.A, h); const y = g.A && g.A.locals ? g.A.locals : void 0 }, 756: (e, t, n) => { "use strict"; n.r(t), n.d(t, { default: () => y }); var r = n(72), o = n.n(r), i = n(825), a = n.n(i), s = n(659), c = n.n(s), l = n(56), u = n.n(l), d = n(540), p = n.n(d), f = n(113), m = n.n(f), g = n(297), h = {}; h.styleTagTransform = m(), h.setAttributes = u(), h.insert = c().bind(null, "head"), h.domAPI = a(), h.insertStyleElement = p(), o()(g.A, h); const y = g.A && g.A.locals ? g.A.locals : void 0 }, 831: (e, t, n) => { "use strict"; n.r(t), n.d(t, { default: () => y }); var r = n(72), o = n.n(r), i = n(825), a = n.n(i), s = n(659), c = n.n(s), l = n(56), u = n.n(l), d = n(540), p = n.n(d), f = n(113), m = n.n(f), g = n(254), h = {}; h.styleTagTransform = m(), h.setAttributes = u(), h.insert = c().bind(null, "head"), h.domAPI = a(), h.insertStyleElement = p(), o()(g.A, h); const y = g.A && g.A.locals ? g.A.locals : void 0 }, 445: (e, t, n) => { "use strict"; n.r(t), n.d(t, { default: () => y }); var r = n(72), o = n.n(r), i = n(825), a = n.n(i), s = n(659), c = n.n(s), l = n(56), u = n.n(l), d = n(540), p = n.n(d), f = n(113), m = n.n(f), g = n(844), h = {}; h.styleTagTransform = m(), h.setAttributes = u(), h.insert = c().bind(null, "head"), h.domAPI = a(), h.insertStyleElement = p(), o()(g.A, h); const y = g.A && g.A.locals ? g.A.locals : void 0 }, 72: e => { "use strict"; var t = []; function n(e) { for (var n = -1, r = 0; r < t.length; r++) if (t[r].identifier === e) { n = r; break } return n } function r(e, r) { for (var i = {}, a = [], s = 0; s < e.length; s++) { var c = e[s], l = r.base ? c[0] + r.base : c[0], u = i[l] || 0, d = "".concat(l, " ").concat(u); i[l] = u + 1; var p = n(d), f = { css: c[1], media: c[2], sourceMap: c[3], supports: c[4], layer: c[5] }; if (-1 !== p) t[p].references++, t[p].updater(f); else { var m = o(f, r); r.byIndex = s, t.splice(s, 0, { identifier: d, updater: m, references: 1 }) } a.push(d) } return a } function o(e, t) { var n = t.domAPI(t); return n.update(e), function(t) { if (t) { if (t.css === e.css && t.media === e.media && t.sourceMap === e.sourceMap && t.supports === e.supports && t.layer === e.layer) return; n.update(e = t) } else n.remove() } } e.exports = function(e, o) { var i = r(e = e || [], o = o || {}); return function(e) { e = e || []; for (var a = 0; a < i.length; a++) { var s = n(i[a]); t[s].references-- } for (var c = r(e, o), l = 0; l < i.length; l++) { var u = n(i[l]); 0 === t[u].references && (t[u].updater(), t.splice(u, 1)) } i = c } } }, 659: e => { "use strict"; var t = {}; e.exports = function(e, n) { var r = function(e) { if (void 0 === t[e]) { var n = document.querySelector(e); if (window.HTMLIFrameElement && n instanceof window.HTMLIFrameElement) try { n = n.contentDocument.head } catch (e) { n = null } t[e] = n } return t[e] }(e); if (!r) throw new Error("Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid."); r.appendChild(n) } }, 540: e => { "use strict"; e.exports = function(e) { var t = document.createElement("style"); return e.setAttributes(t, e.attributes), e.insert(t, e.options), t } }, 56: (e, t, n) => { "use strict"; e.exports = function(e) { var t = n.nc; t && e.setAttribute("nonce", t) } }, 825: e => { "use strict"; e.exports = function(e) { if ("undefined" == typeof document) return { update: function() {}, remove: function() {} }; var t = e.insertStyleElement(e); return { update: function(n) { ! function(e, t, n) { var r = ""; n.supports && (r += "@supports (".concat(n.supports, ") {")), n.media && (r += "@media ".concat(n.media, " {")); var o = void 0 !== n.layer; o && (r += "@layer".concat(n.layer.length > 0 ? " ".concat(n.layer) : "", " {")), r += n.css, o && (r += "}"), n.media && (r += "}"), n.supports && (r += "}"); var i = n.sourceMap; i && "undefined" != typeof btoa && (r += "\n/*# sourceMappingURL=data:application/json;base64,".concat(btoa(unescape(encodeURIComponent(JSON.stringify(i)))), " */")), t.styleTagTransform(r, e, t.options) }(t, e, n) }, remove: function() { ! function(e) { if (null === e.parentNode) return !1; e.parentNode.removeChild(e) }(t) } } } }, 113: e => { "use strict"; e.exports = function(e, t) { if (t.styleSheet) t.styleSheet.cssText = e; else { for (; t.firstChild;) t.removeChild(t.firstChild); t.appendChild(document.createTextNode(e)) } } }, 962: (e, t, n) => { "use strict"; n.r(t), n.d(t, { load: () => s, name: () => o, skip: () => a }); var r = n(99); const o = "更好的 PTA"; function i() { return location.href + location.hash } function a({ namespace: e }) { return "PTA" !== e } function s({ logger: e, clipboard: t }) { async function o() { function n(n) { const r = document.createElement("button"); return r.classList.add("mem-pta-btn"), r.innerText = "复制文本", r.onclick = () => { r.innerText = "已复制", setTimeout((() => { r.innerText = "复制文本" }), 500); const o = function(e) { const t = document.createElement("div"); return t.appendChild(e.cloneNode(!0)), function e(t) { for (; t.children.length > 0;) e(t.children[0]); t.outerHTML = function(e) { return "LABEL" === e.tagName ? "- " + e.innerHTML + "\n\n" : "pc-text-raw" === e.className ? e.innerHTML + " " : "katex-html" === e.className || "mrow" === e.tagName ? "" : "katex" === e.className ? "$" + e.innerHTML + "$" : "IMG" === e.tagName ? `` : "PRE" === e.tagName ? "```\n" + e.innerHTML + "\n```\n" : "P" === e.tagName ? e.innerHTML + "\n\n" : e.innerHTML }(t) }(t.children[0]), t.innerHTML.replace(/\n{2,}/g, "\n\n").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&").replace(/ /g, " ").replace(/"/g, '"').replace(/'/g, "'") }(n); t.copy(o), e.debug("plain text:", o) }, r } Array.from(document.querySelectorAll(".pc-x:not(.mem-pta-rendered)")).filter((t => !!t.id && (e.debug(t.id), t.classList.add("mem-pta-rendered"), function(e) { e.children[0].children[0].appendChild(n(e.children[1])) }(t), !0))), Array.from(document.querySelectorAll(".p-4:not(.mem-pta-rendered)")).filter((t => !(!t.children || !t.children.length || "题目描述" != t.children[0].innerText.trim() || (e.debug(t), t.classList.add("mem-pta-rendered"), function(e) { e.children[0].appendChild(n(e.children[1])) }(t), 0)))) } n(102); let a = 20; document.addEventListener("click", (e => { a < 5 && (a = 5) }), !0), (async () => { let e = i(); for (;;) await (0, r.y)(100), i() !== e && (e = i(), a = 20), a > 0 && (--a, await o()) })() } }, 961: (e, t, n) => { "use strict"; n.r(t), n.d(t, { check: () => s, load: () => c, name: () => o, required: () => i }); var r = n(99); const o = "更好的视频播放器", i = ["builtin-video-pages"]; function a(e) { const t = e.querySelector(".control-bottom .control-right"); return t && t.children && 0 !== t.children.length ? t : null } function s({ document: e }) { return !!a(e) } async function c({ logger: e, document: t, elements: o, addButton: i }) { n(734); const s = a(t), c = t.createElement("div"); c.className = "mem-bvp-btn", c.innerText = "网页全屏", c.onclick = () => async function() { t.body.classList.toggle("mem-bvt-fullscreen"), await (0, r.y)(100), o.playerVue.resizePlayer() }(), s.insertBefore(c, s.firstChild), e.debug("wrapper", s, c) } }, 15: (e, t, n) => { "use strict"; function r(e) { return e && "__vue__" in e } n.r(t), n.d(t, { check: () => s, load: () => c, name: () => o, skip: () => i }); const o = "[builtin]视频页面前置"; function i({ env: e }) { return !e.isVideoPage } function a({ document: e }) { const t = e.querySelector(".living-page-wrapper"), n = e.querySelector("#cmcPlayer_container"), o = e.querySelector(".living-page-wrapper .operate_wrap"); return r(t) && r(n) && o ? { course: t, player: n, wrapper: o, courseVue: t.__vue__, playerVue: n.__vue__ } : null } function s({ document: e }) { return !!a({ document: e }) } function c({ logger: e, document: t, extendContext: r }) { n(756); const o = a({ document: t }); e.debug("视频页面元素:", o), r({ elements: o }); const i = o.wrapper, s = t.createElement("div"); s.className = "mem-btn-group", i.insertBefore(s, i.firstChild), e.debug("wrapper", i), r({ addButton: function(n, r, o) { const i = t.createElement("button"); i.className = "mem-btn mem-btn-primary", i.textContent = r, i.style = "display: inline-block", i.setAttribute("data-key", n), i.onclick = () => { o({ element: i, setStatus: t => { e.debug("(button)" + r, "set status:", t), i.innerText = t ? r + "(" + t + ")" : r } }) }; for (const e of s.children) if (Number(e.getAttribute("data-key")) > n) return s.insertBefore(i, e), i; return s.appendChild(i), i } }) } }, 809: (e, t, n) => { "use strict"; n.r(t), n.d(t, { check: () => u, load: () => d, name: () => a, options: () => c, required: () => s }); var r = n(213), o = n(99), i = n(838); const a = "课件下载", s = ["builtin-video-pages"], c = { "auto-remove": !0 }; function l(e) { return Array.from(e.courseVue.$data.pptList) } function u({ elements: e }) { return l(e).length > 0 } function d({ logger: e, elements: t, addButton: n, loadScript: a }, s) { let c = l(t).map((e => ({ ...e, ppt: { ...e.ppt } }))).map((e => (e.imgSrc = e.imgSrc.replace("http://", "https://"), e.s_imgSrc = e.s_imgSrc.replace("http://", "https://"), e))); e.debug(`PPT下载(共${c.length}个):`, c[0]), c = function(e) { const t = []; for (let n = 0; n < e.length; n++) n + 1 < e.length && e[n + 1].switchTime === e[n].switchTime || t.push(e[n]); return t }(c), e.debug(`删除同一秒内的PPT后(共${c.length}个):`, c[0]), n(1.1, "打包下载", (async ({ setStatus: t }) => { t("加载JSZip库"), a("jszip.min.js"); const n = new JSZip; let i = 0, s = c.length; await (0, o.f)(c.map((async (r, o) => { const a = `ppt-${String(o).padStart(4,"0")}-${r.switchTime.replace(/\:/g,"-")}.jpg`, c = await fetch(r.imgSrc, { method: "GET" }), l = await c.blob(); e.debug("添加图片", a, l), t(`正在下载(${++i}/${s})`), n.file(a, l, { binary: !0 }) })), 8), t("生成Zip"), e.debug(n); const l = await n.generateAsync({ type: "blob" }); e.debug("完成生成zip", l), t("完成"), (0, r.saveAs)(l, "ppt.zip"), t(null) })), n(1.2, "导出为PDF", (async ({ setStatus: t }) => { let n = "", r = 0, a = c.length; const s = await (0, o.f)(c.map((async (n, o) => { const i = await fetch(n.imgSrc, { method: "GET" }); t(`正在下载(${++r}/${a})`); const s = await i.blob(), c = URL.createObjectURL(s); return e.log(o, c), c })), 8); t("生成PDF中"); for (const e of s) n += `<div class="page"><img src="${e}" /></div>`; await (0, i.j)({ width: 1280, height: 720, margin: 0 }, n), t(null) })) } }, 238: (e, t, n) => { "use strict"; n.r(t), n.d(t, { load: () => i, name: () => r, required: () => o }); const r = "视频链接解析", o = ["builtin-video-pages"]; function i({ logger: e, clipboard: t, elements: n, addButton: r }) { r(2, "解析链接", (({ setStatus: r }) => { const o = function() { try { return "live" === n.playerVue.liveType ? JSON.parse(n.playerVue.liveUrl.replace("mutli-rate: ", ""))[0].url : document.querySelector("#cmc_player_video").src } catch (e) { return null } }(); o ? (e.info("视频链接:", o), t.copy(o), r("已拷贝"), setTimeout((() => { r(null) }), 500)) : alert("获取视频地址失败,请待播放器完全加载后再试。") })) } }, 906: (e, t, n) => { "use strict"; n.r(t), n.d(t, { check: () => s, description: () => o, load: () => c, name: () => r, required: () => i, skip: () => a }); const r = "示例插件", o = "这是一个示例插件,他不应该被加载到脚本中。", i = []; function a() { return !1 } function s() { return !0 } function c({ logger: e }) { e.debug("示例插件已被加载。") } }, 928: (e, t, n) => { "use strict"; n.r(t), n.d(t, { load: () => o, name: () => r }); const r = "专注模式"; function o({ logger: e, namespace: t }) { "学在浙大" === t ? n(831) : "智云课堂" === t ? n(445) : e.debug("没有可以加载的样式.") } }, 342: (e, t, n) => { var r = { "./better-pintia/index.js": 962, "./better-video-player/index.js": 961, "./builtin-video-pages/index.js": 15, "./download-ppt/index.js": 809, "./download-video/index.js": 238, "./example-plugin/index.js": 906, "./focus-mode/index.js": 928 }; function o(e) { var t = i(e); return n(t) } function i(e) { if (!n.o(r, e)) { var t = new Error("Cannot find module '" + e + "'"); throw t.code = "MODULE_NOT_FOUND", t } return r[e] } o.keys = function() { return Object.keys(r) }, o.resolve = i, e.exports = o, o.id = 342 }, 838: (e, t, n) => { "use strict"; n.d(t, { j: () => i, l: () => o }); var r = n(484); function o(e) { const t = document.createElement("textarea"); t.style.position = "fixed", t.style.opacity = 0, t.value = e, document.body.appendChild(t), t.select(), document.execCommand("copy"), document.body.removeChild(t) } async function i(e, t) { const { width: n, height: o, margin: i } = e; t = "<style> /* normalize browsers */ html, body { margin: 0 !important; padding: 0 !important; } </style>" + (t = "<style> /* page settings */ @page { size: " + n + "px " + o + "px; margin: " + i + "px; } </style>" + (t = "<style> div.page { width: " + (n - 2 * i) + "px; height: " + (o - 2 * i) + "px; } </style>" + t)); const { style: a } = e; a && (t += "\n\n\n\x3c!-- additional style --\x3e<style>" + a + "</style>\n\n\n"); const s = new Blob([t], { type: "text/html;charset=utf-8" }), c = URL.createObjectURL(s); r.Ay.debug("blobUrl:", c); const l = document.createElement("iframe"); l.style.display = "none", l.src = c, document.body.appendChild(l), l.onload = () => { setTimeout((() => { l.focus(), l.contentWindow.print() }), 1) } } }, 99: (e, t, n) => { "use strict"; async function r(e) { return new Promise((t => setTimeout(t, e))) } function o(e, t) { return new Promise(((n, r) => { let o = 0, i = 0, a = 0, s = []; ! function c() { if (console.log("!! ", i, e.length), i >= e.length) n(s); else for (; a < e.length && o < t;) { let t = a; e[a].then((e => { o--, i++, s[t] = e, c() })).catch((e => { r(e) })), o++, a++ } }() })) } n.d(t, { f: () => o, y: () => r }) }, 484: (e, t, n) => { "use strict"; n.d(t, { Ay: () => o }); class r { log(...e) { console.log(this.prefix, ...e) } warn(...e) { console.warn(this.prefix, ...e) } error(...e) { console.error(this.prefix, ...e) } debug(...e) { console.debug(this.prefix, ...e) } info(...e) { console.info(this.prefix, ...e) } extends(e) { return new r(this.namespace + ":" + e) } constructor(e) { this.namespace = e, this.prefix = "[" + e + "]" } } const o = new r("zju-helper") } }, t = {}; function n(r) { var o = t[r]; if (void 0 !== o) return o.exports; var i = t[r] = { id: r, exports: {} }; return e[r].call(i.exports, i, i.exports, n), i.exports } n.n = e => { var t = e && e.__esModule ? () => e.default : () => e; return n.d(t, { a: t }), t }, n.d = (e, t) => { for (var r in t) n.o(t, r) && !n.o(e, r) && Object.defineProperty(e, r, { enumerable: !0, get: t[r] }) }, n.g = function() { if ("object" == typeof globalThis) return globalThis; try { return this || new Function("return this")() } catch (e) { if ("object" == typeof window) return window } }(), n.o = (e, t) => Object.prototype.hasOwnProperty.call(e, t), n.r = e => { "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e, "__esModule", { value: !0 }) }, n.nc = void 0, (() => { "use strict"; var e = n(484), t = n(99), r = n(838); const o = new class { getNamespace() { const e = location.hostname; return "courses.zju.edu.cn" === e ? "学在浙大" : "classroom.zju.edu.cn" === e || "livingroom.cmc.zju.edu.cn" === e || "onlineroom.cmc.zju.edu.cn" === e || "interactivemeta.cmc.zju.edu.cn" === e ? "智云课堂" : "pintia.cn" === e ? "PTA" : null } loadScript(t) { if (this.loadedScripts.includes(t)) return; this.loadedScripts.push(t), e.Ay.debug(t, GM_getResourceText); const n = GM_getResourceText(t); null === n ? e.Ay.error(`脚本 ${t} 加载失败`) : (e.Ay.debug(n), unsafeWindow.eval(n)) } constructor() { this.plugins = {}; const e = n(342); e.keys().forEach((t => { const n = t.slice(2, -9); "example-plugin" !== n && (this.plugins[n] = e(t), this.plugins[n].slug = n) })), this.loadedScripts = [] } async load() { const n = { namespace: this.getNamespace(), clipboard: { copy: r.l }, window: unsafeWindow, document: unsafeWindow.document, env: { isVideoPage: "classroom.zju.edu.cn" === location.host && "/livingroom" === location.pathname || !("interactivemeta.cmc.zju.edu.cn" !== location.host || "/" !== location.pathname || !location.hash.startsWith("#/replay?")) }, loadScript: e => this.loadScript(e), extendContext: e => { for (const t in e) Object.keys(n).includes(t) && n[t] instanceof Object ? n[t] = { ...n[t], ...e[t] } : n[t] = e[t] } }, o = () => { for (const e in this.plugins) if (!this.plugins[e].loaded) return !1; return !0 }; e.Ay.debug("开始加载插件", this.plugins); let i = 0; do { for (const t in this.plugins) { const r = this.plugins[t]; if (!r.loaded) { if (r.required && r.required instanceof Array && r.required.length > 0) { let t = "ok"; for (const e of r.required) { if (this.plugins[e].skipped) { t = "skip"; break } if (!this.plugins[e].loaded) { t = "wait"; break } } if ("skip" === t) { r.loaded = !0, r.skipped = !0, e.Ay.debug(`跳过加载 ${r.slug} 插件,因为前置插件被跳过`); continue } if ("wait" === t) continue } if (r.skip instanceof Function && await r.skip(n)) { r.loaded = !0, r.skipped = !0, e.Ay.debug(`跳过加载 ${r.slug} 插件`); continue } if (r.check instanceof Function && !await r.check(n)) continue; await r.load({ ...n, logger: e.Ay.extends(r.slug) }), r.loaded = !0 } } await (0, t.y)(100) } while (!o() && ++i < 129); e.Ay.info("插件加载完成!") } safe_load() { (async () => { try { await o.load() } catch (t) { throw e.Ay.error(t), t } })() } }; o.safe_load() })() })();