您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
【(1)收藏视频备注功能】:支持在收藏视频时添加备注信息,然后在收藏夹中快速查看和管理备注内容 ;【(2)视频笔记下载功能】:支持转换单视频、分p视频、合集视频的私人笔记内容为Markdown文件并下载至本地 ;【(3)分p/合集视频列表随机播放功能】:支持单个页面开启/关闭,可自动、点击、快捷键、蓝牙随机切换 ;【(4)数据备份、恢复功能】:支持按时间间隔自动备份数据到云端和手动恢复,同时支持导出到本地和导入 ;(注意:部分功能仅适配B站新版网页端)
// ==UserScript== // @name B站收藏视频备注+自动备份、视频笔记下载、分p/合集视频随机播放…… // @namespace https://github.com/Jayvin-Leung // @version 1.1.1 // @author Jayvin Leung // @description 【(1)收藏视频备注功能】:支持在收藏视频时添加备注信息,然后在收藏夹中快速查看和管理备注内容 ;【(2)视频笔记下载功能】:支持转换单视频、分p视频、合集视频的私人笔记内容为Markdown文件并下载至本地 ;【(3)分p/合集视频列表随机播放功能】:支持单个页面开启/关闭,可自动、点击、快捷键、蓝牙随机切换 ;【(4)数据备份、恢复功能】:支持按时间间隔自动备份数据到云端和手动恢复,同时支持导出到本地和导入 ;(注意:部分功能仅适配B站新版网页端) // @license MIT // @icon https://github.com/user-attachments/assets/b9c1ca07-876b-4fd9-b88e-df10cb29615f // @homepageURL https://github.com/Jayvin-Leung/Bilibili-Memo // @supportURL https://github.com/Jayvin-Leung/Bilibili-Memo/issues // @match https://www.bilibili.com/ // @match https://www.bilibili.com/video/* // @match https://www.bilibili.com/list/* // @match https://space.bilibili.com/*/favlist* // @require https://registry.npmmirror.com/dayjs/1.11.13/files/dayjs.min.js // @require https://registry.npmmirror.com/dayjs/1.11.13/files/plugin/customParseFormat.js // @require https://registry.npmmirror.com/dayjs/1.11.13/files/plugin/weekday.js // @require https://registry.npmmirror.com/dayjs/1.11.13/files/plugin/localeData.js // @require https://registry.npmmirror.com/dayjs/1.11.13/files/plugin/weekOfYear.js // @require https://registry.npmmirror.com/dayjs/1.11.13/files/plugin/weekYear.js // @require https://registry.npmmirror.com/dayjs/1.11.13/files/plugin/advancedFormat.js // @require https://registry.npmmirror.com/dayjs/1.11.13/files/plugin/quarterOfYear.js // @require https://registry.npmmirror.com/vue/3.5.13/files/dist/vue.global.prod.js // @require data:application/javascript,window.Vue%3DVue%3B // @require https://registry.npmmirror.com/ant-design-vue/4.2.6/files/dist/antd.min.js // @require https://registry.npmmirror.com/fflate/0.8.2/files/umd/index.js // @resource ant-design-vue/dist/reset.css https://registry.npmmirror.com/ant-design-vue/4.2.6/files/dist/reset.css // @connect kdocs.cn // @grant GM.deleteValue // @grant GM.getTab // @grant GM.getTabs // @grant GM.getValue // @grant GM.info // @grant GM.saveTab // @grant GM.setValue // @grant GM.xmlHttpRequest // @grant GM_addStyle // @grant GM_addValueChangeListener // @grant GM_deleteValue // @grant GM_getResourceText // @grant GM_getValue // @grant GM_listValues // @grant GM_removeValueChangeListener // @grant GM_setValue // @run-at document-end // ==/UserScript== (a=>{if(typeof GM_addStyle=="function"){GM_addStyle(a);return}const t=document.createElement("style");t.textContent=a,document.head.append(t)})(' .ribbon[data-v-83c9451e]{margin:0;font-size:12px;line-height:16px;color:#fff;text-align:center;width:20px;height:18px;background:linear-gradient(135deg,rgba(255,255,255,.4),transparent) #ea3447;background-blend-mode:soft-light;display:inline-block;border-radius:12px 0 0 12px;position:relative;border:1px solid #fff;cursor:pointer}.ribbon[data-v-83c9451e]:after{position:absolute;content:"";clip-path:polygon(0 0,100% 0,0 100%);width:4px;height:4px;right:0;bottom:-4px;background:linear-gradient(#0000004d,#0000004d);background-color:inherit}.ribbon-new[data-v-83c9451e]{background-color:#696969}.custom-row-time[data-v-83c9451e]{margin-top:8px}.custom-col-time[data-v-83c9451e]{font-size:12px;color:#bbb}.bili-video-card__remark{position:absolute;top:38%;right:-4px;z-index:999}.collection__remark{padding:20px 20px 0;border-top:1px solid #e3e5e7}.custom-loading{position:absolute;z-index:999;border:1px solid #1677ff;border-radius:6px;background:#ffffffb3;text-align:center;padding-top:200px}.custom-more{position:absolute;z-index:999}.items[data-v-1d7c71a3]{width:100%;padding:0 10px;background:#efefef;border-radius:4px}.item[data-v-1d7c71a3]{margin:8px 0;background:#fff;border:1px solid #dbdbdb;border-radius:6px}.moving[data-v-1d7c71a3]{color:transparent;background:transparent;border:1px dashed #ccc;transition:none}.backup-time[data-v-c47228de],.restore-time[data-v-c47228de]{font-size:12px;color:#bbb}.custom-layout[data-v-69aa2ebc]{background-color:#fff;color:#000;max-height:600px;overflow:hidden}.custom-layout-sider[data-v-69aa2ebc]{text-align:right;margin:10px;height:580px;overflow:auto}.custom-layout-sider[data-v-69aa2ebc]::-webkit-scrollbar{width:0px}.custom-layout-sider[data-v-69aa2ebc]::-webkit-scrollbar-thumb{background-color:gray;border-radius:5px}.custom-layout-sider[data-v-69aa2ebc]::-webkit-scrollbar-track{background-color:#dcdcdc}.custom-layout-conten[data-v-69aa2ebc]{text-align:left;margin:10px;height:580px;overflow:auto}.custom-layout-conten[data-v-69aa2ebc]::-webkit-scrollbar{width:0px;height:0px;position:absolute;left:0}.custom-layout-conten[data-v-69aa2ebc]::-webkit-scrollbar-thumb{background-color:gray;border-radius:5px}.custom-layout-conten[data-v-69aa2ebc]::-webkit-scrollbar-track{background-color:transparent}.custom-divider[data-v-69aa2ebc]{font-weight:700;font-size:18px;margin:0}.custom-collapse[data-v-69aa2ebc] .ant-collapse-header{padding:0;background-color:#f0f8ff}.custom-collapse[data-v-69aa2ebc] .ant-collapse-content-box{padding:0}ul li[data-v-16c5d314]{padding:4px 0;line-height:24px;list-style:disc}.custom-row{width:100%;padding:6px 10px}.custom-row:hover{background-color:#f0f8ff}.custom-col-label{font-size:16px;height:32px;line-height:32px}.custom-col-content{height:32px;line-height:32px} '); (async function (vue, Antd, fflate) { 'use strict'; const cssLoader = (e) => { const t = GM_getResourceText(e); return GM_addStyle(t), t; }; cssLoader("ant-design-vue/dist/reset.css"); function bound01(n, max) { if (isOnePointZero(n)) { n = "100%"; } var isPercent = isPercentage(n); n = max === 360 ? n : Math.min(max, Math.max(0, parseFloat(n))); if (isPercent) { n = parseInt(String(n * max), 10) / 100; } if (Math.abs(n - max) < 1e-6) { return 1; } if (max === 360) { n = (n < 0 ? n % max + max : n % max) / parseFloat(String(max)); } else { n = n % max / parseFloat(String(max)); } return n; } function isOnePointZero(n) { return typeof n === "string" && n.indexOf(".") !== -1 && parseFloat(n) === 1; } function isPercentage(n) { return typeof n === "string" && n.indexOf("%") !== -1; } function boundAlpha(a) { a = parseFloat(a); if (isNaN(a) || a < 0 || a > 1) { a = 1; } return a; } function convertToPercentage(n) { if (n <= 1) { return "".concat(Number(n) * 100, "%"); } return n; } function pad2(c) { return c.length === 1 ? "0" + c : String(c); } function rgbToRgb(r, g, b) { return { r: bound01(r, 255) * 255, g: bound01(g, 255) * 255, b: bound01(b, 255) * 255 }; } function hue2rgb(p, q, t) { if (t < 0) { t += 1; } if (t > 1) { t -= 1; } if (t < 1 / 6) { return p + (q - p) * (6 * t); } if (t < 1 / 2) { return q; } if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6; } return p; } function hslToRgb(h2, s, l) { var r; var g; var b; h2 = bound01(h2, 360); s = bound01(s, 100); l = bound01(l, 100); if (s === 0) { g = l; b = l; r = l; } else { var q = l < 0.5 ? l * (1 + s) : l + s - l * s; var p = 2 * l - q; r = hue2rgb(p, q, h2 + 1 / 3); g = hue2rgb(p, q, h2); b = hue2rgb(p, q, h2 - 1 / 3); } return { r: r * 255, g: g * 255, b: b * 255 }; } function rgbToHsv(r, g, b) { r = bound01(r, 255); g = bound01(g, 255); b = bound01(b, 255); var max = Math.max(r, g, b); var min = Math.min(r, g, b); var h2 = 0; var v = max; var d = max - min; var s = max === 0 ? 0 : d / max; if (max === min) { h2 = 0; } else { switch (max) { case r: h2 = (g - b) / d + (g < b ? 6 : 0); break; case g: h2 = (b - r) / d + 2; break; case b: h2 = (r - g) / d + 4; break; } h2 /= 6; } return { h: h2, s, v }; } function hsvToRgb(h2, s, v) { h2 = bound01(h2, 360) * 6; s = bound01(s, 100); v = bound01(v, 100); var i = Math.floor(h2); var f = h2 - i; var p = v * (1 - s); var q = v * (1 - f * s); var t = v * (1 - (1 - f) * s); var mod = i % 6; var r = [v, q, p, p, t, v][mod]; var g = [t, v, v, q, p, p][mod]; var b = [p, p, t, v, v, q][mod]; return { r: r * 255, g: g * 255, b: b * 255 }; } function rgbToHex(r, g, b, allow3Char) { var hex = [ pad2(Math.round(r).toString(16)), pad2(Math.round(g).toString(16)), pad2(Math.round(b).toString(16)) ]; return hex.join(""); } function convertHexToDecimal(h2) { return parseIntFromHex(h2) / 255; } function parseIntFromHex(val) { return parseInt(val, 16); } var names = { aliceblue: "#f0f8ff", antiquewhite: "#faebd7", aqua: "#00ffff", aquamarine: "#7fffd4", azure: "#f0ffff", beige: "#f5f5dc", bisque: "#ffe4c4", black: "#000000", blanchedalmond: "#ffebcd", blue: "#0000ff", blueviolet: "#8a2be2", brown: "#a52a2a", burlywood: "#deb887", cadetblue: "#5f9ea0", chartreuse: "#7fff00", chocolate: "#d2691e", coral: "#ff7f50", cornflowerblue: "#6495ed", cornsilk: "#fff8dc", crimson: "#dc143c", cyan: "#00ffff", darkblue: "#00008b", darkcyan: "#008b8b", darkgoldenrod: "#b8860b", darkgray: "#a9a9a9", darkgreen: "#006400", darkgrey: "#a9a9a9", darkkhaki: "#bdb76b", darkmagenta: "#8b008b", darkolivegreen: "#556b2f", darkorange: "#ff8c00", darkorchid: "#9932cc", darkred: "#8b0000", darksalmon: "#e9967a", darkseagreen: "#8fbc8f", darkslateblue: "#483d8b", darkslategray: "#2f4f4f", darkslategrey: "#2f4f4f", darkturquoise: "#00ced1", darkviolet: "#9400d3", deeppink: "#ff1493", deepskyblue: "#00bfff", dimgray: "#696969", dimgrey: "#696969", dodgerblue: "#1e90ff", firebrick: "#b22222", floralwhite: "#fffaf0", forestgreen: "#228b22", fuchsia: "#ff00ff", gainsboro: "#dcdcdc", ghostwhite: "#f8f8ff", goldenrod: "#daa520", gold: "#ffd700", gray: "#808080", green: "#008000", greenyellow: "#adff2f", grey: "#808080", honeydew: "#f0fff0", hotpink: "#ff69b4", indianred: "#cd5c5c", indigo: "#4b0082", ivory: "#fffff0", khaki: "#f0e68c", lavenderblush: "#fff0f5", lavender: "#e6e6fa", lawngreen: "#7cfc00", lemonchiffon: "#fffacd", lightblue: "#add8e6", lightcoral: "#f08080", lightcyan: "#e0ffff", lightgoldenrodyellow: "#fafad2", lightgray: "#d3d3d3", lightgreen: "#90ee90", lightgrey: "#d3d3d3", lightpink: "#ffb6c1", lightsalmon: "#ffa07a", lightseagreen: "#20b2aa", lightskyblue: "#87cefa", lightslategray: "#778899", lightslategrey: "#778899", lightsteelblue: "#b0c4de", lightyellow: "#ffffe0", lime: "#00ff00", limegreen: "#32cd32", linen: "#faf0e6", magenta: "#ff00ff", maroon: "#800000", mediumaquamarine: "#66cdaa", mediumblue: "#0000cd", mediumorchid: "#ba55d3", mediumpurple: "#9370db", mediumseagreen: "#3cb371", mediumslateblue: "#7b68ee", mediumspringgreen: "#00fa9a", mediumturquoise: "#48d1cc", mediumvioletred: "#c71585", midnightblue: "#191970", mintcream: "#f5fffa", mistyrose: "#ffe4e1", moccasin: "#ffe4b5", navajowhite: "#ffdead", navy: "#000080", oldlace: "#fdf5e6", olive: "#808000", olivedrab: "#6b8e23", orange: "#ffa500", orangered: "#ff4500", orchid: "#da70d6", palegoldenrod: "#eee8aa", palegreen: "#98fb98", paleturquoise: "#afeeee", palevioletred: "#db7093", papayawhip: "#ffefd5", peachpuff: "#ffdab9", peru: "#cd853f", pink: "#ffc0cb", plum: "#dda0dd", powderblue: "#b0e0e6", purple: "#800080", rebeccapurple: "#663399", red: "#ff0000", rosybrown: "#bc8f8f", royalblue: "#4169e1", saddlebrown: "#8b4513", salmon: "#fa8072", sandybrown: "#f4a460", seagreen: "#2e8b57", seashell: "#fff5ee", sienna: "#a0522d", silver: "#c0c0c0", skyblue: "#87ceeb", slateblue: "#6a5acd", slategray: "#708090", slategrey: "#708090", snow: "#fffafa", springgreen: "#00ff7f", steelblue: "#4682b4", tan: "#d2b48c", teal: "#008080", thistle: "#d8bfd8", tomato: "#ff6347", turquoise: "#40e0d0", violet: "#ee82ee", wheat: "#f5deb3", white: "#ffffff", whitesmoke: "#f5f5f5", yellow: "#ffff00", yellowgreen: "#9acd32" }; function inputToRGB(color) { var rgb = { r: 0, g: 0, b: 0 }; var a = 1; var s = null; var v = null; var l = null; var ok = false; var format = false; if (typeof color === "string") { color = stringInputToObject(color); } if (typeof color === "object") { if (isValidCSSUnit(color.r) && isValidCSSUnit(color.g) && isValidCSSUnit(color.b)) { rgb = rgbToRgb(color.r, color.g, color.b); ok = true; format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb"; } else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.v)) { s = convertToPercentage(color.s); v = convertToPercentage(color.v); rgb = hsvToRgb(color.h, s, v); ok = true; format = "hsv"; } else if (isValidCSSUnit(color.h) && isValidCSSUnit(color.s) && isValidCSSUnit(color.l)) { s = convertToPercentage(color.s); l = convertToPercentage(color.l); rgb = hslToRgb(color.h, s, l); ok = true; format = "hsl"; } if (Object.prototype.hasOwnProperty.call(color, "a")) { a = color.a; } } a = boundAlpha(a); return { ok, format: color.format || format, r: Math.min(255, Math.max(rgb.r, 0)), g: Math.min(255, Math.max(rgb.g, 0)), b: Math.min(255, Math.max(rgb.b, 0)), a }; } var CSS_INTEGER = "[-\\+]?\\d+%?"; var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?"; var CSS_UNIT = "(?:".concat(CSS_NUMBER, ")|(?:").concat(CSS_INTEGER, ")"); var PERMISSIVE_MATCH3 = "[\\s|\\(]+(".concat(CSS_UNIT, ")[,|\\s]+(").concat(CSS_UNIT, ")[,|\\s]+(").concat(CSS_UNIT, ")\\s*\\)?"); var PERMISSIVE_MATCH4 = "[\\s|\\(]+(".concat(CSS_UNIT, ")[,|\\s]+(").concat(CSS_UNIT, ")[,|\\s]+(").concat(CSS_UNIT, ")[,|\\s]+(").concat(CSS_UNIT, ")\\s*\\)?"); var matchers = { CSS_UNIT: new RegExp(CSS_UNIT), rgb: new RegExp("rgb" + PERMISSIVE_MATCH3), rgba: new RegExp("rgba" + PERMISSIVE_MATCH4), hsl: new RegExp("hsl" + PERMISSIVE_MATCH3), hsla: new RegExp("hsla" + PERMISSIVE_MATCH4), hsv: new RegExp("hsv" + PERMISSIVE_MATCH3), hsva: new RegExp("hsva" + PERMISSIVE_MATCH4), hex3: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, hex6: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/, hex4: /^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/, hex8: /^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/ }; function stringInputToObject(color) { color = color.trim().toLowerCase(); if (color.length === 0) { return false; } var named = false; if (names[color]) { color = names[color]; named = true; } else if (color === "transparent") { return { r: 0, g: 0, b: 0, a: 0, format: "name" }; } var match = matchers.rgb.exec(color); if (match) { return { r: match[1], g: match[2], b: match[3] }; } match = matchers.rgba.exec(color); if (match) { return { r: match[1], g: match[2], b: match[3], a: match[4] }; } match = matchers.hsl.exec(color); if (match) { return { h: match[1], s: match[2], l: match[3] }; } match = matchers.hsla.exec(color); if (match) { return { h: match[1], s: match[2], l: match[3], a: match[4] }; } match = matchers.hsv.exec(color); if (match) { return { h: match[1], s: match[2], v: match[3] }; } match = matchers.hsva.exec(color); if (match) { return { h: match[1], s: match[2], v: match[3], a: match[4] }; } match = matchers.hex8.exec(color); if (match) { return { r: parseIntFromHex(match[1]), g: parseIntFromHex(match[2]), b: parseIntFromHex(match[3]), a: convertHexToDecimal(match[4]), format: named ? "name" : "hex8" }; } match = matchers.hex6.exec(color); if (match) { return { r: parseIntFromHex(match[1]), g: parseIntFromHex(match[2]), b: parseIntFromHex(match[3]), format: named ? "name" : "hex" }; } match = matchers.hex4.exec(color); if (match) { return { r: parseIntFromHex(match[1] + match[1]), g: parseIntFromHex(match[2] + match[2]), b: parseIntFromHex(match[3] + match[3]), a: convertHexToDecimal(match[4] + match[4]), format: named ? "name" : "hex8" }; } match = matchers.hex3.exec(color); if (match) { return { r: parseIntFromHex(match[1] + match[1]), g: parseIntFromHex(match[2] + match[2]), b: parseIntFromHex(match[3] + match[3]), format: named ? "name" : "hex" }; } return false; } function isValidCSSUnit(color) { return Boolean(matchers.CSS_UNIT.exec(String(color))); } var hueStep = 2; var saturationStep = 0.16; var saturationStep2 = 0.05; var brightnessStep1 = 0.05; var brightnessStep2 = 0.15; var lightColorCount = 5; var darkColorCount = 4; var darkColorMap = [{ index: 7, opacity: 0.15 }, { index: 6, opacity: 0.25 }, { index: 5, opacity: 0.3 }, { index: 5, opacity: 0.45 }, { index: 5, opacity: 0.65 }, { index: 5, opacity: 0.85 }, { index: 4, opacity: 0.9 }, { index: 3, opacity: 0.95 }, { index: 2, opacity: 0.97 }, { index: 1, opacity: 0.98 }]; function toHsv(_ref) { var r = _ref.r, g = _ref.g, b = _ref.b; var hsv = rgbToHsv(r, g, b); return { h: hsv.h * 360, s: hsv.s, v: hsv.v }; } function toHex(_ref2) { var r = _ref2.r, g = _ref2.g, b = _ref2.b; return "#".concat(rgbToHex(r, g, b)); } function mix(rgb1, rgb2, amount) { var p = amount / 100; var rgb = { r: (rgb2.r - rgb1.r) * p + rgb1.r, g: (rgb2.g - rgb1.g) * p + rgb1.g, b: (rgb2.b - rgb1.b) * p + rgb1.b }; return rgb; } function getHue(hsv, i, light) { var hue; if (Math.round(hsv.h) >= 60 && Math.round(hsv.h) <= 240) { hue = light ? Math.round(hsv.h) - hueStep * i : Math.round(hsv.h) + hueStep * i; } else { hue = light ? Math.round(hsv.h) + hueStep * i : Math.round(hsv.h) - hueStep * i; } if (hue < 0) { hue += 360; } else if (hue >= 360) { hue -= 360; } return hue; } function getSaturation(hsv, i, light) { if (hsv.h === 0 && hsv.s === 0) { return hsv.s; } var saturation; if (light) { saturation = hsv.s - saturationStep * i; } else if (i === darkColorCount) { saturation = hsv.s + saturationStep; } else { saturation = hsv.s + saturationStep2 * i; } if (saturation > 1) { saturation = 1; } if (light && i === lightColorCount && saturation > 0.1) { saturation = 0.1; } if (saturation < 0.06) { saturation = 0.06; } return Number(saturation.toFixed(2)); } function getValue(hsv, i, light) { var value; if (light) { value = hsv.v + brightnessStep1 * i; } else { value = hsv.v - brightnessStep2 * i; } if (value > 1) { value = 1; } return Number(value.toFixed(2)); } function generate$1(color) { var opts = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; var patterns = []; var pColor = inputToRGB(color); for (var i = lightColorCount; i > 0; i -= 1) { var hsv = toHsv(pColor); var colorString = toHex(inputToRGB({ h: getHue(hsv, i, true), s: getSaturation(hsv, i, true), v: getValue(hsv, i, true) })); patterns.push(colorString); } patterns.push(toHex(pColor)); for (var _i = 1; _i <= darkColorCount; _i += 1) { var _hsv = toHsv(pColor); var _colorString = toHex(inputToRGB({ h: getHue(_hsv, _i), s: getSaturation(_hsv, _i), v: getValue(_hsv, _i) })); patterns.push(_colorString); } if (opts.theme === "dark") { return darkColorMap.map(function(_ref3) { var index2 = _ref3.index, opacity = _ref3.opacity; var darkColorString = toHex(mix(inputToRGB(opts.backgroundColor || "#141414"), inputToRGB(patterns[index2]), opacity * 100)); return darkColorString; }); } return patterns; } var presetPrimaryColors = { red: "#F5222D", volcano: "#FA541C", orange: "#FA8C16", gold: "#FAAD14", yellow: "#FADB14", lime: "#A0D911", green: "#52C41A", cyan: "#13C2C2", blue: "#1890FF", geekblue: "#2F54EB", purple: "#722ED1", magenta: "#EB2F96", grey: "#666666" }; var presetPalettes = {}; var presetDarkPalettes = {}; Object.keys(presetPrimaryColors).forEach(function(key) { presetPalettes[key] = generate$1(presetPrimaryColors[key]); presetPalettes[key].primary = presetPalettes[key][5]; presetDarkPalettes[key] = generate$1(presetPrimaryColors[key], { theme: "dark", backgroundColor: "#141414" }); presetDarkPalettes[key].primary = presetDarkPalettes[key][5]; }); var blue = presetPalettes.blue; var contextKey = Symbol("iconContext"); var useInjectIconContext = function useInjectIconContext2() { return vue.inject(contextKey, { prefixCls: vue.ref("anticon"), rootClassName: vue.ref(""), csp: vue.ref() }); }; function canUseDom() { return !!(typeof window !== "undefined" && window.document && window.document.createElement); } function contains(root, n) { if (!root) { return false; } if (root.contains) { return root.contains(n); } return false; } var APPEND_ORDER = "data-vc-order"; var MARK_KEY = "vc-icon-key"; var containerCache = /* @__PURE__ */ new Map(); function getMark() { var _ref = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}, mark = _ref.mark; if (mark) { return mark.startsWith("data-") ? mark : "data-".concat(mark); } return MARK_KEY; } function getContainer(option) { if (option.attachTo) { return option.attachTo; } var head = document.querySelector("head"); return head || document.body; } function getOrder(prepend) { if (prepend === "queue") { return "prependQueue"; } return prepend ? "prepend" : "append"; } function findStyles(container) { return Array.from((containerCache.get(container) || container).children).filter(function(node) { return node.tagName === "STYLE"; }); } function injectCSS(css) { var option = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; if (!canUseDom()) { return null; } var csp = option.csp, prepend = option.prepend; var styleNode = document.createElement("style"); styleNode.setAttribute(APPEND_ORDER, getOrder(prepend)); if (csp && csp.nonce) { styleNode.nonce = csp.nonce; } styleNode.innerHTML = css; var container = getContainer(option); var firstChild = container.firstChild; if (prepend) { if (prepend === "queue") { var existStyle = findStyles(container).filter(function(node) { return ["prepend", "prependQueue"].includes(node.getAttribute(APPEND_ORDER)); }); if (existStyle.length) { container.insertBefore(styleNode, existStyle[existStyle.length - 1].nextSibling); return styleNode; } } container.insertBefore(styleNode, firstChild); } else { container.appendChild(styleNode); } return styleNode; } function findExistNode(key) { var option = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {}; var container = getContainer(option); return findStyles(container).find(function(node) { return node.getAttribute(getMark(option)) === key; }); } function syncRealContainer(container, option) { var cachedRealContainer = containerCache.get(container); if (!cachedRealContainer || !contains(document, cachedRealContainer)) { var placeholderStyle = injectCSS("", option); var parentNode = placeholderStyle.parentNode; containerCache.set(container, parentNode); container.removeChild(placeholderStyle); } } function updateCSS(css, key) { var option = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : {}; var container = getContainer(option); syncRealContainer(container, option); var existNode = findExistNode(key, option); if (existNode) { if (option.csp && option.csp.nonce && existNode.nonce !== option.csp.nonce) { existNode.nonce = option.csp.nonce; } if (existNode.innerHTML !== css) { existNode.innerHTML = css; } return existNode; } var newNode = injectCSS(css, option); newNode.setAttribute(getMark(option), key); return newNode; } function _objectSpread$b(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$b(target, key, source[key]); }); } return target; } function _defineProperty$b(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function warning(valid, message) { } function isIconDefinition(target) { return typeof target === "object" && typeof target.name === "string" && typeof target.theme === "string" && (typeof target.icon === "object" || typeof target.icon === "function"); } function generate(node, key, rootProps) { if (!rootProps) { return vue.h(node.tag, _objectSpread$b({ key }, node.attrs), (node.children || []).map(function(child, index2) { return generate(child, "".concat(key, "-").concat(node.tag, "-").concat(index2)); })); } return vue.h(node.tag, _objectSpread$b({ key }, rootProps, node.attrs), (node.children || []).map(function(child, index2) { return generate(child, "".concat(key, "-").concat(node.tag, "-").concat(index2)); })); } function getSecondaryColor(primaryColor) { return generate$1(primaryColor)[0]; } function normalizeTwoToneColors(twoToneColor) { if (!twoToneColor) { return []; } return Array.isArray(twoToneColor) ? twoToneColor : [twoToneColor]; } var iconStyles = "\n.anticon {\n display: inline-block;\n color: inherit;\n font-style: normal;\n line-height: 0;\n text-align: center;\n text-transform: none;\n vertical-align: -0.125em;\n text-rendering: optimizeLegibility;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n.anticon > * {\n line-height: 1;\n}\n\n.anticon svg {\n display: inline-block;\n}\n\n.anticon::before {\n display: none;\n}\n\n.anticon .anticon-icon {\n display: block;\n}\n\n.anticon[tabindex] {\n cursor: pointer;\n}\n\n.anticon-spin::before,\n.anticon-spin {\n display: inline-block;\n -webkit-animation: loadingCircle 1s infinite linear;\n animation: loadingCircle 1s infinite linear;\n}\n\n@-webkit-keyframes loadingCircle {\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n\n@keyframes loadingCircle {\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n"; function getRoot(ele) { return ele && ele.getRootNode && ele.getRootNode(); } function inShadow(ele) { if (!canUseDom()) { return false; } return getRoot(ele) instanceof ShadowRoot; } function getShadowRoot(ele) { return inShadow(ele) ? getRoot(ele) : null; } var useInsertStyles = function useInsertStyles2() { var _useInjectIconContext = useInjectIconContext(), prefixCls = _useInjectIconContext.prefixCls, csp = _useInjectIconContext.csp; var instance = vue.getCurrentInstance(); var mergedStyleStr = iconStyles; if (prefixCls) { mergedStyleStr = mergedStyleStr.replace(/anticon/g, prefixCls.value); } vue.nextTick(function() { if (!canUseDom()) { return; } var ele = instance.vnode.el; var shadowRoot = getShadowRoot(ele); updateCSS(mergedStyleStr, "@ant-design-vue-icons", { prepend: true, csp: csp.value, attachTo: shadowRoot }); }); }; var _excluded$1 = ["icon", "primaryColor", "secondaryColor"]; function _objectWithoutProperties$1(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose$1(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose$1(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _objectSpread$a(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$a(target, key, source[key]); }); } return target; } function _defineProperty$a(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var twoToneColorPalette = vue.reactive({ primaryColor: "#333", secondaryColor: "#E6E6E6", calculated: false }); function setTwoToneColors(_ref) { var primaryColor = _ref.primaryColor, secondaryColor = _ref.secondaryColor; twoToneColorPalette.primaryColor = primaryColor; twoToneColorPalette.secondaryColor = secondaryColor || getSecondaryColor(primaryColor); twoToneColorPalette.calculated = !!secondaryColor; } function getTwoToneColors() { return _objectSpread$a({}, twoToneColorPalette); } var IconBase = function IconBase2(props, context) { var _props$context$attrs = _objectSpread$a({}, props, context.attrs), icon = _props$context$attrs.icon, primaryColor = _props$context$attrs.primaryColor, secondaryColor = _props$context$attrs.secondaryColor, restProps = _objectWithoutProperties$1(_props$context$attrs, _excluded$1); var colors = twoToneColorPalette; if (primaryColor) { colors = { primaryColor, secondaryColor: secondaryColor || getSecondaryColor(primaryColor) }; } warning(isIconDefinition(icon)); if (!isIconDefinition(icon)) { return null; } var target = icon; if (target && typeof target.icon === "function") { target = _objectSpread$a({}, target, { icon: target.icon(colors.primaryColor, colors.secondaryColor) }); } return generate(target.icon, "svg-".concat(target.name), _objectSpread$a({}, restProps, { "data-icon": target.name, width: "1em", height: "1em", fill: "currentColor", "aria-hidden": "true" })); }; IconBase.props = { icon: Object, primaryColor: String, secondaryColor: String, focusable: String }; IconBase.inheritAttrs = false; IconBase.displayName = "IconBase"; IconBase.getTwoToneColors = getTwoToneColors; IconBase.setTwoToneColors = setTwoToneColors; function _slicedToArray$1(arr, i) { return _arrayWithHoles$1(arr) || _iterableToArrayLimit$1(arr, i) || _unsupportedIterableToArray$1(arr, i) || _nonIterableRest$1(); } function _nonIterableRest$1() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen); } function _arrayLikeToArray$1(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit$1(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles$1(arr) { if (Array.isArray(arr)) return arr; } function setTwoToneColor(twoToneColor) { var _normalizeTwoToneColo = normalizeTwoToneColors(twoToneColor), _normalizeTwoToneColo2 = _slicedToArray$1(_normalizeTwoToneColo, 2), primaryColor = _normalizeTwoToneColo2[0], secondaryColor = _normalizeTwoToneColo2[1]; return IconBase.setTwoToneColors({ primaryColor, secondaryColor }); } function getTwoToneColor() { var colors = IconBase.getTwoToneColors(); if (!colors.calculated) { return colors.primaryColor; } return [colors.primaryColor, colors.secondaryColor]; } var InsertStyles = vue.defineComponent({ name: "InsertStyles", setup: function setup() { useInsertStyles(); return function() { return null; }; } }); var _excluded = ["class", "icon", "spin", "rotate", "tabindex", "twoToneColor", "onClick"]; function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _objectSpread$9(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$9(target, key, source[key]); }); } return target; } function _defineProperty$9(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } setTwoToneColor(blue.primary); var Icon = function Icon2(props, context) { var _classObj; var _props$context$attrs = _objectSpread$9({}, props, context.attrs), cls = _props$context$attrs["class"], icon = _props$context$attrs.icon, spin = _props$context$attrs.spin, rotate = _props$context$attrs.rotate, tabindex = _props$context$attrs.tabindex, twoToneColor = _props$context$attrs.twoToneColor, onClick = _props$context$attrs.onClick, restProps = _objectWithoutProperties(_props$context$attrs, _excluded); var _useInjectIconContext = useInjectIconContext(), prefixCls = _useInjectIconContext.prefixCls, rootClassName = _useInjectIconContext.rootClassName; var classObj = (_classObj = {}, _defineProperty$9(_classObj, rootClassName.value, !!rootClassName.value), _defineProperty$9(_classObj, prefixCls.value, true), _defineProperty$9(_classObj, "".concat(prefixCls.value, "-").concat(icon.name), Boolean(icon.name)), _defineProperty$9(_classObj, "".concat(prefixCls.value, "-spin"), !!spin || icon.name === "loading"), _classObj); var iconTabIndex = tabindex; if (iconTabIndex === void 0 && onClick) { iconTabIndex = -1; } var svgStyle = rotate ? { msTransform: "rotate(".concat(rotate, "deg)"), transform: "rotate(".concat(rotate, "deg)") } : void 0; var _normalizeTwoToneColo = normalizeTwoToneColors(twoToneColor), _normalizeTwoToneColo2 = _slicedToArray(_normalizeTwoToneColo, 2), primaryColor = _normalizeTwoToneColo2[0], secondaryColor = _normalizeTwoToneColo2[1]; return vue.createVNode("span", _objectSpread$9({ "role": "img", "aria-label": icon.name }, restProps, { "onClick": onClick, "class": [classObj, cls], "tabindex": iconTabIndex }), [vue.createVNode(IconBase, { "icon": icon, "primaryColor": primaryColor, "secondaryColor": secondaryColor, "style": svgStyle }, null), vue.createVNode(InsertStyles, null, null)]); }; Icon.props = { spin: Boolean, rotate: Number, icon: Object, twoToneColor: [String, Array] }; Icon.displayName = "AntdIcon"; Icon.inheritAttrs = false; Icon.getTwoToneColor = getTwoToneColor; Icon.setTwoToneColor = setTwoToneColor; var BarsOutlined$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "0 0 1024 1024", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M912 192H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 284H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 284H328c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h584c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM104 228a56 56 0 10112 0 56 56 0 10-112 0zm0 284a56 56 0 10112 0 56 56 0 10-112 0zm0 284a56 56 0 10112 0 56 56 0 10-112 0z" } }] }, "name": "bars", "theme": "outlined" }; function _objectSpread$8(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$8(target, key, source[key]); }); } return target; } function _defineProperty$8(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var BarsOutlined = function BarsOutlined2(props, context) { var p = _objectSpread$8({}, props, context.attrs); return vue.createVNode(Icon, _objectSpread$8({}, p, { "icon": BarsOutlined$1 }), null); }; BarsOutlined.displayName = "BarsOutlined"; BarsOutlined.inheritAttrs = false; var CustomerServiceOutlined$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M512 128c-212.1 0-384 171.9-384 384v360c0 13.3 10.7 24 24 24h184c35.3 0 64-28.7 64-64V624c0-35.3-28.7-64-64-64H200v-48c0-172.3 139.7-312 312-312s312 139.7 312 312v48H688c-35.3 0-64 28.7-64 64v208c0 35.3 28.7 64 64 64h184c13.3 0 24-10.7 24-24V512c0-212.1-171.9-384-384-384zM328 632v192H200V632h128zm496 192H696V632h128v192z" } }] }, "name": "customer-service", "theme": "outlined" }; function _objectSpread$7(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$7(target, key, source[key]); }); } return target; } function _defineProperty$7(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var CustomerServiceOutlined = function CustomerServiceOutlined2(props, context) { var p = _objectSpread$7({}, props, context.attrs); return vue.createVNode(Icon, _objectSpread$7({}, p, { "icon": CustomerServiceOutlined$1 }), null); }; CustomerServiceOutlined.displayName = "CustomerServiceOutlined"; CustomerServiceOutlined.inheritAttrs = false; var EditOutlined$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M257.7 752c2 0 4-.2 6-.5L431.9 722c2-.4 3.9-1.3 5.3-2.8l423.9-423.9a9.96 9.96 0 000-14.1L694.9 114.9c-1.9-1.9-4.4-2.9-7.1-2.9s-5.2 1-7.1 2.9L256.8 538.8c-1.5 1.5-2.4 3.3-2.8 5.3l-29.5 168.2a33.5 33.5 0 009.4 29.8c6.6 6.4 14.9 9.9 23.8 9.9zm67.4-174.4L687.8 215l73.3 73.3-362.7 362.6-88.9 15.7 15.6-89zM880 836H144c-17.7 0-32 14.3-32 32v36c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-36c0-17.7-14.3-32-32-32z" } }] }, "name": "edit", "theme": "outlined" }; function _objectSpread$6(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$6(target, key, source[key]); }); } return target; } function _defineProperty$6(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var EditOutlined = function EditOutlined2(props, context) { var p = _objectSpread$6({}, props, context.attrs); return vue.createVNode(Icon, _objectSpread$6({}, p, { "icon": EditOutlined$1 }), null); }; EditOutlined.displayName = "EditOutlined"; EditOutlined.inheritAttrs = false; var ExclamationCircleOutlined$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" } }, { "tag": "path", "attrs": { "d": "M464 688a48 48 0 1096 0 48 48 0 10-96 0zm24-112h48c4.4 0 8-3.6 8-8V296c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8z" } }] }, "name": "exclamation-circle", "theme": "outlined" }; function _objectSpread$5(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$5(target, key, source[key]); }); } return target; } function _defineProperty$5(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var ExclamationCircleOutlined = function ExclamationCircleOutlined2(props, context) { var p = _objectSpread$5({}, props, context.attrs); return vue.createVNode(Icon, _objectSpread$5({}, p, { "icon": ExclamationCircleOutlined$1 }), null); }; ExclamationCircleOutlined.displayName = "ExclamationCircleOutlined"; ExclamationCircleOutlined.inheritAttrs = false; var FolderOutlined$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M880 298.4H521L403.7 186.2a8.15 8.15 0 00-5.5-2.2H144c-17.7 0-32 14.3-32 32v592c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V330.4c0-17.7-14.3-32-32-32zM840 768H184V256h188.5l119.6 114.4H840V768z" } }] }, "name": "folder", "theme": "outlined" }; function _objectSpread$4(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$4(target, key, source[key]); }); } return target; } function _defineProperty$4(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var FolderOutlined = function FolderOutlined2(props, context) { var p = _objectSpread$4({}, props, context.attrs); return vue.createVNode(Icon, _objectSpread$4({}, p, { "icon": FolderOutlined$1 }), null); }; FolderOutlined.displayName = "FolderOutlined"; FolderOutlined.inheritAttrs = false; var PlusOutlined$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z" } }, { "tag": "path", "attrs": { "d": "M192 474h672q8 0 8 8v60q0 8-8 8H160q-8 0-8-8v-60q0-8 8-8z" } }] }, "name": "plus", "theme": "outlined" }; function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$3(target, key, source[key]); }); } return target; } function _defineProperty$3(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var PlusOutlined = function PlusOutlined2(props, context) { var p = _objectSpread$3({}, props, context.attrs); return vue.createVNode(Icon, _objectSpread$3({}, p, { "icon": PlusOutlined$1 }), null); }; PlusOutlined.displayName = "PlusOutlined"; PlusOutlined.inheritAttrs = false; var ProfileOutlined$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32zm-40 728H184V184h656v656zM492 400h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H492c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8zm0 144h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H492c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8zm0 144h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H492c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8zM340 368a40 40 0 1080 0 40 40 0 10-80 0zm0 144a40 40 0 1080 0 40 40 0 10-80 0zm0 144a40 40 0 1080 0 40 40 0 10-80 0z" } }] }, "name": "profile", "theme": "outlined" }; function _objectSpread$2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$2(target, key, source[key]); }); } return target; } function _defineProperty$2(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var ProfileOutlined = function ProfileOutlined2(props, context) { var p = _objectSpread$2({}, props, context.attrs); return vue.createVNode(Icon, _objectSpread$2({}, p, { "icon": ProfileOutlined$1 }), null); }; ProfileOutlined.displayName = "ProfileOutlined"; ProfileOutlined.inheritAttrs = false; var SettingOutlined$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z" } }] }, "name": "setting", "theme": "outlined" }; function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty$1(target, key, source[key]); }); } return target; } function _defineProperty$1(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var SettingOutlined = function SettingOutlined2(props, context) { var p = _objectSpread$1({}, props, context.attrs); return vue.createVNode(Icon, _objectSpread$1({}, p, { "icon": SettingOutlined$1 }), null); }; SettingOutlined.displayName = "SettingOutlined"; SettingOutlined.inheritAttrs = false; var SyncOutlined$1 = { "icon": { "tag": "svg", "attrs": { "viewBox": "64 64 896 896", "focusable": "false" }, "children": [{ "tag": "path", "attrs": { "d": "M168 504.2c1-43.7 10-86.1 26.9-126 17.3-41 42.1-77.7 73.7-109.4S337 212.3 378 195c42.4-17.9 87.4-27 133.9-27s91.5 9.1 133.8 27A341.5 341.5 0 01755 268.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.7 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c0-6.7-7.7-10.5-12.9-6.3l-56.4 44.1C765.8 155.1 646.2 92 511.8 92 282.7 92 96.3 275.6 92 503.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8zm756 7.8h-60c-4.4 0-7.9 3.5-8 7.8-1 43.7-10 86.1-26.9 126-17.3 41-42.1 77.8-73.7 109.4A342.45 342.45 0 01512.1 856a342.24 342.24 0 01-243.2-100.8c-9.9-9.9-19.2-20.4-27.8-31.4l60.2-47a8 8 0 00-3-14.1l-175.7-43c-5-1.2-9.9 2.6-9.9 7.7l-.7 181c0 6.7 7.7 10.5 12.9 6.3l56.4-44.1C258.2 868.9 377.8 932 512.2 932c229.2 0 415.5-183.7 419.8-411.8a8 8 0 00-8-8.2z" } }] }, "name": "sync", "theme": "outlined" }; function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? Object(arguments[i]) : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === "function") { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function(key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } var SyncOutlined = function SyncOutlined2(props, context) { var p = _objectSpread({}, props, context.attrs); return vue.createVNode(Icon, _objectSpread({}, p, { "icon": SyncOutlined$1 }), null); }; SyncOutlined.displayName = "SyncOutlined"; SyncOutlined.inheritAttrs = false; const titleRef = vue.ref(); const templateRef = vue.shallowRef(); const templatePropsRef = vue.ref(); const openRef = vue.ref(false); vue.createApp({ render: () => { return vue.h( Antd.Modal, { centered: true, destroyOnClose: true, footer: null, title: titleRef.value, open: openRef.value, width: "720px", zIndex: 99999, onCancel: () => { openRef.value = false; } }, () => vue.h(templateRef.value, { ...templatePropsRef.value }) ); } }).use(Antd).mount( (() => { const div = document.createElement("div"); document.body.append(div); return div; })() ); const templateModal = ({ title, template, templateProps }) => { openRef.value = true; titleRef.value = title; templateRef.value = template; templatePropsRef.value = templateProps; return () => { openRef.value = false; }; }; const messageModal = ({ title, message, type = "info" }) => { Antd.Modal[type]({ title, content: message, autoFocusButton: null, okText: "确定", zIndex: 99999, style: { "text-align": "left" }, onOk() { Antd.Modal.destroyAll(); }, onCancel() { Antd.Modal.destroyAll(); } }); }; class Storage { constructor() { if (new.target === Storage) { throw new Error("Cannot instantiate an abstract class."); } Reflect.ownKeys(Storage.prototype).forEach((key) => { if (key === "constructor") return; if (!new.target.prototype.hasOwnProperty(key) || new.target.prototype[key].length !== Storage.prototype[key].length) { throw new Error(`Abstract method ${key} must be implemented.`); } }); } /** * 设置缓存 * @abstract * @param {string} key * @param {any} value */ set(key, value) { throw new Error("must be implemented by subclass!"); } /** * 判断缓存是否存在 * @abstract * @param {string} key * @returns {boolean} */ has(key) { throw new Error("must be implemented by subclass!"); } /** * 获取缓存 * @abstract * @param {string} key * @param {any} defaultValue * @returns {any} */ get(key, defaultValue) { throw new Error("must be implemented by subclass!"); } /** * 删除缓存 * @abstract * @param {string} key */ remove(key) { throw new Error("must be implemented by subclass!"); } /** * 清除缓存 * @abstract */ clear() { throw new Error("must be implemented by subclass!"); } /** * 监听缓存变化 * @abstract * @param {string} key 需要监听的key * @param {Function} execute 监听到变化时执行的回调函数 * @param {{ * key: string, * newValue: any, * oldValue: any, * }} execute.params.$0 execute参数1:{key: string, newValue: any, oldVaule: any} * @param {string} execute.params.$0.key 监听的key * @param {any} execute.params.$0.newValue 变化后的新数据 * @param {any} execute.params.$0.oldValue 变化前的旧数据 * @returns {Function} 停止监听函数 */ listen(key, execute) { throw new Error("must be implemented by subclass!"); } } var _GM = /* @__PURE__ */ (() => typeof GM != "undefined" ? GM : void 0)(); var _GM_addValueChangeListener = /* @__PURE__ */ (() => typeof GM_addValueChangeListener != "undefined" ? GM_addValueChangeListener : void 0)(); var _GM_deleteValue = /* @__PURE__ */ (() => typeof GM_deleteValue != "undefined" ? GM_deleteValue : void 0)(); var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)(); var _GM_listValues = /* @__PURE__ */ (() => typeof GM_listValues != "undefined" ? GM_listValues : void 0)(); var _GM_removeValueChangeListener = /* @__PURE__ */ (() => typeof GM_removeValueChangeListener != "undefined" ? GM_removeValueChangeListener : void 0)(); var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)(); class GM_Storage extends Storage { constructor() { super(); } /** @override */ set(key, value) { _GM_setValue(key, value); } /** @override */ has(key) { return _GM_getValue(key, null) ? true : false; } /** @override */ get(key, defaultValue) { return _GM_getValue(key, defaultValue); } /** @override */ remove(key) { _GM_deleteValue(key); } /** @override */ clear() { const keys = _GM_listValues(); keys.forEach((key) => { _GM_deleteValue(key); }); } /** @override */ listen(key, execute) { const listenerId = _GM_addValueChangeListener(key, (key2, oldValue, newValue) => { execute({ key: key2, newValue, oldValue }); }); return () => { _GM_removeValueChangeListener(listenerId); }; } } const _$3 = new GM_Storage(); const constants = Object.freeze({ STORAGE_KEY: { AGREEMENT: `${"Bilibili-Memo"}:Agreement`, BASE_CONFIG: `${"Bilibili-Memo"}:BaseConfig`, PLUGIN_CONFIG: (id) => `${"Bilibili-Memo"}:PluginConfig:${id}` } }); const storageUtil = { getAgreement: () => { const key = constants.STORAGE_KEY.AGREEMENT; return _$3.get(key); }, setAgreement: (choice) => { const key = constants.STORAGE_KEY.AGREEMENT; _$3.set(key, choice); }, listenAgreement: (execute) => { if (!execute || typeof execute !== "function") { throw new Error("TypeError: execute is not a function"); } const key = constants.STORAGE_KEY.AGREEMENT; return _$3.listen(key, execute); }, getBaseConfig: () => { const key = constants.STORAGE_KEY.BASE_CONFIG; return _$3.get(key); }, setBaseConfig: (baseConfig2) => { const key = constants.STORAGE_KEY.BASE_CONFIG; _$3.set(key, baseConfig2); }, listenBaseConfig: (execute) => { if (!execute || typeof execute !== "function") { throw new Error("TypeError: execute is not a function"); } const key = constants.STORAGE_KEY.BASE_CONFIG; return _$3.listen(key, execute); }, getPluginConfig: (id) => { if (!id) throw new Error("Error parameter: id."); const key = constants.STORAGE_KEY.PLUGIN_CONFIG(id); return _$3.get(key); }, setPluginConfig: (id, pluginConfig2) => { if (!id) throw new Error("Error parameter: id."); const key = constants.STORAGE_KEY.PLUGIN_CONFIG(id); _$3.set(key, pluginConfig2); }, listenPluginConfig: (id, execute) => { if (!id) throw new Error("Error parameter: id."); if (!execute || typeof execute !== "function") { throw new Error("TypeError: execute is not a function"); } const key = constants.STORAGE_KEY.PLUGIN_CONFIG(id); return _$3.listen(key, execute); } }; class Plugin { constructor({ name, description, icon, type, $init, $reset, $click }) { this.name = name; this.description = description; this.icon = icon; this.type = type; this.$init = $init; this.$reset = $reset; this.$click = $click; } } const XOR_CODE = 23442827791579n; const MASK_CODE = 2251799813685247n; const MAX_AID = 1n << 51n; const BASE = 58n; const data = "FcwAPNKTMug3GV5Lj7EJnHpWsx4tb8haYeviqBz6rkCy12mUSDQX9RdoZf"; const getCookieValue = (key) => { const cookies = document.cookie.split(";"); for (let i = 0; i < cookies.length; i++) { let cookie = cookies[i].trim().split("="); if (cookie[0] === key) { return cookie.length > 1 ? cookie[1] : ""; } } return null; }; const getUid = () => { return getCookieValue("DedeUserID"); }; const getCsrf = () => { return getCookieValue("bili_jct"); }; const getCurrLocation = () => { const currLocation = location.origin + location.pathname; return currLocation.endsWith("/") ? currLocation : currLocation + "/"; }; const getCurrBvid = () => { if (location.origin != "https://www.bilibili.com") return ""; const arr = location.pathname.split("/"); if (arr[1] !== "video") return ""; if (!new RegExp(/(BV|av)[a-zA-Z0-9]+/).test(arr[2])) return ""; return arr[2]; }; const av2bv = (aid) => { const bytes = ["B", "V", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0"]; let bvIndex = bytes.length - 1; let tmp = (MAX_AID | BigInt(aid)) ^ XOR_CODE; while (tmp > 0) { bytes[bvIndex] = data[Number(tmp % BigInt(BASE))]; tmp = tmp / BASE; bvIndex -= 1; } [bytes[3], bytes[9]] = [bytes[9], bytes[3]]; [bytes[4], bytes[7]] = [bytes[7], bytes[4]]; return bytes.join(""); }; const bv2av = (bvid) => { const bvidArr = Array.from(bvid); [bvidArr[3], bvidArr[9]] = [bvidArr[9], bvidArr[3]]; [bvidArr[4], bvidArr[7]] = [bvidArr[7], bvidArr[4]]; bvidArr.splice(0, 3); const tmp = bvidArr.reduce( (pre, bvidChar) => pre * BASE + BigInt(data.indexOf(bvidChar)), 0n ); return Number(tmp & MASK_CODE ^ XOR_CODE); }; const biliUtil = { getCookieValue, getUid, getCsrf, getCurrLocation, getCurrBvid, av2bv, bv2av }; class PluginConfig { constructor({ base: { match = [], isOnlySwitchCurrActive = false, isActive = false }, option = {}, data: data2 = [] }) { this.base = { // 插件应用的位置,动态信息使用{{x}}表示,默认空数组代表全匹配 match, // 插件是否已激活 isActive, // 插件是否只切换当前页面激活状态 isOnlySwitchCurrActive }; this.option = option; this.data = data2; } } const assignDeep = (target, ...sources) => { if (target === void 0 || target === null) { throw new TypeError("Cannot convert undefined or null to object"); } sources.forEach((source) => { if (source !== void 0 && source !== null) { for (const key in source) { target[key] = cloneDeep(source[key]); } } }); return target; }; const assignTargetDeep = (target, ...sources) => { if (target === void 0 || target === null) { throw new TypeError("Cannot convert undefined or null to object"); } sources.forEach((source) => { if (source !== void 0 && source !== null) { for (const key in target) { if (source.hasOwnProperty(key)) { target[key] = cloneDeep(source[key]); } } } }); return target; }; const cloneDeep = (target) => { const map = /* @__PURE__ */ new WeakMap(); const isObject = (t) => { return typeof t === "object" && t || typeof t === "function"; }; const clone = (data2) => { if (!isObject(data2)) { return data2; } if (typeof data2 === "function") { try { return data2; } catch (error) { return data2; } } if (map.has(data2)) { return map.get(data2); } if ([Date, RegExp].includes(data2.constructor)) { return new data2.constructor(data2); } if (data2.constructor === Map) { const result2 = /* @__PURE__ */ new Map(); map.set(data2, result2); data2.forEach((val, key) => { if (isObject(val)) { result2.set(key, clone(val)); } else { result2.set(key, val); } }); return result2; } if (data2.constructor === Set) { const result2 = /* @__PURE__ */ new Set(); map.set(data2, result2); data2.forEach((val) => { if (isObject(val)) { result2.add(clone(val)); } else { result2.add(val); } }); return result2; } if (Array.isArray(data2)) { const result2 = []; map.set(data2, result2); data2.forEach((val, index2) => { if (isObject(val)) { result2[index2] = clone(val); } else { result2[index2] = val; } }); return result2; } const keys = Reflect.ownKeys(data2); const allDesc = Object.getOwnPropertyDescriptors(data2); const result = Object.create(Object.getPrototypeOf(data2), allDesc); map.set(data2, result); keys.forEach((key) => { const val = data2[key]; if (isObject(val)) { result[key] = clone(val); } else { result[key] = val; } }); return result; }; return clone(target); }; const _$2 = { assignDeep, assignTargetDeep, cloneDeep }; class BaseConfig { constructor({ general: { shortcutMaxShow = 1, shortcutShowMode = "hover", shortcuts = [] }, syncAndBackup: { wps: { isActive = false, airScript: { token = "", webhook = "", isValid = false }, sync: { enabled = false }, backup: { autoBackupInterval = 0, lastBackupTime = 0, lastRestoreTime = 0 } } } }) { this.general = { // 快捷方式栏最大展示数量 shortcutMaxShow, // 快捷方式栏展开方式 shortcutShowMode, // 快捷方式栏插件数组 shortcuts }; this.syncAndBackup = { // WPS 备份设置 wps: { // 是否开启 isActive, // AirScript 配置 airScript: { // AirScript 脚本 APIToken token, // AirScript 脚本对应 webhook webhook, // 是否有效 isValid }, // 同步设置 sync: { // 开启实时同步 enabled }, // 备份设置 backup: { // 自动备份间隔 autoBackupInterval, // 上一次备份数据时间 lastBackupTime, // 上一次恢复数据时间 lastRestoreTime } } }; } } class ConfigRef { constructor(config2) { if (![BaseConfig, PluginConfig].includes(config2.constructor)) { throw new Error("param config expect class [BaseConfig, PluginConfig]."); } this._config = vue.ref(config2); this._changeHandler = null; this._listener = { pause: null, resume: null, stop: null }; } _self() { return this._config.value; } initChangeHandler(handler2) { this._changeHandler = handler2; } useChangeHandler() { this._changeHandler && this._changeHandler(this.getValue()); } getValue() { return _$2.cloneDeep(this._config.value); } setValue(value) { _$2.assignTargetDeep(this._config.value, value); } /** * 监听插件配置变化 * @param {Function} execute 插件配置变化时执行的回调函数 * @param {any} execute.params.$0 execute参数1:变化后的新数据 * @param {any} execute.params.$1 execute参数2:变化前的旧数据 * @param {{realOldValue: boolean}} [option] 可选选项 * @param {boolean} [option.realOldValue] 是否需要返回真正的 oldValue */ listen(execute, option) { if (!execute || typeof execute !== "function") { throw new Error("TypeError: execute is not a function"); } this.stopListen(); if (option && option.realOldValue) { let oldValue = _$2.cloneDeep(this._config.value); this._listener = vue.watch(this._config.value, (value) => { execute(value, oldValue); oldValue = _$2.cloneDeep(value); }); } else { this._listener = vue.watch(this._config.value, (value, oldValue) => { execute(value, oldValue); }); } } pauseListen() { this._listener.pause && this._listener.pause(); } resumeListen() { this._listener.resume && this._listener.resume(); } stopListen() { if (this._listener.stop) { this._listener.stop(); this._listener = { pause: null, resume: null, stop: null }; } } getController() { return { initChangeHandler: (handler2) => this.initChangeHandler(handler2), useChangeHandler: () => this.useChangeHandler(), getValue: () => this.getValue(), setValue: (value) => this.setValue(value), listen: (execute, option) => this.listen(execute, option), pauseListen: () => this.pauseListen(), resumeListen: () => this.resumeListen(), stopListen: () => this.stopListen() }; } } const pluginConfig$2 = new PluginConfig({ base: { match: [ "https://space.bilibili.com/{{uid}}/favlist/", "https://www.bilibili.com/video/{{bvid}}/" ], isActive: false, isOnlySwitchCurrActive: false }, option: {}, data: [] }); const configRef$3 = new ConfigRef(pluginConfig$2); const config$4 = configRef$3._self(); const controller$3 = configRef$3.getController(); const _sfc_main$j = { __name: "DisplayTag", props: { tags: { type: String, required: true, default: "" }, color: { type: String, default: "red" } }, setup(__props) { return (_ctx, _cache) => { const _component_a_tag = vue.resolveComponent("a-tag"); const _component_a_tooltip = vue.resolveComponent("a-tooltip"); return vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.tags ? __props.tags.split(",") : [], (tag) => { return vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: tag }, [ tag.length > 20 ? (vue.openBlock(), vue.createBlock(_component_a_tooltip, { key: 0, title: tag }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_tag, { color: __props.color }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(`${tag.slice(0, 20)}...`), 1) ]), _: 2 }, 1032, ["color"]) ]), _: 2 }, 1032, ["title"])) : (vue.openBlock(), vue.createBlock(_component_a_tag, { key: 1, color: __props.color }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(tag), 1) ]), _: 2 }, 1032, ["color"])) ], 64); }), 128); }; } }; const timestampToDate = [ (timestamp) => { const date = new Date(timestamp); const year = date.getFullYear(); const month = date.getMonth() + 1; const day = date.getDate(); const hours = date.getHours(); const minutes = date.getMinutes(); const seconds = date.getSeconds(); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; }, (timestamp) => { const date = new Date(timestamp); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); const day = String(date.getDate()).padStart(2, "0"); const hours = String(date.getHours()).padStart(2, "0"); const minutes = String(date.getMinutes()).padStart(2, "0"); const seconds = String(date.getSeconds()).padStart(2, "0"); return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } ]; const formatSeconds = [ (seconds) => { const date = new Date(seconds * 1e3); const hh = date.getUTCHours().toString().padStart(2, "0"); const mm = date.getUTCMinutes().toString().padStart(2, "0"); const ss = date.getSeconds().toString().padStart(2, "0"); return `${hh}:${mm}:${ss}`; }, (seconds) => { const date = new Date(seconds * 1e3); const mm = date.getUTCMinutes().toString().padStart(2, "0"); const ss = date.getSeconds().toString().padStart(2, "0"); return `${mm}:${ss}`; } ]; const dateUtil = { timestampToDate, formatSeconds }; const request$1 = async (url, option, execute, error) => { if (!url || !option) { throw new Error("invaild url or option"); } return fetch(url, option).then((response) => response.json()).then((data2) => { if (data2.code === 0) { execute && execute(data2.data); return data2.data; } else { error && error(data2.message); return data2.message; } }).catch((err) => { console.error("请求发生错误:", err); error && error("请求发生错误:" + err); return err; }); }; let Request$1 = class Request { get(url, params = {}, execute, error) { const keys = Object.keys(params).sort(); const query = keys.map((k) => `${k}=${params[k]}`).join("&"); return request$1( query ? `${url}?${query}` : url, { method: "GET", credentials: "include", mode: "cors" }, execute, error ); } post(url, params = {}, execute, error) { const keys = Object.keys(params).sort(); const query = new URLSearchParams(); keys.forEach((k) => query.append(k, params[k])); return request$1( url, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: query.toString(), credentials: "include", mode: "cors" }, execute, error ); } }; const request$2 = new Request$1(); const view = (bvid, execute, error) => { if (!bvid) return; let url = "https://api.bilibili.com/x/web-interface/view"; let params = { bvid }; return request$2.get(url, params, execute, error); }; const _sfc_main$i = { __name: "DynamicTag", props: { tags: { type: String, required: true, default: "" }, color: { type: String, default: "red" } }, emits: ["change"], setup(__props, { emit: __emit }) { const props = __props; const emits = __emit; const inputRef = vue.ref(); const state = vue.ref({ tags: props.tags ? props.tags.split(",") : [], inputVisible: false, inputValue: "" }); const handleClose = (removedTag) => { const tags = state.value.tags.filter((tag) => tag !== removedTag); state.value.tags = tags; emits("change", state.value.tags.join()); }; const showInput = () => { state.value.inputVisible = true; vue.nextTick(() => { inputRef.value.focus(); }); }; const handleInputConfirm = () => { const inputValue = state.value.inputValue; let tags = state.value.tags; if (inputValue && tags.indexOf(inputValue) === -1) { tags = [...tags, inputValue]; } Object.assign(state.value, { tags, inputVisible: false, inputValue: "" }); emits("change", state.value.tags.join()); }; return (_ctx, _cache) => { const _component_a_tag = vue.resolveComponent("a-tag"); const _component_a_tooltip = vue.resolveComponent("a-tooltip"); const _component_a_input = vue.resolveComponent("a-input"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(state.value.tags, (tag) => { return vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: tag }, [ tag.length > 20 ? (vue.openBlock(), vue.createBlock(_component_a_tooltip, { key: 0, title: tag }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_tag, { color: __props.color, closable: "", onClose: ($event) => handleClose(tag) }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(`${tag.slice(0, 20)}...`), 1) ]), _: 2 }, 1032, ["color", "onClose"]) ]), _: 2 }, 1032, ["title"])) : (vue.openBlock(), vue.createBlock(_component_a_tag, { key: 1, color: __props.color, closable: "", onClose: ($event) => handleClose(tag) }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(tag), 1) ]), _: 2 }, 1032, ["color", "onClose"])) ], 64); }), 128)), state.value.inputVisible ? (vue.openBlock(), vue.createBlock(_component_a_input, { key: 0, ref_key: "inputRef", ref: inputRef, value: state.value.inputValue, "onUpdate:value": _cache[0] || (_cache[0] = ($event) => state.value.inputValue = $event), type: "text", size: "small", onBlur: handleInputConfirm, onKeyup: vue.withKeys(handleInputConfirm, ["enter"]), style: { "width": "78px" } }, null, 8, ["value"])) : (vue.openBlock(), vue.createBlock(_component_a_tag, { key: 1, onClick: showInput, style: { "background": "#fff", "border-style": "dashed" } }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(PlusOutlined)), _cache[1] || (_cache[1] = vue.createTextVNode(" New Tag ")) ]), _: 1 })) ], 64); }; } }; const _hoisted_1$2 = { key: 1 }; const _sfc_main$h = { __name: "Info", props: [ "bvid", "pic", "title", "desc", "remark", "tags", "ctime", "mtime" ], emits: ["change", "close"], setup(__props, { emit: __emit }) { const props = __props; const emits = __emit; const container = vue.ref(); const textareaRef = vue.ref(); const formState = vue.ref({ ...props }); const handleTagsChange = (tags) => { formState.value.tags = tags; }; const handleSubmit = () => { if (!formState.value.ctime) { formState.value.ctime = Date.now(); } formState.value.mtime = Date.now(); emits("change", vue.toRaw(formState.value)); emits("close"); }; vue.onMounted(() => { container.value = document.querySelector(".custom-form"); textareaRef.value.focus(); }); return (_ctx, _cache) => { const _component_a_image = vue.resolveComponent("a-image"); const _component_a_form_item = vue.resolveComponent("a-form-item"); const _component_a_input = vue.resolveComponent("a-input"); const _component_a_textarea = vue.resolveComponent("a-textarea"); const _component_a_button = vue.resolveComponent("a-button"); const _component_a_form = vue.resolveComponent("a-form"); return vue.openBlock(), vue.createBlock(_component_a_form, { model: formState.value, "label-col": { span: 5 }, "wrapper-col": { span: 17 }, class: "custom-form" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_form_item, { label: "视频封面" }, { default: vue.withCtx(() => [ formState.value.pic ? (vue.openBlock(), vue.createBlock(_component_a_image, { key: 0, src: formState.value.pic, preview: { getContainer: () => container.value }, width: 200 }, null, 8, ["src", "preview"])) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_1$2, "无")) ]), _: 1 }), vue.createVNode(_component_a_form_item, { label: "视频标题" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_input, { value: formState.value.title, "onUpdate:value": _cache[0] || (_cache[0] = ($event) => formState.value.title = $event), bordered: false, disabled: "", style: { "color": "gray" } }, null, 8, ["value"]) ]), _: 1 }), vue.createVNode(_component_a_form_item, { label: "视频简介" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_textarea, { value: formState.value.desc, "onUpdate:value": _cache[1] || (_cache[1] = ($event) => formState.value.desc = $event), bordered: false, autoSize: "", disabled: "", style: { "color": "gray" } }, null, 8, ["value"]) ]), _: 1 }), vue.createVNode(_component_a_form_item, { label: "备注" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_textarea, { ref_key: "textareaRef", ref: textareaRef, value: formState.value.remark, "onUpdate:value": _cache[2] || (_cache[2] = ($event) => formState.value.remark = $event), "show-count": "", maxlength: 500, "auto-size": { minRows: 4 } }, null, 8, ["value"]) ]), _: 1 }), vue.createVNode(_component_a_form_item, { label: "标签" }, { default: vue.withCtx(() => [ vue.createVNode(_sfc_main$i, { tags: formState.value.tags || "", onChange: handleTagsChange }, null, 8, ["tags"]) ]), _: 1 }), vue.createVNode(_component_a_form_item, { "wrapper-col": { span: 4, offset: 11 } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_button, { type: "primary", onClick: handleSubmit }, { default: vue.withCtx(() => _cache[3] || (_cache[3] = [ vue.createTextVNode("保存") ])), _: 1 }) ]), _: 1 }) ]), _: 1 }, 8, ["model"]); }; } }; const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; const _hoisted_1$1 = { key: 0 }; const _hoisted_2$1 = { key: 2, style: { "text-align": "right" } }; const _sfc_main$g = { __name: "Badge", props: [ "bvid", "pic", "title", "desc", "remark", "tags", "ctime", "mtime" ], emits: ["change"], setup(__props, { emit: __emit }) { const props = __props; const emits = __emit; const handleChange = (record) => { emits("change", record); }; const showModal = () => { view( props.bvid, (result) => { const { pic = props.pic, title = props.title, desc = props.desc } = result || {}; const close = templateModal({ title: "备注信息", template: _sfc_main$h, templateProps: { ...props, pic, title, desc, onChange: handleChange, onClose: () => close() } }); }, (message) => { messageModal({ title: "提示", message, type: "warning" }); } ); }; return (_ctx, _cache) => { const _component_a_divider = vue.resolveComponent("a-divider"); const _component_a_col = vue.resolveComponent("a-col"); const _component_a_row = vue.resolveComponent("a-row"); const _component_a_popover = vue.resolveComponent("a-popover"); return __props.remark || __props.tags ? (vue.openBlock(), vue.createBlock(_component_a_popover, { key: 0, placement: "topRight", arrowPointAtCenter: "", destroyTooltipOnHide: "", overlayInnerStyle: { width: "380px", boxShadow: "0px 0px 20px 5px rgba(0, 0, 0, 0.5)" } }, { content: vue.withCtx(() => [ __props.remark ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_1$1, vue.toDisplayString(__props.remark), 1)) : vue.createCommentVNode("", true), __props.remark && __props.tags ? (vue.openBlock(), vue.createBlock(_component_a_divider, { key: 1, dashed: "", style: { "margin": "12px 0" } })) : vue.createCommentVNode("", true), __props.tags ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_2$1, [ vue.createVNode(_sfc_main$j, { tags: __props.tags || "" }, null, 8, ["tags"]) ])) : vue.createCommentVNode("", true), __props.ctime || __props.mtime ? (vue.openBlock(), vue.createBlock(_component_a_row, { key: 3, justify: "space-between", class: "custom-row-time" }, { default: vue.withCtx(() => [ __props.ctime ? (vue.openBlock(), vue.createBlock(_component_a_col, { key: 0, span: 12, class: "custom-col-time" }, { default: vue.withCtx(() => [ vue.createTextVNode(" 创建时间:" + vue.toDisplayString(vue.unref(dateUtil).timestampToDate[1](__props.ctime)), 1) ]), _: 1 })) : vue.createCommentVNode("", true), __props.mtime ? (vue.openBlock(), vue.createBlock(_component_a_col, { key: 1, span: 12, class: "custom-col-time" }, { default: vue.withCtx(() => [ vue.createTextVNode(" 修改时间:" + vue.toDisplayString(vue.unref(dateUtil).timestampToDate[1](__props.mtime)), 1) ]), _: 1 })) : vue.createCommentVNode("", true) ]), _: 1 })) : vue.createCommentVNode("", true) ]), default: vue.withCtx(() => [ vue.createElementVNode("div", { title: "点击编辑备注", onClick: showModal, class: "ribbon" }, [ vue.createVNode(vue.unref(EditOutlined)) ]) ]), _: 1 })) : (vue.openBlock(), vue.createElementBlock("div", { key: 1, title: "点击编辑备注", onClick: showModal, class: "ribbon ribbon-new" }, [ vue.createVNode(vue.unref(EditOutlined)) ])); }; } }; const Badge = /* @__PURE__ */ _export_sfc(_sfc_main$g, [["__scopeId", "data-v-83c9451e"]]); const _sfc_main$f = { __name: "Edit", props: [ "bvid", "pic", "title", "desc", "remark", "tags", "ctime", "mtime" ], emits: ["change"], setup(__props, { emit: __emit }) { const props = __props; const emits = __emit; const formState = vue.ref({ ...props }); view( props.bvid, (result) => { if (result) { formState.value.pic = result.pic; formState.value.title = result.title; formState.value.desc = result.desc; } }, (message) => { messageModal({ title: "提示", message, type: "warning" }); } ); const handleChange = () => { emits("change", vue.toRaw(formState.value)); }; const handleTagsChange = (tags) => { formState.value.tags = tags; handleChange(); }; return (_ctx, _cache) => { const _component_a_textarea = vue.resolveComponent("a-textarea"); const _component_a_form_item = vue.resolveComponent("a-form-item"); const _component_a_form = vue.resolveComponent("a-form"); return vue.openBlock(), vue.createBlock(_component_a_form, { model: formState.value, "label-col": { span: 3 }, "wrapper-col": { span: 21 } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_form_item, { label: "备注" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_textarea, { value: formState.value.remark, "onUpdate:value": _cache[0] || (_cache[0] = ($event) => formState.value.remark = $event), "show-count": "", maxlength: 500, "auto-size": { minRows: 4, maxRows: 10 }, onChange: handleChange }, null, 8, ["value"]) ]), _: 1 }), vue.createVNode(_component_a_form_item, { label: "标签" }, { default: vue.withCtx(() => [ vue.createVNode(_sfc_main$i, { tags: formState.value.tags || "", onChange: handleTagsChange }, null, 8, ["tags"]) ]), _: 1 }) ]), _: 1 }, 8, ["model"]); }; } }; let currPage$1 = (() => { const curr = biliUtil.getCurrLocation(); if (curr === config$4.base.match[0].replace(/{{uid}}/, biliUtil.getUid())) { return "fav"; } else if (curr === config$4.base.match[1].replace(/{{bvid}}/, biliUtil.getCurrBvid())) { return "video"; } else { return ""; } })(); let fav = null; let nodeList = null; let collection = null; let appInstances = []; const insertOrUpdate = (record) => { let index2 = null; const result = config$4.data.find((o, i) => { index2 = i; return o.bvid === record.bvid; }); if (!result) { config$4.data.push(record); } else { config$4.data.splice(index2, 1); config$4.data.splice(index2, 0, record); } controller$3.useChangeHandler(); }; const unmountApp = () => { appInstances.forEach((item) => { if (item) item.unmount(); }); appInstances = []; }; const fav_getBvid = (el) => { const a = el.querySelector("a:first-child"); const href = a == null ? void 0 : a.getAttribute("href"); const path = href == null ? void 0 : href.split("?")[0]; const temp = path == null ? void 0 : path.split("/video/"); return temp && temp.length > 1 ? temp[1] : ""; }; const fav_render = () => { unmountApp(); nodeList == null ? void 0 : nodeList.forEach((wrap) => { const bvid = fav_getBvid(wrap); const result = config$4.data.find((o) => o.bvid === bvid); const target = vue.ref(result || { bvid }); const app = vue.createApp({ render: () => { return vue.h(Badge, { ...target.value, onChange: (record) => { target.value = record; insertOrUpdate(target.value); } }); } }); app.use(Antd); app.mount( (() => { let remark = wrap.querySelector(".bili-video-card__remark"); if (!remark) { remark = document.createElement("div"); remark.classList.add("bili-video-card__remark"); wrap.appendChild(remark); } return remark; })() ); appInstances.push(app); }); }; const fav_remove = () => { nodeList == null ? void 0 : nodeList.forEach((wrap) => { const remark = wrap.querySelector(".bili-video-card__remark"); remark && remark.remove(); }); }; const fav_observer = new MutationObserver((mutations) => { let newNodeList = []; for (const item of mutations) { let wrap = null; if (item.target.classList.contains("items")) { if (item.addedNodes.length > 0) { const items_item = item.addedNodes[0]; const card = items_item == null ? void 0 : items_item.querySelector(".bili-video-card"); wrap = card == null ? void 0 : card.querySelector(".bili-video-card__wrap"); } } if (item.target.classList.contains("bili-video-card")) { if (item.addedNodes.length > 0) { wrap = item.addedNodes[0]; } } wrap && newNodeList.push(wrap); } if (newNodeList.length > 0) { nodeList = newNodeList; fav_render(); } }); const video_getBvid = () => { return location.pathname.split("/")[2]; }; const video_render = () => { const bvid = video_getBvid(); if (!collection || !bvid) return; unmountApp(); const result = config$4.data.find((o) => o.bvid === bvid); const target = vue.ref(result || { bvid }); const app = vue.createApp({ render: () => { return vue.h(_sfc_main$f, { ...target.value, onChange: (record) => { target.value = record; } }); } }); app.use(Antd); app.mount( (() => { let remark = collection.querySelector(".collection__remark"); if (!remark) { const bottom = collection.querySelector(".bottom"); remark = document.createElement("div"); remark.classList.add("collection__remark"); collection.insertBefore(remark, bottom); const button = bottom.querySelector("button"); button && button.addEventListener("click", () => { if (!target.value.ctime) { target.value.ctime = Date.now(); } target.value.mtime = Date.now(); insertOrUpdate(target.value); }); } return remark; })() ); appInstances.push(app); }; const video_remove = () => { const remark = collection == null ? void 0 : collection.querySelector(".collection__remark"); remark && remark.remove(); }; const video_observer = new MutationObserver((mutations) => { for (const item of mutations) { item.addedNodes.forEach((el) => { var _a; if ((_a = el.classList) == null ? void 0 : _a.contains("bili-dialog-m")) { collection = el.querySelector(".collection-m-exp"); if (collection) { video_render(); return; } } }); } }); const install$1 = () => { if (currPage$1 === "fav") { fav = document.querySelector(".fav-list-main > .items"); nodeList = fav == null ? void 0 : fav.querySelectorAll(".bili-video-card__wrap"); if (nodeList && nodeList.length > 0) fav_render(); fav_observer.observe(document.body, { childList: true, subtree: true }); } else if (currPage$1 === "video") { collection = document.querySelector(".bili-dialog-m .collection-m-exp"); if (collection) video_render(); video_observer.observe(document.body, { childList: true }); } }; const uninstall$1 = () => { if (currPage$1 === "fav") { fav_observer.disconnect(); fav_remove(); nodeList = null; fav = null; } else if (currPage$1 === "video") { video_observer.disconnect(); video_remove(); collection = null; } }; const toggle$1 = () => { if (config$4.base.isActive) { install$1(); console.log("开启收藏夹备注功能"); } else { uninstall$1(); console.log("关闭收藏夹备注功能"); } }; const init$5 = () => { toggle$1(); console.log("初始化收藏夹备注功能完成"); }; const reset$4 = () => { toggle$1(); console.log("重置收藏夹备注功能完成"); }; const click$2 = () => { config$4.base.isActive = !config$4.base.isActive; toggle$1(); controller$3.useChangeHandler(); console.log("切换收藏夹备注功能完成"); }; const plugin$2 = new Plugin({ name: "收藏视频备注", description: "一键开启收藏夹备注功能,支持在视频页面和收藏夹页面内编辑备注信息", icon: FolderOutlined, type: "persistent", $init: init$5, $reset: reset$4, $click: click$2 }); const _sfc_main$e = { __name: "Option", setup(__props) { const handleChange = (_2, e) => { e.preventDefault(); click$2(); }; return (_ctx, _cache) => { const _component_a_col = vue.resolveComponent("a-col"); const _component_a_switch = vue.resolveComponent("a-switch"); const _component_a_row = vue.resolveComponent("a-row"); return vue.openBlock(), vue.createBlock(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { span: 18, style: { "color": "#a9a9a9" } }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(vue.unref(plugin$2).description), 1) ]), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_switch, { checked: vue.unref(config$4).base.isActive, onChange: handleChange }, null, 8, ["checked"]) ]), _: 1 }) ]), _: 1 }); }; } }; const index$2 = { self: plugin$2, config: controller$3, Option: _sfc_main$e }; const __vite_glob_0_0 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: index$2 }, Symbol.toStringTag, { value: "Module" })); const note = (bvid, execute, error) => { if (!bvid) return; let url = "https://api.bilibili.com/x/note/list/archive"; let params = { oid: biliUtil.bv2av(bvid), oid_type: 0 }; return request$2.get(url, params, execute, error); }; const info = (bvid, noteId, execute, error) => { if (!bvid || !noteId) return; let url = "https://api.bilibili.com/x/note/info"; let params = { oid: biliUtil.bv2av(bvid), oid_type: 0, note_id: noteId }; return request$2.get(url, params, execute, error); }; class TemplateFactory { /** * 创建一个模板工厂 * @param {string} videoType 视频类型:single-单视频,multip-选集,season-合集 */ constructor(videoType) { this.videoType = videoType; } /** * 获取对应视频类型的模板 * @returns 模板对象 */ getTemplate() { if (!["single", "multip", "season"].includes(this.videoType)) { throw new Error("parameter videoType is invalid"); } return {}; } } const _template$2 = { tips: () => { return `> [!warning] 警告!!! > - 如果有出链,先查看出链面板下的数据是否识别成功 > - 打开“设置”-“选项”-“文件与链接”-“始终更新内部链接”功能 > - 确认后方可重新修改笔记名称 > - 没有出链的可直接忽略以上步骤 > - 确认笔记无误后可根据情况删除该警告 `; }, info: (type, cover, title, url, desc) => { return `# ${type}信息  **标题:** ${title}[ ](${url}) **简介:** ${desc} `; }, catalog: (catalog) => { return `# 目录清单 ${catalog}`; }, note: (note2) => { return `# 笔记内容 ${note2}`; } }; const renderSingle$1 = ({ info: { cover, title, url, desc }, note: note2 }) => { return _template$2.info("视频", cover, title, url, desc).concat(_template$2.note(note2)); }; const renderMultip$1 = ({ info: { cover, title, url, desc }, catalog, note: note2 }) => { return _template$2.tips().concat( _template$2.info("视频", cover, title, url, desc), _template$2.catalog(catalog), _template$2.note(note2) ); }; const renderSeasonCatalog = ({ info: { cover, title, url, desc }, catalog }) => { return _template$2.tips().concat(_template$2.info("合集", cover, title, url, desc), _template$2.catalog(catalog)); }; class FileTemplateFactory extends TemplateFactory { /** * 创建一个文件模板工厂 * @param {string} videoType 视频类型:single-单视频,multip-选集,season-合集 */ constructor(videoType) { super(videoType); } /** * 获取对应视频类型的文件模板 * @returns {{render: Function}} 文件模板对象 */ getTemplate() { const template = super.getTemplate(); if (this.videoType === "single") { template.render = renderSingle$1; } else if (this.videoType === "multip") { template.render = renderMultip$1; } else if (this.videoType === "season") { template.render = renderSeasonCatalog; } return template; } } const _template$1 = { callout_tasklist: (catalogs, type) => { return renderCallout(type, "- [ ]", catalogs); }, callout_orderedlist: (catalogs, type) => { return renderCalloutOrderedlist(type, catalogs); }, callout_bulletedlist: (catalogs, type) => { return renderCallout(type, "-", catalogs); }, callout: (catalogs, type) => { return renderCallout(type, "", catalogs); }, quotes_tasklist: (catalogs) => { return renderQuotes("- [ ]", catalogs); }, quotes_orderedlist: (catalogs) => { return renderQuotesOrderedlist(catalogs); }, quotes_bulletedlist: (catalogs) => { return renderQuotes("-", catalogs); }, quotes: (catalogs) => { return renderQuotes("", catalogs); }, horizontalrule_tasklist: (catalogs) => { return renderHorizontalrule("- [ ]", catalogs); }, horizontalrule_orderedlist: (catalogs) => { return renderHorizontalruleOrderedlist(catalogs); }, horizontalrule_bulletedlist: (catalogs) => { return renderHorizontalrule("-", catalogs); }, horizontalrule: (catalogs) => { return renderHorizontalrule("", catalogs); } }; const renderCallout = (type, prefix, catalogs) => { return `> [!info]+ 视频${type} ${catalogs.map((item) => `> ${prefix}${prefix && " "}${item.outlink}`).join(" \n").concat(" \n")} `; }; const renderCalloutOrderedlist = (type, catalogs) => { return `> [!info]+ 视频${type} ${catalogs.map((item) => `> ${item.index}. ${item.outlink}`).join(" \n").concat(" \n")} `; }; const renderQuotes = (prefix, catalogs) => { return `${catalogs.map((item) => `> ${prefix}${prefix && " "}${item.outlink}`).join(" \n").concat(" \n")} `; }; const renderQuotesOrderedlist = (catalogs) => { return `${catalogs.map((item) => `> ${item.index}. ${item.outlink}`).join(" \n").concat(" \n")} `; }; const renderHorizontalrule = (prefix, catalogs) => { return `--- ${catalogs.map((item) => `${prefix}${prefix && " "}${item.outlink}`).join(" \n").concat(" \n")}--- `; }; const renderHorizontalruleOrderedlist = (catalogs) => { return `--- ${catalogs.map((item) => `${item.index}. ${item.outlink}`).join(" \n").concat(" \n")}--- `; }; const render = (catalogs, type, style2) => { return _template$1[style2](catalogs, type); }; class CatalogTemplateFactory extends TemplateFactory { /** * 创建一个目录清单模块模板工厂 * @param {string} videoType 视频类型:single-单视频,multip-选集,season-合集 * @param {{style: string}} [option] 可选配置 * @param {string} [option.style] 目录清单风格:同_template的key */ constructor(videoType, option = { style }) { super(videoType); this.style = option == null ? void 0 : option.style; } /** * 获取对应风格的目录清单模块模板 * @returns {{render: Function}} 目录清单模块模板对象 */ getTemplate() { const template = super.getTemplate(); if (this.videoType === "single") { template.render = () => ""; } else if (this.videoType === "multip") { template.render = ({ catalogs }) => { return render(catalogs, "选集", this.style); }; } else if (this.videoType === "season") { template.render = ({ catalogs }) => { return render(catalogs, "合集", this.style); }; } return template; } } const _template = { title: (title, url) => { return `## ${title} > 视频地址:[${url}](${url}) `; }, content: (content) => { return `${content} `; } }; const renderSingle = ({ notes }) => { const note2 = notes == null ? void 0 : notes.find((item) => item.p === 1); return (note2 == null ? void 0 : note2.content) ? _template.content(note2.content) : ""; }; const renderMultip = ({ catalogs, notes }) => { return catalogs.map((item) => { const note2 = notes.find((obj) => obj.p === item.index); return _template.title(item.title, item.url).concat(note2 && note2.content ? _template.content(note2.content) : ""); }).join(""); }; class NoteTemplateFactory extends TemplateFactory { /** * 创建一个笔记内容模块模板工厂 * @param {string} videoType 视频类型:single-单视频,multip-选集,season-合集 */ constructor(videoType) { super(videoType); } /** * 获取对应笔记标题格式的笔记内容模块模板 * @returns {{render: Function}} 笔记内容模块模板对象 */ getTemplate() { const template = super.getTemplate(); if (this.videoType === "single") { template.render = renderSingle; } else if (this.videoType === "multip") { template.render = renderMultip; } else if (this.videoType === "season") { template.render = () => ""; } return template; } } class CatalogItem { constructor(index2, title, url, outlink) { this.index = index2; this.title = title; this.url = url; this.outlink = outlink; } } class EpisodeCatalog { /** * 创建一个合集目录清单处理对象 * @param {{bvid: string, title: string}[]} episodes 合集数组 * @param {string} episodes.item.bvid 视频bvid * @param {string} episodes.item.title 视频标题 * @param {{fileName: string}[]} files 笔记文件数组 * @param {string} files.item.fileName 笔记文件名 * @param {{outlinkHandler: Function}} [option] 可选配置 * @param {Function} [option.outlinkHandler] 出链处理器 */ constructor(episodes, files, option = { outlinkHandler }) { this.episodes = episodes; this.files = files; this.outlinkHandler = option == null ? void 0 : option.outlinkHandler; } /** * 处理合集目录清单数据并输出结果 * @returns {CatalogItem} 处理结果 */ data() { if (!this.episodes || !this.episodes.length || this.episodes.length === 0) return []; return this.episodes.map((o, index2) => { var _a; const fileName = ((_a = this.files[index2]) == null ? void 0 : _a.fileName) || ""; const outlink = this.outlinkHandler ? this.outlinkHandler(fileName) : fileName; const url = `https://www.bilibili.com/video/${o.bvid}`; return new CatalogItem(index2 + 1, o.title, url, outlink); }); } } class PageCaltalog { /** * 创建一个选集目录清单处理对象 * @param {string} bvid 视频bvid * @param {{page: number, part: string}[]} pages 分P数组 * @param {number} pages.item.page 分P数 * @param {string} pages.item.part 分P标题 * @param {{ * titleHandler: Function, * outlinkHandler: Function, * }} [option] 可选配置 * @param {Function} [option.titleHandler] 分P标题处理器 * @param {Function} [option.outlinkHandler] 出链处理器 */ constructor(bvid, pages, option = { titleHandler, outlinkHandler }) { this.bvid = bvid; this.pages = pages; this.titleHandler = option == null ? void 0 : option.titleHandler; this.outlinkHandler = option == null ? void 0 : option.outlinkHandler; } /** * 处理选集目录清单数据并输出结果 * @returns {CatalogItem} 处理结果 */ data() { if (!this.bvid) throw new Error("bvid is not found."); if (!this.pages || !this.pages.length || this.pages.length === 0) return []; return this.pages.map((o) => { const title = this.titleHandler ? this.titleHandler(o.page, o.part) : o.part; const outlink = this.outlinkHandler ? this.outlinkHandler(title) : title; const url = `https://www.bilibili.com/video/${this.bvid}?p=${o.page}`; return new CatalogItem(o.page, title, url, outlink); }); } } class NoteItem { constructor(p, content) { this.p = p; this.content = content; } } class Note { /** * 创建一个笔记内容处理对象 * @param {string} bvid 视频bvid * @param {string} raw B站接口返回的笔记原文 * @param {{ * textHandler: Function, * tagHandler: Function, * imageHandler: Function, * }} [option] 可选配置 * @param {Function} [option.textHandler] 文本处理器 * @param {Function} [option.tagHandler] 时间戳处理器 * @param {Function} [option.imageHandler] 图片处理器 */ constructor(bvid, raw, option = { textHandler, tagHandler, imageHandler }) { this.bvid = bvid; this.raw = raw; this.textHandler = option == null ? void 0 : option.textHandler; this.tagHandler = option == null ? void 0 : option.tagHandler; this.imageHandler = option == null ? void 0 : option.imageHandler; } /** * 处理笔记内容并输出结果 * @returns {NoteItem[]} 处理结果 */ data() { if (!this.bvid) throw new Error("bvid is not found."); if (!this.raw) return []; const contents = JSON.parse(this.raw); if (!contents || !contents.length || contents.length === 0) return []; let line = []; const lines = [line]; for (let item of contents) { if (typeof item.insert === "object") { if (item.insert.tag && line.length > 0) { line = []; lines.push(line); } line.push(item); continue; } if (!/\n/.test(item.insert)) { line.push(item); continue; } const temp = item.insert.split(/\n/); for (let i = 0; i < temp.length; i++) { if (i > 0) { line = []; lines.push(line); } if (i < temp.length - 1 && (temp[i] || item.attributes) || temp[i]) { line.push({ insert: temp[i], attributes: item.attributes }); } } } let note2 = new NoteItem(1, ""); const notes = [note2]; let preLine = null; lines.forEach((line2) => { let lineText = ""; const tagStack = []; let preItem = null; line2.forEach((item, index2) => { if (typeof item.insert === "string") { if (this.textHandler) { lineText = this.textHandler(preLine, lineText, preItem, item, tagStack); if (index2 === line2.length - 1) { lineText = this.textHandler(preLine, lineText, item, null, tagStack); } } else { lineText += item.insert; } } if (item.insert.tag) { const index3 = item.insert.tag.index; if (index3 !== note2.p) { const temp = notes.find((obj) => obj.p === index3); if (!temp) { note2 = new NoteItem(index3, ""); notes.push(note2); } else { note2 = temp; } } lineText += this.tagHandler ? this.tagHandler(this.bvid, { ...item.insert.tag }) : ""; } if (item.insert.imageUpload) { lineText += this.imageHandler ? this.imageHandler({ ...item.insert.imageUpload }) : ""; } preItem = item; preLine = null; }); note2.content = note2.content.concat(lineText, "\n\n"); preLine = line2; }); return notes; } } const pluginConfig$1 = new PluginConfig({ base: { match: ["https://www.bilibili.com/video/{{bvid}}/"], isActive: false, isOnlySwitchCurrActive: false }, option: { isOnlyCurr: true, catalog: { style: "callout_tasklist", newline: " " }, title: { pattern: "P{x} 📺 {xxx}", level: "##" }, note: { mode: "markdown", isExtended: false, syntax: { newline: "\n", bold: "**", list: "-" } } }, data: [] }); const configRef$2 = new ConfigRef(pluginConfig$1); const config$3 = configRef$2._self(); const controller$2 = configRef$2.getController(); const reg = /[\~\`\!\@\#\$\%\^\&\*\(\)\-\_\+\=\{\[\}\]\|\\\:\;\"\'\<\,\>\.\?\/]/g; const fileNameHandler = (fileName) => { return fileName.replace(/[\\\/\:\*\?\"\<\>\|]/g, ""); }; const pageTitleHandler = (p, title) => { title = title.replace(reg, "\\$&"); return config$3.option.title.pattern ? config$3.option.title.pattern.replace(/{x}/g, p).replace(/{xxx}/g, title) : title; }; const mdOutlink = (fileName) => { const ascll = /[\~\`\!\@\#\$\%\^\&\*\(\)\-\_\+\=\{\[\}\]\|\\\:\;\"\'\<\,\>\.\?\/ ]/g; const encode = ($0) => { return !["(", ")"].includes($0) ? encodeURI($0) : $0 == "(" ? "%28" : "%29"; }; const mdDisplayReg = { r: /(\[\])/g, $: "\\$1" }; const mdLinkReg = { r: ascll, $: encode }; return { display: fileName.replace(mdDisplayReg.r, mdDisplayReg.$), link: fileName.replace(mdLinkReg.r, mdLinkReg.$) }; }; const wikiOutlink = (fileName) => { const wikiDisplayReg = { r: /(\[\])/g, $: " $1" }; const wikiLinkReg = { r: /[\#\^\|\\]/g, $: " " }; return { display: fileName.replace(wikiDisplayReg.r, wikiDisplayReg.$), link: fileName.replace(wikiLinkReg.r, wikiLinkReg.$) }; }; const episodeOutlinkHandler = (fileName) => { const md = mdOutlink(fileName); const wiki = wikiOutlink(fileName); return config$3.option.note.mode === "obsidian" ? `[[${wiki.link}|${wiki.display.slice(0, -3)}]]` : `[${md.display.slice(0, -3)}](${md.link})`; }; const pageOutlinkHandler = (fileName) => { return (title) => { const md = mdOutlink(title); const wiki = wikiOutlink(title); return config$3.option.note.mode === "obsidian" ? `[[${fileName}#${wiki.link}|${wiki.display}]]` : `[${md.display}](${mdOutlink(fileName).link}#${md.link})`; }; }; const textHandler$1 = () => { let indentLevel = []; const isExtended = config$3.option.note.isExtended; const rank = (() => { if (isExtended) { return [ { name: "underline", start: "<u>", end: "</u>", sort: 0 }, { name: "strike", start: "<s>", end: "</s>", sort: 1 }, { name: "bold", start: "<b>", end: "</b>", sort: 2 }, { name: "background", start: "<span>", end: "</span>", sort: 3 }, { name: "color", start: "<span>", end: "</span>", sort: 3 }, { name: "size", start: "<span>", end: "</span>", sort: 3 } ]; } else { let temp = config$3.option.note.syntax.bold; if (config$3.option.note.mode === "obsidian") { return [ { name: "bold", start: temp, end: temp, sort: 0 }, { name: "strike", start: "~~", end: "~~", sort: 1 }, { name: "background", start: "==", end: "==", sort: 2 } ]; } else { return [{ name: "bold", start: temp, end: temp }]; } } })(); const cross = (obj1, obj2) => { if (!obj1 || !obj2) return {}; const result = {}; for (const key in obj1) { if (isExtended) { if (obj2.hasOwnProperty(key) && obj1[key] === obj2[key]) { result[key] = obj1[key]; } } else { if (obj2.hasOwnProperty(key)) { result[key] = obj1[key]; } } } return result; }; const diff = (target, pattern) => { if (!target) return {}; const result = {}; for (const key in target) { if (!pattern.hasOwnProperty(key)) { result[key] = target[key]; } } return result; }; const suffix = (tagStack, closedTags, open, close) => { let max = 0; let keyArr = Object.keys(open); if (keyArr.length > 0) { keyArr.forEach((key) => { const target = rank.find((item) => item.name === key); if (target && target.sort > max) max = target.sort; }); } keyArr = Object.keys(close); if (keyArr.length > 0) { keyArr.forEach((key) => { let index2 = -1; const target = tagStack.find((item, i) => { if (item.name === key) { index2 = i; return item; } }); if (index2 > -1) { closedTags.push(...tagStack.splice(index2, 1)); if (target.sort > max) max = target.sort; } }); } if (isExtended) { closedTags.push(...tagStack.filter((item) => item.sort <= max)); } else { closedTags.push(...tagStack.filter((item) => item.sort < max)); } return closedTags.length > 0 ? closedTags.reduce((acc, curr) => { if (!acc.find((item) => item.sort === curr.sort)) acc.push({ ...curr }); return acc; }, []).sort((a, b) => a.sort - b.sort).map((item) => item.end).join("") : ""; }; const prefix = (tagStack, closedTags, same, open) => { const skip = []; let keyArr = Object.keys(same); if (keyArr.length > 0) { keyArr.forEach((key) => { if (!closedTags.find((item) => item.name === key)) skip.push(key); }); } keyArr = Object.keys(open); if (keyArr.length > 0) { keyArr.forEach((key) => { let target = rank.find((item) => item.name === key); if (target) { if (isExtended && target.sort === 3) { const styleName = target.name === "size" ? "font-size" : target.name; if (same.hasOwnProperty(target.name)) { target.start = `${styleName}: ${same[target.name]}`; } if (open.hasOwnProperty(target.name)) { target.start = `${styleName}: ${open[target.name]}`; } } tagStack.push(target); } }); } return tagStack.length > 0 ? tagStack.reduce((acc, curr) => { if (!skip.includes(curr.name)) { const target = acc.find((item) => item.sort === curr.sort); if (target && isExtended && target.sort === 3) { target.name += `,${curr.name}`; target.start += `;${curr.start}`; } else { acc.push({ ...curr }); } } return acc; }, []).sort((a, b) => b.sort - a.sort).map((item) => { if (isExtended && item.sort === 3) { item.start = `<span style="${item.start}">`; } return item.start; }).join("") : ""; }; const listfix = (indent = 0, list) => { if (list === "ordered") { const number = indentLevel[indent] ? indentLevel[indent] + 1 : 1; indentLevel[indent] = number; for (let i = indent + 1; i < indentLevel.length; i++) { indentLevel[i] = 0; } return `${" ".repeat(indent)}${number}. `; } else { return `${" ".repeat(indent)}${config$3.option.note.syntax.list} `; } }; return (preLine, line, preItem, item, tagStack) => { const insert = (item == null ? void 0 : item.insert) || ""; const attributes = (item == null ? void 0 : item.attributes) || {}; const same = cross(preItem == null ? void 0 : preItem.attributes, attributes); const close = diff(preItem == null ? void 0 : preItem.attributes, same); const open = diff(attributes, same); const closedTags = []; line += suffix(tagStack, closedTags, open, close); line += prefix(tagStack, closedTags, same, open); if (attributes == null ? void 0 : attributes.list) { line = listfix(attributes.indent, attributes.list) + line; } if (preLine && !preLine.find((o) => { var _a; return ((_a = o.attributes) == null ? void 0 : _a.list) === "ordered"; })) { indentLevel = []; } if (isExtended && Object.keys(attributes).length > 0) { return `${line}${insert}`; } else { return `${line}${insert.replace(reg, "\\$&")}`; } }; }; const tagHandler$1 = (bvid, { cidCount, desc, index: index2, seconds, title }) => { return cidCount === 1 ? `[🏁 ${dateUtil.formatSeconds[1](seconds)}${desc ? " " + desc : ""}](https://www.bilibili.com/video/${bvid}?t=${seconds})` : `[🏁 ${title} P${index2} - ${dateUtil.formatSeconds[1](seconds)}${desc ? " " + desc : ""}](https://www.bilibili.com/video/${bvid}?p=${index2}#t=${seconds})`; }; const imageHandler$1 = (folder) => { let images = []; return (action) => { if (action === "list") { return images; } else { return ({ id, url }) => { const fileName = `${id}.jpg`; images.push({ fileName, url }); return config$3.option.note.mode === "obsidian" ? `![[${folder}/${fileName}]]` : ``; }; } }; }; let imageActionHandler; const getNoteContent = async (bvid) => { const noteRes = await note(bvid); const noteIds = noteRes == null ? void 0 : noteRes.noteIds; if (!noteIds || !noteIds.length || noteIds.length === 0) return ""; const infoRes = await info(bvid, noteIds[0]); return (infoRes == null ? void 0 : infoRes.content) || ""; }; const getNoteFile = async (data2) => { const fileName = `${fileNameHandler(data2.title)}.md`; const bvid = data2.bvid; const pages = data2.pages; const videoType = pages.length > 1 ? "multip" : "single"; const arcOrData = data2.arc ? data2.arc : data2; const fileTemplate = new FileTemplateFactory(videoType).getTemplate(); const catalogTemplate = new CatalogTemplateFactory(videoType, { style: config$3.option.catalog.style }).getTemplate(); const noteTemplate = new NoteTemplateFactory(videoType).getTemplate(); const info2 = { cover: arcOrData.pic, title: arcOrData.title, url: `https://www.bilibili.com/video/${bvid}`, desc: arcOrData.desc }; const catalog = new PageCaltalog(bvid, pages, { titleHandler: pageTitleHandler, outlinkHandler: pageOutlinkHandler(fileName) }); const catalogs = catalog.data(); const catalogText = catalogTemplate.render({ catalogs }); const note2 = new Note(bvid, await getNoteContent(bvid), { textHandler: textHandler$1(), tagHandler: tagHandler$1, imageHandler: imageActionHandler("save") }); const notes = note2.data(); const noteText = noteTemplate.render({ catalogs, notes }); const fileContent = fileTemplate.render({ info: info2, catalog: catalogText, note: noteText }); return { fileName, fileContent }; }; const getNoteFiles = async (bvid) => { var _a; if (!bvid) return []; const files = []; const result = await view(bvid); if (result.ugc_season && !config$3.option.isOnlyCurr) { const episodes = (_a = result.ugc_season.sections) == null ? void 0 : _a.reduce((acc, curr) => { return acc.concat((curr == null ? void 0 : curr.episodes) || []); }, []); if (!episodes || !episodes.length || episodes.length === 0) return []; const upUid = result.ugc_season.mid; const seasonId = result.ugc_season.id; if (!upUid || !seasonId) return []; for (let i = 0; i < episodes.length; i++) { const item = episodes[i]; item.title = `${i + 1}. ${item.title}`; files.push(await getNoteFile(item)); } const fileTemplate = new FileTemplateFactory("season").getTemplate(); const catalogTemplate = new CatalogTemplateFactory("season", { style: config$3.option.catalog.style }).getTemplate(); const info2 = { cover: result.ugc_season.cover, title: result.ugc_season.title, url: `https://space.bilibili.com/${upUid}/lists/${seasonId}?type=season`, desc: result.ugc_season.intro }; const catalog = new EpisodeCatalog(episodes, files, { outlinkHandler: episodeOutlinkHandler }); const catalogs = catalog.data(); const catalogText = catalogTemplate.render({ catalogs }); const fileName = "0. 合集目录.md"; const fileContent = fileTemplate.render({ info: info2, catalog: catalogText }); files.push({ fileName, fileContent }); } else { files.push(await getNoteFile(result)); } return files; }; const downloadNote = async (bvid) => { const files = {}; const notes = await getNoteFiles(bvid); const images = imageActionHandler("list"); const folderName = `B站笔记${Date.now()}`; const attachmentName = "附件"; notes.forEach((item) => { files[`${folderName}/${item.fileName}`] = fflate.strToU8(item.fileContent); }); if (images && images.length > 0) { for (const item of images) { const content = await fetch(item.url, { method: "GET", credentials: "include", mode: "cors" }).then((response) => response.arrayBuffer()); files[`${folderName}/${attachmentName}/${item.fileName}`] = new Uint8Array(content); } } fflate.zip(files, (error, zipped) => { if (error) throw error; const blob = new Blob([zipped], { type: "application/zip" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = `${folderName}.zip`; a.click(); URL.revokeObjectURL(url); }); }; const init$4 = () => { console.log("初始化笔记&清单功能完成"); }; const reset$3 = () => { console.log("重置笔记&清单功能完成"); }; const click$1 = () => { const bvid = biliUtil.getCurrBvid(); if (!bvid) { messageModal({ title: "信息", message: "请进入视频页再使用!" }); return; } imageActionHandler = imageHandler$1("附件"); messageModal({ title: "信息", message: "处理中……视频数量越多需要时间越长。下载完成后请手动关闭弹窗!" }); downloadNote(bvid); }; const plugin$1 = new Plugin({ name: "视频笔记下载", description: "一键下载视频的分p/合集目录清单及私人笔记内容,进入视频页面后使用", icon: ProfileOutlined, type: "immediate", $init: init$4, $reset: reset$3, $click: click$1 }); const LOADING_TIME$1 = 2e3; const _sfc_main$d = { __name: "Option", props: { container: { type: Object, required: true, default: document.body } }, setup(__props) { const state = vue.ref({ download: false }); const handleClick = () => { state.value.download = true; click$1(); setTimeout(() => { state.value.download = false; }, LOADING_TIME$1); }; const handleChange = () => { controller$2.useChangeHandler(); }; return (_ctx, _cache) => { const _component_a_col = vue.resolveComponent("a-col"); const _component_a_button = vue.resolveComponent("a-button"); const _component_a_row = vue.resolveComponent("a-row"); const _component_a_tooltip = vue.resolveComponent("a-tooltip"); const _component_a_switch = vue.resolveComponent("a-switch"); const _component_a_select_option = vue.resolveComponent("a-select-option"); const _component_a_select = vue.resolveComponent("a-select"); const _component_a_divider = vue.resolveComponent("a-divider"); const _component_a_input = vue.resolveComponent("a-input"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { span: 18, style: { "color": "#a9a9a9" } }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(vue.unref(plugin$1).description), 1) ]), _: 1 }), vue.createVNode(_component_a_col, null, { default: vue.withCtx(() => [ vue.createVNode(_component_a_button, { loading: state.value.download, onClick: handleClick }, { default: vue.withCtx(() => _cache[7] || (_cache[7] = [ vue.createTextVNode("立即执行") ])), _: 1 }, 8, ["loading"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => [ _cache[8] || (_cache[8] = vue.createTextVNode(" 合集视频只下载当前视频的笔记 ")), vue.createVNode(_component_a_tooltip, { getPopupContainer: () => __props.container, title: "合集的视频数量影响笔记下载速度" }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(ExclamationCircleOutlined), { style: { "color": "rgba(0, 0, 0, 0.45)" } }) ]), _: 1 }, 8, ["getPopupContainer"]) ]), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_switch, { checked: vue.unref(config$3).option.isOnlyCurr, "onUpdate:checked": _cache[0] || (_cache[0] = ($event) => vue.unref(config$3).option.isOnlyCurr = $event), onChange: handleChange }, null, 8, ["checked"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => _cache[9] || (_cache[9] = [ vue.createTextVNode("目录清单风格") ])), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select, { getPopupContainer: () => __props.container, value: vue.unref(config$3).option.catalog.style, "onUpdate:value": _cache[1] || (_cache[1] = ($event) => vue.unref(config$3).option.catalog.style = $event), onChange: handleChange, style: { "width": "160px" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select_option, { value: "callout_tasklist" }, { default: vue.withCtx(() => _cache[10] || (_cache[10] = [ vue.createTextVNode("callout + 任务列表") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "callout_orderedlist" }, { default: vue.withCtx(() => _cache[11] || (_cache[11] = [ vue.createTextVNode("callout + 有序列表") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "callout_bulletedlist" }, { default: vue.withCtx(() => _cache[12] || (_cache[12] = [ vue.createTextVNode("callout + 无序列表") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "callout" }, { default: vue.withCtx(() => _cache[13] || (_cache[13] = [ vue.createTextVNode("callout") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "quotes_tasklist" }, { default: vue.withCtx(() => _cache[14] || (_cache[14] = [ vue.createTextVNode("引用块 + 任务列表") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "quotes_orderedlist" }, { default: vue.withCtx(() => _cache[15] || (_cache[15] = [ vue.createTextVNode("引用块 + 有序列表") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "quotes_bulletedlist" }, { default: vue.withCtx(() => _cache[16] || (_cache[16] = [ vue.createTextVNode("引用块 + 无序列表") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "quotes" }, { default: vue.withCtx(() => _cache[17] || (_cache[17] = [ vue.createTextVNode("引用块") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "horizontalrule_tasklist" }, { default: vue.withCtx(() => _cache[18] || (_cache[18] = [ vue.createTextVNode("水平线 + 任务列表") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "horizontalrule_orderedlist" }, { default: vue.withCtx(() => _cache[19] || (_cache[19] = [ vue.createTextVNode("水平线 + 有序列表") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "horizontalrule_bulletedlist" }, { default: vue.withCtx(() => _cache[20] || (_cache[20] = [ vue.createTextVNode("水平线 + 无序列表") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "horizontalrule" }, { default: vue.withCtx(() => _cache[21] || (_cache[21] = [ vue.createTextVNode("水平线") ])), _: 1 }) ]), _: 1 }, 8, ["getPopupContainer", "value"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => _cache[22] || (_cache[22] = [ vue.createTextVNode("目录清单分P标题格式") ])), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_input, { value: vue.unref(config$3).option.title.pattern, "onUpdate:value": _cache[2] || (_cache[2] = ($event) => vue.unref(config$3).option.title.pattern = $event), onChange: handleChange, style: { "width": "160px" } }, { suffix: vue.withCtx(() => [ vue.createVNode(_component_a_tooltip, { getPopupContainer: () => __props.container }, { title: vue.withCtx(() => [ _cache[23] || (_cache[23] = vue.createElementVNode("p", null, "{x}:表示分p数", -1)), _cache[24] || (_cache[24] = vue.createElementVNode("p", null, "{xxx}:表示分p标题", -1)), vue.createVNode(_component_a_divider, { dashed: "", style: { "border-color": "gray" } }), _cache[25] || (_cache[25] = vue.createElementVNode("p", null, "示例:第 {x} 集 《{xxx}》", -1)), _cache[26] || (_cache[26] = vue.createElementVNode("p", null, "输出:第 1 集 《导学》", -1)) ]), default: vue.withCtx(() => [ vue.createVNode(vue.unref(ExclamationCircleOutlined), { style: { "color": "rgba(0, 0, 0, 0.45)" } }) ]), _: 1 }, 8, ["getPopupContainer"]) ]), _: 1 }, 8, ["value"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => [ _cache[27] || (_cache[27] = vue.createTextVNode(" 使用B站视频笔记格式 ")), vue.createVNode(_component_a_tooltip, { getPopupContainer: () => __props.container, title: "该模式生成的笔记包含大量HTML标签" }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(ExclamationCircleOutlined), { style: { "color": "rgba(0, 0, 0, 0.45)" } }) ]), _: 1 }, 8, ["getPopupContainer"]) ]), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_switch, { checked: vue.unref(config$3).option.note.isExtended, "onUpdate:checked": _cache[3] || (_cache[3] = ($event) => vue.unref(config$3).option.note.isExtended = $event), onChange: handleChange }, null, 8, ["checked"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => _cache[28] || (_cache[28] = [ vue.createTextVNode("笔记语法风格") ])), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select, { getPopupContainer: () => __props.container, disabled: vue.unref(config$3).option.note.isExtended, value: vue.unref(config$3).option.note.mode, "onUpdate:value": _cache[4] || (_cache[4] = ($event) => vue.unref(config$3).option.note.mode = $event), onChange: handleChange, style: { "width": "110px" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select_option, { value: "markdown" }, { default: vue.withCtx(() => _cache[29] || (_cache[29] = [ vue.createTextVNode("markdown") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "obsidian" }, { default: vue.withCtx(() => _cache[30] || (_cache[30] = [ vue.createTextVNode("obsidian") ])), _: 1 }) ]), _: 1 }, 8, ["getPopupContainer", "disabled", "value"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_divider, { dashed: "", style: { "border-color": "gray" } }, { default: vue.withCtx(() => _cache[31] || (_cache[31] = [ vue.createTextVNode("markdown/obsidian 语法设置") ])), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => _cache[32] || (_cache[32] = [ vue.createTextVNode("笔记加粗方式") ])), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select, { getPopupContainer: () => __props.container, disabled: vue.unref(config$3).option.note.isExtended, value: vue.unref(config$3).option.note.syntax.bold, "onUpdate:value": _cache[5] || (_cache[5] = ($event) => vue.unref(config$3).option.note.syntax.bold = $event), onChange: handleChange, style: { "width": "130px" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select_option, { value: "**" }, { default: vue.withCtx(() => _cache[33] || (_cache[33] = [ vue.createTextVNode("双星号包裹") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "__" }, { default: vue.withCtx(() => _cache[34] || (_cache[34] = [ vue.createTextVNode("双下划线包裹") ])), _: 1 }) ]), _: 1 }, 8, ["getPopupContainer", "disabled", "value"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => _cache[35] || (_cache[35] = [ vue.createTextVNode("笔记无序列表方式") ])), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select, { getPopupContainer: () => __props.container, disabled: vue.unref(config$3).option.note.isExtended, value: vue.unref(config$3).option.note.syntax.list, "onUpdate:value": _cache[6] || (_cache[6] = ($event) => vue.unref(config$3).option.note.syntax.list = $event), onChange: handleChange, style: { "width": "90px" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select_option, { value: "-" }, { default: vue.withCtx(() => _cache[36] || (_cache[36] = [ vue.createTextVNode("单减号") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "+" }, { default: vue.withCtx(() => _cache[37] || (_cache[37] = [ vue.createTextVNode("单加号") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "*" }, { default: vue.withCtx(() => _cache[38] || (_cache[38] = [ vue.createTextVNode("单星号") ])), _: 1 }) ]), _: 1 }, 8, ["getPopupContainer", "disabled", "value"]) ]), _: 1 }) ]), _: 1 }) ], 64); }; } }; const index$1 = { self: plugin$1, config: controller$2, Option: _sfc_main$d }; const __vite_glob_0_1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: index$1 }, Symbol.toStringTag, { value: "Module" })); const pluginConfig = new PluginConfig({ base: { match: [ "https://www.bilibili.com/video/*/", "https://www.bilibili.com/list/*/" ], isActive: false, isOnlySwitchCurrActive: true }, option: {}, data: [] }); const configRef$1 = new ConfigRef(pluginConfig); const config$2 = configRef$1._self(); const controller$1 = configRef$1.getController(); const _sfc_main$c = {}; function _sfc_render(_ctx, _cache) { const _component_a_spin = vue.resolveComponent("a-spin"); return vue.openBlock(), vue.createBlock(_component_a_spin, { size: "large", tip: "加载中…" }); } const Mask = /* @__PURE__ */ _export_sfc(_sfc_main$c, [["render", _sfc_render]]); const _sfc_main$b = { __name: "More", props: { disabled: { type: Boolean, required: true, default: false }, message: { type: String, required: false, default: "加载中…" } }, emits: ["click"], setup(__props, { emit: __emit }) { const emits = __emit; const handleClick = ({ key }) => { emits("click", key); }; return (_ctx, _cache) => { const _component_a_button = vue.resolveComponent("a-button"); const _component_a_tooltip = vue.resolveComponent("a-tooltip"); const _component_a_menu_item = vue.resolveComponent("a-menu-item"); const _component_a_menu = vue.resolveComponent("a-menu"); const _component_a_dropdown = vue.resolveComponent("a-dropdown"); return vue.openBlock(), vue.createBlock(_component_a_dropdown, { disabled: __props.disabled }, { overlay: vue.withCtx(() => [ vue.createVNode(_component_a_menu, { onClick: handleClick }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_menu_item, { key: "1" }, { default: vue.withCtx(() => _cache[0] || (_cache[0] = [ vue.createTextVNode("加载10次") ])), _: 1 }), vue.createVNode(_component_a_menu_item, { key: "5" }, { default: vue.withCtx(() => _cache[1] || (_cache[1] = [ vue.createTextVNode("加载50次") ])), _: 1 }), vue.createVNode(_component_a_menu_item, { key: "10" }, { default: vue.withCtx(() => _cache[2] || (_cache[2] = [ vue.createTextVNode("加载100次") ])), _: 1 }), vue.createVNode(_component_a_menu_item, { key: "-1" }, { default: vue.withCtx(() => _cache[3] || (_cache[3] = [ vue.createTextVNode("加载全部") ])), _: 1 }) ]), _: 1 }) ]), default: vue.withCtx(() => [ vue.createVNode(_component_a_tooltip, null, { title: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(__props.message || "加载中…"), 1) ]), default: vue.withCtx(() => [ vue.createVNode(_component_a_button, { size: "large", disabled: __props.disabled }, { icon: vue.withCtx(() => [ vue.createVNode(vue.unref(SyncOutlined)) ]), _: 1 }, 8, ["disabled"]) ]), _: 1 }) ]), _: 1 }, 8, ["disabled"]); }; } }; let currPage = (() => { const curr = biliUtil.getCurrLocation(); if (/^https:\/\/www\.bilibili\.com\/video\/[^/]+\/$/.test(curr)) { return "video"; } else if (/^https:\/\/www\.bilibili\.com\/list\/[^/]+\/$/.test(curr)) { return "list"; } else { return ""; } })(); let video = null; let loading = null; let more = null; let next = null; let originalBluetoothHandler = null; const random = (min, max) => { return Math.floor(Math.random() * (max - min + 1)) + min; }; const initVideoPageNext = async () => { var _a; const result = await view(biliUtil.getCurrBvid()); if (!result) return; let videos = 0; if (result.ugc_season) { videos = (_a = result.ugc_season.sections) == null ? void 0 : _a.reduce((acc, curr) => { var _a2; acc += (_a2 = curr == null ? void 0 : curr.episodes) == null ? void 0 : _a2.reduce((acc2, curr2) => { var _a3; acc2 += ((_a3 = curr2 == null ? void 0 : curr2.pages) == null ? void 0 : _a3.length) || 0; return acc2; }, 0); return acc; }, 0); } else { videos = result.videos; } next = () => { if (!videos || videos <= 1) return; player == null ? void 0 : player.goto(random(1, videos), true); }; }; const initListPageNext = async () => { const origin = document.querySelector(".action-list-container"); if (!origin) return; const list = origin.querySelector("#playlist-video-action-list"); if (!list) return; let eplist = []; const disabledRef = vue.ref(false); const messageRef = vue.ref(eplist.length + "个视频可播放"); const _renderLoading = () => { if (loading) return; loading = document.createElement("div"); loading.classList.add("custom-loading"); loading.style.width = origin.clientWidth + "px"; loading.style.height = origin.clientHeight + "px"; loading.style.display = "none"; origin.parentNode.insertBefore(loading, origin); vue.createApp({ render: () => vue.h(Mask) }).use(Antd).mount(loading); }; const _showLoading = () => { disabledRef.value = true; messageRef.value = "加载中…"; loading && (loading.style.display = ""); }; const _hideLoading = (isEnd) => { if (isEnd) { disabledRef.value = true; messageRef.value = "已全部加载,共" + eplist.length + "个视频可播放"; } else { disabledRef.value = false; messageRef.value = eplist.length + "个视频可播放"; } loading && (loading.style.display = "none"); }; const _loadElement = (MAX_COUNT = 20) => { _showLoading(); let count = 0; let timerId = setInterval(() => { var _a, _b, _c, _d; const startFlag = list.querySelector("#actionListAheadAnchor"); const endFlag = list.querySelector("#actionListBehindAnchor"); if (((_a = startFlag == null ? void 0 : startFlag.style) == null ? void 0 : _a.display) === "none" && ((_b = endFlag == null ? void 0 : endFlag.style) == null ? void 0 : _b.display) === "none" || MAX_COUNT > -1 && count >= MAX_COUNT) { clearInterval(timerId); timerId = null; const single = ".singlep-list-item-inner"; const multip = ".multip-list-item-inner .multip-list-item"; eplist = list.querySelectorAll(`${single}, ${multip}`); if (eplist && eplist.length > 0) { for (const item of eplist) { if (item.classList.contains("siglep-active") || item.classList.contains("multip-list-item-active")) { setTimeout(() => { var _a2, _b2; list.scrollTo({ top: item.offsetTop, behavior: "smooth" }); _hideLoading( ((_a2 = startFlag == null ? void 0 : startFlag.style) == null ? void 0 : _a2.display) === "none" && ((_b2 = endFlag == null ? void 0 : endFlag.style) == null ? void 0 : _b2.display) === "none" ); }, 10); return; } } } } if (((_c = endFlag == null ? void 0 : endFlag.style) == null ? void 0 : _c.display) === "") { list.scrollTop += list.scrollHeight; } else if (((_d = startFlag == null ? void 0 : startFlag.style) == null ? void 0 : _d.display) === "") { list.scroll(null, 0); } count++; }, random(300, 600)); }; const _renderMore = () => { if (more) return; more = document.createElement("div"); more.classList.add("custom-more"); more.style.marginLeft = origin.clientWidth + 10 + "px"; origin.parentNode.insertBefore(more, origin); vue.createApp({ render: () => vue.h(_sfc_main$b, { disabled: disabledRef.value, message: messageRef.value, onClick: (key) => { _loadElement(key === -1 ? -1 : key * 10); } }) }).use(Antd).mount(more); }; const _render = () => { _renderLoading(); _renderMore(); }; _render(); _loadElement(); next = () => { if (!eplist || eplist.length <= 0) return; const target = eplist[random(0, eplist.length - 1)]; if (!target) return; if (target.classList.contains("multip-list-item")) { target.parentElement.style.display = ""; } target.click(); setTimeout(() => { list.scrollTo({ top: target.offsetTop, behavior: "smooth" }); }, random(10, 200)); }; }; const initNext = async () => { if (currPage === "video") { initVideoPageNext(); } else if (currPage === "list") { initListPageNext(); } }; const handler = () => { next && next(); }; const buttonHandler = (event) => { event.preventDefault(); event.stopPropagation(); handler(); }; const observer = new MutationObserver((mutations) => { for (const item of mutations) { if (item.target.classList.contains("bpx-player-control-bottom-left")) { if (item.addedNodes.length > 0) { const button = item.addedNodes[0]; if (button.classList.contains("bpx-player-ctrl-next")) { button.addEventListener("click", buttonHandler); } } } } }); const keydownHandler = (event) => { if (event.key === "]") { event.preventDefault(); handler(); } }; const bluetoothHandler = () => { handler(); }; const install = async () => { var _a, _b; video = document.querySelector("#bilibili-player video"); if (!video) return; initNext(); video == null ? void 0 : video.addEventListener("ended", handler); observer.observe(document.body, { childList: true, subtree: true }); (_a = document.querySelector(".bpx-player-ctrl-next")) == null ? void 0 : _a.addEventListener("click", buttonHandler); document.addEventListener("keydown", keydownHandler); if (!((_b = navigator.mediaSession) == null ? void 0 : _b.setActionHandler)) return; originalBluetoothHandler = navigator.mediaSession.setActionHandler; navigator.mediaSession.setActionHandler = function($0, $1) { if ($0 === "nexttrack" && $1 !== bluetoothHandler) $1 = bluetoothHandler; originalBluetoothHandler.call(this, $0, $1); }; navigator.mediaSession.setActionHandler("nexttrack", bluetoothHandler); }; const uninstall = () => { var _a, _b; if (((_a = navigator.mediaSession) == null ? void 0 : _a.setActionHandler) && originalBluetoothHandler) { navigator.mediaSession.setActionHandler = originalBluetoothHandler; originalBluetoothHandler = null; navigator.mediaSession.setActionHandler("nexttrack", () => player == null ? void 0 : player.next()); } document.removeEventListener("keydown", keydownHandler); (_b = document.querySelector(".bpx-player-ctrl-next")) == null ? void 0 : _b.removeEventListener("click", buttonHandler); observer.disconnect(); video == null ? void 0 : video.removeEventListener("ended", handler); next = null; more && more.parentNode.removeChild(more) && (more = null); loading && loading.parentNode.removeChild(loading) && (loading = null); video = null; }; const toggle = () => { if (config$2.base.isActive) { install(); console.log("开启列表随机播放功能"); } else { uninstall(); console.log("关闭列表随机播放功能"); } }; const init$3 = () => { toggle(); console.log("初始化列表随机播放功能完成"); }; const reset$2 = () => { toggle(); console.log("重置列表随机播放功能完成"); }; const click = () => { config$2.base.isActive = !config$2.base.isActive; toggle(); controller$1.useChangeHandler(); console.log("切换列表随机播放功能完成"); }; const plugin = new Plugin({ name: "列表随机播放", description: "一键开启分p/合集视频的列表随机播放功能,当前页面状态切换不影响其他页面", icon: CustomerServiceOutlined, type: "persistent", $init: init$3, $reset: reset$2, $click: click }); const _sfc_main$a = { __name: "Option", setup(__props) { const handleChange = (_2, e) => { e.preventDefault(); click(); }; return (_ctx, _cache) => { const _component_a_col = vue.resolveComponent("a-col"); const _component_a_switch = vue.resolveComponent("a-switch"); const _component_a_row = vue.resolveComponent("a-row"); return vue.openBlock(), vue.createBlock(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { span: 18, style: { "color": "#a9a9a9" } }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(vue.unref(plugin).description), 1) ]), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_switch, { checked: vue.unref(config$2).base.isActive, onChange: handleChange }, null, 8, ["checked"]) ]), _: 1 }) ]), _: 1 }); }; } }; const index = { self: plugin, config: controller$1, Option: _sfc_main$a }; const __vite_glob_0_2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, default: index }, Symbol.toStringTag, { value: "Module" })); const plugins = []; const modules = /* @__PURE__ */ Object.assign({ "./fav/index.js": __vite_glob_0_0, "./note/index.js": __vite_glob_0_1, "./pod/index.js": __vite_glob_0_2 }); Object.keys(modules).forEach((path) => { const plugin2 = modules[path].default; plugin2.id = path.split("/")[1]; plugin2.path = path; plugins.push(plugin2); }); plugins.sort((a, b) => { var _a; return (_a = a.id) == null ? void 0 : _a.localeCompare(b.id); }); console.log("插件注册完成"); const _hoisted_1 = { class: "items" }; const _hoisted_2 = ["onDragstart", "onDragenter"]; const _hoisted_3 = { key: 1 }; const _sfc_main$9 = { __name: "DraggableList", props: { list: { type: Array, required: true, default: [] } }, emits: ["change"], setup(__props, { emit: __emit }) { const props = __props; const emits = __emit; let dragIndex = 0; const dragstart = (e, index2) => { e.stopPropagation(); setTimeout(() => { e.target.classList.add("moving"); }, 0); dragIndex = index2; }; const dragover = (e) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; }; const dragenter = (e, index2) => { e.preventDefault(); if (dragIndex !== index2) { const source = props.list[dragIndex]; props.list.splice(dragIndex, 1); props.list.splice(index2, 0, source); dragIndex = index2; } }; const dragend = (e) => { e.target.classList.remove("moving"); emits("change", props.list); }; return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("ul", _hoisted_1, [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(props.list, (item, index2) => { return vue.openBlock(), vue.createElementBlock("li", { key: item.id, draggable: true, onDragstart: ($event) => dragstart($event, index2), onDragover: dragover, onDragenter: ($event) => dragenter($event, index2), onDragend: dragend, class: "item" }, [ _ctx.$slots.item ? vue.renderSlot(_ctx.$slots, "item", vue.mergeProps({ key: 0, ref_for: true }, { ...item, index: index2 }), void 0, true) : (vue.openBlock(), vue.createElementBlock("span", _hoisted_3, vue.toDisplayString(item.text), 1)) ], 40, _hoisted_2); }), 128)) ]); }; } }; const DraggableList = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-1d7c71a3"]]); class PluginVO { constructor({ id, name, icon, type, isActive, $click }) { this.id = id; this.name = name; this.icon = icon; this.type = type; this.isActive = isActive; this.$click = $click; } } const request = async (method, webhook, token, data2, execute, error) => { if (!method || !webhook || !token) { throw new Error("invaild method or webhook or token"); } return _GM.xmlHttpRequest({ method, url: webhook, headers: { "Content-Type": "application/json", "AirScript-Token": token }, data: data2, anonymous: true, onerror: (response) => { console.error("请求发生错误:", response.status, response.statusText); error && error("请求发生错误:" + response.status); return response.status; }, onload: (response) => { if (response.status === 200) { const text = JSON.parse(response.responseText); execute && execute(text.data); return text.data; } let message = null; if (response.status === 404) { message = "webhook有误,请仔细检查是否填写正确"; } else if (response.status === 403) { const text = JSON.parse(response.responseText); if (text.result === "ApiTokenNotExists") { message = "脚本令牌有误,请检查令牌是否过期或填写有误"; } else if (text.result === "lightLinkNotExist") { message = "webhook不存在,请重新复制并填写"; } else if (text.result === "ScriptNotExists") { message = "脚本不存在,请先创建脚本"; } else { message = "webhook有误,请仔细检查是否填写正确"; } } else { message = response.statusText; } error && error(message); return message; } }); }; class Request2 { constructor(webhook, token) { this.webhook = webhook; this.token = token; } validate(execute, error) { const data2 = JSON.stringify({ Context: { argv: null } }); return request("POST", this.webhook, this.token, data2, execute, error); } get(params = {}, execute, error) { const keys = Object.keys(params).sort(); const query = keys.map((k) => `${k}=${encodeURIComponent(params[k])}`).join("&"); if (query) this.webhook = `${this.webhook}?${query}`; return request("GET", this.webhook, this.token, null, execute, error); } post(url, params = {}, execute, error) { if (!url || url.split("/").length < 2) { throw new Error("invaild url"); } const lastIndex = url.lastIndexOf("/"); const body = { target: url.substring(0, lastIndex), action: url.substring(lastIndex + 1), params }; const data2 = JSON.stringify({ Context: { argv: body } }); return request("POST", this.webhook, this.token, data2, execute, error); } } const backup$1 = (request2, config2, execute, error) => { return request2 && request2.post("base/backup", { config: config2 }, execute, error); }; const task$1 = (request2, task_id, execute, error) => { return request2 && request2.get({ task_id }, execute, error); }; const restore$1 = (request2, execute, error) => { return request2 && request2.post("base/restore", null, execute, error); }; const baseConfig = new BaseConfig({ general: { shortcutMaxShow: 1, shortcutShowMode: "hover", shortcuts: [] }, syncAndBackup: { wps: { isActive: false, airScript: { token: "", webhook: "", isValid: false }, sync: { enabled: false }, backup: { autoBackupInterval: 0, lastBackupTime: 0, lastRestoreTime: 0 } } } }); const configRef = new ConfigRef(baseConfig); const config$1 = configRef._self(); const controller = configRef.getController(); const KEY = `${"Bilibili-Memo"}:AUTO_BACKUP_LOCK`; let timer = null; const _$1 = await (async () => { const info2 = await _GM.info; if (info2.scriptHandler === "Tampermonkey") { return async (execute) => { const tab = await _GM.getTab(); if (!tab.id) return; const tabs = await _GM.getTabs(); if (tab.id !== Object.keys(tabs)[0]) return; execute && execute(); }; } else { return async (execute) => { const lock = await _GM.getValue(KEY); if (!lock || JSON.parse(lock) + 5 * 60 * 1e3 < Date.now()) { await _GM.setValue(KEY, Date.now()); } execute && execute(); await _GM.deleteValue(KEY); }; } })(); const removeTimer = () => { timer && clearInterval(timer); }; const setTimer = (interval, execute) => { removeTimer(); if (interval > 0) { timer = setInterval(() => { _$1 && _$1(execute); }, interval * 0.25 * 60 * 1e3); _$1 && _$1(execute); } }; class ConfigOutput { constructor() { this.base = controller.getValue(); this.plugins = plugins.reduce((acc, curr) => { return { ...acc, [curr.id]: curr.config.getValue() }; }, {}); } } const reload = (data2) => { const baseConfig2 = data2.base; if (baseConfig2) { controller.setValue(baseConfig2); controller.useChangeHandler(); } if (data2.plugins && Object.keys(data2.plugins).length > 0) { plugins.forEach((item) => { const pluginConfig2 = data2.plugins[item.id]; if (pluginConfig2) { item.config.setValue(pluginConfig2); item.config.useChangeHandler(); if (item.self.type === "persistent") item.self.$reset(); } }); } if (data2.base || data2.plugins) nav.self.$init(); }; const download = (success) => { const _download = (data2, filename) => { const blob = new Blob([JSON.stringify(data2)], { type: "application/json" }); const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = filename; a.click(); a.remove(); URL.revokeObjectURL(a.href); }; _download(new ConfigOutput(), "config.json"); messageModal({ title: "信息", message: "处理中……下载完成后请手动关闭弹窗!" }); success && success(); }; const upload = (success) => { const _upload = (execute) => { const input = document.createElement("input"); input.type = "file"; input.accept = ".json"; input.addEventListener("change", (event) => { const file = event.target.files[0]; if (!file) return; if (file.type !== "application/json") { messageModal({ title: "提示", message: "文件格式有误,请选择 .json 后缀格式的文件", type: "warning" }); return; } const reader = new FileReader(); reader.onload = (e) => { execute && execute(e.target.result); }; reader.onerror = (e) => { console.error("文件读取出错:", e.target.error); messageModal({ title: "错误", message: "文件读取出错", type: "error" }); }; reader.readAsText(file); }); input.click(); input.remove(); }; _upload((result) => { const data2 = JSON.parse(result); if (data2) { reload(data2); messageModal({ title: "成功", message: "配置导入完成", type: "success" }); } }); success && success(); }; const validate = (success, failure) => { if (!config$1.syncAndBackup.wps.isActive) return; const condition = "https://www.kdocs.cn/api/v3/ide/"; if (!config$1.syncAndBackup.wps.airScript.webhook.startsWith(condition)) { messageModal({ title: "提示", message: "webhook有误,请仔细检查是否填写正确", type: "warning" }); failure && failure(); return; } const request2 = new Request2( config$1.syncAndBackup.wps.airScript.webhook, config$1.syncAndBackup.wps.airScript.token ); request2.validate( (data2) => { if ((data2 == null ? void 0 : data2.result) && data2.result.isValid) { config$1.syncAndBackup.wps.airScript.isValid = true; controller.useChangeHandler(); } success && success(); }, (message) => { messageModal({ title: "提示", message, type: "warning" }); failure && failure(); } ); }; const backup = (success, failure) => { if (!config$1.syncAndBackup.wps.isActive) return; if (!config$1.syncAndBackup.wps.airScript.isValid) return; const request2 = new Request2( config$1.syncAndBackup.wps.airScript.webhook, config$1.syncAndBackup.wps.airScript.token ); backup$1( request2, new ConfigOutput(), (data2) => { const result = data2 == null ? void 0 : data2.result; if (result && result.lastBackupTime && result.lastBackupTime > 0) { config$1.syncAndBackup.wps.backup.lastBackupTime = result.lastBackupTime; controller.useChangeHandler(); messageModal({ title: "成功", message: "备份完成", type: "success" }); success && success(); } else { messageModal({ title: "提示", message: "稍后再试", type: "warning" }); failure && failure(); } }, (message) => { messageModal({ title: "提示", message, type: "warning" }); config$1.syncAndBackup.wps.airScript.isValid = false; controller.useChangeHandler(); failure && failure(); } ); }; const task = (task_id) => { if (!config$1.syncAndBackup.wps.isActive) return; if (!config$1.syncAndBackup.wps.airScript.isValid) return; if (!task_id) return; const request2 = new Request2( "https://www.kdocs.cn/api/v3/script/task", config$1.syncAndBackup.wps.airScript.token ); task$1(request2, task_id, (data2) => { const result = data2 == null ? void 0 : data2.result; if (result && result.lastBackupTime && result.lastBackupTime > 0) { config$1.syncAndBackup.wps.backup.lastBackupTime = result.lastBackupTime; controller.useChangeHandler(); } else { setTimeout(() => { task(task_id); }, 5e3); } }); }; const autoBackup = () => { if (!config$1.syncAndBackup.wps.isActive) return; if (!config$1.syncAndBackup.wps.airScript.isValid) return; const interval = config$1.syncAndBackup.wps.backup.autoBackupInterval; if (interval <= 0) return; const time = config$1.syncAndBackup.wps.backup.lastBackupTime + interval * 60 * 1e3; if (time > Date.now()) return; const request2 = new Request2( config$1.syncAndBackup.wps.airScript.webhook.replace("sync_task", "task"), config$1.syncAndBackup.wps.airScript.token ); backup$1( request2, new ConfigOutput(), (data2) => { task(data2 == null ? void 0 : data2.task_id); }, () => { config$1.syncAndBackup.wps.airScript.isValid = false; controller.useChangeHandler(); } ); }; const restore = (success, failure) => { if (!config$1.syncAndBackup.wps.isActive) return; if (!config$1.syncAndBackup.wps.airScript.isValid) return; const request2 = new Request2( config$1.syncAndBackup.wps.airScript.webhook, config$1.syncAndBackup.wps.airScript.token ); restore$1( request2, (data2) => { if (data2 == null ? void 0 : data2.result) reload(data2 == null ? void 0 : data2.result); messageModal({ title: "成功", message: "恢复完成", type: "success" }); success && success(); }, (message) => { messageModal({ title: "提示", message, type: "warning" }); config$1.syncAndBackup.wps.airScript.isValid = false; controller.useChangeHandler(); failure && failure(); } ); }; const init$2 = () => { setTimer(config$1.syncAndBackup.wps.backup.autoBackupInterval, autoBackup); }; const reset$1 = () => { removeTimer(); setTimer(config$1.syncAndBackup.wps.backup.autoBackupInterval, autoBackup); }; const menu = { self: { $init: init$2, $reset: reset$1 }, config: controller }; const config = vue.ref({ pluginVOs: [] }).value; const _ = vue.ref([]); const pluginToPluginVO = (item) => { return new PluginVO({ id: item.id, name: item.self.name, icon: item.self.icon, type: item.self.type, isActive: item.config.getValue().base.isActive, $click: item.self.$click }); }; const reset = () => { config.pluginVOs = []; menu.config.getValue().general.shortcuts.forEach((shortcut) => { const pluginVO = _.value.find((item) => item.id === shortcut.id && shortcut.isShow); if (pluginVO) config.pluginVOs.push(pluginVO); }); }; const init$1 = () => { _.value = plugins.map((item) => pluginToPluginVO(item)); reset(); }; const switchActive = (pluginId, isActive) => { const pluginVO = _.value.find((item) => item.id === pluginId); if (!pluginVO) return; pluginVO.isActive = isActive; }; const nav = { self: { $init: init$1, $reset: reset, $switchActive: switchActive } }; const _sfc_main$8 = { __name: "OptionGeneral", props: { container: { type: Object, required: true, default: document.body } }, setup(__props) { const handleChangeSort = (newShortcuts) => { config$1.general.shortcuts = newShortcuts; handleChangeShow(); }; const handleChangeShow = () => { nav.self.$reset(); handleChange(); }; const handleChange = () => { controller.useChangeHandler(); }; return (_ctx, _cache) => { const _component_a_tooltip = vue.resolveComponent("a-tooltip"); const _component_a_col = vue.resolveComponent("a-col"); const _component_a_select_option = vue.resolveComponent("a-select-option"); const _component_a_select = vue.resolveComponent("a-select"); const _component_a_row = vue.resolveComponent("a-row"); const _component_a_divider = vue.resolveComponent("a-divider"); const _component_a_switch = vue.resolveComponent("a-switch"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => [ _cache[2] || (_cache[2] = vue.createTextVNode(" 快捷方式栏最大显示数量 ")), vue.createVNode(_component_a_tooltip, { getPopupContainer: () => __props.container, title: "大于该数量将收起为一个按钮" }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(ExclamationCircleOutlined), { style: { "color": "rgba(0, 0, 0, 0.45)" } }) ]), _: 1 }, 8, ["getPopupContainer"]) ]), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select, { getPopupContainer: () => __props.container, value: vue.unref(config$1).general.shortcutMaxShow, "onUpdate:value": _cache[0] || (_cache[0] = ($event) => vue.unref(config$1).general.shortcutMaxShow = $event), onChange: handleChange, style: { "width": "60px" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select_option, { value: 0 }, { default: vue.withCtx(() => _cache[3] || (_cache[3] = [ vue.createTextVNode("0") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: 1 }, { default: vue.withCtx(() => _cache[4] || (_cache[4] = [ vue.createTextVNode("1") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: 2 }, { default: vue.withCtx(() => _cache[5] || (_cache[5] = [ vue.createTextVNode("2") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: 3 }, { default: vue.withCtx(() => _cache[6] || (_cache[6] = [ vue.createTextVNode("3") ])), _: 1 }) ]), _: 1 }, 8, ["getPopupContainer", "value"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => _cache[7] || (_cache[7] = [ vue.createTextVNode("快捷方式栏展开方式") ])), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select, { getPopupContainer: () => __props.container, value: vue.unref(config$1).general.shortcutShowMode, "onUpdate:value": _cache[1] || (_cache[1] = ($event) => vue.unref(config$1).general.shortcutShowMode = $event), onChange: handleChange, style: { "width": "70px" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select_option, { value: "hover" }, { default: vue.withCtx(() => _cache[8] || (_cache[8] = [ vue.createTextVNode("触碰") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: "click" }, { default: vue.withCtx(() => _cache[9] || (_cache[9] = [ vue.createTextVNode("点击") ])), _: 1 }) ]), _: 1 }, 8, ["getPopupContainer", "value"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_divider, { dashed: "", style: { "border-color": "gray" } }, { default: vue.withCtx(() => _cache[10] || (_cache[10] = [ vue.createTextVNode(" 拖住排序(快捷方式的显示/隐藏不影响功能的开启/关闭) ") ])), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(DraggableList, { list: vue.unref(config$1).general.shortcuts, onChange: handleChangeSort }, { item: vue.withCtx(({ id, name, index: index2 }) => [ vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => { var _a; return [ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent((_a = vue.unref(plugins).find((item) => item.id === id)) == null ? void 0 : _a.self.icon))), vue.createTextVNode(" " + vue.toDisplayString(name), 1) ]; }), _: 2 }, 1024), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_switch, { checked: vue.unref(config$1).general.shortcuts[index2].isShow, "onUpdate:checked": ($event) => vue.unref(config$1).general.shortcuts[index2].isShow = $event, onChange: handleChangeShow }, null, 8, ["checked", "onUpdate:checked"]) ]), _: 2 }, 1024) ]), _: 2 }, 1024) ]), _: 1 }, 8, ["list"]) ]), _: 1 }) ], 64); }; } }; const _sfc_main$7 = { __name: "OptionWPS", props: { container: { type: Object, required: true, default: document.body } }, setup(__props) { const state = vue.ref({ token: "", webhook: "", vaild: false, backup: false, restore: false }); const handleChangeToken = (e) => { if (e.target.value) state.value.token = ""; }; const handleChangeWebhook = (e) => { if (e.target.value) state.value.webhook = ""; }; const handleValidate = () => { const token = config$1.syncAndBackup.wps.airScript.token; const webhook = config$1.syncAndBackup.wps.airScript.webhook; if (!token || !webhook) { if (!token) state.value.token = "error"; if (!webhook) state.value.webhook = "error"; return; } state.value.vaild = true; validate( () => { state.value.vaild = false; }, () => { state.value.vaild = false; } ); }; const handleBackup = () => { state.value.backup = true; backup( () => { state.value.backup = false; }, () => { state.value.backup = false; } ); }; const handleRestore = () => { state.value.restore = true; restore( () => { state.value.restore = false; }, () => { state.value.restore = false; } ); }; const handleChangeAutoBackupInterval = () => { controller.useChangeHandler(); setTimer(config$1.syncAndBackup.wps.backup.autoBackupInterval, autoBackup); }; return (_ctx, _cache) => { const _component_a_col = vue.resolveComponent("a-col"); const _component_a_input = vue.resolveComponent("a-input"); const _component_a_row = vue.resolveComponent("a-row"); const _component_a_button = vue.resolveComponent("a-button"); const _component_a_select_option = vue.resolveComponent("a-select-option"); const _component_a_select = vue.resolveComponent("a-select"); const _component_a_tooltip = vue.resolveComponent("a-tooltip"); const _component_a_popconfirm = vue.resolveComponent("a-popconfirm"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => _cache[3] || (_cache[3] = [ vue.createTextVNode("脚本令牌") ])), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_input, { "allow-clear": "", status: state.value.token, value: vue.unref(config$1).syncAndBackup.wps.airScript.token, "onUpdate:value": _cache[0] || (_cache[0] = ($event) => vue.unref(config$1).syncAndBackup.wps.airScript.token = $event), onChange: handleChangeToken, style: { "width": "220px" } }, null, 8, ["status", "value"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => _cache[4] || (_cache[4] = [ vue.createTextVNode("脚本webhook") ])), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_input, { "allow-clear": "", status: state.value.webhook, value: vue.unref(config$1).syncAndBackup.wps.airScript.webhook, "onUpdate:value": _cache[1] || (_cache[1] = ($event) => vue.unref(config$1).syncAndBackup.wps.airScript.webhook = $event), onChange: handleChangeWebhook, style: { "width": "300px" } }, null, 8, ["status", "value"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_button, { type: "primary", loading: state.value.vaild, onClick: handleValidate }, { default: vue.withCtx(() => _cache[5] || (_cache[5] = [ vue.createTextVNode(" 验证 ") ])), _: 1 }, 8, ["loading"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => [ _cache[12] || (_cache[12] = vue.createTextVNode(" 间隔 ")), vue.createVNode(_component_a_select, { getPopupContainer: () => __props.container, disabled: !vue.unref(config$1).syncAndBackup.wps.airScript.isValid, value: vue.unref(config$1).syncAndBackup.wps.backup.autoBackupInterval, "onUpdate:value": _cache[2] || (_cache[2] = ($event) => vue.unref(config$1).syncAndBackup.wps.backup.autoBackupInterval = $event), onChange: handleChangeAutoBackupInterval }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_select_option, { value: 0 }, { default: vue.withCtx(() => _cache[6] || (_cache[6] = [ vue.createTextVNode("0") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: 5 }, { default: vue.withCtx(() => _cache[7] || (_cache[7] = [ vue.createTextVNode("5") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: 10 }, { default: vue.withCtx(() => _cache[8] || (_cache[8] = [ vue.createTextVNode("10") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: 15 }, { default: vue.withCtx(() => _cache[9] || (_cache[9] = [ vue.createTextVNode("15") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: 30 }, { default: vue.withCtx(() => _cache[10] || (_cache[10] = [ vue.createTextVNode("30") ])), _: 1 }), vue.createVNode(_component_a_select_option, { value: 60 }, { default: vue.withCtx(() => _cache[11] || (_cache[11] = [ vue.createTextVNode("60") ])), _: 1 }) ]), _: 1 }, 8, ["getPopupContainer", "disabled", "value"]), _cache[13] || (_cache[13] = vue.createTextVNode(" 分钟自动备份 ")), vue.createVNode(_component_a_tooltip, { getPopupContainer: () => __props.container, title: "间隔0分钟表示不开启自动备份" }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(ExclamationCircleOutlined), { style: { "color": "rgba(0, 0, 0, 0.45)" } }) ]), _: 1 }, 8, ["getPopupContainer"]) ]), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_button, { disabled: !vue.unref(config$1).syncAndBackup.wps.airScript.isValid, loading: state.value.backup, onClick: handleBackup, style: { "margin-right": "5px" } }, { default: vue.withCtx(() => _cache[14] || (_cache[14] = [ vue.createTextVNode(" 备份至云端 ") ])), _: 1 }, 8, ["disabled", "loading"]), vue.createVNode(_component_a_popconfirm, { getPopupContainer: () => __props.container, disabled: !vue.unref(config$1).syncAndBackup.wps.airScript.isValid, title: "该操作会覆盖掉当前全部数据,确定吗?", "ok-text": "确定", "cancel-text": "取消", onConfirm: handleRestore, overlayInnerStyle: { width: "300px" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_button, { disabled: !vue.unref(config$1).syncAndBackup.wps.airScript.isValid, loading: state.value.restore, danger: "", style: { "margin-left": "5px" } }, { default: vue.withCtx(() => _cache[15] || (_cache[15] = [ vue.createTextVNode(" 从云端恢复 ") ])), _: 1 }, 8, ["disabled", "loading"]) ]), _: 1 }, 8, ["getPopupContainer", "disabled"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label backup-time" }, { default: vue.withCtx(() => [ vue.createTextVNode(" 上一次备份时间: " + vue.toDisplayString(vue.unref(config$1).syncAndBackup.wps.backup.lastBackupTime ? vue.unref(dateUtil).timestampToDate[1](vue.unref(config$1).syncAndBackup.wps.backup.lastBackupTime) : "无备份历史"), 1) ]), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content restore-time" }, { default: vue.withCtx(() => [ vue.createTextVNode(" 上一次恢复时间: " + vue.toDisplayString(vue.unref(config$1).syncAndBackup.wps.backup.lastRestoreTime ? vue.unref(dateUtil).timestampToDate[1](vue.unref(config$1).syncAndBackup.wps.backup.lastRestoreTime) : "无恢复历史"), 1) ]), _: 1 }) ]), _: 1 }) ], 64); }; } }; const OptionWPS = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-c47228de"]]); const LOADING_TIME = 2e3; const _sfc_main$6 = { __name: "OptionSyncAndBackup", props: { container: { type: Object, required: true, default: document.body } }, setup(__props) { const state = vue.ref({ exp: false, imp: false }); const visible = vue.ref(false); const handleExport = () => { state.value.exp = true; download(() => { setTimeout(() => { state.value.exp = false; }, LOADING_TIME); }); }; const handleImport = () => { state.value.imp = true; upload(() => { setTimeout(() => { state.value.imp = false; }, LOADING_TIME); }); }; const handleChangeActive = (checked, event) => { if (checked) { event.preventDefault(); visible.value = true; return; } config$1.syncAndBackup.wps.isActive = false; controller.useChangeHandler(); }; const handleConfirm = () => { visible.value = false; config$1.syncAndBackup.wps.isActive = true; controller.useChangeHandler(); }; const handleCancel = () => { visible.value = false; }; return (_ctx, _cache) => { const _component_a_col = vue.resolveComponent("a-col"); const _component_a_button = vue.resolveComponent("a-button"); const _component_a_popconfirm = vue.resolveComponent("a-popconfirm"); const _component_a_row = vue.resolveComponent("a-row"); const _component_a_tooltip = vue.resolveComponent("a-tooltip"); const _component_a_switch = vue.resolveComponent("a-switch"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => _cache[0] || (_cache[0] = [ vue.createTextVNode("下载插件数据到本地") ])), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_button, { loading: state.value.exp, onClick: handleExport }, { default: vue.withCtx(() => _cache[1] || (_cache[1] = [ vue.createTextVNode("导出") ])), _: 1 }, 8, ["loading"]), vue.createVNode(_component_a_popconfirm, { getPopupContainer: () => __props.container, title: "该操作会覆盖掉当前全部数据,确定吗?", "ok-text": "确定", "cancel-text": "取消", onConfirm: handleImport, overlayInnerStyle: { width: "300px" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_button, { danger: "", loading: state.value.imp, style: { "margin-left": "10px" } }, { default: vue.withCtx(() => _cache[2] || (_cache[2] = [ vue.createTextVNode("导入") ])), _: 1 }, 8, ["loading"]) ]), _: 1 }, 8, ["getPopupContainer"]) ]), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { justify: "space-between", class: "custom-row" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_col, { class: "custom-col-label" }, { default: vue.withCtx(() => [ _cache[3] || (_cache[3] = vue.createTextVNode(" 备份插件数据到WPS ")), vue.createVNode(_component_a_tooltip, { getPopupContainer: () => __props.container, title: "该功能依赖网络连接及第三方软件(金山文档WPS)接口的稳定性" }, { default: vue.withCtx(() => [ vue.createVNode(vue.unref(ExclamationCircleOutlined), { style: { "color": "rgba(0, 0, 0, 0.45)" } }) ]), _: 1 }, 8, ["getPopupContainer"]) ]), _: 1 }), vue.createVNode(_component_a_col, { class: "custom-col-content" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_popconfirm, { getPopupContainer: () => __props.container, open: visible.value, title: "该功能将会使插件数据传输至第三方软件(金山文档WPS),传输只会在本插件及您指定的WPS账号的指定文档之间进行,确定开启吗?", "ok-text": "确定", "cancel-text": "取消", onConfirm: handleConfirm, onCancel: handleCancel, overlayInnerStyle: { width: "300px" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_switch, { checked: vue.unref(config$1).syncAndBackup.wps.isActive, onChange: handleChangeActive }, null, 8, ["checked"]) ]), _: 1 }, 8, ["getPopupContainer", "open"]) ]), _: 1 }) ]), _: 1 }), vue.unref(config$1).syncAndBackup.wps.isActive ? (vue.openBlock(), vue.createBlock(OptionWPS, { key: 0, container: __props.container }, null, 8, ["container"])) : vue.createCommentVNode("", true) ], 64); }; } }; const _sfc_main$5 = { __name: "Option", setup(__props) { const settings = [ { id: "general", self: { name: "通用" }, Option: _sfc_main$8 }, { id: "syncAndBackup", self: { name: "同步&备份" }, Option: _sfc_main$6 } ]; const anchorItems = settings.concat(plugins).map((item) => { return { key: item.id, href: "#" + item.id, title: item.self.name }; }); const contentItems = settings.concat(plugins).map((item) => { return { id: item.id, name: item.self.name, option: item.Option }; }); const activeKey = vue.ref(settings[0].id); const container = vue.ref(); const handleClickAnchor = (e, link) => { e.preventDefault(); activeKey.value = link.href.substring(1); }; vue.onMounted(() => { container.value = document.querySelector(".custom-layout-conten"); }); return (_ctx, _cache) => { const _component_a_anchor = vue.resolveComponent("a-anchor"); const _component_a_layout_sider = vue.resolveComponent("a-layout-sider"); const _component_a_divider = vue.resolveComponent("a-divider"); const _component_a_collapse_panel = vue.resolveComponent("a-collapse-panel"); const _component_a_collapse = vue.resolveComponent("a-collapse"); const _component_a_layout_content = vue.resolveComponent("a-layout-content"); const _component_a_layout = vue.resolveComponent("a-layout"); return vue.openBlock(), vue.createBlock(_component_a_layout, { class: "custom-layout" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_layout_sider, { theme: "light", width: "auto", class: "custom-layout-sider" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_anchor, { getContainer: () => container.value, items: vue.unref(anchorItems), affix: false, onClick: handleClickAnchor }, null, 8, ["getContainer", "items"]) ]), _: 1 }), vue.createVNode(_component_a_divider, { type: "vertical", style: { "height": "auto" } }), vue.createVNode(_component_a_layout_content, { width: "auto", class: "custom-layout-conten" }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_collapse, { activeKey: activeKey.value, "onUpdate:activeKey": _cache[0] || (_cache[0] = ($event) => activeKey.value = $event), ghost: "", accordion: "", class: "custom-collapse" }, { default: vue.withCtx(() => [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(contentItems), (item) => { return vue.openBlock(), vue.createBlock(_component_a_collapse_panel, { key: item.id }, { header: vue.withCtx(() => [ vue.createVNode(_component_a_divider, { id: item.id, orientation: "left", orientationMargin: "0px", class: "custom-divider" }, { default: vue.withCtx(() => [ vue.createTextVNode(vue.toDisplayString(item.name), 1) ]), _: 2 }, 1032, ["id"]) ]), default: vue.withCtx(() => [ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(item.option), { container: container.value }, null, 8, ["container"])) ]), _: 2 }, 1024); }), 128)) ]), _: 1 }, 8, ["activeKey"]) ]), _: 1 }) ]), _: 1 }); }; } }; const Option = /* @__PURE__ */ _export_sfc(_sfc_main$5, [["__scopeId", "data-v-69aa2ebc"]]); const _sfc_main$4 = { __name: "Button", setup(__props) { const showModal = () => { templateModal({ title: "设置", template: Option }); }; return (_ctx, _cache) => { const _component_a_float_button = vue.resolveComponent("a-float-button"); return vue.openBlock(), vue.createBlock(_component_a_float_button, vue.mergeProps(_ctx.$attrs, { onClick: showModal }), { icon: vue.withCtx(() => [ vue.createVNode(vue.unref(SettingOutlined)) ]), _: 1 }, 16); }; } }; const _sfc_main$3 = { __name: "Button", setup(__props) { const handleTrigger = () => { const baseConfig2 = menu.config.getValue(); const max = baseConfig2.general.shortcutMaxShow; const mode = baseConfig2.general.shortcutShowMode; return config.pluginVOs.length > max ? mode : ""; }; const handleType = (item) => { if (item.type === "immediate") return "default"; return item.isActive ? "primary" : "default"; }; return (_ctx, _cache) => { const _component_a_float_button = vue.resolveComponent("a-float-button"); const _component_a_float_button_group = vue.resolveComponent("a-float-button-group"); return vue.openBlock(), vue.createBlock(_component_a_float_button_group, { trigger: handleTrigger() }, { icon: vue.withCtx(() => [ vue.createVNode(vue.unref(BarsOutlined)) ]), default: vue.withCtx(() => [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(config).pluginVOs, (item) => { return vue.openBlock(), vue.createBlock(_component_a_float_button, { key: item.id, tooltip: item.name, type: handleType(item), onClick: item.$click }, { icon: vue.withCtx(() => [ (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(item.icon))) ]), _: 2 }, 1032, ["tooltip", "type", "onClick"]); }), 128)) ]), _: 1 }, 8, ["trigger"]); }; } }; const _sfc_main$2 = { __name: "Toolbar", setup(__props) { return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createVNode(_sfc_main$3, vue.mergeProps(_ctx.$attrs, { style: { "left": "24px", "bottom": "80px" } }), null, 16), vue.createVNode(_sfc_main$4, vue.mergeProps(_ctx.$attrs, { style: { "left": "24px", "bottom": "24px" } }), null, 16) ], 64); }; } }; const _sfc_main$1 = { __name: "Agreement", setup(__props) { const projectName = "Bilibili-Memo"; const state = vue.ref({ agree: false }); const handleAgree = () => { state.value.agree = true; setTimeout(() => { storageUtil.setAgreement(true); }, 100); }; return (_ctx, _cache) => { const _component_a_typography_title = vue.resolveComponent("a-typography-title"); const _component_a_typography_paragraph = vue.resolveComponent("a-typography-paragraph"); const _component_a_typography = vue.resolveComponent("a-typography"); const _component_a_button = vue.resolveComponent("a-button"); const _component_a_row = vue.resolveComponent("a-row"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createVNode(_component_a_typography, null, { default: vue.withCtx(() => [ vue.createVNode(_component_a_typography_title, { level: 5 }, { default: vue.withCtx(() => _cache[0] || (_cache[0] = [ vue.createTextVNode(" 欢迎使用本插件!请务必知悉以下事项: ") ])), _: 1 }), vue.createVNode(_component_a_typography_paragraph, null, { default: vue.withCtx(() => [ vue.createElementVNode("ul", null, [ vue.createElementVNode("li", null, " 本插件完全免费开源,代码公开透明(https://github.com/Jayvin-Leung/" + vue.toDisplayString(vue.unref(projectName)) + ") ", 1), _cache[1] || (_cache[1] = vue.createElementVNode("li", null, "本插件不涉及修改您的B站用户数据(以下称“B站数据”)", -1)), _cache[2] || (_cache[2] = vue.createElementVNode("li", null, "使用本插件时产生的数据(以下称“插件数据”)都会保存在浏览器本地", -1)), _cache[3] || (_cache[3] = vue.createElementVNode("li", null, "本插件不会收集您的B站数据和插件数据", -1)), _cache[4] || (_cache[4] = vue.createElementVNode("li", null, " 受技术和能力所限,本插件可能存在未测试到的bug,可能会导致部分插件数据异常,请定期导出到本地或备份到云端 ", -1)) ]) ]), _: 1 }), vue.createVNode(_component_a_typography_title, { level: 5 }, { default: vue.withCtx(() => _cache[5] || (_cache[5] = [ vue.createTextVNode("您需知悉:") ])), _: 1 }), vue.createVNode(_component_a_typography_paragraph, null, { default: vue.withCtx(() => _cache[6] || (_cache[6] = [ vue.createElementVNode("ul", null, [ vue.createElementVNode("li", null, "开发者无法为您因插件数据丢失或异常所导致的损失负责"), vue.createElementVNode("li", null, "使用即表示您愿意接受插件数据可能丢失或异常的风险") ], -1) ])), _: 1 }) ]), _: 1 }), vue.createVNode(_component_a_row, { style: { "justify-content": "center" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_a_button, { type: "primary", loading: state.value.agree, onClick: handleAgree }, { default: vue.withCtx(() => _cache[7] || (_cache[7] = [ vue.createTextVNode("确定") ])), _: 1 }, 8, ["loading"]) ]), _: 1 }) ], 64); }; } }; const Agreement = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-16c5d314"]]); const _sfc_main = { __name: "App", setup(__props) { const showModal = () => { templateModal({ title: "使用须知", template: Agreement }); }; return (_ctx, _cache) => { const _component_a_float_button = vue.resolveComponent("a-float-button"); return vue.unref(storageUtil).getAgreement() ? (vue.openBlock(), vue.createBlock(_sfc_main$2, { key: 0, style: { "z-index": "9999" } })) : (vue.openBlock(), vue.createBlock(_component_a_float_button, { key: 1, style: { "z-index": "9999", "left": "24px", "bottom": "24px" }, onClick: showModal }, { icon: vue.withCtx(() => [ vue.createVNode(vue.unref(SettingOutlined)) ]), _: 1 })); }; } }; const initPluginConfig = () => { plugins.forEach((item) => { const cache = storageUtil.getPluginConfig(item.id); if (!cache) { storageUtil.setPluginConfig(item.id, item.config.getValue()); } else { item.config.setValue(cache); } item.config.initChangeHandler((config2) => { storageUtil.setPluginConfig(item.id, config2); if (item.self.type === "persistent") { nav.self.$switchActive(item.id, config2.base.isActive); } }); item.self.$init(); }); }; const initBaseConfig = () => { const cache = storageUtil.getBaseConfig(); if (!cache) { const baseConfig2 = menu.config.getValue(); plugins.forEach((item) => { const shortcut = { id: item.id, name: item.self.name, isShow: true }; baseConfig2.general.shortcuts.push(shortcut); }); storageUtil.setBaseConfig(baseConfig2); } else { menu.config.setValue(cache); } menu.config.initChangeHandler((config2) => { storageUtil.setBaseConfig(config2); }); menu.self.$init(); }; const initListener = () => { let listeners = []; listeners.push( storageUtil.listenAgreement(({ newValue, oldValue }) => { if (JSON.stringify(oldValue) === JSON.stringify(newValue)) return; location.reload(); }) ); listeners.push( storageUtil.listenBaseConfig(({ newValue }) => { const oldValue = menu.config.getValue(); if (JSON.stringify(oldValue) === JSON.stringify(newValue)) return; menu.config.setValue(newValue); if (newValue.syncAndBackup.wps.backup.autoBackupInterval !== oldValue.syncAndBackup.wps.backup.autoBackupInterval) { menu.self.$reset(); } nav.self.$reset(); }) ); plugins.forEach((item) => { listeners.push( storageUtil.listenPluginConfig(item.id, ({ newValue }) => { const oldValue = item.config.getValue(); if (JSON.stringify(oldValue) === JSON.stringify(newValue)) return; if (oldValue.base.isOnlySwitchCurrActive) { newValue.base.isActive = oldValue.base.isActive; } item.config.setValue(newValue); if (item.self.type === "persistent" && newValue.base.isActive !== oldValue.base.isActive) { item.self.$reset(); nav.self.$switchActive(item.id, newValue.base.isActive); } }) ); }); return listeners; }; const init = () => { initPluginConfig(); initBaseConfig(); nav.self.$init(); initListener(); console.log("初始化完成"); }; const register = async () => { const info2 = await _GM.info; if (info2.scriptHandler === "Tampermonkey") { const tab = await _GM.getTab(); if (tab.id) return; const tabs = await _GM.getTabs(); tab.id = Object.keys(tabs).pop(); await _GM.saveTab(tab); } }; await( register()); init(); vue.createApp(_sfc_main).use(Antd).mount( (() => { const app = document.createElement("div"); document.body.append(app); return app; })() ); })(Vue, antd, fflate);