// ==UserScript==
// @name 知库全平台答题助手
// @namespace zhiku
// @version 1.0.6
// @author 知库工作空间
// @description 知库全平台答题助手:在课程页识别题目、查询题库并核对选项后回填;本地缓存可免费复用,个人空间统一管理积分、贡献与账户。查询顺序支持本地缓存 → 知库官方题库 → 可选外部题库 → 个人/公共 AI。适配作业、考试与章节测验等常见场景。已适配【超星学习通、智慧树、中国大学MOOC、智慧职教/职教云、云班课、UMU、青书学堂、168网校、国家开放大学及分站、广东开放大学、上海开放大学、江苏开放大学、云南开放大学、安徽继续教育、河南开放相关站点、优课在线UOOC、西财在线、华医网、柠檬文才、21tb、出头系统、芯位教育、learnin 等】共计 40+ 学习平台,持续补充中。
// @homepage https://zhiku.ahzsksw.cn/
// @supportURL https://zhiku.ahzsksw.cn/space
// @antifeature payment 联网题库有效查询可能消耗积分;个人AI需自备密钥
// @icon data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2264%22%20height%3D%2264%22%20viewBox%3D%220%200%2064%2064%22%20fill%3D%22none%22%3E%0A%20%20%3Cdefs%3E%0A%20%20%20%20%3ClinearGradient%20id%3D%22ink%22%20x1%3D%225%22%20y1%3D%222%22%20x2%3D%2260%22%20y2%3D%2265%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20stop-color%3D%22%237165EA%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%23393184%22%2F%3E%3C%2FlinearGradient%3E%0A%20%20%20%20%3ClinearGradient%20id%3D%22leaf%22%20x1%3D%2239%22%20y1%3D%2230%22%20x2%3D%2247%22%20y2%3D%2253%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20stop-color%3D%22%23A1F7DE%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%2347CBB5%22%2F%3E%3C%2FlinearGradient%3E%0A%20%20%3C%2Fdefs%3E%0A%20%20%3Crect%20x%3D%221%22%20y%3D%221%22%20width%3D%2262%22%20height%3D%2262%22%20rx%3D%2219%22%20fill%3D%22url%28%23ink%29%22%2F%3E%0A%20%20%3Crect%20x%3D%221.5%22%20y%3D%221.5%22%20width%3D%2261%22%20height%3D%2261%22%20rx%3D%2218.5%22%20stroke%3D%22white%22%20stroke-opacity%3D%22.18%22%2F%3E%0A%20%20%3Cpath%20d%3D%22M16%2018H41C43.2%2018%2045%2019.8%2045%2022V24L23%2043H45V48H20C17.8%2048%2016%2046.2%2016%2044V42L38%2023H16V18Z%22%20fill%3D%22white%22%2F%3E%0A%20%20%3Cpath%20d%3D%22M34%2037L49%2029V47L34%2055V37Z%22%20fill%3D%22url%28%23leaf%29%22%2F%3E%0A%20%20%3Cpath%20d%3D%22M39%2039L44%2036M39%2044L44%2041%22%20stroke%3D%22%23245A65%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%20opacity%3D%22.6%22%2F%3E%0A%20%20%3Cpath%20d%3D%22M48%2010L49.8%2014.2L54%2016L49.8%2017.8L48%2022L46.2%2017.8L42%2016L46.2%2014.2L48%2010Z%22%20fill%3D%22%23A1F7DE%22%2F%3E%0A%3C%2Fsvg%3E%0A
// @match *://*.w-ling.cn/*
// @match *://moodle.syxy.ouchn.cn/*
// @match *://*.open.ha.cn/*
// @match *://cce.org.uooconline.com/*
// @match *://*.wdjycj.com/*
// @match *://lms.cjzx.hblll.com/*
// @match *://*.chaoxing.com/*
// @match *://mooc1.ceduacad.ahut.edu.cn/*
// @match *://www.asklib.com/*
// @match *://*.ls365.net/*
// @match *://www.mosoteach.cn/*
// @match *://xczxzdbf.moodle.qwbx.ouchn.cn/*
// @match *://*.wwwwsoft.com/*
// @match *://*.edu-edu.com/*
// @match *://*.csmu.edu.cn/*
// @match *://lms.ouchn.cn/*
// @match *://*.hbcjpt.com/*
// @match *://lhycjy.cloudwis.tech/*
// @match *://*.ouc-online.com.cn/*
// @match *://*.xust.edu.cn/*
// @match *://*.lut.edu.cn/*
// @match *://*.cep.webtrn.cn/*
// @match *://gdrtvu.exam-cloud.cn/*
// @match *://*.ahjxjy.cn/*
// @match *://*.aufe.edu.cn/*
// @match *://*.tongyi.com/*
// @match *://*.telfri-edu.com/*
// @match *://*.zhihuishu.com/*
// @match *://*.icve.com.cn/*
// @match *://*.jsnu.edu.cn/*
// @match *://*.ouchn.edu.cn/*
// @match *://*.ketangx.net/*
// @match *://*.wxic.edu.cn/*
// @match *://*.learnin.com.cn/*
// @match *://*.cnzx.info/*
// @match *://*.geovisearth.com/*
// @match *://*.cqie.cn/*
// @match *://*.edu-edu.com.cn/*
// @match *://*.ytccr.com/*
// @match *://*.lygtc.edu.cn/*
// @match *://*.ecust.edu.cn/*
// @match *://moodle.qwbx.ouchn.cn/*
// @match *://*.jijiaool.com/*
// @match *://*.swufe-online.com/*
// @match *://*.dufe.edu.cn/*
// @match *://*.mynep.com/*
// @match *://*.yxbyun.com/*
// @match *://whkpc.hnqtyq.cn:5678/*
// @match *://*.wencaischool.net/*
// @match *://*.exam-cloud.cn/*
// @match *://*.21tb.com/*
// @match *://sdrz.gxk.yxlearning.com/*
// @match *://*.web2.superchutou.com/*
// @match *://*.sclecb.cn/*
// @match *://any.cnzx.info:81/*
// @match *://*.qau.edu.cn/*
// @match *://*.jxjypt.cn/*
// @match *://www.beeline-ai.com/*
// @match *://chat.deepseek.com/*
// @match *://teach.ynou.edu.cn/*
// @match *://zice.cnzx.info/*
// @match *://*.iwdjy.com/*
// @match *://*.whut.edu.cn/*
// @match *://*.shou.org.cn/*
// @match *://ks.cqsdx.cn/*
// @match *://*.chinaedu.net/*
// @match *://*.webtrn.cn/*
// @match *://elearning.bjou.edu.cn/*
// @match *://www.51xinwei.com/*
// @match *://*.168wangxiao.com/*
// @match *://www.icourse163.org/*
// @match *://study.ouchn.cn/*
// @match *://xuexi.jsou.cn/*
// @match *://*.jijiaox.com/*
// @match *://*.ouchn.cn/*
// @match *://*.cjnep.net/*
// @match https://zhiku.ahzsksw.cn/demo*
// @match https://new.oberyun.com/*
// @match *://course.ougd.cn/*
// @match *://*.hlju.edu.cn/*
// @match *://*.cfyedu.com/*
// @match *://*.courshare.cn/*
// @match *://*.qingshuxuetang.com/*
// @match https://m.umu.cn/*
// @match *://*.91huayi.com/*
// @match *://*.cj-edu.com/*
// @match *://*.crjxjy.net/*
// @match *://*.lsedu.vip/*
// @match *://*.bgzk-edu.cn/*
// @match *://*.gdufemooc.cn/*
// @require https://cdn.jsdelivr.net/npm/vue@3.4.27/dist/vue.global.prod.js
// @require https://cdn.jsdelivr.net/npm/vue-demi@0.14.6/lib/index.iife.js
// @require data:application/javascript,%3Bwindow.Vue%3DVue%3B
// @require https://cdn.jsdelivr.net/npm/@iconify/vue@5.0.0/dist/iconify.js
// @require https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js
// @require https://cdn.jsdelivr.net/npm/dompurify@3.1.6/dist/purify.min.js
// @require https://cdn.jsdelivr.net/npm/crypto-js@4.2.0/crypto-js.js
// @require https://cdn.jsdelivr.net/npm/pinia@2.2.4/dist/pinia.iife.prod.js
// @connect lut.edu.cn
// @connect ks.cqsdx.cn
// @connect jijiaool.com
// @connect exam-cloud.cn
// @connect cep.webtrn.cn
// @connect qau.edu.cn
// @connect lsedu.vip
// @connect *
// @connect www.beeline-ai.com
// @connect ouchn.edu.cn
// @connect csmu.edu.cn
// @connect gdrtvu.exam-cloud.cn
// @connect open.bigmodel.cn
// @connect chat.deepseek.com
// @connect cqie.cn
// @connect crjxjy.net
// @connect ark.cn-beijing.volces.com
// @connect dufe.edu.cn
// @connect iwdjy.com
// @connect www.icourse163.org
// @connect api.groq.com
// @connect api.longcat.chat
// @connect generativelanguage.googleapis.com
// @connect new.oberyun.com
// @connect whkpc.hnqtyq.cn
// @connect moodle.qwbx.ouchn.cn
// @connect hbcjpt.com
// @connect api.moonshot.ai
// @connect w-ling.cn
// @connect moodle.syxy.ouchn.cn
// @connect mynep.com
// @connect sdrz.gxk.yxlearning.com
// @connect gdufemooc.cn
// @connect xust.edu.cn
// @connect hlju.edu.cn
// @connect www.51xinwei.com
// @connect ecust.edu.cn
// @connect cce.org.uooconline.com
// @connect teach.ynou.edu.cn
// @connect webtrn.cn
// @connect lms.ouchn.cn
// @connect telfri-edu.com
// @connect dashscope.aliyuncs.com
// @connect api.hunyuan.cloud.tencent.com
// @connect qingshuxuetang.com
// @connect m.umu.cn
// @connect api.openai.com
// @connect wdjycj.com
// @connect whut.edu.cn
// @connect api.together.ai
// @connect zhihuishu.com
// @connect lygtc.edu.cn
// @connect 21tb.com
// @connect wencaischool.net
// @connect www.asklib.com
// @connect xuexi.jsou.cn
// @connect icve.com.cn
// @connect open.ha.cn
// @connect cjnep.net
// @connect 91huayi.com
// @connect yxbyun.com
// @connect sclecb.cn
// @connect courshare.cn
// @connect api.siliconflow.cn
// @connect qianfan.baidubce.com
// @connect lms.cjzx.hblll.com
// @connect mooc1.ceduacad.ahut.edu.cn
// @connect 168wangxiao.com
// @connect ahjxjy.cn
// @connect ketangx.net
// @connect edu-edu.com
// @connect cnzx.info
// @connect shou.org.cn
// @connect learnin.com.cn
// @connect lhycjy.cloudwis.tech
// @connect course.ougd.cn
// @connect zhiku.ahzsksw.cn
// @connect jijiaox.com
// @connect forestpolice.org
// @connect ls365.net
// @connect study.ouchn.cn
// @connect tongyi.com
// @connect any.cnzx.info
// @connect api.anthropic.com
// @connect elearning.bjou.edu.cn
// @connect cj-edu.com
// @connect openrouter.ai
// @connect bgzk-edu.cn
// @connect ouc-online.com.cn
// @connect chinaedu.net
// @connect geovisearth.com
// @connect jsdelivr.net
// @connect api.mistral.ai
// @connect zice.cnzx.info
// @connect www.mosoteach.cn
// @connect swufe-online.com
// @connect ouchn.cn
// @connect wwwwsoft.com
// @connect jsnu.edu.cn
// @connect edu-edu.com.cn
// @connect jxjypt.cn
// @connect wxic.edu.cn
// @connect web2.superchutou.com
// @connect aufe.edu.cn
// @connect api.deepseek.com
// @connect cfyedu.com
// @connect jsdmirror.cn
// @connect chaoxing.com
// @connect xczxzdbf.moodle.qwbx.ouchn.cn
// @connect vxo.im
// @connect ytccr.com
// @grant GM.xmlHttpRequest
// @grant GM_deleteValue
// @grant GM_getValue
// @grant GM_info
// @grant GM_listValues
// @grant GM_setValue
// @grant GM_xmlhttpRequest
// @grant unsafeWindow
// @run-at document-start
// ==/UserScript==
(function (vue, vue$1, pinia, M, j, O) {
'use strict';
var e = Object.defineProperty, __publicField = (t, n, a) => ((t, n, a) => n in t ? e(t, n, {
enumerable: true,
configurable: true,
writable: true,
value: a
}) : t[n] = a)(t, "symbol" != typeof n ? n + "" : n, a);
const z = new Set([ "preparing", "searching", "matched", "published", "rendering", "filling" ]), D = {
todo: "\u672a\u7b54",
run: "\u67e5\u627e\u4e2d",
done: "\u5df2\u7b54",
none: "\u65e0\u7b54\u6848",
wait: "AI \u5f85\u786e\u8ba4"
};
function tallyMarks(e) {
const t = {
done: 0,
none: 0,
wait: 0,
todo: 0
};
for (const n of e) "run" === n ? t.todo++ : t[n]++;
return t;
}
const F = "\u672c\u5730\u7f13\u5b58", isAiForm = (e = "") => /AI/i.test(e), hasAnswer = e => {
if (e.needLogin) return false;
const t = e.answer;
return Array.isArray(t) ? t.length > 0 : t && "object" == typeof t ? Object.keys(t).length > 0 : "string" == typeof t ? t.trim().length > 0 : !!t;
};
var X = (() => "undefined" != typeof GM_deleteValue ? GM_deleteValue : void 0)(), ee = (() => "undefined" != typeof GM_getValue ? GM_getValue : void 0)(), te = (() => "undefined" != typeof GM_info ? GM_info : void 0)(), ne = (() => "undefined" != typeof GM_listValues ? GM_listValues : void 0)(), ae = (() => "undefined" != typeof GM_setValue ? GM_setValue : void 0)(), re = function (details) { const xhr = (typeof getRuntimeGmXmlhttpRequest === "function" && getRuntimeGmXmlhttpRequest()) || (typeof GM_xmlhttpRequest === "function" ? GM_xmlhttpRequest : (typeof GM !== "undefined" && typeof GM.xmlHttpRequest === "function" ? GM.xmlHttpRequest : null)); if (typeof xhr !== "function") throw new Error("GM_xmlhttpRequest unavailable"); return xhr(details); }, ie = (() => "undefined" != typeof unsafeWindow ? unsafeWindow : void 0)();
const se = "PrivateStudy_";
class Cache {
static set(e, t, n = 0) {
e = se + e;
const a = {
value: t,
expire: n > 0 ? Date.now() + 1e3 * n : 0
};
return ae(e, a), ee(e);
}
static get(e, t = null) {
const n = ee(e = se + e);
return n && n.expire && n.expire < Date.now() ? (X(e), t) : n ? n.value : t;
}
static match(e) {
return e = se + e, ne().filter((t => t.startsWith(e)));
}
static matchGet(e) {
const t = se + e;
let n = ne().filter((e => e.startsWith(t))).map((e => function(e, t, n) {
if (t && t.expire && t.expire < Date.now()) return n(e), null;
const a = t ? t.value : null;
return a && (a.key = e.replace("PrivateStudy_", "")), a;
}(e, ee(e, {
value: null,
expire: 0
}), X))).filter((e => null !== e));
return n.sort(((e, t) => (t.createTime || 0) - (e.createTime || 0))), n;
}
static remove(e) {
X(se + e);
}
static clear() {
ne().filter((e => e.startsWith(se))).forEach(X);
}
static matchRemove(e) {
e = se + e, ne().filter((t => t.startsWith(e))).forEach(X);
}
}
let oe = null;
function log$1(...e) {}
let panelNotification = null;
const addLog = (content, type = "info") => {
const app = oe?.();
if (app) app.addLog({time: new Date().toLocaleString(), type, content});
};
function msg(content, type = "info") {
addLog(content, type);
if (panelNotification) panelNotification(cleanQuestionText(content), type);
}
async function encrypt(e = "", t = "asdgdfghfghfghfg", n = "1234567890123456") {
try {
if (!e) return "";
if (t = t.substring(0, 16), n = n.substring(0, 16), !window.crypto || !window.crypto.subtle) {
const a = j.enc.Utf8.parse(t), r = j.enc.Utf8.parse(n);
return j.AES.encrypt(e, a, {
iv: r,
mode: j.mode.CBC,
padding: j.pad.Pkcs7
}).toString();
}
const r = new TextEncoder, i = r.encode(e), s = r.encode(t), o = r.encode(n), l = await crypto.subtle.importKey("raw", s, {
name: "AES-CBC"
}, !1, [ "encrypt" ]), c = await crypto.subtle.encrypt({
name: "AES-CBC",
iv: o
}, l, i), u = new Uint8Array(c), p = 1024;
let d, m = "";
for (let e = 0; e < u.length; e += p) {
const t = u.slice(e, Math.min(e + p, u.length));
m += String.fromCharCode.apply(null, Array.from(t));
}
try {
d = btoa(m);
} catch (a) {
d = m.split("").map((e => ("0" + e.charCodeAt(0).toString(16)).slice(-2))).join("");
}
return d;
} catch (r) {
return addLog(`\u52a0\u5bc6\u5f02\u5e38: ${r instanceof Error ? r.message : "\u672a\u77e5\u9519\u8bef"}`, "error"),
"";
}
}
async function decrypt(e = "", t = "asdgdfghfghfghfg", n = "1234567890123456") {
try {
if (!e) return "";
if (t = t.substring(0, 16), n = n.substring(0, 16), !window.crypto || !window.crypto.subtle) {
const a = j.enc.Utf8.parse(t), r = j.enc.Utf8.parse(n);
return j.AES.decrypt(e, a, {
iv: r,
mode: j.mode.CBC,
padding: j.pad.Pkcs7
}).toString(j.enc.Utf8);
}
/^[A-Za-z0-9+/]*={0,2}$/.test(e);
const r = new TextEncoder, i = r.encode(t), s = r.encode(n);
let o;
try {
o = atob(e);
} catch (a) {
throw new Error("Base64 \u89e3\u7801\u5931\u8d25\uff0c\u6570\u636e\u683c\u5f0f\u4e0d\u6b63\u786e");
}
const l = new Uint8Array(o.length);
for (let e = 0; e < o.length; e++) l[e] = o.charCodeAt(e);
if (l.length % 16 != 0) throw new Error("\u52a0\u5bc6\u6570\u636e\u957f\u5ea6\u4e0d\u6b63\u786e\uff0c\u4e0d\u662f16\u7684\u500d\u6570");
const c = await crypto.subtle.importKey("raw", i, {
name: "AES-CBC"
}, !1, [ "decrypt" ]), u = await crypto.subtle.decrypt({
name: "AES-CBC",
iv: s
}, c, l);
return new TextDecoder("utf-8", {
fatal: !0
}).decode(u);
} catch (r) {
return addLog(`\u89e3\u5bc6\u5f02\u5e38: ${r instanceof Error ? r.message : "\u672a\u77e5\u9519\u8bef"}`, "error"),
"";
}
}
function md5(e) {
return j.MD5(e).toString();
}
function somd5(e) {
return md5(e);
}
const isPlainObject$1 = e => "object" == typeof e && null !== e && !Array.isArray(e), flattenForSignature = (e, t = "") => {
const n = [];
return Object.keys(e).sort().forEach((a => {
if (!t && "html" === a) return;
const r = t ? `${t}.${a}` : a, i = e[a];
(e => null == e || !(!Array.isArray(e) || 0 !== e.length) || !(!isPlainObject$1(e) || 0 !== Object.keys(e).length))(i) || (Array.isArray(i) ? n.push(`${r}=${(e => e.every((e => "object" != typeof e)) ? [ ...e ].sort().join(",") : JSON.stringify(e))(i)}`) : isPlainObject$1(i) ? n.push(...flattenForSignature(i, r)) : n.push(`${r}=${String(i)}`));
})), n;
};
function get_t(e = {}) {
return md5(flattenForSignature(e).join("&"));
}
const getImageSrc = e => {
const t = String(e).match(/(?:^|\s)src\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i);
return t && (t[1] || t[2] || t[3]) || "";
}, stripImageSrcQuery = e => e.replace(/[?#].*$/, ""), cleanQuestionText = (e, t = false) => String(e ?? "").replace(/
]*)>/gi, ((e, t) => getImageSrc(t))).replace(/
/gi, "\n").replace(/<(\/)?(p|div).*?>/gi, "\n").replace(/<[^>]+>/g, "").replace(t ? /[\r\xa0]/g : /[\t\r\xa0]/g, " ").replace(/[\u2000-\u200a]/g, " ").replace(/ {2,}/g, " ").replace(/\n{2,}/g, "\n").replace(t ? /^[^\S\t]+|[^\S\t]+$/g : /^\s+|\s+$/g, ""), cleanQuestionTextWithImageHtml = (e, t = false) => {
const n = [];
return String(e ?? "").replace(/
]*)>/gi, ((e, t) => {
const a = getImageSrc(t);
if (!a) return "";
const r = `\0AAH_IMAGE_PLACEHOLDER_${n.length}\0`;
return n.push(`
/g, ">"))(a)}">`),
r;
})).replace(/
/gi, "\n").replace(/<(\/)?(p|div).*?>/gi, "\n").replace(/<[^>]+>/g, "").replace(/\u0000AAH_IMAGE_PLACEHOLDER_(\d+)\u0000/g, ((e, t) => n[Number(t)] || "")).replace(t ? /[\r\xa0]/g : /[\t\r\xa0]/g, " ").replace(/[\u2000-\u200a]/g, " ").replace(/ {2,}/g, " ").replace(/\n{2,}/g, "\n").replace(t ? /^[^\S\t]+|[^\S\t]+$/g : /^\s+|\s+$/g, "");
}, cleanQuestionTitle = (e, t = false) => e.replace(/^[.*?]\s*/, "").replace(/^\u3010.*?\u3011\s*/, "").replace(/\s*[\uff08(]\s*\d+(?:\.\d+)?\s*\u5206?\s*[\uff09)]\s*$/, "").replace(/^\d+\./, "").replace(t ? /^[^\S\t]+|[^\S\t]+$/g : /^\s+|\s+$/g, "").replace(/^\d+\uff0e/, "").replace(t ? /^[^\S\t]+|[^\S\t]+$/g : /^\s+|\s+$/g, ""), normalizeComparableText = e => (e => {
if (/^[+-]?\d+(\.\d+)?$/.test(e)) return e;
const t = e.replace(/\s+/g, "");
return t.replace(new RegExp("\\p{P}", "gu"), "") || t;
})((e => String(e ?? "").replace(/
]*)>/gi, ((e, t) => stripImageSrcQuery(getImageSrc(t)))).replace(/<[^>]*>/g, ""))(e)).trim(), removeOptionPrefixes = (e, {removeBareLetter: t = false} = {}) => e.map(((e, n) => {
const a = String.fromCharCode(65 + n), r = t ? `^${a}(?:\\s*[.\u3001\uff0e)\uff09:\uff1a]\\s*|\\s+)?` : `^${a}\\s*[.\u3001\uff0e)\uff09:\uff1a]\\s*`;
return e.replace(new RegExp(r), "").trim();
})), normalizeHashText = e => String(e ?? "").replace(/
]*)>/gi, ((e, t) => {
const n = getImageSrc(t);
return n ? `
` : "";
})), questionHash = (e, t, n, a = true) => {
if (("15" === e || 15 === e) && Array.isArray(n) && n.length > 0 && "object" == typeof n[0]) {
const r = n.map((e => {
if (e.question && e.options) {
const t = Array.from(e.options).map(normalizeHashText);
a && t.sort();
const n = t.join("");
return `${e.type || "0"}${normalizeHashText(e.question)}${n}`;
}
return "";
})).filter(Boolean);
let i = `${e}${normalizeHashText(t)}${r.join("")}`;
return i = i.replace(/\s/g, ""), md5(i);
}
const r = Array.from(n).map(normalizeHashText);
a && r.sort();
const i = r.join("");
let s = `${e}${normalizeHashText(t)}${i}`;
return s = s.replace(/\s/g, ""), md5(s);
}, sanitizeHtml = (e, t, n) => {
const a = M.sanitize;
return "function" == typeof a ? a(e, {
ALLOWED_TAGS: t,
ALLOWED_ATTR: n,
ALLOW_DATA_ATTR: false,
KEEP_CONTENT: true
}) : ((e, t, n) => {
const a = new Set(t), r = new Set(n);
return e.replace(/