您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
为斗鱼(6657)发送弹幕提供便利畅快的输入体验与补全功能
// ==UserScript== // @name 斗鱼弹幕助手 // @namespace http://tampermonkey.net/ // @version 1.0.0 // @author ienone // @description 为斗鱼(6657)发送弹幕提供便利畅快的输入体验与补全功能 // @license MIT // @match *://www.douyu.com/* // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/system.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/extras/named-register.min.js // @require data:application/javascript,%3B(typeof%20System!%3D'undefined')%26%26(System%3Dnew%20System.constructor())%3B // @connect data.ienone.top // @connect localhost:* // @grant GM_addStyle // @grant GM_deleteValue // @grant GM_getValue // @grant GM_listValues // @grant GM_log // @grant GM_notification // @grant GM_setValue // @grant GM_xmlhttpRequest // @run-at document-start // ==/UserScript== System.register("./__entry.js", [], (function (exports, module) { 'use strict'; return { execute: (function () { const d=new Set;const importCSS = async e=>{d.has(e)||(d.add(e),(t=>{typeof GM_addStyle=="function"?GM_addStyle(t):document.head.appendChild(document.createElement("style")).append(t);})(e));}; var __defProp = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __pow = Math.pow; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; const CONFIG = { SCRIPT_PREFIX: "[斗鱼弹幕助手]", DB_NAME: "DouyuDanmukuAssistant", DB_VERSION: 2, DB_STORE_NAME: "danmuku_templates", SETTINGS_KEY_PREFIX: "dda_", CSS_CLASSES: { POPUP: "dda-popup", POPUP_SHOW: "show", POPUP_CONTENT: "dda-popup-content", POPUP_ITEM: "dda-popup-item", POPUP_ITEM_ACTIVE: "dda-popup-item-active", POPUP_ITEM_TEXT: "dda-popup-item-text", POPUP_EMPTY: "dda-popup-empty", EMPTY_MESSAGE: "dda-empty-message" }, KEYBOARD: { ENTER: "Enter", ESCAPE: "Escape", ARROW_UP: "ArrowUp", ARROW_DOWN: "ArrowDown", ARROW_LEFT: "ArrowLeft", ARROW_RIGHT: "ArrowRight", TAB: "Tab", BACKSPACE: "Backspace" }, API: { BASE_URL: "https://api.example.com", TIMEOUT: 5e3, RETRY_ATTEMPTS: 3 }, DEBUG: false, LOG_LEVEL: "info" }; const DEFAULT_SETTINGS = { minSearchLength: 1, maxSuggestions: 10, debounceDelay: 300, sortBy: "relevance", autoImportEnabled: false, autoImportMaxPages: 5, autoImportPageSize: 50, autoImportSortByPopularity: true, enterSelectionModeKey: "ArrowUp", exitSelectionModeKey: "ArrowDown", expandCandidatesKey: "ArrowUp", navigationLeftKey: "ArrowLeft", navigationRightKey: "ArrowRight", selectKey: "Enter", cancelKey: "Escape", popupShowDelay: 100, popupHideDelay: 200, animationDuration: 200, maxPopupHeight: 300, itemHeight: 40, maxCandidateWidth: 200, capsule: { maxWidth: 150, height: 24, padding: 16, margin: 16, totalHeight: 40, fontSize: 12, itemsPerRow: 4, singleRowMaxItems: 8, preview: { enabled: true, showDelay: 500, hideDelay: 100, maxWidth: 300, animationDuration: 200, keyboardShowDelay: 150, verticalOffset: 8, horizontalOffset: 0, preferredPosition: "top" } }, enableAutoComplete: true, enableKeyboardShortcuts: true, enableSelectionMode: true, enableSound: false, enableSync: false, syncInterval: 3e5, maxCacheSize: 1e3, cacheExpireTime: 864e5 }; const Utils = { log(message, level = "log") { const logMsg = `${CONFIG.SCRIPT_PREFIX} ${message}`; try { if (typeof GM_log !== "undefined") { GM_log(logMsg); } else { console[level](logMsg); } } catch (e) { console[level](logMsg); } }, sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); }, debounce(func, delay) { let timeoutId; return function(...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => func.apply(this, args), delay); }; }, throttle(func, delay) { let lastCall = 0; return function(...args) { const now = Date.now(); if (now - lastCall >= delay) { lastCall = now; return func.apply(this, args); } }; }, getCurrentRoomId() { const match = window.location.href.match( /douyu\.com\/(?:beta\/)?(?:topic\/[^?]+\?rid=|(\d+))/ ); return match ? match[1] || new URLSearchParams(window.location.search).get("rid") : null; }, isInLiveRoom() { const roomId = this.getCurrentRoomId(); return roomId !== null && document.querySelector("[data-v-5aa519d2]"); }, getElementPosition(element) { const rect = element.getBoundingClientRect(); return { x: rect.left + window.scrollX, y: rect.top + window.scrollY, width: rect.width, height: rect.height }; }, safeExecute(func, context = "unknown") { try { return func(); } catch (error) { this.log(`执行函数时出错 [${context}]: ${error.message}`, "error"); return null; } }, generateId(prefix = "dda") { return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; }, deepClone(obj) { if (obj === null || typeof obj !== "object") { return obj; } if (obj instanceof Date) { return new Date(obj.getTime()); } if (obj instanceof Array) { return obj.map((item) => this.deepClone(item)); } if (typeof obj === "object") { const cloned = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { cloned[key] = this.deepClone(obj[key]); } } return cloned; } } }; const scriptRel = (function detectScriptRel() { const relList = typeof document !== "undefined" && document.createElement("link").relList; return relList && relList.supports && relList.supports("modulepreload") ? "modulepreload" : "preload"; })(); const assetsURL = function(dep) { return "/" + dep; }; const seen = {}; const __vitePreload = function preload(baseModule, deps, importerUrl) { let promise = Promise.resolve(); if (deps && deps.length > 0) { let allSettled = function(promises$2) { return Promise.all(promises$2.map((p) => Promise.resolve(p).then((value$1) => ({ status: "fulfilled", value: value$1 }), (reason) => ({ status: "rejected", reason })))); }; document.getElementsByTagName("link"); const cspNonceMeta = document.querySelector("meta[property=csp-nonce]"); const cspNonce = (cspNonceMeta == null ? void 0 : cspNonceMeta.nonce) || (cspNonceMeta == null ? void 0 : cspNonceMeta.getAttribute("nonce")); promise = allSettled(deps.map((dep) => { dep = assetsURL(dep); if (dep in seen) return; seen[dep] = true; const isCss = dep.endsWith(".css"); const cssSelector = isCss ? '[rel="stylesheet"]' : ""; if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) return; const link = document.createElement("link"); link.rel = isCss ? "stylesheet" : scriptRel; if (!isCss) link.as = "script"; link.crossOrigin = ""; link.href = dep; if (cspNonce) link.setAttribute("nonce", cspNonce); document.head.appendChild(link); if (isCss) return new Promise((res, rej) => { link.addEventListener("load", res); link.addEventListener("error", () => rej( new Error(`Unable to preload CSS for ${dep}`))); }); })); } function handlePreloadError(err$2) { const e$1 = new Event("vite:preloadError", { cancelable: true }); e$1.payload = err$2; window.dispatchEvent(e$1); if (!e$1.defaultPrevented) throw err$2; } return promise.then((res) => { for (const item of res || []) { if (item.status !== "rejected") continue; handlePreloadError(item.reason); } return baseModule().catch(handlePreloadError); }); }; var w; function H(a, c, b) { const e = typeof b, d = typeof a; if (e !== "undefined") { if (d !== "undefined") { if (b) { if (d === "function" && e === d) return function(k) { return a(b(k)); }; c = a.constructor; if (c === b.constructor) { if (c === Array) return b.concat(a); if (c === Map) { var f = new Map(b); for (var g of a) f.set(g[0], g[1]); return f; } if (c === Set) { g = new Set(b); for (f of a.values()) g.add(f); return g; } } } return a; } return b; } return d === "undefined" ? c : a; } function aa(a, c) { return typeof a === "undefined" ? c : a; } function I() { return Object.create(null); } function M(a) { return typeof a === "string"; } function ba(a) { return typeof a === "object"; } function ca(a, c) { if (M(c)) a = a[c]; else for (let b = 0; a && b < c.length; b++) a = a[c[b]]; return a; } const ea = /[^\p{L}\p{N}]+/u, fa = /(\d{3})/g, ha = /(\D)(\d{3})/g, ia = /(\d{3})(\D)/g, ja = /[\u0300-\u036f]/g; function ka(a = {}) { if (!this || this.constructor !== ka) return new ka(...arguments); if (arguments.length) for (a = 0; a < arguments.length; a++) this.assign(arguments[a]); else this.assign(a); } w = ka.prototype; w.assign = function(a) { this.normalize = H(a.normalize, true, this.normalize); let c = a.include, b = c || a.exclude || a.split, e; if (b || b === "") { if (typeof b === "object" && b.constructor !== RegExp) { let d = ""; e = !c; c || (d += "\\p{Z}"); b.letter && (d += "\\p{L}"); b.number && (d += "\\p{N}", e = !!c); b.symbol && (d += "\\p{S}"); b.punctuation && (d += "\\p{P}"); b.control && (d += "\\p{C}"); if (b = b.char) d += typeof b === "object" ? b.join("") : b; try { this.split = new RegExp("[" + (c ? "^" : "") + d + "]+", "u"); } catch (f) { this.split = /\s+/; } } else this.split = b, e = b === false || "a1a".split(b).length < 2; this.numeric = H(a.numeric, e); } else { try { this.split = H(this.split, ea); } catch (d) { this.split = /\s+/; } this.numeric = H(a.numeric, H(this.numeric, true)); } this.prepare = H(a.prepare, null, this.prepare); this.finalize = H(a.finalize, null, this.finalize); b = a.filter; this.filter = typeof b === "function" ? b : H(b && new Set(b), null, this.filter); this.dedupe = H(a.dedupe, true, this.dedupe); this.matcher = H((b = a.matcher) && new Map(b), null, this.matcher); this.mapper = H((b = a.mapper) && new Map(b), null, this.mapper); this.stemmer = H( (b = a.stemmer) && new Map(b), null, this.stemmer ); this.replacer = H(a.replacer, null, this.replacer); this.minlength = H(a.minlength, 1, this.minlength); this.maxlength = H(a.maxlength, 1024, this.maxlength); this.rtl = H(a.rtl, false, this.rtl); if (this.cache = b = H(a.cache, true, this.cache)) this.F = null, this.L = typeof b === "number" ? b : 2e5, this.B = new Map(), this.D = new Map(), this.I = this.H = 128; this.h = ""; this.J = null; this.A = ""; this.K = null; if (this.matcher) for (const d of this.matcher.keys()) this.h += (this.h ? "|" : "") + d; if (this.stemmer) for (const d of this.stemmer.keys()) this.A += (this.A ? "|" : "") + d; return this; }; w.addStemmer = function(a, c) { this.stemmer || (this.stemmer = new Map()); this.stemmer.set(a, c); this.A += (this.A ? "|" : "") + a; this.K = null; this.cache && Q(this); return this; }; w.addFilter = function(a) { typeof a === "function" ? this.filter = a : (this.filter || (this.filter = new Set()), this.filter.add(a)); this.cache && Q(this); return this; }; w.addMapper = function(a, c) { if (typeof a === "object") return this.addReplacer(a, c); if (a.length > 1) return this.addMatcher(a, c); this.mapper || (this.mapper = new Map()); this.mapper.set(a, c); this.cache && Q(this); return this; }; w.addMatcher = function(a, c) { if (typeof a === "object") return this.addReplacer(a, c); if (a.length < 2 && (this.dedupe || this.mapper)) return this.addMapper(a, c); this.matcher || (this.matcher = new Map()); this.matcher.set(a, c); this.h += (this.h ? "|" : "") + a; this.J = null; this.cache && Q(this); return this; }; w.addReplacer = function(a, c) { if (typeof a === "string") return this.addMatcher(a, c); this.replacer || (this.replacer = []); this.replacer.push(a, c); this.cache && Q(this); return this; }; w.encode = function(a, c) { if (this.cache && a.length <= this.H) if (this.F) { if (this.B.has(a)) return this.B.get(a); } else this.F = setTimeout(Q, 50, this); this.normalize && (typeof this.normalize === "function" ? a = this.normalize(a) : a = ja ? a.normalize("NFKD").replace(ja, "").toLowerCase() : a.toLowerCase()); this.prepare && (a = this.prepare(a)); this.numeric && a.length > 3 && (a = a.replace(ha, "$1 $2").replace(ia, "$1 $2").replace(fa, "$1 ")); const b = !(this.dedupe || this.mapper || this.filter || this.matcher || this.stemmer || this.replacer); let e = [], d = I(), f, g, k = this.split || this.split === "" ? a.split(this.split) : [a]; for (let l = 0, m, p; l < k.length; l++) if ((m = p = k[l]) && !(m.length < this.minlength || m.length > this.maxlength)) { if (c) { if (d[m]) continue; d[m] = 1; } else { if (f === m) continue; f = m; } if (b) e.push(m); else if (!this.filter || (typeof this.filter === "function" ? this.filter(m) : !this.filter.has(m))) { if (this.cache && m.length <= this.I) if (this.F) { var h = this.D.get(m); if (h || h === "") { h && e.push(h); continue; } } else this.F = setTimeout(Q, 50, this); if (this.stemmer) { this.K || (this.K = new RegExp("(?!^)(" + this.A + ")$")); let u; for (; u !== m && m.length > 2; ) u = m, m = m.replace(this.K, (r) => this.stemmer.get(r)); } if (m && (this.mapper || this.dedupe && m.length > 1)) { h = ""; for (let u = 0, r = "", t, n; u < m.length; u++) t = m.charAt(u), t === r && this.dedupe || ((n = this.mapper && this.mapper.get(t)) || n === "" ? n === r && this.dedupe || !(r = n) || (h += n) : h += r = t); m = h; } this.matcher && m.length > 1 && (this.J || (this.J = new RegExp("(" + this.h + ")", "g")), m = m.replace(this.J, (u) => this.matcher.get(u))); if (m && this.replacer) for (h = 0; m && h < this.replacer.length; h += 2) m = m.replace( this.replacer[h], this.replacer[h + 1] ); this.cache && p.length <= this.I && (this.D.set(p, m), this.D.size > this.L && (this.D.clear(), this.I = this.I / 1.1 | 0)); if (m) { if (m !== p) if (c) { if (d[m]) continue; d[m] = 1; } else { if (g === m) continue; g = m; } e.push(m); } } } this.finalize && (e = this.finalize(e) || e); this.cache && a.length <= this.H && (this.B.set(a, e), this.B.size > this.L && (this.B.clear(), this.H = this.H / 1.1 | 0)); return e; }; function Q(a) { a.F = null; a.B.clear(); a.D.clear(); } function la(a, c, b) { b || (c || typeof a !== "object" ? typeof c === "object" && (b = c, c = 0) : b = a); b && (a = b.query || a, c = b.limit || c); let e = "" + (c || 0); b && (e += (b.offset || 0) + !!b.context + !!b.suggest + (b.resolve !== false) + (b.resolution || this.resolution) + (b.boost || 0)); a = ("" + a).toLowerCase(); this.cache || (this.cache = new ma()); let d = this.cache.get(a + e); if (!d) { const f = b && b.cache; f && (b.cache = false); d = this.search(a, c, b); f && (b.cache = f); this.cache.set(a + e, d); } return d; } function ma(a) { this.limit = a && a !== true ? a : 1e3; this.cache = new Map(); this.h = ""; } ma.prototype.set = function(a, c) { this.cache.set(this.h = a, c); this.cache.size > this.limit && this.cache.delete(this.cache.keys().next().value); }; ma.prototype.get = function(a) { const c = this.cache.get(a); c && this.h !== a && (this.cache.delete(a), this.cache.set(this.h = a, c)); return c; }; ma.prototype.remove = function(a) { for (const c of this.cache) { const b = c[0]; c[1].includes(a) && this.cache.delete(b); } }; ma.prototype.clear = function() { this.cache.clear(); this.h = ""; }; const na = { normalize: false, numeric: false, dedupe: false }; const oa = {}; const ra = new Map([["b", "p"], ["v", "f"], ["w", "f"], ["z", "s"], ["x", "s"], ["d", "t"], ["n", "m"], ["c", "k"], ["g", "k"], ["j", "k"], ["q", "k"], ["i", "e"], ["y", "e"], ["u", "o"]]); const sa = new Map([["ae", "a"], ["oe", "o"], ["sh", "s"], ["kh", "k"], ["th", "t"], ["ph", "f"], ["pf", "f"]]), ta = [/([^aeo])h(.)/g, "$1$2", /([aeo])h([^aeo]|$)/g, "$1$2", /(.)\1+/g, "$1"]; const ua = { a: "", e: "", i: "", o: "", u: "", y: "", b: 1, f: 1, p: 1, v: 1, c: 2, g: 2, j: 2, k: 2, q: 2, s: 2, x: 2, z: 2, "ß": 2, d: 3, t: 3, l: 4, m: 5, n: 5, r: 6 }; var va = { Exact: na, Default: oa, Normalize: oa, LatinBalance: { mapper: ra }, LatinAdvanced: { mapper: ra, matcher: sa, replacer: ta }, LatinExtra: { mapper: ra, replacer: ta.concat([/(?!^)[aeo]/g, ""]), matcher: sa }, LatinSoundex: { dedupe: false, include: { letter: true }, finalize: function(a) { for (let b = 0; b < a.length; b++) { var c = a[b]; let e = c.charAt(0), d = ua[e]; for (let f = 1, g; f < c.length && (g = c.charAt(f), g === "h" || g === "w" || !(g = ua[g]) || g === d || (e += g, d = g, e.length !== 4)); f++) ; a[b] = e; } } }, CJK: { split: "" }, LatinExact: na, LatinDefault: oa, LatinSimple: oa }; function wa(a, c, b, e) { let d = []; for (let f = 0, g; f < a.index.length; f++) if (g = a.index[f], c >= g.length) c -= g.length; else { c = g[e ? "splice" : "slice"](c, b); const k = c.length; if (k && (d = d.length ? d.concat(c) : c, b -= k, e && (a.length -= k), !b)) break; c = 0; } return d; } function xa(a) { if (!this || this.constructor !== xa) return new xa(a); this.index = a ? [a] : []; this.length = a ? a.length : 0; const c = this; return new Proxy([], { get(b, e) { if (e === "length") return c.length; if (e === "push") return function(d) { c.index[c.index.length - 1].push(d); c.length++; }; if (e === "pop") return function() { if (c.length) return c.length--, c.index[c.index.length - 1].pop(); }; if (e === "indexOf") return function(d) { let f = 0; for (let g = 0, k, h; g < c.index.length; g++) { k = c.index[g]; h = k.indexOf(d); if (h >= 0) return f + h; f += k.length; } return -1; }; if (e === "includes") return function(d) { for (let f = 0; f < c.index.length; f++) if (c.index[f].includes(d)) return true; return false; }; if (e === "slice") return function(d, f) { return wa(c, d || 0, f || c.length, false); }; if (e === "splice") return function(d, f) { return wa(c, d || 0, f || c.length, true); }; if (e === "constructor") return Array; if (typeof e !== "symbol") return (b = c.index[e / __pow(2, 31) | 0]) && b[e]; }, set(b, e, d) { b = e / __pow(2, 31) | 0; (c.index[b] || (c.index[b] = []))[e] = d; c.length++; return true; } }); } xa.prototype.clear = function() { this.index.length = 0; }; xa.prototype.push = function() { }; function R(a = 8) { if (!this || this.constructor !== R) return new R(a); this.index = I(); this.h = []; this.size = 0; a > 32 ? (this.B = Aa, this.A = BigInt(a)) : (this.B = Ba, this.A = a); } R.prototype.get = function(a) { const c = this.index[this.B(a)]; return c && c.get(a); }; R.prototype.set = function(a, c) { var b = this.B(a); let e = this.index[b]; e ? (b = e.size, e.set(a, c), (b -= e.size) && this.size++) : (this.index[b] = e = new Map([[a, c]]), this.h.push(e), this.size++); }; function S(a = 8) { if (!this || this.constructor !== S) return new S(a); this.index = I(); this.h = []; this.size = 0; a > 32 ? (this.B = Aa, this.A = BigInt(a)) : (this.B = Ba, this.A = a); } S.prototype.add = function(a) { var c = this.B(a); let b = this.index[c]; b ? (c = b.size, b.add(a), (c -= b.size) && this.size++) : (this.index[c] = b = new Set([a]), this.h.push(b), this.size++); }; w = R.prototype; w.has = S.prototype.has = function(a) { const c = this.index[this.B(a)]; return c && c.has(a); }; w.delete = S.prototype.delete = function(a) { const c = this.index[this.B(a)]; c && c.delete(a) && this.size--; }; w.clear = S.prototype.clear = function() { this.index = I(); this.h = []; this.size = 0; }; w.values = S.prototype.values = function* () { for (let a = 0; a < this.h.length; a++) for (let c of this.h[a].values()) yield c; }; w.keys = S.prototype.keys = function* () { for (let a = 0; a < this.h.length; a++) for (let c of this.h[a].keys()) yield c; }; w.entries = S.prototype.entries = function* () { for (let a = 0; a < this.h.length; a++) for (let c of this.h[a].entries()) yield c; }; function Ba(a) { let c = __pow(2, this.A) - 1; if (typeof a == "number") return a & c; let b = 0, e = this.A + 1; for (let d = 0; d < a.length; d++) b = (b * e ^ a.charCodeAt(d)) & c; return this.A === 32 ? b + __pow(2, 31) : b; } function Aa(a) { let c = __pow(BigInt(2), this.A) - BigInt(1); var b = typeof a; if (b === "bigint") return a & c; if (b === "number") return BigInt(a) & c; b = BigInt(0); let e = this.A + BigInt(1); for (let d = 0; d < a.length; d++) b = (b * e ^ BigInt(a.charCodeAt(d))) & c; return b; } let Ca, Da; function Ea(a) { return __async(this, null, function* () { a = a.data; var c = a.task; const b = a.id; let e = a.args; switch (c) { case "init": Da = a.options || {}; (c = a.factory) ? (Function("return " + c)()(self), Ca = new self.FlexSearch.Index(Da), delete self.FlexSearch) : Ca = new T(Da); postMessage({ id: b }); break; default: let d; c === "export" && (e[1] ? (e[0] = Da.export, e[2] = 0, e[3] = 1) : e = null); c === "import" ? e[0] && (a = yield Da.import.call(Ca, e[0]), Ca.import(e[0], a)) : ((d = e && Ca[c].apply(Ca, e)) && d.then && (d = yield d), d && d.await && (d = yield d.await), c === "search" && d.result && (d = d.result)); postMessage(c === "search" ? { id: b, msg: d } : { id: b }); } }); } function Fa(a) { Ga.call(a, "add"); Ga.call(a, "append"); Ga.call(a, "search"); Ga.call(a, "update"); Ga.call(a, "remove"); Ga.call(a, "searchCache"); } let Ha, Ia, Ja; function Ka() { Ha = Ja = 0; } function Ga(a) { this[a + "Async"] = function() { const c = arguments; var b = c[c.length - 1]; let e; typeof b === "function" && (e = b, delete c[c.length - 1]); Ha ? Ja || (Ja = Date.now() - Ia >= this.priority * this.priority * 3) : (Ha = setTimeout(Ka, 0), Ia = Date.now()); if (Ja) { const f = this; return new Promise((g) => { setTimeout(function() { g(f[a + "Async"].apply(f, c)); }, 0); }); } const d = this[a].apply(this, c); b = d.then ? d : new Promise((f) => f(d)); e && b.then(e); return b; }; } let V = 0; function La(a = {}, c) { function b(k) { function h(l) { l = l.data || l; const m = l.id, p = m && f.h[m]; p && (p(l.msg), delete f.h[m]); } this.worker = k; this.h = I(); if (this.worker) { d ? this.worker.on("message", h) : this.worker.onmessage = h; if (a.config) return new Promise(function(l) { V > 1e9 && (V = 0); f.h[++V] = function() { l(f); }; f.worker.postMessage({ id: V, task: "init", factory: e, options: a }); }); this.priority = a.priority || 4; this.encoder = c || null; this.worker.postMessage({ task: "init", factory: e, options: a }); return this; } } if (!this || this.constructor !== La) return new La(a); let e = typeof self !== "undefined" ? self._factory : typeof window !== "undefined" ? window._factory : null; e && (e = e.toString()); const d = typeof window === "undefined", f = this, g = Ma(e, d, a.worker); return g.then ? g.then(function(k) { return b.call(f, k); }) : b.call(this, g); } W("add"); W("append"); W("search"); W("update"); W("remove"); W("clear"); W("export"); W("import"); La.prototype.searchCache = la; Fa(La.prototype); function W(a) { La.prototype[a] = function() { const c = this, b = [].slice.call(arguments); var e = b[b.length - 1]; let d; typeof e === "function" && (d = e, b.pop()); e = new Promise(function(f) { a === "export" && typeof b[0] === "function" && (b[0] = null); V > 1e9 && (V = 0); c.h[++V] = f; c.worker.postMessage({ task: a, id: V, args: b }); }); return d ? (e.then(d), this) : e; }; } function Ma(a, c, b) { return c ? typeof module !== "undefined" ? new (require("worker_threads"))["Worker"](__dirname + "/worker/node.js") : __vitePreload(() => module.import('./__vite-browser-external-2Ng8QIWW-Xya9USxv.js'), void 0 ).then(function(worker) { return new worker["Worker"](module.meta.dirname + "/node/node.mjs"); }) : a ? new window.Worker(URL.createObjectURL(new Blob(["onmessage=" + Ea.toString()], { type: "text/javascript" }))) : new window.Worker(typeof b === "string" ? b : module.meta.url.replace("/worker.js", "/worker/worker.js").replace( "flexsearch.bundle.module.min.js", "module/worker/worker.js" ).replace("flexsearch.bundle.module.min.mjs", "module/worker/worker.js"), { type: "module" }); } Na.prototype.add = function(a, c, b) { ba(a) && (c = a, a = ca(c, this.key)); if (c && (a || a === 0)) { if (!b && this.reg.has(a)) return this.update(a, c); for (let k = 0, h; k < this.field.length; k++) { h = this.B[k]; var e = this.index.get(this.field[k]); if (typeof h === "function") { var d = h(c); d && e.add(a, d, b, true); } else if (d = h.G, !d || d(c)) h.constructor === String ? h = ["" + h] : M(h) && (h = [h]), Qa(c, h, this.D, 0, e, a, h[0], b); } if (this.tag) for (e = 0; e < this.A.length; e++) { var f = this.A[e]; d = this.tag.get(this.F[e]); let k = I(); if (typeof f === "function") { if (f = f(c), !f) continue; } else { var g = f.G; if (g && !g(c)) continue; f.constructor === String && (f = "" + f); f = ca(c, f); } if (d && f) { M(f) && (f = [f]); for (let h = 0, l, m; h < f.length; h++) if (l = f[h], !k[l] && (k[l] = 1, (g = d.get(l)) ? m = g : d.set(l, m = []), !b || !m.includes(a))) { if (m.length === __pow(2, 31) - 1) { g = new xa(m); if (this.fastupdate) for (let p of this.reg.values()) p.includes(m) && (p[p.indexOf(m)] = g); d.set(l, m = g); } m.push(a); this.fastupdate && ((g = this.reg.get(a)) ? g.push(m) : this.reg.set(a, [m])); } } } if (this.store && (!b || !this.store.has(a))) { let k; if (this.h) { k = I(); for (let h = 0, l; h < this.h.length; h++) { l = this.h[h]; if ((b = l.G) && !b(c)) continue; let m; if (typeof l === "function") { m = l(c); if (!m) continue; l = [l.O]; } else if (M(l) || l.constructor === String) { k[l] = c[l]; continue; } Ra(c, k, l, 0, l[0], m); } } this.store.set(a, k || c); } this.worker && (this.fastupdate || this.reg.add(a)); } return this; }; function Ra(a, c, b, e, d, f) { a = a[d]; if (e === b.length - 1) c[d] = f || a; else if (a) if (a.constructor === Array) for (c = c[d] = Array(a.length), d = 0; d < a.length; d++) Ra(a, c, b, e, d); else c = c[d] || (c[d] = I()), d = b[++e], Ra(a, c, b, e, d); } function Qa(a, c, b, e, d, f, g, k) { if (a = a[g]) if (e === c.length - 1) { if (a.constructor === Array) { if (b[e]) { for (c = 0; c < a.length; c++) d.add(f, a[c], true, true); return; } a = a.join(" "); } d.add(f, a, k, true); } else if (a.constructor === Array) for (g = 0; g < a.length; g++) Qa(a, c, b, e, d, f, g, k); else g = c[++e], Qa(a, c, b, e, d, f, g, k); } function Sa(a, c, b, e) { if (!a.length) return a; if (a.length === 1) return a = a[0], a = b || a.length > c ? a.slice(b, b + c) : a, e ? Ta.call(this, a) : a; let d = []; for (let f = 0, g, k; f < a.length; f++) if ((g = a[f]) && (k = g.length)) { if (b) { if (b >= k) { b -= k; continue; } g = g.slice(b, b + c); k = g.length; b = 0; } k > c && (g = g.slice(0, c), k = c); if (!d.length && k >= c) return e ? Ta.call(this, g) : g; d.push(g); c -= k; if (!c) break; } d = d.length > 1 ? [].concat.apply([], d) : d[0]; return e ? Ta.call(this, d) : d; } function Ua(a, c, b, e) { var d = e[0]; if (d[0] && d[0].query) return a[c].apply(a, d); if (!(c !== "and" && c !== "not" || a.result.length || a.await || d.suggest)) return e.length > 1 && (d = e[e.length - 1]), (e = d.resolve) ? a.await || a.result : a; let f = [], g = 0, k = 0, h, l, m, p, u; for (c = 0; c < e.length; c++) if (d = e[c]) { var r = void 0; if (d.constructor === X) r = d.await || d.result; else if (d.then || d.constructor === Array) r = d; else { g = d.limit || 0; k = d.offset || 0; m = d.suggest; l = d.resolve; h = ((p = d.highlight || a.highlight) || d.enrich) && l; r = d.queue; let t = d.async || r, n = d.index, q = d.query; n ? a.index || (a.index = n) : n = a.index; if (q || d.tag) { const x = d.field || d.pluck; x && (!q || a.query && !p || (a.query = q, a.field = x, a.highlight = p), n = n.index.get(x)); if (r && (u || a.await)) { u = 1; let v; const A = a.C.length, D = new Promise(function(F) { v = F; }); (function(F, E) { D.h = function() { E.index = null; E.resolve = false; let B = t ? F.searchAsync(E) : F.search(E); if (B.then) return B.then(function(z) { a.C[A] = z = z.result || z; v(z); return z; }); B = B.result || B; v(B); return B; }; })(n, Object.assign({}, d)); a.C.push(D); f[c] = D; continue; } else d.resolve = false, d.index = null, r = t ? n.searchAsync(d) : n.search(d), d.resolve = l, d.index = n; } else if (d.and) r = Va(d, "and", n); else if (d.or) r = Va(d, "or", n); else if (d.not) r = Va(d, "not", n); else if (d.xor) r = Va(d, "xor", n); else continue; } r.await ? (u = 1, r = r.await) : r.then ? (u = 1, r = r.then(function(t) { return t.result || t; })) : r = r.result || r; f[c] = r; } u && !a.await && (a.await = new Promise(function(t) { a.return = t; })); if (u) { const t = Promise.all(f).then(function(n) { for (let q = 0; q < a.C.length; q++) if (a.C[q] === t) { a.C[q] = function() { return b.call(a, n, g, k, h, l, m, p); }; break; } Wa(a); }); a.C.push(t); } else if (a.await) a.C.push(function() { return b.call(a, f, g, k, h, l, m, p); }); else return b.call(a, f, g, k, h, l, m, p); return l ? a.await || a.result : a; } function Va(a, c, b) { a = a[c]; const e = a[0] || a; e.index || (e.index = b); b = new X(e); a.length > 1 && (b = b[c].apply(b, a.slice(1))); return b; } X.prototype.or = function() { return Ua(this, "or", Xa, arguments); }; function Xa(a, c, b, e, d, f, g) { a.length && (this.result.length && a.push(this.result), a.length < 2 ? this.result = a[0] : (this.result = Ya(a, c, b, false, this.h), b = 0)); d && (this.await = null); return d ? this.resolve(c, b, e, g) : this; } X.prototype.and = function() { return Ua(this, "and", Za, arguments); }; function Za(a, c, b, e, d, f, g) { if (!f && !this.result.length) return d ? this.result : this; let k; if (a.length) if (this.result.length && a.unshift(this.result), a.length < 2) this.result = a[0]; else { let h = 0; for (let l = 0, m, p; l < a.length; l++) if ((m = a[l]) && (p = m.length)) h < p && (h = p); else if (!f) { h = 0; break; } h ? (this.result = $a(a, h, c, b, f, this.h, d), k = true) : this.result = []; } else f || (this.result = a); d && (this.await = null); return d ? this.resolve(c, b, e, g, k) : this; } X.prototype.xor = function() { return Ua(this, "xor", ab, arguments); }; function ab(a, c, b, e, d, f, g) { if (a.length) if (this.result.length && a.unshift(this.result), a.length < 2) this.result = a[0]; else { a: { f = b; var k = this.h; const h = [], l = I(); let m = 0; for (let p = 0, u; p < a.length; p++) if (u = a[p]) { m < u.length && (m = u.length); for (let r = 0, t; r < u.length; r++) if (t = u[r]) for (let n = 0, q; n < t.length; n++) q = t[n], l[q] = l[q] ? 2 : 1; } for (let p = 0, u, r = 0; p < m; p++) for (let t = 0, n; t < a.length; t++) if (n = a[t]) { if (u = n[p]) { for (let q = 0, x; q < u.length; q++) if (x = u[q], l[x] === 1) if (f) f--; else if (d) { if (h.push(x), h.length === c) { a = h; break a; } } else { const v = p + (t ? k : 0); h[v] || (h[v] = []); h[v].push(x); if (++r === c) { a = h; break a; } } } } a = h; } this.result = a; k = true; } else f || (this.result = a); d && (this.await = null); return d ? this.resolve(c, b, e, g, k) : this; } X.prototype.not = function() { return Ua(this, "not", bb, arguments); }; function bb(a, c, b, e, d, f, g) { if (!f && !this.result.length) return d ? this.result : this; if (a.length && this.result.length) { a: { f = b; var k = []; a = new Set(a.flat().flat()); for (let h = 0, l, m = 0; h < this.result.length; h++) if (l = this.result[h]) { for (let p = 0, u; p < l.length; p++) if (u = l[p], !a.has(u)) { if (f) f--; else if (d) { if (k.push(u), k.length === c) { a = k; break a; } } else if (k[h] || (k[h] = []), k[h].push(u), ++m === c) { a = k; break a; } } } a = k; } this.result = a; k = true; } d && (this.await = null); return d ? this.resolve(c, b, e, g, k) : this; } function cb(a, c, b, e, d) { let f, g, k; typeof d === "string" ? (f = d, d = "") : f = d.template; g = f.indexOf("$1"); k = f.substring(g + 2); g = f.substring(0, g); let h = d && d.boundary, l = !d || d.clip !== false, m = d && d.merge && k && g && new RegExp(k + " " + g, "g"); d = d && d.ellipsis; var p = 0; if (typeof d === "object") { var u = d.template; p = u.length - 2; d = d.pattern; } typeof d !== "string" && (d = d === false ? "" : "..."); p && (d = u.replace("$1", d)); u = d.length - p; let r, t; typeof h === "object" && (r = h.before, r === 0 && (r = -1), t = h.after, t === 0 && (t = -1), h = h.total || 9e5); p = new Map(); for (let Oa = 0, da, db, pa; Oa < c.length; Oa++) { let qa; if (e) qa = c, pa = e; else { var n = c[Oa]; pa = n.field; if (!pa) continue; qa = n.result; } db = b.get(pa); da = db.encoder; n = p.get(da); typeof n !== "string" && (n = da.encode(a), p.set(da, n)); for (let ya = 0; ya < qa.length; ya++) { var q = qa[ya].doc; if (!q) continue; q = ca(q, pa); if (!q) continue; var x = q.trim().split(/\s+/); if (!x.length) continue; q = ""; var v = []; let za = []; var A = -1, D = -1, F = 0; for (var E = 0; E < x.length; E++) { var B = x[E], z = da.encode(B); z = z.length > 1 ? z.join(" ") : z[0]; let y; if (z && B) { var C = B.length, J = (da.split ? B.replace(da.split, "") : B).length - z.length, G = "", N = 0; for (var O = 0; O < n.length; O++) { var P = n[O]; if (P) { var L = P.length; L += J < 0 ? 0 : J; N && L <= N || (P = z.indexOf(P), P > -1 && (G = (P ? B.substring(0, P) : "") + g + B.substring(P, P + L) + k + (P + L < C ? B.substring(P + L) : ""), N = L, y = true)); } } G && (h && (A < 0 && (A = q.length + (q ? 1 : 0)), D = q.length + (q ? 1 : 0) + G.length, F += C, za.push(v.length), v.push({ match: G })), q += (q ? " " : "") + G); } if (!y) B = x[E], q += (q ? " " : "") + B, h && v.push({ text: B }); else if (h && F >= h) break; } F = za.length * (f.length - 2); if (r || t || h && q.length - F > h) if (F = h + F - u * 2, E = D - A, r > 0 && (E += r), t > 0 && (E += t), E <= F) x = r ? A - (r > 0 ? r : 0) : A - ((F - E) / 2 | 0), v = t ? D + (t > 0 ? t : 0) : x + F, l || (x > 0 && q.charAt(x) !== " " && q.charAt(x - 1) !== " " && (x = q.indexOf(" ", x), x < 0 && (x = 0)), v < q.length && q.charAt(v - 1) !== " " && q.charAt(v) !== " " && (v = q.lastIndexOf(" ", v), v < D ? v = D : ++v)), q = (x ? d : "") + q.substring(x, v) + (v < q.length ? d : ""); else { D = []; A = {}; F = {}; E = {}; B = {}; z = {}; G = J = C = 0; for (O = N = 1; ; ) { var U = void 0; for (let y = 0, K; y < za.length; y++) { K = za[y]; if (G) if (J !== G) { if (E[y + 1]) continue; K += G; if (A[K]) { C -= u; F[y + 1] = 1; E[y + 1] = 1; continue; } if (K >= v.length - 1) { if (K >= v.length) { E[y + 1] = 1; K >= x.length && (F[y + 1] = 1); continue; } C -= u; } q = v[K].text; if (L = t && z[y]) if (L > 0) { if (q.length > L) if (E[y + 1] = 1, l) q = q.substring(0, L); else continue; (L -= q.length) || (L = -1); z[y] = L; } else { E[y + 1] = 1; continue; } if (C + q.length + 1 <= h) q = " " + q, D[y] += q; else if (l) U = h - C - 1, U > 0 && (q = " " + q.substring(0, U), D[y] += q), E[y + 1] = 1; else { E[y + 1] = 1; continue; } } else { if (E[y]) continue; K -= J; if (A[K]) { C -= u; E[y] = 1; F[y] = 1; continue; } if (K <= 0) { if (K < 0) { E[y] = 1; F[y] = 1; continue; } C -= u; } q = v[K].text; if (L = r && B[y]) if (L > 0) { if (q.length > L) if (E[y] = 1, l) q = q.substring(q.length - L); else continue; (L -= q.length) || (L = -1); B[y] = L; } else { E[y] = 1; continue; } if (C + q.length + 1 <= h) q += " ", D[y] = q + D[y]; else if (l) U = q.length + 1 - (h - C), U >= 0 && U < q.length && (q = q.substring(U) + " ", D[y] = q + D[y]), E[y] = 1; else { E[y] = 1; continue; } } else { q = v[K].match; r && (B[y] = r); t && (z[y] = t); y && C++; let Pa; K ? !y && u && (C += u) : (F[y] = 1, E[y] = 1); K >= x.length - 1 ? Pa = 1 : K < v.length - 1 && v[K + 1].match ? Pa = 1 : u && (C += u); C -= f.length - 2; if (!y || C + q.length <= h) D[y] = q; else { U = N = O = F[y] = 0; break; } Pa && (F[y + 1] = 1, E[y + 1] = 1); } C += q.length; U = A[K] = 1; } if (U) J === G ? G++ : J++; else { J === G ? N = 0 : O = 0; if (!N && !O) break; N ? (J++, G = J) : G++; } } q = ""; for (let y = 0, K; y < D.length; y++) K = (F[y] ? y ? " " : "" : (y && !d ? " " : "") + d) + D[y], q += K; d && !F[D.length] && (q += d); } m && (q = q.replace(m, " ")); qa[ya].highlight = q; } if (e) break; } return c; } function X(a, c) { if (!this || this.constructor !== X) return new X(a, c); let b = 0, e, d, f, g, k, h; if (a && a.index) { const l = a; c = l.index; b = l.boost || 0; if (d = l.query) { f = l.field || l.pluck; g = l.highlight; const m = l.resolve; a = l.async || l.queue; l.resolve = false; l.index = null; a = a ? c.searchAsync(l) : c.search(l); l.resolve = m; l.index = c; a = a.result || a; } else a = []; } if (a && a.then) { const l = this; a = a.then(function(m) { l.C[0] = l.result = m.result || m; Wa(l); }); e = [a]; a = []; k = new Promise(function(m) { h = m; }); } this.index = c || null; this.result = a || []; this.h = b; this.C = e || []; this.await = k || null; this.return = h || null; this.highlight = g || null; this.query = d || ""; this.field = f || ""; } w = X.prototype; w.limit = function(a) { if (this.await) { const c = this; this.C.push(function() { return c.limit(a).result; }); } else if (this.result.length) { const c = []; for (let b = 0, e; b < this.result.length; b++) if (e = this.result[b]) if (e.length <= a) { if (c[b] = e, a -= e.length, !a) break; } else { c[b] = e.slice(0, a); break; } this.result = c; } return this; }; w.offset = function(a) { if (this.await) { const c = this; this.C.push(function() { return c.offset(a).result; }); } else if (this.result.length) { const c = []; for (let b = 0, e; b < this.result.length; b++) if (e = this.result[b]) e.length <= a ? a -= e.length : (c[b] = e.slice(a), a = 0); this.result = c; } return this; }; w.boost = function(a) { if (this.await) { const c = this; this.C.push(function() { return c.boost(a).result; }); } else this.h += a; return this; }; function Wa(a, c) { let b = a.result; var e = a.await; a.await = null; for (let d = 0, f; d < a.C.length; d++) if (f = a.C[d]) { if (typeof f === "function") b = f(), a.C[d] = b = b.result || b, d--; else if (f.h) b = f.h(), a.C[d] = b = b.result || b, d--; else if (f.then) return a.await = e; } e = a.return; a.C = []; a.return = null; c || e(b); return b; } w.resolve = function(a, c, b, e, d) { let f = this.await ? Wa(this, true) : this.result; if (f.then) { const g = this; return f.then(function() { return g.resolve(a, c, b, e, d); }); } f.length && (typeof a === "object" ? (e = a.highlight || this.highlight, b = !!e || a.enrich, c = a.offset, a = a.limit) : (e = e || this.highlight, b = !!e || b), f = d ? b ? Ta.call(this.index, f) : f : Sa.call(this.index, f, a || 100, c, b)); return this.finalize(f, e); }; w.finalize = function(a, c) { if (a.then) { const e = this; return a.then(function(d) { return e.finalize(d, c); }); } c && a.length && this.query && (a = cb(this.query, a, this.index.index, this.field, c)); const b = this.return; this.highlight = this.index = this.result = this.C = this.await = this.return = null; this.query = this.field = ""; b && b(a); return a; }; function $a(a, c, b, e, d, f, g) { const k = a.length; let h = [], l, m; l = I(); for (let p = 0, u, r, t, n; p < c; p++) for (let q = 0; q < k; q++) if (t = a[q], p < t.length && (u = t[p])) for (let x = 0; x < u.length; x++) { r = u[x]; (m = l[r]) ? l[r]++ : (m = 0, l[r] = 1); n = h[m] || (h[m] = []); if (!g) { let v = p + (q || !d ? 0 : f || 0); n = n[v] || (n[v] = []); } n.push(r); if (g && b && m === k - 1 && n.length - e === b) return e ? n.slice(e) : n; } if (a = h.length) if (d) h = h.length > 1 ? Ya(h, b, e, g, f) : (h = h[0]) && b && h.length > b || e ? h.slice(e, b + e) : h; else { if (a < k) return []; h = h[a - 1]; if (b || e) if (g) { if (h.length > b || e) h = h.slice(e, b + e); } else { d = []; for (let p = 0, u; p < h.length; p++) if (u = h[p]) if (e && u.length > e) e -= u.length; else { if (b && u.length > b || e) u = u.slice(e, b + e), b -= u.length, e && (e -= u.length); d.push(u); if (!b) break; } h = d; } } return h; } function Ya(a, c, b, e, d) { const f = [], g = I(); let k; var h = a.length; let l; if (e) for (d = h - 1; d >= 0; d--) { if (l = (e = a[d]) && e.length) { for (h = 0; h < l; h++) if (k = e[h], !g[k]) { if (g[k] = 1, b) b--; else if (f.push(k), f.length === c) return f; } } } else for (let m = h - 1, p, u = 0; m >= 0; m--) { p = a[m]; for (let r = 0; r < p.length; r++) if (l = (e = p[r]) && e.length) { for (let t = 0; t < l; t++) if (k = e[t], !g[k]) if (g[k] = 1, b) b--; else { let n = (r + (m < h - 1 ? d || 0 : 0)) / (m + 1) | 0; (f[n] || (f[n] = [])).push(k); if (++u === c) return f; } } } return f; } function eb(a, c, b, e, d) { const f = I(), g = []; for (let k = 0, h; k < c.length; k++) { h = c[k]; for (let l = 0; l < h.length; l++) f[h[l]] = 1; } if (d) for (let k = 0, h; k < a.length; k++) { if (h = a[k], f[h]) { if (e) e--; else if (g.push(h), f[h] = 0, b && --b === 0) break; } } else for (let k = 0, h, l; k < a.result.length; k++) for (h = a.result[k], c = 0; c < h.length; c++) l = h[c], f[l] && ((g[k] || (g[k] = [])).push(l), f[l] = 0); return g; } Na.prototype.search = function(a, c, b, e) { b || (!c && ba(a) ? (b = a, a = "") : ba(c) && (b = c, c = 0)); let d = []; var f = []; let g; let k, h, l, m, p; let u = 0, r = true, t; if (b) { b.constructor === Array && (b = { index: b }); a = b.query || a; g = b.pluck; k = b.merge; l = b.boost; p = g || b.field || (p = b.index) && (p.index ? null : p); var n = this.tag && b.tag; h = b.suggest; r = b.resolve !== false; m = b.cache; t = r && this.store && b.highlight; var q = !!t || r && this.store && b.enrich; c = b.limit || c; var x = b.offset || 0; c || (c = r ? 100 : 0); if (n && (!this.db || !e)) { n.constructor !== Array && (n = [n]); var v = []; for (let B = 0, z; B < n.length; B++) if (z = n[B], z.field && z.tag) { var A = z.tag; if (A.constructor === Array) for (var D = 0; D < A.length; D++) v.push(z.field, A[D]); else v.push(z.field, A); } else { A = Object.keys(z); for (let C = 0, J, G; C < A.length; C++) if (J = A[C], G = z[J], G.constructor === Array) for (D = 0; D < G.length; D++) v.push(J, G[D]); else v.push(J, G); } n = v; if (!a) { f = []; if (v.length) for (n = 0; n < v.length; n += 2) { if (this.db) { e = this.index.get(v[n]); if (!e) continue; f.push(e = e.db.tag(v[n + 1], c, x, q)); } else e = fb.call(this, v[n], v[n + 1], c, x, q); d.push(r ? { field: v[n], tag: v[n + 1], result: e } : [e]); } if (f.length) { const B = this; return Promise.all(f).then(function(z) { for (let C = 0; C < z.length; C++) r ? d[C].result = z[C] : d[C] = z[C]; return r ? d : new X(d.length > 1 ? $a(d, 1, 0, 0, h, l) : d[0], B); }); } return r ? d : new X(d.length > 1 ? $a(d, 1, 0, 0, h, l) : d[0], this); } } r || g || !(p = p || this.field) || (M(p) ? g = p : (p.constructor === Array && p.length === 1 && (p = p[0]), g = p.field || p.index)); p && p.constructor !== Array && (p = [p]); } p || (p = this.field); let F; v = (this.worker || this.db) && !e && []; for (let B = 0, z, C, J; B < p.length; B++) { C = p[B]; if (this.db && this.tag && !this.B[B]) continue; let G; M(C) || (G = C, C = G.field, a = G.query || a, c = aa(G.limit, c), x = aa(G.offset, x), h = aa(G.suggest, h), t = r && this.store && aa(G.highlight, t), q = !!t || r && this.store && aa(G.enrich, q), m = aa(G.cache, m)); if (e) z = e[B]; else { A = G || b || {}; D = A.enrich; var E = this.index.get(C); n && (this.db && (A.tag = n, A.field = p, F = E.db.support_tag_search), !F && D && (A.enrich = false), F || (A.limit = 0, A.offset = 0)); z = m ? E.searchCache(a, n && !F ? 0 : c, A) : E.search(a, n && !F ? 0 : c, A); n && !F && (A.limit = c, A.offset = x); D && (A.enrich = D); if (v) { v[B] = z; continue; } } J = (z = z.result || z) && z.length; if (n && J) { A = []; D = 0; if (this.db && e) { if (!F) for (E = p.length; E < e.length; E++) { let N = e[E]; if (N && N.length) D++, A.push(N); else if (!h) return r ? d : new X(d, this); } } else for (let N = 0, O, P; N < n.length; N += 2) { O = this.tag.get(n[N]); if (!O) if (h) continue; else return r ? d : new X(d, this); if (P = (O = O && O.get(n[N + 1])) && O.length) D++, A.push(O); else if (!h) return r ? d : new X(d, this); } if (D) { z = eb(z, A, c, x, r); J = z.length; if (!J && !h) return r ? z : new X(z, this); D--; } } if (J) f[u] = C, d.push(z), u++; else if (p.length === 1) return r ? d : new X( d, this ); } if (v) { if (this.db && n && n.length && !F) for (q = 0; q < n.length; q += 2) { f = this.index.get(n[q]); if (!f) if (h) continue; else return r ? d : new X(d, this); v.push(f.db.tag(n[q + 1], c, x, false)); } const B = this; return Promise.all(v).then(function(z) { b && (b.resolve = r); z.length && (z = B.search(a, c, b, z)); return z; }); } if (!u) return r ? d : new X(d, this); if (g && (!q || !this.store)) return d = d[0], r ? d : new X(d, this); v = []; for (x = 0; x < f.length; x++) { n = d[x]; q && n.length && typeof n[0].doc === "undefined" && (this.db ? v.push(n = this.index.get(this.field[0]).db.enrich(n)) : n = Ta.call(this, n)); if (g) return r ? t ? cb(a, n, this.index, g, t) : n : new X(n, this); d[x] = { field: f[x], result: n }; } if (q && this.db && v.length) { const B = this; return Promise.all(v).then(function(z) { for (let C = 0; C < z.length; C++) d[C].result = z[C]; t && (d = cb(a, d, B.index, g, t)); return k ? gb(d) : d; }); } t && (d = cb(a, d, this.index, g, t)); return k ? gb(d) : d; }; function gb(a) { const c = [], b = I(), e = I(); for (let d = 0, f, g, k, h, l, m, p; d < a.length; d++) { f = a[d]; g = f.field; k = f.result; for (let u = 0; u < k.length; u++) if (l = k[u], typeof l !== "object" ? l = { id: h = l } : h = l.id, (m = b[h]) ? m.push(g) : (l.field = b[h] = [g], c.push(l)), p = l.highlight) m = e[h], m || (e[h] = m = {}, l.highlight = m), m[g] = p; } return c; } function fb(a, c, b, e, d) { a = this.tag.get(a); if (!a) return []; a = a.get(c); if (!a) return []; c = a.length - e; if (c > 0) { if (b && c > b || e) a = a.slice(e, e + b); d && (a = Ta.call(this, a)); } return a; } function Ta(a) { if (!this || !this.store) return a; if (this.db) return this.index.get(this.field[0]).db.enrich(a); const c = Array(a.length); for (let b = 0, e; b < a.length; b++) e = a[b], c[b] = { id: e, doc: this.store.get(e) }; return c; } function Na(a) { if (!this || this.constructor !== Na) return new Na(a); const c = a.document || a.doc || a; let b, e; this.B = []; this.field = []; this.D = []; this.key = (b = c.key || c.id) && hb(b, this.D) || "id"; (e = a.keystore || 0) && (this.keystore = e); this.fastupdate = !!a.fastupdate; this.reg = !this.fastupdate || a.worker || a.db ? e ? new S(e) : new Set() : e ? new R(e) : new Map(); this.h = (b = c.store || null) && b && b !== true && []; this.store = b ? e ? new R(e) : new Map() : null; this.cache = (b = a.cache || null) && new ma(b); a.cache = false; this.worker = a.worker || false; this.priority = a.priority || 4; this.index = ib.call(this, a, c); this.tag = null; if (b = c.tag) { if (typeof b === "string" && (b = [b]), b.length) { this.tag = new Map(); this.A = []; this.F = []; for (let d = 0, f, g; d < b.length; d++) { f = b[d]; g = f.field || f; if (!g) throw Error("The tag field from the document descriptor is undefined."); f.custom ? this.A[d] = f.custom : (this.A[d] = hb(g, this.D), f.filter && (typeof this.A[d] === "string" && (this.A[d] = new String(this.A[d])), this.A[d].G = f.filter)); this.F[d] = g; this.tag.set(g, new Map()); } } } if (this.worker) { this.fastupdate = false; a = []; for (const d of this.index.values()) d.then && a.push(d); if (a.length) { const d = this; return Promise.all(a).then(function(f) { let g = 0; for (const k of d.index.entries()) { const h = k[0]; let l = k[1]; l.then && (l = f[g], d.index.set(h, l), g++); } return d; }); } } else a.db && (this.fastupdate = false, this.mount(a.db)); } w = Na.prototype; w.mount = function(a) { let c = this.field; if (this.tag) for (let f = 0, g; f < this.F.length; f++) { g = this.F[f]; var b = void 0; this.index.set(g, b = new T({}, this.reg)); c === this.field && (c = c.slice(0)); c.push(g); b.tag = this.tag.get(g); } b = []; const e = { db: a.db, type: a.type, fastupdate: a.fastupdate }; for (let f = 0, g, k; f < c.length; f++) { e.field = k = c[f]; g = this.index.get(k); const h = new a.constructor(a.id, e); h.id = a.id; b[f] = h.mount(g); g.document = true; f ? g.bypass = true : g.store = this.store; } const d = this; return this.db = Promise.all(b).then(function() { d.db = true; }); }; w.commit = function() { return __async(this, null, function* () { const a = []; for (const c of this.index.values()) a.push(c.commit()); yield Promise.all(a); this.reg.clear(); }); }; w.destroy = function() { const a = []; for (const c of this.index.values()) a.push(c.destroy()); return Promise.all(a); }; function ib(a, c) { const b = new Map(); let e = c.index || c.field || c; M(e) && (e = [e]); for (let f = 0, g, k; f < e.length; f++) { g = e[f]; M(g) || (k = g, g = g.field); k = ba(k) ? Object.assign({}, a, k) : a; if (this.worker) { var d = void 0; d = (d = k.encoder) && d.encode ? d : new ka(typeof d === "string" ? va[d] : d || {}); d = new La(k, d); b.set(g, d); } this.worker || b.set(g, new T(k, this.reg)); k.custom ? this.B[f] = k.custom : (this.B[f] = hb(g, this.D), k.filter && (typeof this.B[f] === "string" && (this.B[f] = new String(this.B[f])), this.B[f].G = k.filter)); this.field[f] = g; } if (this.h) { a = c.store; M(a) && (a = [a]); for (let f = 0, g, k; f < a.length; f++) g = a[f], k = g.field || g, g.custom ? (this.h[f] = g.custom, g.custom.O = k) : (this.h[f] = hb(k, this.D), g.filter && (typeof this.h[f] === "string" && (this.h[f] = new String(this.h[f])), this.h[f].G = g.filter)); } return b; } function hb(a, c) { const b = a.split(":"); let e = 0; for (let d = 0; d < b.length; d++) a = b[d], a[a.length - 1] === "]" && (a = a.substring(0, a.length - 2)) && (c[e] = true), a && (b[e++] = a); e < b.length && (b.length = e); return e > 1 ? b : b[0]; } w.append = function(a, c) { return this.add(a, c, true); }; w.update = function(a, c) { return this.remove(a).add(a, c); }; w.remove = function(a) { ba(a) && (a = ca(a, this.key)); for (var c of this.index.values()) c.remove(a, true); if (this.reg.has(a)) { if (this.tag && !this.fastupdate) for (let b of this.tag.values()) for (let e of b) { c = e[0]; const d = e[1], f = d.indexOf(a); f > -1 && (d.length > 1 ? d.splice(f, 1) : b.delete(c)); } this.store && this.store.delete(a); this.reg.delete(a); } this.cache && this.cache.remove(a); return this; }; w.clear = function() { const a = []; for (const c of this.index.values()) { const b = c.clear(); b.then && a.push(b); } if (this.tag) for (const c of this.tag.values()) c.clear(); this.store && this.store.clear(); this.cache && this.cache.clear(); return a.length ? Promise.all(a) : this; }; w.contain = function(a) { return this.db ? this.index.get(this.field[0]).db.has(a) : this.reg.has(a); }; w.cleanup = function() { for (const a of this.index.values()) a.cleanup(); return this; }; w.get = function(a) { return this.db ? this.index.get(this.field[0]).db.enrich(a).then(function(c) { return c[0] && c[0].doc || null; }) : this.store.get(a) || null; }; w.set = function(a, c) { typeof a === "object" && (c = a, a = ca(c, this.key)); this.store.set(a, c); return this; }; w.searchCache = la; w.export = jb; w.import = kb; Fa(Na.prototype); function lb(a, c = 0) { let b = [], e = []; c && (c = 25e4 / c * 5e3 | 0); for (const d of a.entries()) e.push(d), e.length === c && (b.push(e), e = []); e.length && b.push(e); return b; } function mb(a, c) { c || (c = new Map()); for (let b = 0, e; b < a.length; b++) e = a[b], c.set(e[0], e[1]); return c; } function nb(a, c = 0) { let b = [], e = []; c && (c = 25e4 / c * 1e3 | 0); for (const d of a.entries()) e.push([d[0], lb(d[1])[0] || []]), e.length === c && (b.push(e), e = []); e.length && b.push(e); return b; } function ob(a, c) { c || (c = new Map()); for (let b = 0, e, d; b < a.length; b++) e = a[b], d = c.get(e[0]), c.set(e[0], mb(e[1], d)); return c; } function pb(a) { let c = [], b = []; for (const e of a.keys()) b.push(e), b.length === 25e4 && (c.push(b), b = []); b.length && c.push(b); return c; } function qb(a, c) { c || (c = new Set()); for (let b = 0; b < a.length; b++) c.add(a[b]); return c; } function rb(a, c, b, e, d, f, g = 0) { const k = e && e.constructor === Array; var h = k ? e.shift() : e; if (!h) return this.export(a, c, d, f + 1); if ((h = a((c ? c + "." : "") + (g + 1) + "." + b, JSON.stringify(h))) && h.then) { const l = this; return h.then(function() { return rb.call(l, a, c, b, k ? e : null, d, f, g + 1); }); } return rb.call(this, a, c, b, k ? e : null, d, f, g + 1); } function jb(a, c, b = 0, e = 0) { if (b < this.field.length) { const g = this.field[b]; if ((c = this.index.get(g).export(a, g, b, e = 1)) && c.then) { const k = this; return c.then(function() { return k.export(a, g, b + 1); }); } return this.export(a, g, b + 1); } let d, f; switch (e) { case 0: d = "reg"; f = pb(this.reg); c = null; break; case 1: d = "tag"; f = this.tag && nb(this.tag, this.reg.size); c = null; break; case 2: d = "doc"; f = this.store && lb(this.store); c = null; break; default: return; } return rb.call(this, a, c, d, f || null, b, e); } function kb(a, c) { var b = a.split("."); b[b.length - 1] === "json" && b.pop(); const e = b.length > 2 ? b[0] : ""; b = b.length > 2 ? b[2] : b[1]; if (this.worker && e) return this.index.get(e).import(a); if (c) { typeof c === "string" && (c = JSON.parse(c)); if (e) return this.index.get(e).import(b, c); switch (b) { case "reg": this.fastupdate = false; this.reg = qb(c, this.reg); for (let d = 0, f; d < this.field.length; d++) f = this.index.get(this.field[d]), f.fastupdate = false, f.reg = this.reg; if (this.worker) { c = []; for (const d of this.index.values()) c.push(d.import(a)); return Promise.all(c); } break; case "tag": this.tag = ob(c, this.tag); break; case "doc": this.store = mb(c, this.store); } } } function sb(a, c) { let b = ""; for (const e of a.entries()) { a = e[0]; const d = e[1]; let f = ""; for (let g = 0, k; g < d.length; g++) { k = d[g] || [""]; let h = ""; for (let l = 0; l < k.length; l++) h += (h ? "," : "") + (c === "string" ? '"' + k[l] + '"' : k[l]); h = "[" + h + "]"; f += (f ? "," : "") + h; } f = '["' + a + '",[' + f + "]]"; b += (b ? "," : "") + f; } return b; } T.prototype.remove = function(a, c) { const b = this.reg.size && (this.fastupdate ? this.reg.get(a) : this.reg.has(a)); if (b) { if (this.fastupdate) for (let e = 0, d, f; e < b.length; e++) { if ((d = b[e]) && (f = d.length)) if (d[f - 1] === a) d.pop(); else { const g = d.indexOf(a); g >= 0 && d.splice(g, 1); } } else tb(this.map, a), this.depth && tb(this.ctx, a); c || this.reg.delete(a); } this.db && (this.commit_task.push({ del: a }), this.M && ub(this)); this.cache && this.cache.remove(a); return this; }; function tb(a, c) { let b = 0; var e = typeof c === "undefined"; if (a.constructor === Array) for (let d = 0, f, g, k; d < a.length; d++) { if ((f = a[d]) && f.length) { if (e) return 1; g = f.indexOf(c); if (g >= 0) { if (f.length > 1) return f.splice(g, 1), 1; delete a[d]; if (b) return 1; k = 1; } else { if (k) return 1; b++; } } } else for (let d of a.entries()) e = d[0], tb(d[1], c) ? b++ : a.delete(e); return b; } const vb = { memory: { resolution: 1 }, performance: { resolution: 3, fastupdate: true, context: { depth: 1, resolution: 1 } }, match: { tokenize: "forward" }, score: { resolution: 9, context: { depth: 2, resolution: 3 } } }; T.prototype.add = function(a, c, b, e) { if (c && (a || a === 0)) { if (!e && !b && this.reg.has(a)) return this.update(a, c); e = this.depth; c = this.encoder.encode(c, !e); const l = c.length; if (l) { const m = I(), p = I(), u = this.resolution; for (let r = 0; r < l; r++) { let t = c[this.rtl ? l - 1 - r : r]; var d = t.length; if (d && (e || !p[t])) { var f = this.score ? this.score(c, t, r, null, 0) : wb(u, l, r), g = ""; switch (this.tokenize) { case "tolerant": Y(this, p, t, f, a, b); if (d > 2) { for (let n = 1, q, x, v, A; n < d - 1; n++) q = t.charAt(n), x = t.charAt(n + 1), v = t.substring(0, n) + x, A = t.substring(n + 2), g = v + q + A, Y(this, p, g, f, a, b), g = v + A, Y(this, p, g, f, a, b); Y(this, p, t.substring(0, t.length - 1), f, a, b); } break; case "full": if (d > 2) { for (let n = 0, q; n < d; n++) for (f = d; f > n; f--) { g = t.substring(n, f); q = this.rtl ? d - 1 - n : n; var k = this.score ? this.score(c, t, r, g, q) : wb(u, l, r, d, q); Y(this, p, g, k, a, b); } break; } case "bidirectional": case "reverse": if (d > 1) { for (k = d - 1; k > 0; k--) { g = t[this.rtl ? d - 1 - k : k] + g; var h = this.score ? this.score(c, t, r, g, k) : wb(u, l, r, d, k); Y(this, p, g, h, a, b); } g = ""; } case "forward": if (d > 1) { for (k = 0; k < d; k++) g += t[this.rtl ? d - 1 - k : k], Y( this, p, g, f, a, b ); break; } default: if (Y(this, p, t, f, a, b), e && l > 1 && r < l - 1) for (d = this.N, g = t, f = Math.min(e + 1, this.rtl ? r + 1 : l - r), k = 1; k < f; k++) { t = c[this.rtl ? l - 1 - r - k : r + k]; h = this.bidirectional && t > g; const n = this.score ? this.score(c, g, r, t, k - 1) : wb(d + (l / 2 > d ? 0 : 1), l, r, f - 1, k - 1); Y(this, m, h ? g : t, n, a, b, h ? t : g); } } } } this.fastupdate || this.reg.add(a); } } this.db && (this.commit_task.push(b ? { ins: a } : { del: a }), this.M && ub(this)); return this; }; function Y(a, c, b, e, d, f, g) { let k, h; if (!(k = c[b]) || g && !k[g]) { g ? (c = k || (c[b] = I()), c[g] = 1, h = a.ctx, (k = h.get(g)) ? h = k : h.set(g, h = a.keystore ? new R(a.keystore) : new Map())) : (h = a.map, c[b] = 1); (k = h.get(b)) ? h = k : h.set(b, h = k = []); if (f) { for (let l = 0, m; l < k.length; l++) if ((m = k[l]) && m.includes(d)) { if (l <= e) return; m.splice(m.indexOf(d), 1); a.fastupdate && (c = a.reg.get(d)) && c.splice(c.indexOf(m), 1); break; } } h = h[e] || (h[e] = []); h.push(d); if (h.length === __pow(2, 31) - 1) { c = new xa(h); if (a.fastupdate) for (let l of a.reg.values()) l.includes(h) && (l[l.indexOf(h)] = c); k[e] = h = c; } a.fastupdate && ((e = a.reg.get(d)) ? e.push(h) : a.reg.set(d, [h])); } } function wb(a, c, b, e, d) { return b && a > 1 ? c + (e || 0) <= a ? b + (d || 0) : (a - 1) / (c + (e || 0)) * (b + (d || 0)) + 1 | 0 : 0; } T.prototype.search = function(a, c, b) { b || (c || typeof a !== "object" ? typeof c === "object" && (b = c, c = 0) : (b = a, a = "")); if (b && b.cache) return b.cache = false, a = this.searchCache(a, c, b), b.cache = true, a; let e = [], d, f, g, k = 0, h, l, m, p, u; b && (a = b.query || a, c = b.limit || c, k = b.offset || 0, f = b.context, g = b.suggest, u = (h = b.resolve) && b.enrich, m = b.boost, p = b.resolution, l = this.db && b.tag); typeof h === "undefined" && (h = this.resolve); f = this.depth && f !== false; let r = this.encoder.encode(a, !f); d = r.length; c = c || (h ? 100 : 0); if (d === 1) return xb.call( this, r[0], "", c, k, h, u, l ); if (d === 2 && f && !g) return xb.call(this, r[1], r[0], c, k, h, u, l); let t = I(), n = 0, q; f && (q = r[0], n = 1); p || p === 0 || (p = q ? this.N : this.resolution); if (this.db) { if (this.db.search && (b = this.db.search(this, r, c, k, g, h, u, l), b !== false)) return b; const x = this; return (function() { return __async(this, null, function* () { for (let v, A; n < d; n++) { if ((A = r[n]) && !t[A]) { t[A] = 1; v = yield yb(x, A, q, 0, 0, false, false); if (v = zb(v, e, g, p)) { e = v; break; } q && (g && v && e.length || (q = A)); } g && q && n === d - 1 && !e.length && (p = x.resolution, q = "", n = -1, t = I()); } return Ab(e, p, c, k, g, m, h); }); })(); } for (let x, v; n < d; n++) { if ((v = r[n]) && !t[v]) { t[v] = 1; x = yb(this, v, q, 0, 0, false, false); if (x = zb(x, e, g, p)) { e = x; break; } q && (g && x && e.length || (q = v)); } g && q && n === d - 1 && !e.length && (p = this.resolution, q = "", n = -1, t = I()); } return Ab(e, p, c, k, g, m, h); }; function Ab(a, c, b, e, d, f, g) { let k = a.length, h = a; if (k > 1) h = $a(a, c, b, e, d, f, g); else if (k === 1) return g ? Sa.call(null, a[0], b, e) : new X(a[0], this); return g ? h : new X(h, this); } function xb(a, c, b, e, d, f, g) { a = yb(this, a, c, b, e, d, f, g); return this.db ? a.then(function(k) { return d ? k || [] : new X(k, this); }) : a && a.length ? d ? Sa.call(this, a, b, e) : new X(a, this) : d ? [] : new X([], this); } function zb(a, c, b, e) { let d = []; if (a && a.length) { if (a.length <= e) { c.push(a); return; } for (let f = 0, g; f < e; f++) if (g = a[f]) d[f] = g; if (d.length) { c.push(d); return; } } if (!b) return d; } function yb(a, c, b, e, d, f, g, k) { let h; b && (h = a.bidirectional && c > b) && (h = b, b = c, c = h); if (a.db) return a.db.get(c, b, e, d, f, g, k); a = b ? (a = a.ctx.get(b)) && a.get(c) : a.map.get(c); return a; } function T(a, c) { if (!this || this.constructor !== T) return new T(a); if (a) { var b = M(a) ? a : a.preset; b && (a = Object.assign({}, vb[b], a)); } else a = {}; b = a.context; const e = b === true ? { depth: 1 } : b || {}, d = M(a.encoder) ? va[a.encoder] : a.encode || a.encoder || {}; this.encoder = d.encode ? d : typeof d === "object" ? new ka(d) : { encode: d }; this.resolution = a.resolution || 9; this.tokenize = b = (b = a.tokenize) && b !== "default" && b !== "exact" && b || "strict"; this.depth = b === "strict" && e.depth || 0; this.bidirectional = e.bidirectional !== false; this.fastupdate = !!a.fastupdate; this.score = a.score || null; (b = a.keystore || 0) && (this.keystore = b); this.map = b ? new R(b) : new Map(); this.ctx = b ? new R(b) : new Map(); this.reg = c || (this.fastupdate ? b ? new R(b) : new Map() : b ? new S(b) : new Set()); this.N = e.resolution || 3; this.rtl = d.rtl || a.rtl || false; this.cache = (b = a.cache || null) && new ma(b); this.resolve = a.resolve !== false; if (b = a.db) this.db = this.mount(b); this.M = a.commit !== false; this.commit_task = []; this.commit_timer = null; this.priority = a.priority || 4; } w = T.prototype; w.mount = function(a) { this.commit_timer && (clearTimeout(this.commit_timer), this.commit_timer = null); return a.mount(this); }; w.commit = function() { this.commit_timer && (clearTimeout(this.commit_timer), this.commit_timer = null); return this.db.commit(this); }; w.destroy = function() { this.commit_timer && (clearTimeout(this.commit_timer), this.commit_timer = null); return this.db.destroy(); }; function ub(a) { a.commit_timer || (a.commit_timer = setTimeout(function() { a.commit_timer = null; a.db.commit(a); }, 1)); } w.clear = function() { this.map.clear(); this.ctx.clear(); this.reg.clear(); this.cache && this.cache.clear(); return this.db ? (this.commit_timer && clearTimeout(this.commit_timer), this.commit_timer = null, this.commit_task = [], this.db.clear()) : this; }; w.append = function(a, c) { return this.add(a, c, true); }; w.contain = function(a) { return this.db ? this.db.has(a) : this.reg.has(a); }; w.update = function(a, c) { const b = this, e = this.remove(a); return e && e.then ? e.then(() => b.add(a, c)) : this.add(a, c); }; w.cleanup = function() { if (!this.fastupdate) return this; tb(this.map); this.depth && tb(this.ctx); return this; }; w.searchCache = la; w.export = function(a, c, b = 0, e = 0) { let d, f; switch (e) { case 0: d = "reg"; f = pb(this.reg); break; case 1: d = "cfg"; f = null; break; case 2: d = "map"; f = lb(this.map, this.reg.size); break; case 3: d = "ctx"; f = nb(this.ctx, this.reg.size); break; default: return; } return rb.call(this, a, c, d, f, b, e); }; w.import = function(a, c) { if (c) switch (typeof c === "string" && (c = JSON.parse(c)), a = a.split("."), a[a.length - 1] === "json" && a.pop(), a.length === 3 && a.shift(), a = a.length > 1 ? a[1] : a[0], a) { case "reg": this.fastupdate = false; this.reg = qb(c, this.reg); break; case "map": this.map = mb(c, this.map); break; case "ctx": this.ctx = ob(c, this.ctx); } }; w.serialize = function(a = true) { let c = "", b = "", e = ""; if (this.reg.size) { let f; for (var d of this.reg.keys()) f || (f = typeof d), c += (c ? "," : "") + (f === "string" ? '"' + d + '"' : d); c = "index.reg=new Set([" + c + "]);"; b = sb(this.map, f); b = "index.map=new Map([" + b + "]);"; for (const g of this.ctx.entries()) { d = g[0]; let k = sb(g[1], f); k = "new Map([" + k + "])"; k = '["' + d + '",' + k + "]"; e += (e ? "," : "") + k; } e = "index.ctx=new Map([" + e + "]);"; } return a ? "function inject(index){" + c + b + e + "}" : c + b + e; }; Fa(T.prototype); const Bb = typeof window !== "undefined" && (window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB), Cb = ["map", "ctx", "tag", "reg", "cfg"], Db = I(); function Eb(a, c = {}) { if (!this || this.constructor !== Eb) return new Eb(a, c); typeof a === "object" && (c = a, a = a.name); a || console.info("Default storage space was used, because a name was not passed."); this.id = "flexsearch" + (a ? ":" + a.toLowerCase().replace(/[^a-z0-9_\-]/g, "") : ""); this.field = c.field ? c.field.toLowerCase().replace(/[^a-z0-9_\-]/g, "") : ""; this.type = c.type; this.fastupdate = this.support_tag_search = false; this.db = null; this.h = {}; } w = Eb.prototype; w.mount = function(a) { if (a.index) return a.mount(this); a.db = this; return this.open(); }; w.open = function() { if (this.db) return this.db; let a = this; navigator.storage && navigator.storage.persist && navigator.storage.persist(); Db[a.id] || (Db[a.id] = []); Db[a.id].push(a.field); const c = Bb.open(a.id, 1); c.onupgradeneeded = function() { const b = a.db = this.result; for (let e = 0, d; e < Cb.length; e++) { d = Cb[e]; for (let f = 0, g; f < Db[a.id].length; f++) g = Db[a.id][f], b.objectStoreNames.contains(d + (d !== "reg" ? g ? ":" + g : "" : "")) || b.createObjectStore(d + (d !== "reg" ? g ? ":" + g : "" : "")); } }; return a.db = Z(c, function(b) { a.db = b; a.db.onversionchange = function() { a.close(); }; }); }; w.close = function() { this.db && this.db.close(); this.db = null; }; w.destroy = function() { const a = Bb.deleteDatabase(this.id); return Z(a); }; w.clear = function() { const a = []; for (let b = 0, e; b < Cb.length; b++) { e = Cb[b]; for (let d = 0, f; d < Db[this.id].length; d++) f = Db[this.id][d], a.push(e + (e !== "reg" ? f ? ":" + f : "" : "")); } const c = this.db.transaction(a, "readwrite"); for (let b = 0; b < a.length; b++) c.objectStore(a[b]).clear(); return Z(c); }; w.get = function(a, c, b = 0, e = 0, d = true, f = false) { a = this.db.transaction((c ? "ctx" : "map") + (this.field ? ":" + this.field : ""), "readonly").objectStore((c ? "ctx" : "map") + (this.field ? ":" + this.field : "")).get(c ? c + ":" + a : a); const g = this; return Z(a).then(function(k) { let h = []; if (!k || !k.length) return h; if (d) { if (!b && !e && k.length === 1) return k[0]; for (let l = 0, m; l < k.length; l++) if ((m = k[l]) && m.length) { if (e >= m.length) { e -= m.length; continue; } const p = b ? e + Math.min(m.length - e, b) : m.length; for (let u = e; u < p; u++) h.push(m[u]); e = 0; if (h.length === b) break; } return f ? g.enrich(h) : h; } return k; }); }; w.tag = function(a, c = 0, b = 0, e = false) { a = this.db.transaction("tag" + (this.field ? ":" + this.field : ""), "readonly").objectStore("tag" + (this.field ? ":" + this.field : "")).get(a); const d = this; return Z(a).then(function(f) { if (!f || !f.length || b >= f.length) return []; if (!c && !b) return f; f = f.slice(b, b + c); return e ? d.enrich(f) : f; }); }; w.enrich = function(a) { typeof a !== "object" && (a = [a]); const c = this.db.transaction("reg", "readonly").objectStore("reg"), b = []; for (let e = 0; e < a.length; e++) b[e] = Z(c.get(a[e])); return Promise.all(b).then(function(e) { for (let d = 0; d < e.length; d++) e[d] = { id: a[d], doc: e[d] ? JSON.parse(e[d]) : null }; return e; }); }; w.has = function(a) { a = this.db.transaction("reg", "readonly").objectStore("reg").getKey(a); return Z(a).then(function(c) { return !!c; }); }; w.search = null; w.info = function() { }; w.transaction = function(a, c, b) { a += a !== "reg" ? this.field ? ":" + this.field : "" : ""; let e = this.h[a + ":" + c]; if (e) return b.call(this, e); let d = this.db.transaction(a, c); this.h[a + ":" + c] = e = d.objectStore(a); const f = b.call(this, e); this.h[a + ":" + c] = null; return Z(d).finally(function() { return f; }); }; w.commit = function(a) { return __async(this, null, function* () { let c = a.commit_task, b = []; a.commit_task = []; for (let e = 0, d; e < c.length; e++) d = c[e], d.del && b.push(d.del); b.length && (yield this.remove(b)); a.reg.size && (yield this.transaction("map", "readwrite", function(e) { for (const d of a.map) { const f = d[0], g = d[1]; g.length && (e.get(f).onsuccess = function() { let k = this.result; var h; if (k && k.length) { const l = Math.max(k.length, g.length); for (let m = 0, p, u; m < l; m++) if ((u = g[m]) && u.length) { if ((p = k[m]) && p.length) for (h = 0; h < u.length; h++) p.push(u[h]); else k[m] = u; h = 1; } } else k = g, h = 1; h && e.put(k, f); }); } }), yield this.transaction("ctx", "readwrite", function(e) { for (const d of a.ctx) { const f = d[0], g = d[1]; for (const k of g) { const h = k[0], l = k[1]; l.length && (e.get(f + ":" + h).onsuccess = function() { let m = this.result; var p; if (m && m.length) { const u = Math.max(m.length, l.length); for (let r = 0, t, n; r < u; r++) if ((n = l[r]) && n.length) { if ((t = m[r]) && t.length) for (p = 0; p < n.length; p++) t.push(n[p]); else m[r] = n; p = 1; } } else m = l, p = 1; p && e.put(m, f + ":" + h); }); } } }), a.store ? yield this.transaction( "reg", "readwrite", function(e) { for (const d of a.store) { const f = d[0], g = d[1]; e.put(typeof g === "object" ? JSON.stringify(g) : 1, f); } } ) : a.bypass || (yield this.transaction("reg", "readwrite", function(e) { for (const d of a.reg.keys()) e.put(1, d); })), a.tag && (yield this.transaction("tag", "readwrite", function(e) { for (const d of a.tag) { const f = d[0], g = d[1]; g.length && (e.get(f).onsuccess = function() { let k = this.result; k = k && k.length ? k.concat(g) : g; e.put(k, f); }); } })), a.map.clear(), a.ctx.clear(), a.tag && a.tag.clear(), a.store && a.store.clear(), a.document || a.reg.clear()); }); }; function Fb(a, c, b) { const e = a.value; let d, f = 0; for (let g = 0, k; g < e.length; g++) { if (k = b ? e : e[g]) { for (let h = 0, l, m; h < c.length; h++) if (m = c[h], l = k.indexOf(m), l >= 0) if (d = 1, k.length > 1) k.splice(l, 1); else { e[g] = []; break; } f += k.length; } if (b) break; } f ? d && a.update(e) : a.delete(); a.continue(); } w.remove = function(a) { typeof a !== "object" && (a = [a]); return Promise.all([this.transaction("map", "readwrite", function(c) { c.openCursor().onsuccess = function() { const b = this.result; b && Fb(b, a); }; }), this.transaction("ctx", "readwrite", function(c) { c.openCursor().onsuccess = function() { const b = this.result; b && Fb(b, a); }; }), this.transaction("tag", "readwrite", function(c) { c.openCursor().onsuccess = function() { const b = this.result; b && Fb(b, a, true); }; }), this.transaction("reg", "readwrite", function(c) { for (let b = 0; b < a.length; b++) c.delete(a[b]); })]); }; function Z(a, c) { return new Promise((b, e) => { a.onsuccess = a.oncomplete = function() { c && c(this.result); c = null; b(this.result); }; a.onerror = a.onblocked = e; a = null; }); } const Index = T; const DanmukuDB = { db: null, initialized: false, memoryCache: new Map(), searchIndex: null, indexBuilt: false, init() { return __async(this, null, function* () { if (this.initialized) { return true; } try { this.db = yield this._openDatabase(); this.initialized = true; yield this._buildMemoryIndex(); Utils.log("弹幕数据库初始化成功"); return true; } catch (error) { Utils.log(`弹幕数据库初始化失败: ${error.message}`, "error"); return false; } }); }, _openDatabase() { return new Promise((resolve, reject) => { const request = indexedDB.open(CONFIG.DB_NAME, CONFIG.DB_VERSION); request.onerror = () => { reject(new Error("数据库打开失败")); }; request.onsuccess = (event) => { resolve(event.target.result); }; request.onupgradeneeded = (event) => { const db = event.target.result; if (!db.objectStoreNames.contains(CONFIG.DB_STORE_NAME)) { const store = db.createObjectStore(CONFIG.DB_STORE_NAME, { keyPath: "id", autoIncrement: true }); store.createIndex("text", "text", { unique: false }); store.createIndex("tags", "tags", { unique: false, multiEntry: true }); store.createIndex("syncState", "syncState", { unique: false }); store.createIndex("lastUsed", "lastUsed", { unique: false }); store.createIndex("useCount", "useCount", { unique: false }); store.createIndex("popularity", "popularity", { unique: false }); store.createIndex("originalId", "originalId", { unique: false }); store.createIndex("category", "category", { unique: false }); } if (!db.objectStoreNames.contains("tag_dictionary")) { const tagStore = db.createObjectStore("tag_dictionary", { keyPath: "dictValue" }); tagStore.createIndex("dictLabel", "dictLabel", { unique: false }); tagStore.createIndex("dictType", "dictType", { unique: false }); } if (!db.objectStoreNames.contains("import_logs")) { const logStore = db.createObjectStore("import_logs", { keyPath: "id", autoIncrement: true }); logStore.createIndex("timestamp", "timestamp", { unique: false }); logStore.createIndex("status", "status", { unique: false }); } }; }); }, add(_0) { return __async(this, arguments, function* (text, tags = []) { if (!this.initialized) { Utils.log("数据库未初始化", "error"); return null; } try { const danmukuData = { text: text.trim(), tags: tags.filter((tag) => tag.trim()), syncState: "pending", createdAt: Date.now(), lastUsed: Date.now(), useCount: 1 }; const transaction = this.db.transaction([CONFIG.DB_STORE_NAME], "readwrite"); const store = transaction.objectStore(CONFIG.DB_STORE_NAME); const request = store.add(danmukuData); return new Promise((resolve, reject) => { request.onsuccess = (event) => { const id = event.target.result; const newData = __spreadProps(__spreadValues({}, danmukuData), { id }); this.memoryCache.set(id, newData); if (this.searchIndex) { const searchContent = [newData.text, ...newData.tags].join(" "); this.searchIndex.add(newData.id, searchContent); } Utils.log(`弹幕模板添加成功: ${text}`); resolve(id); }; request.onerror = () => { reject(new Error("添加弹幕模板失败")); }; }); } catch (error) { Utils.log(`添加弹幕模板异常: ${error.message}`, "error"); return null; } }); }, search(_0) { return __async(this, arguments, function* (query, limit = DEFAULT_SETTINGS.maxSuggestions, sortBy = "relevance") { if (!this.initialized || !query) { Utils.log("搜索条件无效: 数据库未初始化或查询为空"); return []; } try { if (!this.indexBuilt) { yield this._buildMemoryIndex(); } const searchIds = this.searchIndex.search(query, limit * 2); let matchedDanmuku = searchIds.map((id) => this.memoryCache.get(id)).filter((item) => item); switch (sortBy) { case "popularity": matchedDanmuku.sort((a, b) => (b.popularity || 0) - (a.popularity || 0)); break; case "recent": matchedDanmuku.sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0)); break; case "usage": matchedDanmuku.sort((a, b) => { if (b.useCount !== a.useCount) { return (b.useCount || 0) - (a.useCount || 0); } return (b.lastUsed || 0) - (a.lastUsed || 0); }); break; default: matchedDanmuku.sort((a, b) => { const scoreA = (a.useCount || 0) * 0.4 + (a.popularity || 0) * 0.3 + (a.lastUsed || 0) / 1e6 * 0.3; const scoreB = (b.useCount || 0) * 0.4 + (b.popularity || 0) * 0.3 + (b.lastUsed || 0) / 1e6 * 0.3; return scoreB - scoreA; }); break; } const finalResults = matchedDanmuku.slice(0, limit); Utils.log(`搜索 "${query}" (${sortBy}) 返回 ${finalResults.length} 条结果`); return finalResults; } catch (error) { Utils.log(`搜索弹幕模板异常: ${error.message}`, "error"); return []; } }); }, updateUsage(id) { return __async(this, null, function* () { if (!this.initialized) { return false; } try { const transaction = this.db.transaction([CONFIG.DB_STORE_NAME], "readwrite"); const store = transaction.objectStore(CONFIG.DB_STORE_NAME); const getRequest = store.get(id); return new Promise((resolve) => { getRequest.onsuccess = (event) => { const data = event.target.result; if (data) { data.useCount = (data.useCount || 0) + 1; data.lastUsed = Date.now(); const putRequest = store.put(data); putRequest.onsuccess = () => { this.memoryCache.set(id, data); if (this.searchIndex) { const searchContent = [data.text, ...data.tags].join(" "); this.searchIndex.update(data.id, searchContent); } resolve(true); }; putRequest.onerror = () => resolve(false); } else { resolve(false); } }; getRequest.onerror = () => resolve(false); }); } catch (error) { Utils.log(`更新使用统计异常: ${error.message}`, "error"); return false; } }); }, delete(id) { return __async(this, null, function* () { if (!this.initialized) { return false; } try { const transaction = this.db.transaction([CONFIG.DB_STORE_NAME], "readwrite"); const store = transaction.objectStore(CONFIG.DB_STORE_NAME); const request = store.delete(id); return new Promise((resolve) => { request.onsuccess = () => { this.memoryCache.delete(id); if (this.searchIndex) { this.searchIndex.remove(id); } Utils.log(`弹幕模板删除成功: ID ${id}`); resolve(true); }; request.onerror = () => { Utils.log(`弹幕模板删除失败: ID ${id}`, "error"); resolve(false); }; }); } catch (error) { Utils.log(`删除弹幕模板异常: ${error.message}`, "error"); return false; } }); }, getAll() { return __async(this, null, function* () { if (!this.initialized) { return []; } try { const transaction = this.db.transaction([CONFIG.DB_STORE_NAME], "readonly"); const store = transaction.objectStore(CONFIG.DB_STORE_NAME); const request = store.getAll(); return new Promise((resolve) => { request.onsuccess = (event) => { resolve(event.target.result || []); }; request.onerror = () => { Utils.log("获取所有弹幕模板失败", "error"); resolve([]); }; }); } catch (error) { Utils.log(`获取所有弹幕模板异常: ${error.message}`, "error"); return []; } }); }, clear() { return __async(this, null, function* () { if (!this.initialized) { return false; } try { const transaction = this.db.transaction([CONFIG.DB_STORE_NAME], "readwrite"); const store = transaction.objectStore(CONFIG.DB_STORE_NAME); const request = store.clear(); return new Promise((resolve) => { request.onsuccess = () => { this.memoryCache.clear(); if (this.searchIndex) { this.searchIndex = null; this.indexBuilt = false; } Utils.log("弹幕数据库已清空"); resolve(true); }; request.onerror = () => { Utils.log("清空弹幕数据库失败", "error"); resolve(false); }; }); } catch (error) { Utils.log(`清空数据库异常: ${error.message}`, "error"); return false; } }); }, initTagDictionary() { return __async(this, null, function* () { try { const response = yield fetch("https://hguofichp.cn:10086/machine/dictList"); const result = yield response.json(); if (result.code === 200 && result.data) { const transaction = this.db.transaction(["tag_dictionary"], "readwrite"); const store = transaction.objectStore("tag_dictionary"); yield new Promise((resolve, reject) => { const clearRequest = store.clear(); clearRequest.onsuccess = () => resolve(); clearRequest.onerror = () => reject(new Error("清空标签字典失败")); }); for (const tag of result.data) { yield new Promise((resolve, reject) => { const addRequest = store.add(tag); addRequest.onsuccess = () => resolve(); addRequest.onerror = () => reject(new Error("添加标签失败")); }); } Utils.log(`标签字典初始化完成,共 ${result.data.length} 个标签`); return true; } return false; } catch (error) { Utils.log(`标签字典初始化失败: ${error.message}`, "error"); return false; } }); }, getTagDictionary() { return __async(this, null, function* () { try { const transaction = this.db.transaction(["tag_dictionary"], "readonly"); const store = transaction.objectStore("tag_dictionary"); const request = store.getAll(); return new Promise((resolve) => { request.onsuccess = (event) => { resolve(event.target.result || []); }; request.onerror = () => resolve([]); }); } catch (error) { Utils.log(`获取标签字典失败: ${error.message}`, "error"); return []; } }); }, importFromUrl(url) { return __async(this, null, function* () { Utils.log(`开始从 URL 下载弹幕数据: ${url}`); try { const response = yield fetch(url, { method: "GET", headers: { "Accept": "application/json" } }); if (!response.ok) { throw new Error(`网络响应错误: ${response.status} ${response.statusText}`); } const jsonData = yield response.json(); Utils.log(`数据下载成功,共 ${jsonData.length} 条。开始导入数据库...`); return yield this.importFromJson(jsonData); } catch (error) { Utils.log(`从 URL 导入数据失败: ${error.message}`, "error"); return null; } }); }, importFromJson(jsonData) { return __async(this, null, function* () { const startTime = Date.now(); const importLog = { timestamp: startTime, source: "json_data", status: "running", totalProcessed: 0, successCount: 0, failCount: 0, duplicateCount: 0, errors: [] }; try { const tagDict = yield this.getTagDictionary(); const tagMap = new Map(tagDict.map((tag) => [tag.dictValue, tag.dictLabel])); const existingData = yield this.getAll(); const existingTexts = new Set(existingData.map((item) => item.text)); importLog.totalProcessed = jsonData.length; for (const item of jsonData) { try { if (existingTexts.has(item.barrage)) { importLog.duplicateCount++; continue; } const tagValues = item.tags ? String(item.tags).split(",").map((t) => t.trim()) : []; const tagLabels = tagValues.map((value) => tagMap.get(value) || value).filter(Boolean); const danmakuData = { text: item.barrage.trim(), tags: tagLabels, originalId: item.id, popularity: parseInt(item.cnt) || 0, category: "imported", syncState: "synced", createdAt: new Date(item.submitTime).getTime(), lastUsed: 0, useCount: 0, source: "json_import", importBatch: startTime }; const transaction = this.db.transaction([CONFIG.DB_STORE_NAME], "readwrite"); const store = transaction.objectStore(CONFIG.DB_STORE_NAME); yield new Promise((resolve, reject) => { const addRequest = store.add(danmakuData); addRequest.onsuccess = () => resolve(); addRequest.onerror = (e) => reject(new Error(`数据库添加失败: ${e.target.error}`)); }); existingTexts.add(item.barrage); importLog.successCount++; } catch (error) { importLog.failCount++; importLog.errors.push(`处理弹幕 (ID: ${item.id}) 失败: ${error.message}`); } } importLog.status = "completed"; importLog.duration = Date.now() - startTime; yield this._saveImportLog(importLog); yield this._buildMemoryIndex(); Utils.log(`JSON数据导入完成!成功 ${importLog.successCount}, 失败 ${importLog.failCount}, 重复 ${importLog.duplicateCount}`); return importLog; } catch (error) { importLog.status = "failed"; importLog.duration = Date.now() - startTime; importLog.errors.push(`导入过程异常: ${error.message}`); yield this._saveImportLog(importLog); Utils.log(`从JSON导入数据失败: ${error.message}`, "error"); return importLog; } }); }, autoImportData() { return __async(this, null, function* () { const startTime = Date.now(); const importLog = { timestamp: startTime, source: "url_import", status: "running", errors: [] }; try { yield this.initTagDictionary(); const dataUrl = "https://data.ienone.top/danmuku/danmuku_v0.json"; const result = yield this.importFromUrl(dataUrl); if (result) { Utils.log(`弹幕数据导入完成!`); return result; } else { throw new Error("从URL导入返回了null"); } } catch (error) { importLog.status = "failed"; importLog.duration = Date.now() - startTime; importLog.errors.push(`导入过程异常: ${error.message}`); yield this._saveImportLog(importLog); Utils.log(`弹幕数据导入失败: ${error.message}`, "error"); return importLog; } }); }, _saveImportLog(logData) { return __async(this, null, function* () { try { const transaction = this.db.transaction(["import_logs"], "readwrite"); const store = transaction.objectStore("import_logs"); yield new Promise((resolve, reject) => { const addRequest = store.add(logData); addRequest.onsuccess = () => resolve(); addRequest.onerror = () => reject(new Error("保存日志失败")); }); } catch (error) { Utils.log(`保存导入日志失败: ${error.message}`, "error"); } }); }, getImportLogs(limit = 10) { return __async(this, null, function* () { try { const transaction = this.db.transaction(["import_logs"], "readonly"); const store = transaction.objectStore("import_logs"); const index = store.index("timestamp"); const request = index.openCursor(null, "prev"); return new Promise((resolve) => { const logs = []; let count = 0; request.onsuccess = (event) => { const cursor = event.target.result; if (cursor && count < limit) { logs.push(cursor.value); count++; cursor.continue(); } else { resolve(logs); } }; request.onerror = () => resolve([]); }); } catch (error) { Utils.log(`获取导入日志失败: ${error.message}`, "error"); return []; } }); }, _buildMemoryIndex() { return __async(this, null, function* () { if (this.indexBuilt || !this.initialized) { return; } try { const allData = yield this.getAll(); this.memoryCache.clear(); allData.forEach((item) => { this.memoryCache.set(item.id, item); }); this.searchIndex = new Index({ tokenize: "forward", resolution: 9, depth: 3, encode: false, cache: true }); allData.forEach((item) => { const searchContent = [item.text, ...item.tags].join(" "); this.searchIndex.add(item.id, searchContent); }); this.indexBuilt = true; Utils.log(`内存索引构建完成,缓存 ${allData.length} 条弹幕模板`); } catch (error) { Utils.log(`构建内存索引异常: ${error.message}`, "error"); } }); }, testAutoImport() { return __async(this, null, function* () { Utils.log(`=== 开始测试自动导入功能 ===`); const result = yield this.autoImportData(); Utils.log("=== 导入测试完成,结果统计 ==="); Utils.log(`导入状态: ${result.status}`); Utils.log(`总处理数量: ${result.totalProcessed}`); Utils.log(`成功导入: ${result.successCount}`); Utils.log(`失败数量: ${result.failCount}`); Utils.log(`重复跳过: ${result.duplicateCount}`); Utils.log(`耗时: ${(result.duration / 1e3).toFixed(2)} 秒`); if (result.errors.length > 0) { Utils.log("错误详情:", "warn"); result.errors.forEach((error, index) => { Utils.log(`${index + 1}. ${error}`, "warn"); }); } const totalCount = yield this.getDataCount(); Utils.log(`当前数据库总数据量: ${totalCount}`); return result; }); }, getDataCount() { return __async(this, null, function* () { try { const transaction = this.db.transaction([CONFIG.DB_STORE_NAME], "readonly"); const store = transaction.objectStore(CONFIG.DB_STORE_NAME); const request = store.count(); return new Promise((resolve) => { request.onsuccess = (event) => { resolve(event.target.result || 0); }; request.onerror = () => resolve(0); }); } catch (error) { Utils.log(`获取数据总量失败: ${error.message}`, "error"); return 0; } }); }, getStatistics() { return __async(this, null, function* () { try { const allData = yield this.getAll(); const imported = allData.filter((item) => item.category === "imported"); const userCreated = allData.filter((item) => item.category !== "imported"); const stats = { total: allData.length, imported: imported.length, userCreated: userCreated.length, avgPopularity: imported.length > 0 ? (imported.reduce((sum, item) => sum + (item.popularity || 0), 0) / imported.length).toFixed(1) : 0, topUsed: allData.sort((a, b) => (b.useCount || 0) - (a.useCount || 0)).slice(0, 5).map((item) => ({ text: item.text, useCount: item.useCount || 0 })) }; Utils.log("=== 数据库统计信息 ==="); Utils.log(`总数据量: ${stats.total}`); Utils.log(`导入数据: ${stats.imported}`); Utils.log(`用户创建: ${stats.userCreated}`); Utils.log(`平均人气: ${stats.avgPopularity}`); Utils.log("最常用弹幕:"); stats.topUsed.forEach((item, index) => { Utils.log(`${index + 1}. "${item.text}" (使用${item.useCount}次)`); }); return stats; } catch (error) { Utils.log(`获取统计信息失败: ${error.message}`, "error"); return {}; } }); } }; const PanelState = { HIDDEN: "hidden", VISIBLE: "visible" }; const SelectionMode = { KEYBOARD: "keyboard", MOUSE: "mouse" }; const CandidateItem = { createCandidateItem(candidate, index, isActive = false) { const item = document.createElement("div"); item.className = CONFIG.CSS_CLASSES.POPUP_ITEM; item.dataset.index = index; if (isActive) { item.classList.add(CONFIG.CSS_CLASSES.POPUP_ITEM_ACTIVE); } const textElement = document.createElement("div"); textElement.className = CONFIG.CSS_CLASSES.POPUP_ITEM_TEXT; textElement.textContent = candidate.getDisplayText ? candidate.getDisplayText() : candidate.text; if (candidate.useCount > 0) { textElement.title = `使用次数: ${candidate.useCount}`; } item.appendChild(textElement); this.bindItemEvents(item, candidate, index); return item; }, bindItemEvents(itemEl, candidate, index) { this.bindItemClick(itemEl, candidate, index); this.bindItemHover(itemEl, index); }, bindItemClick(itemEl, candidate, index) { itemEl.addEventListener("click", (event) => { event.preventDefault(); event.stopPropagation(); this._emitSelectEvent(candidate, index, "click"); }); }, bindItemHover(itemEl, index) { let previewTimer = null; itemEl.addEventListener("mouseenter", () => { var _a, _b, _c; this._emitHoverEvent(index); previewTimer = setTimeout(() => { this._showPreview(itemEl); }, ((_c = (_b = (_a = CONFIG.DEFAULT_SETTINGS) == null ? void 0 : _a.capsule) == null ? void 0 : _b.preview) == null ? void 0 : _c.showDelay) || 500); }); itemEl.addEventListener("mouseleave", () => { if (previewTimer) { clearTimeout(previewTimer); previewTimer = null; } this._hidePreview(); }); }, updateActiveState(itemEl, isActive) { if (isActive) { itemEl.classList.add(CONFIG.CSS_CLASSES.POPUP_ITEM_ACTIVE); } else { itemEl.classList.remove(CONFIG.CSS_CLASSES.POPUP_ITEM_ACTIVE); } }, updateActiveStates(container, activeIndex) { const items = container.querySelectorAll(`.${CONFIG.CSS_CLASSES.POPUP_ITEM}`); items.forEach((item, index) => { this.updateActiveState(item, index === activeIndex); }); }, _emitSelectEvent(candidate, index, trigger) { const event = new CustomEvent("candidateSelected", { detail: { candidate, index, trigger } }); document.dispatchEvent(event); }, _emitHoverEvent(index) { const event = new CustomEvent("candidateHovered", { detail: { index } }); document.dispatchEvent(event); }, _showPreview(itemEl) { var _a, _b, _c; const previewElement = document.createElement("div"); previewElement.className = CONFIG.CSS_CLASSES.PREVIEW_POPUP; previewElement.textContent = itemEl.textContent; document.body.appendChild(previewElement); const itemRect = itemEl.getBoundingClientRect(); const previewWidth = 200; const previewHeight = 100; const verticalOffset = ((_c = (_b = (_a = CONFIG.DEFAULT_SETTINGS) == null ? void 0 : _a.capsule) == null ? void 0 : _b.preview) == null ? void 0 : _c.verticalOffset) || 8; let left = itemRect.left + window.scrollX; let top = itemRect.top + window.scrollY - previewHeight - verticalOffset; const rightEdge = left + previewWidth; if (rightEdge > window.innerWidth) { left = window.innerWidth - previewWidth - 10; } if (top < window.scrollY) { top = itemRect.bottom + window.scrollY + verticalOffset; } previewElement.style.left = `${left}px`; previewElement.style.top = `${top}px`; previewElement.classList.add("fade-in"); }, _hidePreview() { const previewElement = document.querySelector(`.${CONFIG.CSS_CLASSES.PREVIEW_POPUP}`); if (previewElement) { previewElement.classList.add("fade-out"); previewElement.addEventListener("animationend", () => { previewElement.remove(); }, { once: true }); } }, getItemHeight() { return CONFIG.ITEM_HEIGHT; } }; const CandidatePanel = { panelElement: null, contentElement: null, currentCandidates: [], currentActiveIndex: -1, showTimer: null, hideTimer: null, init() { this.createPanelDOM(); this.bindPanelEvents(); console.log("CandidatePanel initialized"); }, createPanelDOM() { this.panelElement = document.createElement("div"); this.panelElement.className = CONFIG.CSS_CLASSES.POPUP; this.panelElement.style.display = "none"; console.log("创建弹窗元素:", this.panelElement); console.log("弹窗CSS类名:", CONFIG.CSS_CLASSES.POPUP); this.contentElement = document.createElement("div"); this.contentElement.className = CONFIG.CSS_CLASSES.POPUP_CONTENT; this.panelElement.appendChild(this.contentElement); document.body.appendChild(this.panelElement); const addedElement = document.querySelector(`.${CONFIG.CSS_CLASSES.POPUP}`); console.log("弹窗是否成功添加到DOM:", !!addedElement); console.log("添加的弹窗元素:", addedElement); }, renderCandidatePanel(candidates, activeIndex = 0) { this.currentCandidates = candidates || []; this.currentActiveIndex = activeIndex; this.contentElement.innerHTML = ""; if (this.currentCandidates.length === 0) { this._renderEmptyState(); return; } this.currentCandidates.forEach((candidate, index) => { const isActive = index === activeIndex; const itemElement = CandidateItem.createCandidateItem(candidate, index, isActive); this.contentElement.appendChild(itemElement); }); this._updatePanelHeight(); }, showPanel(targetInput) { if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null; } this.showTimer = setTimeout(() => { this._positionPanel(targetInput); this.panelElement.style.display = "block"; requestAnimationFrame(() => { this.panelElement.classList.add(CONFIG.CSS_CLASSES.POPUP_SHOW); }); this._emitPanelEvent("panelShown"); }, CONFIG.POPUP_SHOW_DELAY); }, hidePanel() { if (this.showTimer) { clearTimeout(this.showTimer); this.showTimer = null; } this.hideTimer = setTimeout(() => { this.panelElement.classList.remove(CONFIG.CSS_CLASSES.POPUP_SHOW); setTimeout(() => { this.panelElement.style.display = "none"; }, CONFIG.ANIMATION_DURATION); this._emitPanelEvent("panelHidden"); }, CONFIG.POPUP_HIDE_DELAY); }, setActiveIndex(newActiveIndex) { if (newActiveIndex === this.currentActiveIndex) return; this.currentActiveIndex = newActiveIndex; CandidateItem.updateActiveStates(this.contentElement, newActiveIndex); this._emitPanelEvent("activeIndexChanged", { activeIndex: newActiveIndex, candidate: this.currentCandidates[newActiveIndex] || null }); }, getActiveCandidate() { if (this.currentActiveIndex >= 0 && this.currentActiveIndex < this.currentCandidates.length) { return this.currentCandidates[this.currentActiveIndex]; } return null; }, isVisible() { return this.panelElement.style.display !== "none" && this.panelElement.classList.contains(CONFIG.CSS_CLASSES.POPUP_SHOW); }, bindPanelEvents() { document.addEventListener("candidateSelected", (event) => { const { candidate, index } = event.detail; this._handleCandidateSelected(candidate, index); }); document.addEventListener("candidateHovered", (event) => { const { index } = event.detail; this.setActiveIndex(index); }); this.panelElement.addEventListener("click", (event) => { event.stopPropagation(); }); }, _renderEmptyState() { this.contentElement.innerHTML = ""; this.panelElement.classList.add(CONFIG.CSS_CLASSES.POPUP_EMPTY); const emptyElement = document.createElement("div"); emptyElement.className = CONFIG.CSS_CLASSES.EMPTY_MESSAGE; emptyElement.textContent = "暂无匹配的弹幕模板"; this.contentElement.appendChild(emptyElement); this.contentElement.style.maxHeight = "60px"; }, _positionPanel(targetInput) { if (!targetInput) return; const inputRect = targetInput.getBoundingClientRect(); const panelRect = this.panelElement.getBoundingClientRect(); let left = inputRect.left; let top = inputRect.bottom + 5; const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; if (left + panelRect.width > windowWidth - 20) { left = windowWidth - panelRect.width - 20; } if (left < 20) { left = 20; } if (top + panelRect.height > windowHeight - 20) { top = inputRect.top - panelRect.height - 5; } this.panelElement.style.left = `${left}px`; this.panelElement.style.top = `${top}px`; }, _updatePanelHeight() { const itemCount = this.currentCandidates.length; const itemHeight = CandidateItem.getItemHeight(); const maxHeight = CONFIG.MAX_POPUP_HEIGHT; let height = Math.min(itemCount * itemHeight, maxHeight); this.contentElement.style.maxHeight = `${height}px`; this.panelElement.classList.remove(CONFIG.CSS_CLASSES.POPUP_EMPTY); }, _handleCandidateSelected(candidate, index) { this._emitPanelEvent("candidateSelected", { candidate, index }); }, _emitPanelEvent(eventName, detail = {}) { const event = new CustomEvent(eventName, { detail }); document.dispatchEvent(event); }, destroy() { if (this.showTimer) { clearTimeout(this.showTimer); } if (this.hideTimer) { clearTimeout(this.hideTimer); } if (this.panelElement && this.panelElement.parentNode) { this.panelElement.parentNode.removeChild(this.panelElement); } this.panelElement = null; this.contentElement = null; this.currentCandidates = []; this.currentActiveIndex = -1; } }; const NativeSetter = { inputValueDescriptor: null, textareaValueDescriptor: null, init() { this.inputValueDescriptor = Object.getOwnPropertyDescriptor( HTMLInputElement.prototype, "value" ); this.textareaValueDescriptor = Object.getOwnPropertyDescriptor( HTMLTextAreaElement.prototype, "value" ); console.log("NativeSetter initialized"); }, setValue(element, value) { if (!element) return false; try { let descriptor = null; if (element.tagName === "INPUT") { descriptor = this.inputValueDescriptor; } else if (element.tagName === "TEXTAREA") { descriptor = this.textareaValueDescriptor; } if (!descriptor || !descriptor.set) { element.value = value; return true; } descriptor.set.call(element, value); this.dispatchInputEvent(element); return true; } catch (error) { console.warn("NativeSetter failed, falling back to direct assignment:", error); element.value = value; this.dispatchInputEvent(element); return false; } }, dispatchInputEvent(element) { try { const inputEvent = new Event("input", { bubbles: true, cancelable: true }); element.dispatchEvent(inputEvent); const changeEvent = new Event("change", { bubbles: true, cancelable: true }); element.dispatchEvent(changeEvent); } catch (error) { console.warn("Failed to dispatch input event:", error); } }, isFrameworkManaged(element) { return element && (element.dataset.frameworkManaged === "true" || element.hasAttribute("v-model") || element.hasAttribute("ng-model") || element._valueTracker || element.__reactInternalFiber || element.__reactInternalInstance); }, smartSetValue(element, value, options = {}) { const { forceNative = false, skipEvents = false } = options; if (!element) return false; try { if (forceNative || this.isFrameworkManaged(element)) { const result = this.setValue(element, value); if (!skipEvents && result) { this.dispatchAdditionalEvents(element); } return result; } else { element.value = value; if (!skipEvents) { this.dispatchInputEvent(element); } return true; } } catch (error) { console.error("SmartSetValue failed:", error); return false; } }, dispatchAdditionalEvents(element) { try { ["keydown", "keyup"].forEach((eventType) => { const keyEvent = new KeyboardEvent(eventType, { bubbles: true, cancelable: true, key: "Unidentified" }); element.dispatchEvent(keyEvent); }); if (document.activeElement !== element) { const focusEvent = new FocusEvent("focus", { bubbles: true, cancelable: true }); element.dispatchEvent(focusEvent); } } catch (error) { console.warn("Failed to dispatch additional events:", error); } }, getValue(element) { if (!element) return ""; try { let descriptor = null; if (element.tagName === "INPUT") { descriptor = this.inputValueDescriptor; } else if (element.tagName === "TEXTAREA") { descriptor = this.textareaValueDescriptor; } if (descriptor && descriptor.get) { return descriptor.get.call(element) || ""; } return element.value || ""; } catch (error) { console.warn("Failed to get value using native getter:", error); return element.value || ""; } } }; const InputInteraction = { activeInput: null, inputListeners: new Map(), init() { this.bindGlobalEvents(); console.log("InputInteraction initialized"); }, bindInputEvents(inputEl) { if (!inputEl || this.inputListeners.has(inputEl)) { return; } const listeners = { focus: (event) => this._handleInputFocus(event, inputEl), blur: (event) => this._handleInputBlur(event, inputEl), input: (event) => this._handleInputChange(event, inputEl), keydown: (event) => this._handleInputKeyDown(event, inputEl) }; Object.entries(listeners).forEach(([eventName, listener]) => { inputEl.addEventListener(eventName, listener); }); this.inputListeners.set(inputEl, listeners); }, unbindInputEvents(inputEl) { if (!this.inputListeners.has(inputEl)) return; const listeners = this.inputListeners.get(inputEl); Object.entries(listeners).forEach(([eventName, listener]) => { inputEl.removeEventListener(eventName, listener); }); this.inputListeners.delete(inputEl); }, replaceInputWithText(inputEl, text) { if (!inputEl) return; NativeSetter.setValue(inputEl, text); this._setCursorToEnd(inputEl); this._triggerInputEvent(inputEl); }, getActiveInput() { return this.activeInput; }, bindGlobalEvents() { document.addEventListener("candidateSelected", (event) => { const { candidate } = event.detail; this._handleCandidateSelected(candidate); }); }, _handleInputFocus(event, inputEl) { this.activeInput = inputEl; this._emitInputEvent("inputFocused", { inputEl, event }); }, _handleInputBlur(event, inputEl) { setTimeout(() => { if (this.activeInput === inputEl) { this.activeInput = null; this._emitInputEvent("inputBlurred", { inputEl, event }); } }, 200); }, _handleInputChange(event, inputEl) { this._emitInputEvent("inputChanged", { inputEl, value: inputEl.value, event }); }, _handleInputKeyDown(event, inputEl) { this._emitInputEvent("inputKeyDown", { inputEl, key: event.key, event }); }, _handleCandidateSelected(candidate) { if (this.activeInput && candidate) { const text = candidate.getDisplayText ? candidate.getDisplayText() : candidate.text; this.replaceInputWithText(this.activeInput, text); } }, _emitInputEvent(eventName, detail) { const event = new CustomEvent(eventName, { detail }); document.dispatchEvent(event); }, _triggerInputEvent(inputEl) { const inputEvent = new Event("input", { bubbles: true }); inputEl.dispatchEvent(inputEvent); }, _setCursorToEnd(inputEl) { if (inputEl.setSelectionRange) { const len = inputEl.value.length; inputEl.setSelectionRange(len, len); } }, cleanup() { for (const inputEl of this.inputListeners.keys()) { this.unbindInputEvents(inputEl); } this.activeInput = null; } }; const CandidatePanelState = { currentState: PanelState.HIDDEN, candidates: [], activeIndex: 0, selectionMode: SelectionMode.KEYBOARD, panelElement: null, targetInput: null, listeners: new Map(), getPanelState() { return { state: this.currentState, activeIndex: this.activeIndex, candidateCount: this.candidates.length, isVisible: this.currentState === PanelState.VISIBLE, hasSelection: this.activeIndex >= 0 && this.activeIndex < this.candidates.length }; }, setCandidates(candidates) { this.candidates = candidates || []; this.activeIndex = this.candidates.length > 0 ? 0 : -1; }, navigateLeft() { if (this.candidates.length === 0) return; this.activeIndex = this.activeIndex > 0 ? this.activeIndex - 1 : this.candidates.length - 1; this.selectionMode = SelectionMode.KEYBOARD; this._updateActiveItem(); this._emitNavigationEvent("left"); }, navigateRight() { if (this.candidates.length === 0) return; this.activeIndex = this.activeIndex < this.candidates.length - 1 ? this.activeIndex + 1 : 0; this.selectionMode = SelectionMode.KEYBOARD; this._updateActiveItem(); this._emitNavigationEvent("right"); }, navigateUp() { this.navigateLeft(); this._emitNavigationEvent("up"); }, navigateDown() { this.navigateRight(); this._emitNavigationEvent("down"); }, selectActiveCandidate() { if (this.activeIndex >= 0 && this.activeIndex < this.candidates.length) { const selected = this.candidates[this.activeIndex]; if (selected && typeof selected.updateUsage === "function") { selected.updateUsage(); } return selected; } return null; }, setActiveByMouse(index) { if (index >= 0 && index < this.candidates.length) { this.activeIndex = index; this.selectionMode = SelectionMode.MOUSE; this._updateActiveItem(); } }, resetSelection() { this.activeIndex = this.candidates.length > 0 ? 0 : -1; this.selectionMode = SelectionMode.KEYBOARD; this._updateActiveItem(); }, setState(newState) { const oldState = this.currentState; this.currentState = newState; this._onStateChange(oldState, newState); }, setPanelElement(element) { this.panelElement = element; }, setTargetInput(input) { this.targetInput = input; }, addEventListener(event, callback) { if (!this.listeners.has(event)) { this.listeners.set(event, []); } this.listeners.get(event).push(callback); }, removeEventListener(event, callback) { if (this.listeners.has(event)) { const callbacks = this.listeners.get(event); const index = callbacks.indexOf(callback); if (index > -1) { callbacks.splice(index, 1); } } }, _emit(event, data) { if (this.listeners.has(event)) { this.listeners.get(event).forEach((callback) => { try { callback(data); } catch (error) { console.error(`Error in event listener for ${event}:`, error); } }); } }, _updateActiveItem() { this._emit("activeIndexChanged", { activeIndex: this.activeIndex, selectionMode: this.selectionMode, candidate: this.candidates[this.activeIndex] || null }); }, _onStateChange(oldState, newState) { this._emit("stateChanged", { oldState, newState, panelState: this.getPanelState() }); }, _emitNavigationEvent(direction) { this._emit("navigation", { direction, activeIndex: this.activeIndex, candidate: this.candidates[this.activeIndex] || null }); } }; const CapsulePreview = { previewElement: null, currentCapsule: null, showTimer: null, hideTimer: null, currentTriggerSource: null, isInSelectionMode: false, initialized: false, enterSelectionMode() { this.isInSelectionMode = true; Utils.log("预览框进入选择模式,将持续显示"); }, exitSelectionMode() { this.isInSelectionMode = false; this.hidePreview(0, "keyboard"); Utils.log("预览框退出选择模式"); }, updateSelectionModePreview(capsule, text) { if (!this.isInSelectionMode || !capsule || !text) return; if (this.showTimer) { clearTimeout(this.showTimer); this.showTimer = null; } if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null; } this.currentCapsule = capsule; this.currentTriggerSource = "keyboard"; this.previewElement.textContent = text; this.previewElement.classList.add("active"); this.positionPreview(capsule); if (this.previewElement.style.display !== "block") { this.previewElement.style.display = "block"; requestAnimationFrame(() => { this.previewElement.classList.add("show"); }); } Utils.log(`选择模式预览已更新: ${text.substring(0, 20)}...`); }, init() { if (this.initialized) return; this.createPreviewElement(); this.bindGlobalEvents(); this.initialized = true; Utils.log("胶囊悬浮框预览组件已初始化"); }, createPreviewElement() { this.previewElement = document.createElement("div"); this.previewElement.className = "ddp-capsule-preview"; this.previewElement.style.display = "none"; document.body.appendChild(this.previewElement); }, showPreview(capsule, text, isActive = false, triggerSource = "mouse") { if (!this.initialized || !text || text.length <= 15) { return; } if (this.currentTriggerSource === "keyboard" && triggerSource === "mouse") { Utils.log("键盘预览活跃中,忽略鼠标悬停事件"); return; } if (this.hideTimer) { clearTimeout(this.hideTimer); this.hideTimer = null; } const config = DEFAULT_SETTINGS.capsule.preview; const delay = triggerSource === "keyboard" ? 0 : config.showDelay; Utils.log(`显示预览框: 触发源=${triggerSource}, 文本=${text.substring(0, 20)}...`); this.showTimer = setTimeout(() => { this.currentCapsule = capsule; this.currentTriggerSource = triggerSource; this.previewElement.textContent = text; if (isActive || triggerSource === "keyboard") { this.previewElement.classList.add("active"); } else { this.previewElement.classList.remove("active"); } this.positionPreview(capsule); this.previewElement.style.display = "block"; requestAnimationFrame(() => { this.previewElement.classList.add("show"); }); Utils.log(`悬浮框预览已显示 (${triggerSource}): ${text.substring(0, 20)}...`); }, delay); }, hidePreview(delay = null, triggerSource = "mouse") { if (!this.initialized) return; if (this.currentTriggerSource === "keyboard" && triggerSource === "mouse") { Utils.log("键盘预览活跃中,忽略鼠标离开事件"); return; } if (this.showTimer) { clearTimeout(this.showTimer); this.showTimer = null; } const config = DEFAULT_SETTINGS.capsule.preview; const hideDelay = delay !== null ? delay : config.hideDelay; Utils.log(`隐藏预览框: 触发源=${triggerSource}, 延迟=${hideDelay}ms`); this.hideTimer = setTimeout(() => { this.previewElement.classList.remove("show"); setTimeout(() => { this.previewElement.style.display = "none"; this.previewElement.classList.remove("active"); this.previewElement.classList.remove("show-below"); this.currentCapsule = null; this.currentTriggerSource = null; }, config.animationDuration); }, hideDelay); }, positionPreview(capsule) { const capsuleRect = capsule.getBoundingClientRect(); Utils.log(`=== 预览框定位(强制上方) ===`); Utils.log(`胶囊位置: top=${capsuleRect.top}px, left=${capsuleRect.left}px, width=${capsuleRect.width}px`); this.previewElement.style.visibility = "hidden"; this.previewElement.style.display = "block"; const previewRect = this.previewElement.getBoundingClientRect(); const previewWidth = previewRect.width || 300; const previewHeight = previewRect.height || 40; this.previewElement.style.visibility = ""; Utils.log(`预览框尺寸: width=${previewWidth}px, height=${previewHeight}px`); let left = capsuleRect.left + capsuleRect.width / 2 - previewWidth / 2; const verticalGap = 8; let top = capsuleRect.top - previewHeight - verticalGap; Utils.log(`强制上方显示: top=${top}px (胶囊顶部${capsuleRect.top} - 预览框高度${previewHeight} - 间距${verticalGap})`); const windowWidth = window.innerWidth; const horizontalPadding = 10; if (left < horizontalPadding) { left = horizontalPadding; } else if (left + previewWidth > windowWidth - horizontalPadding) { left = windowWidth - previewWidth - horizontalPadding; } this.previewElement.classList.remove("show-below"); this.previewElement.style.left = `${left}px`; this.previewElement.style.top = `${top}px`; Utils.log(`最终位置: left=${left}px, top=${top}px, 显示位置: 上方`); Utils.log(`=== 预览框定位完成 ===`); }, updateActiveState(isActive) { if (!this.initialized || !this.currentCapsule) return; if (isActive) { this.previewElement.classList.add("active"); } else { this.previewElement.classList.remove("active"); } }, bindGlobalEvents() { document.addEventListener("scroll", () => { this.hidePreview(0); }, true); window.addEventListener("resize", () => { if (this.currentCapsule) { this.positionPreview(this.currentCapsule); } }); }, bindCapsuleEvents(capsule, text) { if (!capsule || !text) return; capsule.addEventListener("mouseenter", () => { this.showPreview(capsule, text, false, "mouse"); }); capsule.addEventListener("mouseleave", () => { this.hidePreview(null, "mouse"); }); }, destroy() { if (!this.initialized) return; if (this.showTimer) { clearTimeout(this.showTimer); } if (this.hideTimer) { clearTimeout(this.hideTimer); } if (this.previewElement && this.previewElement.parentNode) { this.previewElement.parentNode.removeChild(this.previewElement); } this.previewElement = null; this.currentCapsule = null; this.currentTriggerSource = null; this.isInSelectionMode = false; this.initialized = false; Utils.log("胶囊悬浮框预览组件已销毁"); } }; const UIManager = { initialized: false, currentState: "idle", currentTargetInput: null, currentSuggestions: [], activeIndex: 0, isSelectionModeActive: false, init() { return __async(this, null, function* () { if (this.initialized) { return true; } try { CandidatePanel.init(); InputInteraction.init(); CapsulePreview.init(); this.bindComponentEvents(); this.initialized = true; Utils.log("UI管理器初始化成功"); return true; } catch (error) { Utils.log(`UI管理器初始化失败: ${error.message}`, "error"); return false; } }); }, showPopup(suggestions, targetInput) { if (!this.initialized) { Utils.log("UIManager未初始化", "warn"); return; } this.currentSuggestions = suggestions || []; this.currentTargetInput = targetInput; this.activeIndex = -1; if (this.currentSuggestions.length === 0) { this.hidePopup(); return; } this.currentState = "showing"; CandidatePanelState.setCandidates(this.currentSuggestions); CandidatePanelState.setTargetInput(targetInput); CandidatePanelState.resetSelection(); const isChatInput = targetInput && targetInput.closest(".ChatSend"); if (isChatInput) { this.showChatCandidateList(this.currentSuggestions, targetInput); } else { CandidatePanel.renderCandidatePanel(this.currentSuggestions, this.activeIndex); CandidatePanel.showPanel(targetInput); } if (targetInput) { InputInteraction.bindInputEvents(targetInput); } setTimeout(() => { if (this.currentState === "showing") { this.currentState = "selecting"; } }, 100); Utils.log(`弹窗已显示,包含 ${this.currentSuggestions.length} 个候选项`); }, showChatCandidateList(suggestions, targetInput, multiRow = false) { var _a; const capsuleConfig = DEFAULT_SETTINGS.capsule; document.documentElement.style.setProperty("--ddp-capsule-item-height", `${capsuleConfig.height}px`); document.documentElement.style.setProperty("--ddp-capsule-padding", "8px"); document.documentElement.style.setProperty("--ddp-capsule-margin", "8px"); document.documentElement.style.setProperty("--ddp-capsule-item-padding", "3px"); Utils.log(`CSS变量已设置 (margin会计入高度):`); Utils.log(`--ddp-capsule-item-height: 24px (胶囊高度)`); Utils.log(`--ddp-capsule-padding: 8px (容器padding,计入高度)`); Utils.log(`--ddp-capsule-margin: 8px (容器margin,计入高度)`); Utils.log(`--ddp-capsule-item-padding: 3px (胶囊内padding)`); Utils.log(`预期测量高度: 24px + 3*2 + 8*2 + 8*2 = 62px (margin计入高度)`); const chat = document.querySelector(".layout-Player-chat .Chat"); if (!chat) { Utils.log("未找到 Chat 容器,回退到普通弹窗模式"); CandidatePanel.renderCandidatePanel(suggestions, this.activeIndex); CandidatePanel.showPanel(targetInput); return; } chat.style.paddingBottom = ""; this.applyChatLayoutFix(); const existingList = document.querySelector(".ddp-candidate-capsules"); if (existingList) { if (existingList._dynamicStyle) { existingList._dynamicStyle.remove(); } existingList.remove(); } const candidateList = document.createElement("div"); candidateList.className = `ddp-candidate-capsules ${multiRow ? "multi-row" : ""}`; const maxItems = multiRow ? suggestions.length : ( Math.min(suggestions.length, ((_a = DEFAULT_SETTINGS == null ? void 0 : DEFAULT_SETTINGS.capsule) == null ? void 0 : _a.singleRowMaxItems) || 8) ); const displaySuggestions = suggestions.slice(0, maxItems); displaySuggestions.forEach((suggestion, index) => { const capsule = document.createElement("div"); capsule.className = `ddp-candidate-capsule ${index === this.activeIndex ? "active" : ""}`; capsule.dataset.index = index; const text = suggestion.getDisplayText ? suggestion.getDisplayText() : suggestion.text; capsule.textContent = text; this.bindCapsulePreviewEvents(capsule, suggestion, text); capsule.addEventListener("click", () => { this.selectCandidate(suggestion); }); candidateList.appendChild(capsule); }); const chatSpeak = chat.querySelector(".ChatSpeak"); if (chatSpeak) { chatSpeak.parentNode.insertBefore(candidateList, chatSpeak); } else { chat.appendChild(candidateList); } this.updateChatLayoutForCandidates(candidateList); this.currentCandidateMode = multiRow ? "multi-row" : "single-row"; Utils.log(`胶囊候选列表已显示 (${this.currentCandidateMode}),包含 ${displaySuggestions.length}/${suggestions.length} 个候选项,布局已调整`); Utils.log(`DOM结构: Chat > [ChatToolBar, ddp-candidate-capsules, ChatSpeak]`); }, hidePopup() { if (!this.initialized) return; console.log("=== HIDEOPOPUP 被调用 ==="); console.log(`当前状态: ${this.currentState}`); console.log("完整调用栈:"); console.trace("hidePopup调用追踪"); Utils.log(`隐藏弹窗,当前状态: ${this.currentState}`); CapsulePreview.hidePreview(0, "keyboard"); CapsulePreview.hidePreview(0, "mouse"); CandidatePanel.hidePanel(); const existingList = document.querySelector(".ddp-candidate-capsules"); if (existingList) { if (existingList._dynamicStyle) { existingList._dynamicStyle.remove(); } existingList.remove(); } this.removeChatLayoutFix(); this.currentSuggestions = []; this.currentTargetInput = null; this.activeIndex = -1; this.currentState = "idle"; this.currentCandidateMode = null; Utils.log("弹窗已隐藏,布局已恢复"); }, applyChatLayoutFix() { Utils.log("=== 应用CSS布局修复 ==="); const chatArea = document.querySelector(".layout-Player-chat"); if (!chatArea) { Utils.log("未找到聊天区域,跳过布局修复"); return; } chatArea.classList.add("ddp-candidates-visible"); Utils.log("已添加 ddp-candidates-visible 类,CSS样式将控制布局"); Utils.log("=== CSS布局修复完成 ==="); }, updateChatLayoutForCandidates(candidateList) { const chat = document.querySelector(".layout-Player-chat .Chat"); if (!chat || !candidateList) { Utils.log("缺少必要元素,跳过padding更新"); return; } chat.style.paddingBottom = ""; const beforeHeight = chat.getBoundingClientRect().height; const currentPadding = getComputedStyle(chat).paddingBottom; const initialPaddingValue = parseFloat(currentPadding) || 0; Utils.log(`=== 更新候选框布局开始 ===`); Utils.log(`Chat当前高度: ${beforeHeight}px`); Utils.log(`Chat初始paddingBottom: ${initialPaddingValue}px (必须保留)`); const configuredHeight = DEFAULT_SETTINGS.capsule.totalHeight; const marginTop = parseFloat(getComputedStyle(candidateList).marginTop) || 0; const marginBottom = parseFloat(getComputedStyle(candidateList).marginBottom) || 0; const totalMargin = marginTop + marginBottom; requestAnimationFrame(() => { requestAnimationFrame(() => { const actualHeight = Math.round(candidateList.getBoundingClientRect().height); const candidateHeightWithMargin = actualHeight + totalMargin; const heightDifference = Math.abs(candidateHeightWithMargin - configuredHeight); const candidateHeight = heightDifference <= 2 ? configuredHeight : candidateHeightWithMargin; const finalPadding = initialPaddingValue + candidateHeight; document.documentElement.style.setProperty("--ddp-candidate-height", `${candidateHeight}px`); chat.style.paddingBottom = `${finalPadding}px`; const afterHeight = chat.getBoundingClientRect().height; const actualPaddingBottom = getComputedStyle(chat).paddingBottom; const heightIncrease = afterHeight - beforeHeight; Utils.log(`候选项所需高度(含margin): ${candidateHeight}px`); Utils.log(`最终设置padding: ${finalPadding}px (初始${initialPaddingValue}px + 候选项${candidateHeight}px)`); Utils.log(`transform向上移动距离: ${candidateHeight}px`); Utils.log(`实际应用padding: ${actualPaddingBottom}`); Utils.log(`Chat更新后高度: ${afterHeight}px`); Utils.log(`实际高度增加: ${heightIncrease}px (应约等于${candidateHeight}px)`); Utils.log(`=== 候选框布局更新完成 ===`); }); }); }, removeChatLayoutFix() { Utils.log("=== 移除CSS布局修复 ==="); const chatArea = document.querySelector(".layout-Player-chat"); const chat = chatArea ? chatArea.querySelector(".Chat") : null; if (!chatArea) { Utils.log("未找到聊天区域,跳过布局恢复"); return; } chatArea.classList.remove("ddp-candidates-visible"); document.documentElement.style.removeProperty("--ddp-candidate-height"); document.documentElement.style.removeProperty("--ddp-capsule-item-height"); document.documentElement.style.removeProperty("--ddp-capsule-padding"); document.documentElement.style.removeProperty("--ddp-capsule-margin"); document.documentElement.style.removeProperty("--ddp-capsule-total-height"); document.documentElement.style.removeProperty("--ddp-capsule-item-padding"); if (chat) { chat.style.paddingBottom = ""; } Utils.log("已移除 ddp-candidates-visible 类,清理所有CSS变量和padding,布局已恢复"); Utils.log("=== CSS布局恢复完成 ==="); }, setActiveIndex(index) { if (!this.initialized || index < 0 || index >= this.currentSuggestions.length) { return; } const oldIndex = this.activeIndex; this.activeIndex = index; const isChatInput = this.currentTargetInput && this.currentTargetInput.closest(".ChatSend"); if (isChatInput) { this.updateChatCandidateStyles(oldIndex, index); } else { CandidatePanel.setActiveIndex(index); CandidatePanelState.setActiveByMouse(index); } }, updateChatCandidateStyles(oldIndex, newIndex) { const candidateList = document.querySelector(".ddp-candidate-capsules"); if (!candidateList) return; Utils.log(`=== 更新胶囊样式 ===`); Utils.log(`从索引 ${oldIndex} 切换到索引 ${newIndex}`); if (oldIndex >= 0) { const oldCapsule = candidateList.querySelector(`[data-index="${oldIndex}"]`); if (oldCapsule) { oldCapsule.classList.remove("active"); Utils.log(`已移除旧胶囊 ${oldIndex} 的活跃状态`); } } const newCapsule = candidateList.querySelector(`[data-index="${newIndex}"]`); if (newCapsule) { newCapsule.classList.add("active"); Utils.log(`已设置新胶囊 ${newIndex} 为活跃状态`); if (!candidateList.classList.contains("multi-row")) { this.scrollCapsuleIntoView(candidateList, newCapsule); const capsuleIndex = parseInt(newCapsule.dataset.index) || 0; const isCircularNavigation = capsuleIndex === 0 && candidateList.scrollLeft > candidateList.offsetWidth || capsuleIndex === this.currentSuggestions.length - 1 && candidateList.scrollLeft === 0; const delay = isCircularNavigation ? 50 : 150; Utils.log(`等待滚动完成,延迟: ${delay}ms (循环导航: ${isCircularNavigation})`); setTimeout(() => { this.showPreviewForCapsule(newCapsule, newIndex); }, delay); } else { newCapsule.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "center" }); setTimeout(() => { this.showPreviewForCapsule(newCapsule, newIndex); }, 150); } } else { Utils.log(`未找到索引为 ${newIndex} 的胶囊元素,隐藏预览框`); CapsulePreview.hidePreview(0, "keyboard"); } Utils.log(`=== 胶囊样式更新完成 ===`); }, scrollCapsuleIntoView(candidateList, capsule) { if (!candidateList || !capsule) { Utils.log("scrollCapsuleIntoView: 缺少必要元素"); return; } try { const listRect = candidateList.getBoundingClientRect(); const capsuleRect = capsule.getBoundingClientRect(); const scrollLeft = candidateList.scrollLeft; const capsuleRelativeLeft = capsule.offsetLeft; const capsuleWidth = capsule.offsetWidth; const listWidth = candidateList.offsetWidth; const capsuleIndex = parseInt(capsule.dataset.index) || 0; Utils.log(`滚动检查: 胶囊索引=${capsuleIndex}, 位置=${capsuleRelativeLeft}px, 宽度=${capsuleWidth}px, 容器宽度=${listWidth}px, 当前滚动=${scrollLeft}px`); const isCircularNavigation = capsuleIndex === 0 && scrollLeft > listWidth || capsuleIndex === this.currentSuggestions.length - 1 && scrollLeft === 0; const scrollBehavior = isCircularNavigation ? "instant" : "smooth"; Utils.log(`循环导航检测: ${isCircularNavigation}, 滚动行为: ${scrollBehavior}`); if (capsuleRelativeLeft + capsuleWidth > scrollLeft + listWidth) { const newScrollLeft = capsuleRelativeLeft + capsuleWidth - listWidth + 20; Utils.log(`向右滚动到: ${newScrollLeft}px`); candidateList.scrollTo({ left: newScrollLeft, behavior: scrollBehavior }); } else if (capsuleRelativeLeft < scrollLeft) { const newScrollLeft = Math.max(0, capsuleRelativeLeft - 20); Utils.log(`向左滚动到: ${newScrollLeft}px`); candidateList.scrollTo({ left: newScrollLeft, behavior: scrollBehavior }); } else { Utils.log("胶囊已在可见区域,无需滚动"); } } catch (error) { Utils.log(`滚动出错: ${error.message}`, "error"); console.error("scrollCapsuleIntoView error:", error); } }, bindCapsulePreviewEvents(capsule, suggestion, text) { capsule.removeAttribute("title"); Object.defineProperty(capsule, "title", { set: function() { Utils.log("阻止设置title属性,避免双重预览"); }, get: function() { return ""; }, configurable: true }); CapsulePreview.bindCapsuleEvents(capsule, text); }, showPreviewForCapsule(capsule, index) { if (!capsule || index < 0 || index >= this.currentSuggestions.length) { Utils.log(`无法为胶囊显示预览: 胶囊=${!!capsule}, 索引=${index}, 总数=${this.currentSuggestions.length}`); return; } const candidate = this.currentSuggestions[index]; const text = candidate ? candidate.getDisplayText ? candidate.getDisplayText() : candidate.text : capsule.textContent; Utils.log(`胶囊文本: "${text}", 长度: ${text ? text.length : 0}`); const capsuleRect = capsule.getBoundingClientRect(); Utils.log(`滚动后胶囊位置: left=${capsuleRect.left}px, top=${capsuleRect.top}px, 可见=${capsuleRect.left >= 0 && capsuleRect.left < window.innerWidth}`); if (text && text.length > 8) { Utils.log(`键盘选中胶囊,显示预览: ${text.substring(0, 20)}...`); CapsulePreview.showPreview(capsule, text, true, "keyboard"); } else { Utils.log(`文本过短或不存在,隐藏预览框`); CapsulePreview.hidePreview(0, "keyboard"); } }, navigateUp() { if (!this.initialized || this.currentSuggestions.length === 0) return; const isChatInput = this.currentTargetInput && this.currentTargetInput.closest(".ChatSend"); if (isChatInput) { this.navigateLeft(); } else { if (!this.isSelectionModeActive) { this.setSelectionModeActive(true); } CandidatePanelState.navigateUp(); const newIndex = CandidatePanelState.activeIndex; this.setActiveIndex(newIndex); } }, navigateDown() { if (!this.initialized || this.currentSuggestions.length === 0) return; const isChatInput = this.currentTargetInput && this.currentTargetInput.closest(".ChatSend"); if (isChatInput) { this.navigateRight(); } else { if (!this.isSelectionModeActive) { this.setSelectionModeActive(true); } CandidatePanelState.navigateDown(); const newIndex = CandidatePanelState.activeIndex; this.setActiveIndex(newIndex); } }, navigateLeft() { if (!this.initialized || this.currentSuggestions.length === 0) return; if (!this.isSelectionModeActive) { this.setSelectionModeActive(true); } let newIndex = this.activeIndex - 1; if (newIndex < 0) { newIndex = this.currentSuggestions.length - 1; } this.setActiveIndex(newIndex); }, navigateRight() { if (!this.initialized || this.currentSuggestions.length === 0) return; if (!this.isSelectionModeActive) { this.setSelectionModeActive(true); } let newIndex = this.activeIndex + 1; if (newIndex >= this.currentSuggestions.length) { newIndex = 0; } this.setActiveIndex(newIndex); }, selectActiveCandidate() { if (!this.initialized || this.activeIndex < 0 || this.activeIndex >= this.currentSuggestions.length) { return; } const selectedCandidate = this.currentSuggestions[this.activeIndex]; this.selectCandidate(selectedCandidate); }, selectCandidate(candidate) { if (!candidate || !this.currentTargetInput) return; const text = candidate.getDisplayText ? candidate.getDisplayText() : candidate.text; if (typeof candidate.updateUsage === "function") { candidate.updateUsage(); } InputInteraction.replaceInputWithText(this.currentTargetInput, text); this.hidePopup(); this.currentState = "idle"; Utils.log(`候选项已选择并填入输入框: ${text}`); }, isPopupVisible() { const chatCandidateList = document.querySelector(".ddp-candidate-capsules"); if (chatCandidateList && chatCandidateList.style.display !== "none") { return true; } return this.initialized && CandidatePanel.isVisible(); }, clearActiveIndex() { this.activeIndex = -1; if (this.isSelectionModeActive) { this.setSelectionModeActive(false); } const chatCandidateList = document.querySelector(".ddp-candidate-capsules"); if (chatCandidateList) { const capsules = chatCandidateList.querySelectorAll(".ddp-candidate-capsule"); capsules.forEach((capsule) => { capsule.classList.remove("active"); }); } if (CandidatePanel.panelElement) { const items = CandidatePanel.panelElement.querySelectorAll(".dda-popup-item"); items.forEach((item) => { item.classList.remove("dda-popup-item-active"); }); } }, setSelectionModeActive(active) { this.isSelectionModeActive = active; if (active) { CapsulePreview.enterSelectionMode(); if (this.activeIndex === -1 && this.currentSuggestions.length > 0) { this.setActiveIndex(0); } } else { CapsulePreview.exitSelectionMode(); this.clearActiveIndex(); } const chatCandidateList = document.querySelector(".ddp-candidate-capsules"); if (chatCandidateList) { if (active) { chatCandidateList.classList.add("selection-mode-active"); } else { chatCandidateList.classList.remove("selection-mode-active"); } } if (CandidatePanel.panelElement) { if (active) { CandidatePanel.panelElement.classList.add("selection-mode-active"); } else { CandidatePanel.panelElement.classList.remove("selection-mode-active"); } } Utils.log(`选择模式: ${active ? "激活" : "关闭"}`); }, updateCandidates(suggestions) { this.currentSuggestions = suggestions; if (this.currentTargetInput) { const isChatInput = this.currentTargetInput.closest(".ChatSend"); if (isChatInput) { this.showChatCandidateList(suggestions, this.currentTargetInput); } else { CandidatePanel.renderCandidatePanel(suggestions, this.activeIndex); } } }, getCurrentState() { return this.currentState; }, bindComponentEvents() { document.addEventListener("blur", (event) => { if (event.target && event.target.matches && event.target.matches("input, textarea")) { console.log("🔍 全局检测到输入框失焦:", event.target.className, "value:", event.target.value); } }, true); const originalDispatchEvent = document.dispatchEvent; document.dispatchEvent = function(event) { if (event.type.includes("input") || event.type.includes("blur") || event.type.includes("focus")) { console.log("🎯 自定义事件被触发:", event.type, event.detail); } return originalDispatchEvent.call(this, event); }; document.addEventListener("candidateSelected", (event) => { const { candidate } = event.detail; this.selectCandidate(candidate); }); document.addEventListener("candidateHovered", (event) => { const { index } = event.detail; this.setActiveIndex(index); }); document.addEventListener("inputFocused", (event) => { const { inputEl } = event.detail; this.currentTargetInput = inputEl; }); document.addEventListener("inputBlurred", (event) => { Utils.log("=== 输入框失焦事件触发(已完全禁用隐藏逻辑) ==="); return; }); document.addEventListener("panelShown", () => { this.currentState = "selecting"; }); document.addEventListener("panelHidden", () => { this.currentState = "idle"; }); }, destroy() { if (!this.initialized) return; CandidatePanel.destroy(); InputInteraction.cleanup(); CapsulePreview.destroy(); this.initialized = false; this.currentState = "idle"; this.currentTargetInput = null; this.currentSuggestions = []; this.activeIndex = 0; Utils.log("UI管理器已销毁"); }, calculateCandidateListHeight(suggestions) { const baseHeight = 12; const capsuleHeight = 32; const maxCapsulesPerRow = Math.floor(window.innerWidth * 0.6 / 120); const rows = Math.ceil(suggestions.length / maxCapsulesPerRow); const calculatedHeight = baseHeight + rows * capsuleHeight; Utils.log(`计算候选列表高度:`); Utils.log(`- 建议数量: ${suggestions.length}`); Utils.log(`- 窗口宽度: ${window.innerWidth}px`); Utils.log(`- 每行最大胶囊数: ${maxCapsulesPerRow}`); Utils.log(`- 计算行数: ${rows}`); Utils.log(`- 基础高度: ${baseHeight}px`); Utils.log(`- 胶囊高度: ${capsuleHeight}px`); Utils.log(`- 计算总高度: ${calculatedHeight}px`); return calculatedHeight; }, calculateCandidateListHeight(suggestions) { const baseHeight = 12; const capsuleHeight = 32; const maxCapsulesPerRow = Math.floor(window.innerWidth * 0.6 / 120); const rows = Math.ceil(suggestions.length / maxCapsulesPerRow); const calculatedHeight = baseHeight + rows * capsuleHeight; Utils.log(`计算候选列表高度:`); Utils.log(`- 建议数量: ${suggestions.length}`); Utils.log(`- 窗口宽度: ${window.innerWidth}px`); Utils.log(`- 每行最大胶囊数: ${maxCapsulesPerRow}`); Utils.log(`- 计算行数: ${rows}`); Utils.log(`- 基础高度: ${baseHeight}px`); Utils.log(`- 胶囊高度: ${capsuleHeight}px`); Utils.log(`- 计算总高度: ${calculatedHeight}px`); return calculatedHeight; } }; const INPUT_TYPES = { MAIN_CHAT: "main_chat", FULLSCREEN_FLOAT: "fullscreen", UNKNOWN: "unknown" }; const InputDetector = { mutationObserver: null, detectedInputs: new WeakSet(), onInputDetected: null, onInputRemoved: null, init(callbacks = {}) { this.onInputDetected = callbacks.onInputDetected || (() => { }); this.onInputRemoved = callbacks.onInputRemoved || (() => { }); this.detectExistingInputs(); this.startMutationObserver(); console.log("InputDetector initialized"); }, detectExistingInputs() { this.detectMainChatInput(); this.detectFullscreenInput(); }, detectMainChatInput() { const checkMainInput = () => { const mainInput = document.querySelector(".ChatSend-txt"); if (mainInput && !this.detectedInputs.has(mainInput)) { this.handleInputDetected(mainInput, INPUT_TYPES.MAIN_CHAT); return true; } return false; }; if (!checkMainInput()) { let attempts = 0; const maxAttempts = 50; const pollInterval = setInterval(() => { attempts++; if (checkMainInput() || attempts >= maxAttempts) { clearInterval(pollInterval); } }, 200); } }, detectFullscreenInput() { const fullscreenInput = document.querySelector(".inputView-2a65aa"); if (fullscreenInput && !this.detectedInputs.has(fullscreenInput)) { this.handleInputDetected(fullscreenInput, INPUT_TYPES.FULLSCREEN_FLOAT); } }, startMutationObserver() { if (this.mutationObserver) { this.mutationObserver.disconnect(); } this.mutationObserver = new MutationObserver((mutations) => { mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.nodeType === Node.ELEMENT_NODE) { this.checkNodeForInputs(node, true); } }); mutation.removedNodes.forEach((node) => { if (node.nodeType === Node.ELEMENT_NODE) { this.checkNodeForInputs(node, false); } }); }); }); const playerContainer = document.querySelector("#js-player-video-case") || document.body; this.mutationObserver.observe(playerContainer, { childList: true, subtree: true }); }, checkNodeForInputs(node, isAdded) { const inputType = this.getInputType(node); if (inputType !== INPUT_TYPES.UNKNOWN) { if (isAdded) { this.handleInputDetected(node, inputType); } else { this.handleInputRemoved(node, inputType); } return; } const selectors = [ ".ChatSend-txt", ".inputView-2a65aa" ]; selectors.forEach((selector) => { const inputs = node.querySelectorAll(selector); inputs.forEach((input) => { const type = this.getInputType(input); if (type !== INPUT_TYPES.UNKNOWN) { if (isAdded) { this.handleInputDetected(input, type); } else { this.handleInputRemoved(input, type); } } }); }); }, handleInputDetected(input, type) { if (this.detectedInputs.has(input)) return; this.detectedInputs.add(input); console.log(`Detected ${type} input:`, input); this.setupInputSpecialHandling(input, type); this.onInputDetected(input, type); }, handleInputRemoved(input, type) { if (!this.detectedInputs.has(input)) return; this.detectedInputs.delete(input); console.log(`Removed ${type} input:`, input); this.onInputRemoved(input, type); }, setupInputSpecialHandling(input, type) { switch (type) { case INPUT_TYPES.MAIN_CHAT: this.setupMainChatInput(input); break; case INPUT_TYPES.FULLSCREEN_FLOAT: this.setupFullscreenInput(input); break; } }, setupMainChatInput(input) { let hasSetupFocusHandler = false; const setupFocusHandler = () => { if (hasSetupFocusHandler) return; hasSetupFocusHandler = true; input.addEventListener("focus", () => { console.log("Main chat input focused"); input.dataset.frameworkManaged = "true"; }, { once: true }); }; if (document.readyState === "complete") { setupFocusHandler(); } else { document.addEventListener("DOMContentLoaded", setupFocusHandler); } }, setupFullscreenInput(input) { console.log("Fullscreen input detected and ready"); input.dataset.frameworkManaged = "true"; input.dataset.dynamicCreated = "true"; }, getInputType(element) { if (!element || element.tagName !== "INPUT" && element.tagName !== "TEXTAREA") { return INPUT_TYPES.UNKNOWN; } if (element.classList.contains("ChatSend-txt")) { return INPUT_TYPES.MAIN_CHAT; } return INPUT_TYPES.UNKNOWN; }, isChatInput(element) { return this.getInputType(element) !== INPUT_TYPES.UNKNOWN; }, getSendButton(input) { const type = this.getInputType(input); switch (type) { case INPUT_TYPES.MAIN_CHAT: const chatSend = input.closest(".ChatSend"); return chatSend ? chatSend.querySelector(".ChatSend-button") : null; case INPUT_TYPES.FULLSCREEN_FLOAT: const fullscreenSendor = input.closest('[class*="fullScreenSendor-"]'); return fullscreenSendor ? fullscreenSendor.querySelector('.sendDanmu-592760, [class*="sendDanmu-"]') : null; default: return null; } }, destroy() { if (this.mutationObserver) { this.mutationObserver.disconnect(); this.mutationObserver = null; } this.detectedInputs = new WeakSet(); this.onInputDetected = null; this.onInputRemoved = null; console.log("InputDetector destroyed"); } }; const SettingsManager = { STORAGE_KEY_PREFIX: CONFIG.SETTINGS_KEY_PREFIX, get(key, defaultValue = null) { const storageKey = `${this.STORAGE_KEY_PREFIX}${key}`; return GM_getValue(storageKey, defaultValue); }, set(key, value) { const storageKey = `${this.STORAGE_KEY_PREFIX}${key}`; GM_setValue(storageKey, value); }, remove(key) { const storageKey = `${this.STORAGE_KEY_PREFIX}${key}`; GM_deleteValue(storageKey); }, getAll() { const allKeys = GM_listValues(); const settings = {}; allKeys.forEach((key) => { if (key.startsWith(this.STORAGE_KEY_PREFIX)) { const settingKey = key.replace(this.STORAGE_KEY_PREFIX, ""); settings[settingKey] = GM_getValue(key); } }); return settings; }, getSettings() { const userSettings = this.getAll(); return __spreadValues(__spreadValues({}, DEFAULT_SETTINGS), userSettings); }, setAll(settings) { Object.entries(settings).forEach(([key, value]) => { this.set(key, value); }); }, reset() { const allKeys = GM_listValues(); allKeys.forEach((key) => { if (key.startsWith(this.STORAGE_KEY_PREFIX)) { GM_deleteValue(key); } }); }, getDefaults() { return { maxSuggestions: CONFIG.MAX_SUGGESTIONS, minSearchLength: CONFIG.MIN_SEARCH_LENGTH, enableSync: false, triggerKeys: CONFIG.TRIGGER_KEYS, navigationKeys: CONFIG.NAVIGATION_KEYS, debounceDelay: CONFIG.DEBOUNCE_DELAY, sortBy: "relevance", autoImport: { maxPages: 5, pageSize: 50, sortByPopularity: true } }; }, applyDefaults() { const defaults = this.getDefaults(); Object.entries(defaults).forEach(([key, value]) => { if (this.get(key) === null) { this.set(key, value); } }); } }; const APP_STATES = { IDLE: "idle", TYPING: "typing", SELECTING: "selecting" }; const InputManager = { currentState: APP_STATES.IDLE, currentInput: null, currentSuggestions: [], activeIndex: -1, isInSelectionMode: false, debounceTimer: null, processedInputs: new WeakSet(), init() { return __async(this, null, function* () { NativeSetter.init(); yield UIManager.init(); InputDetector.init({ onInputDetected: this.handleInputDetected.bind(this), onInputRemoved: this.handleInputRemoved.bind(this) }); this.bindInputEvents(); console.log("InputManager initialized"); }); }, bindInputEvents() { document.addEventListener("focusin", this.handleFocusIn.bind(this)); document.addEventListener("focusout", this.handleFocusOut.bind(this)); document.addEventListener("keydown", this.handleKeyDown.bind(this), true); document.addEventListener("input", this.handleInput.bind(this)); this.startInputValueWatcher(); }, startInputValueWatcher() { setInterval(() => { if (this.currentInput && this.currentSuggestions.length > 0) { const currentValue = this.currentInput.value; if (currentValue.length === 0) { this.hidePopup(); this.setState(APP_STATES.IDLE); this.isInSelectionMode = false; this.activeIndex = -1; } } }, 100); }, handleInputDetected(input, type) { if (this.processedInputs.has(input)) return; this.processedInputs.add(input); console.log(`Processing detected input of type: ${type}`); this.setupInputByType(input, type); }, handleInputRemoved(input, type) { if (!this.processedInputs.has(input)) return; this.processedInputs.delete(input); if (this.currentInput === input) { this.currentInput = null; this.setState(APP_STATES.IDLE); UIManager.hidePopup(); } console.log(`Removed input of type: ${type}`); }, setupInputByType(input, type) { switch (type) { case INPUT_TYPES.MAIN_CHAT: this.setupMainChatInput(input); break; case INPUT_TYPES.FULLSCREEN_FLOAT: this.setupFullscreenInput(input); break; } }, setupMainChatInput(input) { const focusHandler = (event) => { this.currentInput = input; this.setState(APP_STATES.IDLE); console.log("Main chat input focused and activated"); }; input.addEventListener("focus", focusHandler, { once: true }); input.addEventListener("blur", () => { setTimeout(() => { input.addEventListener("focus", focusHandler, { once: true }); }, 100); }); }, setupFullscreenInput(input) { console.log("Fullscreen input setup completed"); const focusHandler = (event) => { this.currentInput = input; this.setState(APP_STATES.IDLE); console.log("Fullscreen input focused and activated"); }; input.addEventListener("focus", focusHandler); }, handleFocusIn(event) { const target = event.target; if (InputDetector.isChatInput(target)) { this.currentInput = target; this.setState(APP_STATES.IDLE); } }, handleFocusOut(event) { console.log("=== InputManager.handleFocusOut 被调用 ==="); console.log("失焦的元素:", event.target.className, "value:", event.target.value); if (event.target === this.currentInput) { console.log("当前输入框失焦,检查焦点转移目标..."); const related = event.relatedTarget; const isPluginUI = related && (related.closest(".dda-popup") || related.closest(".ddp-candidate-capsules")); if (!isPluginUI) { setTimeout(() => { const hasContent = this.currentInput && this.currentInput.value && this.currentInput.value.trim().length > 0; console.log("焦点转移到非插件UI,输入框有内容:", hasContent); this.setState(APP_STATES.IDLE); this.currentInput = null; if (!hasContent) { console.log("输入框为空,隐藏候选项"); this.hidePopup(); } else { console.log("输入框有内容,保持候选项显示"); } }, 150); } else { console.log("焦点转移到插件UI内,保持候选项显示"); } } }, handleInput(event) { if (event.target !== this.currentInput) return; const inputValue = event.target.value; if (inputValue.length === 0) { this.hidePopup(); this.setState(APP_STATES.IDLE); this.isInSelectionMode = false; this.activeIndex = -1; if (this.debounceTimer) clearTimeout(this.debounceTimer); return; } this.debounceProcessInput(inputValue); }, debounceProcessInput(inputValue) { if (this.debounceTimer) { clearTimeout(this.debounceTimer); } const settings = SettingsManager.getSettings(); this.debounceTimer = setTimeout(() => { this.processInput(inputValue); }, settings.debounceDelay); }, handleKeyDown(event) { if (event.target !== this.currentInput) return; const key = event.key; SettingsManager.getSettings(); const hasVisibleCandidates = UIManager.isPopupVisible(); if (hasVisibleCandidates) { if (this.isInSelectionMode) { if (key === CONFIG.KEYBOARD.ARROW_UP) { event.preventDefault(); this.navigateUp(); } else if (key === CONFIG.KEYBOARD.ARROW_DOWN) { event.preventDefault(); this.exitSelectionMode(); } else if (key === CONFIG.KEYBOARD.ARROW_LEFT) { event.preventDefault(); this.navigateLeft(); } else if (key === CONFIG.KEYBOARD.ARROW_RIGHT) { event.preventDefault(); this.navigateRight(); } else if (key === CONFIG.KEYBOARD.ENTER && !event.shiftKey) { event.preventDefault(); event.stopPropagation(); this.selectActiveCandidate(); this.exitSelectionMode(); } else if (key === CONFIG.KEYBOARD.ESCAPE) { event.preventDefault(); this.exitSelectionMode(); this.hidePopup(); } } else { if (key === CONFIG.KEYBOARD.ARROW_UP) { event.preventDefault(); event.stopPropagation(); this.enterSelectionMode(); } } } }, enterSelectionMode() { this.isInSelectionMode = true; this.setState(APP_STATES.SELECTING); UIManager.setSelectionModeActive(true); if (this.currentSuggestions.length > 0) { this.setActiveIndex(0); } Utils.log("进入候选项选择模式"); }, exitSelectionMode() { this.isInSelectionMode = false; this.setState(APP_STATES.TYPING); UIManager.setSelectionModeActive(false); this.setActiveIndex(-1); Utils.log("退出候选项选择模式"); }, navigateUp() { if (this.currentSuggestions.length === 0) return; let newIndex = this.activeIndex - 1; if (newIndex < 0) { newIndex = this.currentSuggestions.length - 1; } this.setActiveIndex(newIndex); }, navigateDown() { if (this.currentSuggestions.length === 0) return; let newIndex = this.activeIndex + 1; if (newIndex >= this.currentSuggestions.length) { newIndex = 0; } this.setActiveIndex(newIndex); }, navigateLeft() { this.navigateUp(); }, navigateRight() { this.navigateDown(); }, setActiveIndex(index) { if (index < -1 || index >= this.currentSuggestions.length && index !== -1) { return; } this.activeIndex = index; UIManager.setActiveIndex(index); }, selectActiveCandidate() { if (this.activeIndex >= 0 && this.activeIndex < this.currentSuggestions.length) { const selectedCandidate = this.currentSuggestions[this.activeIndex]; this.selectCandidate(selectedCandidate); } }, selectCandidate(candidate) { if (!candidate || !this.currentInput) return; const text = candidate.getDisplayText ? candidate.getDisplayText() : candidate.text; if (typeof candidate.updateUsage === "function") { candidate.updateUsage(); } else if (candidate.id) { DanmukuDB.updateUsage(candidate.id); } NativeSetter.setValue(this.currentInput, text); this.hidePopup(); this.setState(APP_STATES.IDLE); this.isInSelectionMode = false; this.activeIndex = -1; Utils.log(`候选项已选择并填入输入框: ${text}`); }, hidePopup() { UIManager.hidePopup(); this.currentSuggestions = []; this.activeIndex = -1; }, processInput(inputValue) { return __async(this, null, function* () { const settings = SettingsManager.getSettings(); if (inputValue.length < settings.minSearchLength) { this.setState(APP_STATES.IDLE); this.isInSelectionMode = false; this.activeIndex = -1; this.hidePopup(); return; } let suggestions = yield DanmukuDB.search(inputValue); this.currentSuggestions = suggestions; if (suggestions.length > 0) { this.setState(APP_STATES.TYPING); this.isInSelectionMode = false; UIManager.showPopup(suggestions, this.currentInput); } else { this.setState(APP_STATES.IDLE); this.isInSelectionMode = false; this.hidePopup(); } }); }, setState(newState) { const oldState = this.currentState; this.currentState = newState; console.log(`State changed: ${oldState} -> ${newState}`); this.onStateChange(oldState, newState); }, onStateChange(oldState, newState) { console.log(`=== onStateChange: ${oldState} -> ${newState} ===`); switch (newState) { case APP_STATES.IDLE: console.log("状态变为IDLE,但不自动隐藏弹窗"); break; case APP_STATES.TYPING: console.log("状态变为TYPING"); break; case APP_STATES.SELECTING: console.log("状态变为SELECTING,设置活跃索引"); if (this.activeIndex === -1 && this.currentSuggestions.length > 0) { this.setActiveIndex(0); } break; } }, isChatInput(element) { return InputDetector.isChatInput(element); } }; const KeyboardController = { activeIndex: 0, enabled: true, init() { console.log("KeyboardController initialized"); }, handleKeyDown(event, currentState) { if (!this.enabled) return; const key = event.code || event.key; switch (currentState) { case APP_STATES.IDLE: this.handleIdleState(event, key); break; case APP_STATES.TYPING: this.handleTypingState(event, key); break; case APP_STATES.SELECTING: this.handleSelectingState(event, key); break; } }, handleIdleState(event, key) { if (this.isTriggerKey(key)) { event.preventDefault(); } }, handleTypingState(event, key) { if (this.isTriggerKey(key)) { event.preventDefault(); } else if (this.isCancelKey(key)) { event.preventDefault(); } }, handleSelectingState(event, key) { if (this.isNavigationKey(key)) { this.handleNavigation(event, key); } else if (this.isSelectKey(key)) { this.handleSelection(event); } else if (this.isCancelKey(key)) { this.handleCancel(event); } }, handleNavigation(event, key) { event.preventDefault(); const direction = this.getNavigationDirection(key); if (direction === "up") { this.moveSelection(-1); } else if (direction === "down") { this.moveSelection(1); } }, handleSelection(event) { event.preventDefault(); if (UIManager) { UIManager.selectActiveCandidate(); } }, handleCancel(event) { event.preventDefault(); if (UIManager) { UIManager.hidePopup(); } }, moveSelection(delta) { if (UIManager) { if (delta < 0) { UIManager.navigateUp(); } else { UIManager.navigateDown(); } } }, resetSelection() { this.activeIndex = 0; }, isTriggerKey(key) { return CONFIG.TRIGGER_KEYS.includes(key) || key === "Tab" && CONFIG.TRIGGER_KEYS.includes("Tab"); }, isNavigationKey(key) { return CONFIG.NAVIGATION_KEYS.includes(key) || ["ArrowUp", "ArrowDown", "KeyW", "KeyS"].includes(key); }, isSelectKey(key) { return CONFIG.SELECT_KEYS.includes(key) || ["Enter", "Tab"].includes(key); }, isCancelKey(key) { return CONFIG.CANCEL_KEYS.includes(key) || key === "Escape"; }, getNavigationDirection(key) { switch (key) { case "ArrowUp": case "KeyW": return "up"; case "ArrowDown": case "KeyS": return "down"; default: return null; } }, enable() { this.enabled = true; }, disable() { this.enabled = false; } }; const mainCss = ':root{color-scheme:light dark;--motion-easing: cubic-bezier(.4, 0, .2, 1);--status-color-waiting: #4CAF50;--status-color-claiming: #2196F3;--status-color-switching: #FFC107;--status-color-error: #F44336;--status-color-opening: #9C27B0;--status-color-dormant: #757575;--status-color-unresponsive: #FFA000;--status-color-disconnected: #BDBDBD;--status-color-stalled: #9af39dff}body[data-theme=dark]{--md-sys-color-primary: #D0BCFF;--md-sys-color-on-primary: #381E72;--md-sys-color-primary-container: #4F378B;--md-sys-color-on-primary-container: #EADDFF;--md-sys-color-surface-container: #211F26;--md-sys-color-on-surface: #E6E1E5;--md-sys-color-on-surface-variant: #CAC4D0;--md-sys-color-outline: #938F99;--md-sys-color-surface-bright: #36343B;--md-sys-color-tertiary: #EFB8C8;--md-sys-color-scrim: #000000;--surface-container-highest: #3D3B42}body[data-theme=light]{--md-sys-color-primary: #6750A4;--md-sys-color-on-primary: #FFFFFF;--md-sys-color-primary-container: #EADDFF;--md-sys-color-on-primary-container: #21005D;--md-sys-color-surface-container: #F3EDF7;--md-sys-color-surface-bright: #FEF7FF;--md-sys-color-on-surface: #1C1B1F;--md-sys-color-on-surface-variant: #49454F;--md-sys-color-outline: #79747E;--md-sys-color-tertiary: #7D5260;--md-sys-color-scrim: #000000;--surface-container-highest: #E6E0E9}.qmx-hidden{display:none!important}.qmx-modal-open-scroll-lock{overflow:hidden!important}.is-dragging{transition:none!important}.qmx-flex-center{display:flex;align-items:center;justify-content:center}.qmx-flex-between{display:flex;align-items:center;justify-content:space-between}.qmx-flex-column{display:flex;flex-direction:column}.qmx-modal-base{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) scale(.95);z-index:10001;background-color:var(--md-sys-color-surface-bright);color:var(--md-sys-color-on-surface);border-radius:28px;box-shadow:0 12px 32px #00000080;display:flex;flex-direction:column;opacity:0;visibility:hidden;transition:opacity .25s cubic-bezier(.4,0,.2,1),visibility .25s cubic-bezier(.4,0,.2,1),transform .25s cubic-bezier(.4,0,.2,1)}.qmx-modal-base.visible{opacity:1;visibility:visible;transform:translate(-50%,-50%) scale(1)}.qmx-backdrop{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:var(--md-sys-color-scrim);z-index:9998;opacity:0;visibility:hidden;transition:opacity .25s cubic-bezier(.4,0,.2,1)}.qmx-backdrop.visible{opacity:.5;visibility:visible}.qmx-btn{padding:10px 24px;border:1px solid var(--md-sys-color-outline);background-color:transparent;color:var(--md-sys-color-primary);border-radius:20px;font-size:14px;font-weight:500;cursor:pointer;transition:background-color .2s var(--motion-easing),transform .2s var(--motion-easing),box-shadow .2s var(--motion-easing);user-select:none;display:inline-flex;align-items:center;justify-content:center;gap:8px;height:40px}.qmx-btn:hover{background-color:var(--md-sys-color-primary-container);box-shadow:0 1px 2px #0000004d,0 1px 3px 1px #00000026}.qmx-btn:active{transform:scale(.98);box-shadow:none}.qmx-btn:disabled{opacity:.38;cursor:not-allowed;background-color:var(--md-sys-color-on-surface);color:var(--md-sys-color-surface-container)}.qmx-btn--primary{background-color:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary);border:none}.qmx-btn--primary:hover{background-color:var(--md-sys-color-on-primary-container);color:var(--md-sys-color-on-primary-container);box-shadow:0 1px 2px #0000004d,0 2px 6px 2px #00000026}.qmx-btn--danger{border-color:var(--status-color-error);color:var(--status-color-error)}.qmx-btn--danger:hover{background-color:#f443361a}.qmx-btn--icon{width:40px;height:40px;padding:0;border-radius:50%;background-color:transparent;border:none;color:var(--md-sys-color-on-surface-variant)}.qmx-btn--icon:hover{background-color:#d0bcff26;color:var(--md-sys-color-primary)}.qmx-styled-list{list-style:none;padding-left:0}.qmx-styled-list li{position:relative;padding-left:20px;margin-bottom:8px}.qmx-styled-list li:before{content:"◆";position:absolute;left:0;top:2px;color:var(--md-sys-color-primary);font-size:12px}.qmx-scrollbar::-webkit-scrollbar{width:10px}.qmx-scrollbar::-webkit-scrollbar-track{background:var(--md-sys-color-surface-bright);border-radius:10px}.qmx-scrollbar::-webkit-scrollbar-thumb{background-color:var(--md-sys-color-primary);border-radius:10px;border:2px solid var(--md-sys-color-surface-bright)}.qmx-scrollbar::-webkit-scrollbar-thumb:hover{background-color:var(--md-sys-color-on-primary-container)}.dda-popup{position:fixed;z-index:9999;background:var(--md-sys-color-surface-container);border:1px solid var(--md-sys-color-outline);transition:all .3s var(--motion-easing),box-shadow .3s var(--motion-easing);border-radius:12px;box-shadow:0 4px 8px 3px #00000026,0 1px 3px #0000004d;max-width:400px;max-height:300px;overflow:hidden;opacity:0;transform:translateY(-10px)}.dda-popup.show{opacity:1;transform:translateY(0)}.dda-popup.selection-mode-active{border-color:var(--md-sys-color-primary);box-shadow:0 6px 16px 4px #0003,0 2px 6px #0006,0 0 0 1px var(--md-sys-color-primary);background:var(--md-sys-color-surface-bright)}.dda-popup-content{max-height:300px;overflow-y:auto;padding:4px 0}.dda-popup-item{padding:8px 16px;cursor:pointer;border-bottom:1px solid var(--md-sys-color-outline);transition:all .25s cubic-bezier(.4,0,.2,1);min-height:40px;display:flex;flex-direction:column;justify-content:center;position:relative;border-left:6px solid transparent;will-change:transform}.dda-popup-item-active{background-color:var(--md-sys-color-tertiary-container);border-left-color:var(--md-sys-color-tertiary);transform:translate(2px);box-shadow:0 4px 12px #0003,inset 0 0 0 2px rgba(var(--md-sys-color-tertiary-rgb),.3);z-index:10}.dda-popup-item:last-child{border-bottom:none}.dda-popup-item:hover{background-color:var(--md-sys-color-surface-bright);transform:translate(4px)}.dda-preview-tooltip{position:fixed;z-index:10000;background:var(--md-sys-color-surface-bright);border:1px solid var(--md-sys-color-outline);border-radius:8px;padding:12px 16px;box-shadow:0 8px 24px #0000004d;max-width:400px;word-wrap:break-word;font-size:14px;color:var(--md-sys-color-on-surface);opacity:0;transform:translateY(-10px);transition:opacity .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1);pointer-events:none}.dda-preview-tooltip.show{opacity:1;transform:translateY(0)}.dda-popup-item-text{font-size:14px;color:var(--md-sys-color-on-surface);line-height:1.4;margin-bottom:4px}.dda-popup-item-active .dda-popup-item-text{color:var(--md-sys-color-on-tertiary-container);font-weight:600}.dda-popup-item-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.dda-popup-tag{display:inline-block;padding:2px 6px;background-color:var(--md-sys-color-tertiary);color:var(--md-sys-color-on-primary);font-size:11px;border-radius:12px;line-height:1.2}.dda-popup-item-active .dda-popup-tag{background-color:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.dda-popup-empty{max-height:60px}.dda-empty-message{padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);font-size:13px}@media (max-width: 480px){.dda-popup{max-width:90vw;left:5vw!important;right:5vw!important}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.dda-popup.animate-in{animation:fadeInUp .2s var(--motion-easing)}.send-button:hover{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.send-button:active{transform:scale(.98)}.ddp-candidate-capsules{display:flex;flex-wrap:nowrap;gap:6px;padding:var(--ddp-capsule-padding, 8px) 12px;background:#000000d9;border-radius:8px;margin:var(--ddp-capsule-margin, 8px) 12px;max-width:calc(100% - 24px);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none;position:relative;z-index:1000}.ddp-candidate-capsules::-webkit-scrollbar{display:none}.ddp-candidate-capsules.multi-row{flex-wrap:wrap;max-height:120px;overflow-y:auto;mask:none;-webkit-mask:none}.ddp-candidate-capsule{flex-shrink:0;padding:var(--ddp-capsule-item-padding, 3px) 8px;background:#ffffff1a;border:1px solid rgba(255,255,255,.2);border-radius:12px;color:#fff;font-size:12px;line-height:1.3;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:ltr;text-align:left;max-width:150px;min-width:30px;height:var(--ddp-capsule-item-height, 24px);display:flex;align-items:center;justify-content:flex-start;box-sizing:border-box;user-select:none;position:relative}.ddp-candidate-capsules.multi-row .ddp-candidate-capsule{flex:0 0 calc(25% - 5px);max-width:calc(25% - 5px);min-width:60px}.ddp-candidate-capsule:hover{background:#fff3;border-color:#fff6;transform:translateY(-1px);box-shadow:0 2px 4px #0003}.ddp-candidate-capsule.active{background:#f60;border-color:#f83;color:#fff;font-weight:500;box-shadow:0 2px 6px #ff66004d}.ddp-candidate-capsules.selection-mode-active{box-shadow:0 0 0 2px #f60;background:#000000e6}.ddp-candidate-capsule[title]{position:relative}.ddp-capsule-preview{position:fixed;z-index:10000;background:#282828f2;border:1px solid rgba(255,255,255,.2);border-radius:8px;padding:8px 12px;box-shadow:0 4px 8px 3px #0000004d,0 1px 3px #0006;max-width:300px;min-width:100px;word-wrap:break-word;white-space:normal;opacity:0;transform:translateY(-5px);transition:opacity .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1);pointer-events:none;font-size:13px;line-height:1.4;color:#fff;backdrop-filter:blur(4px)}.ddp-capsule-preview.show{opacity:1;transform:translateY(0)}.ddp-capsule-preview:before{content:"";position:absolute;bottom:-5px;left:50%;transform:translate(-50%);width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid rgba(40,40,40,.95)}.ddp-capsule-preview.show-below:before{bottom:auto;top:-5px;border-top:none;border-bottom:5px solid rgba(40,40,40,.95)}.ddp-capsule-preview.active{border-color:#f60;background:#323232f2;box-shadow:0 4px 8px 3px #0000004d,0 1px 3px #0006,0 0 0 1px #f60}.ddp-capsule-preview.active:before{border-top-color:#323232f2}.ddp-capsule-preview.active.show-below:before{border-bottom-color:#323232f2}.layout-Player-chat .Chat .ddp-candidate-capsules{z-index:1000;position:relative}@media (max-width: 768px){.ddp-candidate-capsules{gap:6px;padding:6px 8px}.ddp-candidate-capsule{padding:4px 8px;font-size:12px;max-width:150px}}@media (prefers-color-scheme: dark){.ddp-candidate-capsules{box-shadow:0 2px 8px #00000040}.ddp-candidate-capsule:hover{box-shadow:0 2px 8px #0000004d}}@keyframes ddp-capsule-appear{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ddp-candidate-capsules{animation:ddp-capsule-appear .2s var(--motion-easing)}.ddp-candidate-capsule{animation:ddp-capsule-appear .3s var(--motion-easing) backwards}.ddp-candidate-capsule:nth-child(1){animation-delay:.05s}.ddp-candidate-capsule:nth-child(2){animation-delay:.1s}.ddp-candidate-capsule:nth-child(3){animation-delay:.15s}.ddp-candidate-capsule:nth-child(4){animation-delay:.2s}.ddp-candidate-capsule:nth-child(5){animation-delay:.25s}.dda-settings-content{width:90%;max-width:600px;max-height:80vh;overflow:hidden}.dda-settings-header{display:flex;justify-content:space-between;align-items:center;padding:16px 24px;border-bottom:1px solid var(--md-sys-color-outline)}.dda-settings-header h2{margin:0;color:var(--md-sys-color-on-surface);font-size:22px;font-weight:400}.dda-settings-body{padding:24px;max-height:calc(80vh - 130px);overflow-y:auto}.dda-settings-section{margin-bottom:32px}.dda-settings-section:last-child{margin-bottom:0}.dda-settings-section h3{margin:0 0 16px;color:var(--md-sys-color-primary);font-size:16px;font-weight:500;padding-bottom:8px;border-bottom:1px solid var(--md-sys-color-outline)}.dda-setting-item{display:flex;justify-content:space-between;align-items:center;padding:16px 0;border-bottom:1px solid var(--md-sys-color-outline)}.dda-setting-item:last-child{border-bottom:none}.dda-setting-item label{color:var(--md-sys-color-on-surface-variant);font-size:14px;font-weight:400;flex:1}.dda-key-group{display:flex;gap:16px;flex-wrap:wrap;align-items:center}.dda-key-group label{display:flex;align-items:center;font-size:14px;color:var(--md-sys-color-on-surface-variant);flex:none}.dda-settings-footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--md-sys-color-outline)}@media (max-width: 640px){.dda-settings-content{width:100%;height:100%;max-height:100vh;border-radius:0;margin:0}.dda-settings-header,.dda-settings-footer{padding:16px}.dda-settings-body{padding:16px;max-height:calc(100vh - 120px)}.dda-setting-item{flex-direction:column;align-items:flex-start;gap:12px}}.qmx-input{background-color:var(--md-sys-color-surface-container);border:1px solid var(--md-sys-color-outline);color:var(--md-sys-color-on-surface);border-radius:4px;padding:16px;width:100%;box-sizing:border-box;transition:box-shadow .2s var(--motion-easing),border-color .2s var(--motion-easing);font-size:16px;height:56px}.qmx-input:hover{border-color:var(--md-sys-color-on-surface)}.qmx-input:focus{outline:none;border-color:var(--md-sys-color-primary);border-width:2px;padding:15px}.qmx-input[type=number]::-webkit-inner-spin-button,.qmx-input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.qmx-input[type=number]{-moz-appearance:textfield;appearance:textfield}.qmx-fieldset-unit{position:relative;padding:0;margin:0;border:1px solid var(--md-sys-color-outline);border-radius:4px;background-color:var(--md-sys-color-surface-container);transition:border-color .25s cubic-bezier(.4,0,.2,1);width:100%;box-sizing:border-box;height:56px;display:flex;align-items:center}.qmx-fieldset-unit:hover{border-color:var(--md-sys-color-on-surface)}.qmx-fieldset-unit:focus-within{border-color:var(--md-sys-color-primary);border-width:2px}.qmx-fieldset-unit input[type=number]{border:none;background:none;outline:none;color:var(--md-sys-color-on-surface);padding:16px;width:100%;box-sizing:border-box;font-size:16px}.qmx-fieldset-unit legend{padding:0 4px;font-size:12px;color:var(--md-sys-color-on-surface-variant);margin-left:12px;pointer-events:none;position:absolute;top:-8px;background-color:var(--md-sys-color-surface-container)}.qmx-toggle{position:relative;display:inline-block;width:52px;height:32px}.qmx-toggle input{opacity:0;width:0;height:0}.qmx-toggle .slider{position:absolute;cursor:pointer;inset:0;background-color:var(--md-sys-color-surface-container);border:2px solid var(--md-sys-color-outline);border-radius:16px;transition:background-color .3s var(--motion-easing),border-color .3s var(--motion-easing)}.qmx-toggle .slider:before{position:absolute;content:"";height:16px;width:16px;left:6px;bottom:6px;background-color:var(--md-sys-color-outline);border-radius:50%;transition:all .3s var(--motion-easing)}.qmx-toggle input:checked+.slider{background-color:var(--md-sys-color-primary);border-color:var(--md-sys-color-primary)}.qmx-toggle input:checked+.slider:before{background-color:var(--md-sys-color-on-primary);transform:translate(20px);height:24px;width:24px;left:2px;bottom:2px}.qmx-toggle:hover .slider{border-color:var(--md-sys-color-on-surface-variant)}.qmx-select{position:relative;width:100%}.qmx-select-styled{position:relative;padding:16px 40px 16px 16px;background-color:var(--md-sys-color-surface-container);border:1px solid var(--md-sys-color-outline);border-radius:4px;cursor:pointer;transition:all .2s var(--motion-easing);user-select:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:56px;box-sizing:border-box;font-size:16px;color:var(--md-sys-color-on-surface)}.qmx-select-styled:after{content:"▼";position:absolute;top:50%;right:16px;transform:translateY(-50%);color:var(--md-sys-color-on-surface-variant);transition:transform .3s var(--motion-easing);font-size:12px}.qmx-select:hover .qmx-select-styled{border-color:var(--md-sys-color-on-surface)}.qmx-select.active .qmx-select-styled{border-color:var(--md-sys-color-primary);border-width:2px}.qmx-select.active .qmx-select-styled:after{transform:translateY(-50%) rotate(180deg)}.qmx-select-options{position:absolute;top:105%;left:0;right:0;z-index:10;background-color:var(--md-sys-color-surface-bright);border:1px solid var(--md-sys-color-outline);border-radius:4px;max-height:0;overflow:hidden;opacity:0;transform:translateY(-10px);transition:all .3s var(--motion-easing);padding:8px 0;box-shadow:0 4px 8px 3px #00000026,0 1px 3px #0000004d}.qmx-select.active .qmx-select-options{max-height:200px;opacity:1;transform:translateY(0)}.qmx-select-options div{padding:12px 16px;cursor:pointer;transition:background-color .2s var(--motion-easing);font-size:16px}.qmx-select-options div:hover{background-color:var(--md-sys-color-on-primary-container)}.qmx-select-options div.selected{background-color:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary);font-weight:500}.qmx-range-slider-wrapper{display:flex;flex-direction:column;gap:8px;padding:16px 0}.qmx-range-slider-container{position:relative;height:24px;display:flex;align-items:center}.qmx-range-slider-container input[type=range]{position:absolute;width:100%;height:4px;-webkit-appearance:none;appearance:none;background:none;pointer-events:none;margin:0}.qmx-range-slider-container input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;pointer-events:auto;width:20px;height:20px;background-color:var(--md-sys-color-primary);border-radius:50%;cursor:grab;border:none;transition:transform .2s var(--motion-easing),box-shadow .2s var(--motion-easing)}.qmx-range-slider-container input[type=range]::-webkit-slider-thumb:active{cursor:grabbing;transform:scale(1.2);box-shadow:0 0 0 10px #d0bcff4d}.qmx-range-slider-container input[type=range]::-moz-range-thumb{pointer-events:auto;width:20px;height:20px;background-color:var(--md-sys-color-primary);border-radius:50%;cursor:grab;border:none;transition:transform .2s var(--motion-easing),box-shadow .2s var(--motion-easing)}.qmx-range-slider-container input[type=range]::-moz-range-thumb:active{cursor:grabbing;transform:scale(1.2);box-shadow:0 0 0 10px #d0bcff4d}.qmx-range-slider-track-container{position:absolute;width:100%;height:4px;background-color:var(--md-sys-color-surface-container);border-radius:2px}.qmx-range-slider-progress{position:absolute;height:100%;background-color:var(--md-sys-color-primary);border-radius:2px}.qmx-range-slider-values{font-size:14px;color:var(--md-sys-color-primary);text-align:center;font-weight:500}.qmx-tooltip-icon{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background-color:var(--md-sys-color-outline);color:var(--md-sys-color-surface-container);font-size:14px;font-weight:700;cursor:help;user-select:none;transition:background-color .2s var(--motion-easing),transform .2s var(--motion-easing)}.qmx-tooltip-icon:hover{background-color:var(--md-sys-color-on-surface-variant);transform:scale(1.1)}#qmx-global-tooltip{position:fixed;background-color:var(--surface-container-highest);color:var(--md-sys-color-on-surface);padding:6px 12px;border-radius:4px;box-shadow:0 4px 8px 3px #00000026,0 1px 3px #0000004d;font-size:14px;font-weight:400;line-height:1.4;z-index:10002;max-width:320px;opacity:0;visibility:hidden;transform:scale(.9);transition:opacity .15s var(--motion-easing),transform .15s var(--motion-easing),visibility .15s;pointer-events:none}#qmx-global-tooltip.visible{opacity:1;visibility:visible;transform:scale(1)}'; importCSS(mainCss); const danmukuPopupCss = ".dda-popup{position:fixed;z-index:9999;background:var(--md-sys-color-surface-container);border:1px solid var(--md-sys-color-outline);transition:all .3s var(--motion-easing),box-shadow .3s var(--motion-easing);border-radius:12px;box-shadow:0 4px 8px 3px #00000026,0 1px 3px #0000004d;max-width:400px;max-height:300px;overflow:hidden;opacity:0;transform:translateY(-10px)}.dda-popup.show{opacity:1;transform:translateY(0)}.dda-popup.selection-mode-active{border-color:var(--md-sys-color-primary);box-shadow:0 6px 16px 4px #0003,0 2px 6px #0006,0 0 0 1px var(--md-sys-color-primary);background:var(--md-sys-color-surface-bright)}.dda-popup-content{max-height:300px;overflow-y:auto;padding:4px 0}.dda-popup-item{padding:8px 16px;cursor:pointer;border-bottom:1px solid var(--md-sys-color-outline);transition:all .25s cubic-bezier(.4,0,.2,1);min-height:40px;display:flex;flex-direction:column;justify-content:center;position:relative;border-left:6px solid transparent;will-change:transform}.dda-popup-item-active{background-color:var(--md-sys-color-tertiary-container);border-left-color:var(--md-sys-color-tertiary);transform:translate(2px);box-shadow:0 4px 12px #0003,inset 0 0 0 2px rgba(var(--md-sys-color-tertiary-rgb),.3);z-index:10}.dda-popup-item:last-child{border-bottom:none}.dda-popup-item:hover{background-color:var(--md-sys-color-surface-bright);transform:translate(4px)}.dda-preview-tooltip{position:fixed;z-index:10000;background:var(--md-sys-color-surface-bright);border:1px solid var(--md-sys-color-outline);border-radius:8px;padding:12px 16px;box-shadow:0 8px 24px #0000004d;max-width:400px;word-wrap:break-word;font-size:14px;color:var(--md-sys-color-on-surface);opacity:0;transform:translateY(-10px);transition:opacity .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1);pointer-events:none}.dda-preview-tooltip.show{opacity:1;transform:translateY(0)}.dda-popup-item-text{font-size:14px;color:var(--md-sys-color-on-surface);line-height:1.4;margin-bottom:4px}.dda-popup-item-active .dda-popup-item-text{color:var(--md-sys-color-on-tertiary-container);font-weight:600}.dda-popup-item-tags{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.dda-popup-tag{display:inline-block;padding:2px 6px;background-color:var(--md-sys-color-tertiary);color:var(--md-sys-color-on-primary);font-size:11px;border-radius:12px;line-height:1.2}.dda-popup-item-active .dda-popup-tag{background-color:var(--md-sys-color-primary);color:var(--md-sys-color-on-primary)}.dda-popup-empty{max-height:60px}.dda-empty-message{padding:16px;text-align:center;color:var(--md-sys-color-on-surface-variant);font-size:13px}@media (max-width: 480px){.dda-popup{max-width:90vw;left:5vw!important;right:5vw!important}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.dda-popup.animate-in{animation:fadeInUp .2s var(--motion-easing)}.send-button:hover{background:var(--md-sys-color-primary-container);color:var(--md-sys-color-on-primary-container)}.send-button:active{transform:scale(.98)}"; importCSS(danmukuPopupCss); const candidateCapsulesCss = '.ddp-candidate-capsules{display:flex;flex-wrap:nowrap;gap:6px;padding:var(--ddp-capsule-padding, 8px) 12px;background:#000000d9;border-radius:8px;margin:var(--ddp-capsule-margin, 8px) 12px;max-width:calc(100% - 24px);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none;position:relative;z-index:1000}.ddp-candidate-capsules::-webkit-scrollbar{display:none}.ddp-candidate-capsules.multi-row{flex-wrap:wrap;max-height:120px;overflow-y:auto;mask:none;-webkit-mask:none}.ddp-candidate-capsule{flex-shrink:0;padding:var(--ddp-capsule-item-padding, 3px) 8px;background:#ffffff1a;border:1px solid rgba(255,255,255,.2);border-radius:12px;color:#fff;font-size:12px;line-height:1.3;cursor:pointer;transition:all .25s cubic-bezier(.4,0,.2,1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:ltr;text-align:left;max-width:150px;min-width:30px;height:var(--ddp-capsule-item-height, 24px);display:flex;align-items:center;justify-content:flex-start;box-sizing:border-box;user-select:none;position:relative}.ddp-candidate-capsules.multi-row .ddp-candidate-capsule{flex:0 0 calc(25% - 5px);max-width:calc(25% - 5px);min-width:60px}.ddp-candidate-capsule:hover{background:#fff3;border-color:#fff6;transform:translateY(-1px);box-shadow:0 2px 4px #0003}.ddp-candidate-capsule.active{background:#f60;border-color:#f83;color:#fff;font-weight:500;box-shadow:0 2px 6px #ff66004d}.ddp-candidate-capsules.selection-mode-active{box-shadow:0 0 0 2px #f60;background:#000000e6}.ddp-candidate-capsule[title]{position:relative}.ddp-capsule-preview{position:fixed;z-index:10000;background:#282828f2;border:1px solid rgba(255,255,255,.2);border-radius:8px;padding:8px 12px;box-shadow:0 4px 8px 3px #0000004d,0 1px 3px #0006;max-width:300px;min-width:100px;word-wrap:break-word;white-space:normal;opacity:0;transform:translateY(-5px);transition:opacity .2s cubic-bezier(.4,0,.2,1),transform .2s cubic-bezier(.4,0,.2,1);pointer-events:none;font-size:13px;line-height:1.4;color:#fff;backdrop-filter:blur(4px)}.ddp-capsule-preview.show{opacity:1;transform:translateY(0)}.ddp-capsule-preview:before{content:"";position:absolute;bottom:-5px;left:50%;transform:translate(-50%);width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;border-top:5px solid rgba(40,40,40,.95)}.ddp-capsule-preview.show-below:before{bottom:auto;top:-5px;border-top:none;border-bottom:5px solid rgba(40,40,40,.95)}.ddp-capsule-preview.active{border-color:#f60;background:#323232f2;box-shadow:0 4px 8px 3px #0000004d,0 1px 3px #0006,0 0 0 1px #f60}.ddp-capsule-preview.active:before{border-top-color:#323232f2}.ddp-capsule-preview.active.show-below:before{border-bottom-color:#323232f2}.layout-Player-chat .Chat .ddp-candidate-capsules{z-index:1000;position:relative}@media (max-width: 768px){.ddp-candidate-capsules{gap:6px;padding:6px 8px}.ddp-candidate-capsule{padding:4px 8px;font-size:12px;max-width:150px}}@media (prefers-color-scheme: dark){.ddp-candidate-capsules{box-shadow:0 2px 8px #00000040}.ddp-candidate-capsule:hover{box-shadow:0 2px 8px #0000004d}}@keyframes ddp-capsule-appear{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ddp-candidate-capsules{animation:ddp-capsule-appear .2s var(--motion-easing)}.ddp-candidate-capsule{animation:ddp-capsule-appear .3s var(--motion-easing) backwards}.ddp-candidate-capsule:nth-child(1){animation-delay:.05s}.ddp-candidate-capsule:nth-child(2){animation-delay:.1s}.ddp-candidate-capsule:nth-child(3){animation-delay:.15s}.ddp-candidate-capsule:nth-child(4){animation-delay:.2s}.ddp-candidate-capsule:nth-child(5){animation-delay:.25s}'; importCSS(candidateCapsulesCss); class DouyuDanmukuAssistant { constructor() { this.initialized = false; this.modules = {}; } init() { return __async(this, null, function* () { try { Utils.log("初始化斗鱼弹幕助手..."); if (document.readyState === "loading") { yield new Promise((resolve) => { document.addEventListener("DOMContentLoaded", resolve); }); } const dbSuccess = yield DanmukuDB.init(); if (!dbSuccess) { Utils.log("数据库初始化失败,某些功能可能无法正常工作", "warn"); } yield this.firstTimeImport(); KeyboardController.init(); yield InputManager.init(); this.initialized = true; Utils.log("斗鱼弹幕助手初始化完成"); } catch (error) { Utils.log(`初始化失败: ${error.message}`, "error"); } }); } firstTimeImport() { return __async(this, null, function* () { try { const dataCount = yield DanmukuDB.getDataCount(); if (dataCount === 0) { Utils.log("数据库为空,开始首次数据导入..."); const result = yield DanmukuDB.autoImportData(); if (result && result.successCount > 0) { Utils.log(`首次数据导入成功,共导入 ${result.successCount} 条弹幕。`); } else { Utils.log("首次数据导入失败或没有导入任何数据。", "warn"); } } else { Utils.log(`数据库中已存在 ${dataCount} 条数据,跳过首次导入。`); } } catch (error) { Utils.log(`检查首次导入时发生错误: ${error.message}`, "error"); } }); } destroy() { if (!this.initialized) return; this.initialized = false; Utils.log("斗鱼弹幕助手已销毁"); } } if (window.douyuDanmakuAssistantLoaded) { Utils.log("检测到重复执行,已阻止。请检查是否安装了多个版本的插件。", "warn"); } else { window.douyuDanmakuAssistantLoaded = true; const app = new DouyuDanmukuAssistant(); if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", () => { app.init(); }); } else { app.init(); } window.addEventListener("beforeunload", () => { app.destroy(); }); window.DouyuDanmukuAssistant = app; window.DanmukuDB = DanmukuDB; } }) }; })); System.register("./__vite-browser-external-2Ng8QIWW-Xya9USxv.js", [], (function (exports, module) { 'use strict'; return { execute: (function () { const __viteBrowserExternal = exports("default", {}); }) }; })); System.import("./__entry.js", "./");