JHS

JAV Helper Suite:为 JavDB / JavBus 提供浏览、收藏、筛选、资源检索、数据备份与统计增强。

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

作者のサイトでサポートを受ける。または、このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         JHS
// @namespace    https://sleazyfork.org/zh-CN/scripts/578503-jhs-ya
// @version      6.5.0
// @author       JHS Contributors
// @description  JAV Helper Suite:为 JavDB / JavBus 提供浏览、收藏、筛选、资源检索、数据备份与统计增强。
// @license      MIT
// @icon         https://www.google.com/s2/favicons?sz=64&domain=javdb.com
// @homepageURL  https://github.com/Teamper/JHS
// @supportURL   https://github.com/Teamper/JHS/issues
// @match        https://javdb.com/*
// @match        https://www.javbus.com/*
// @match        *://*.123pan.com/*
// @include      https://javdb*.com/*
// @include      https://*javbus*/*
// @include      https://*javsee*/*
// @include      https://*seejav*/*
// @include      https://javtrailers.com/*
// @include      https://subtitlecat.com/*
// @exclude      https://*javbus*/forum/*
// @exclude      https://*javbus*/*actresses
// @exclude      https://*javsee*/forum/*
// @exclude      https://*javsee*/*actresses
// @exclude      https://*seejav*/forum/*
// @exclude      https://*seejav*/*actresses
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/js/tabulator.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/layer.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/js/md5.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/src/toastify.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/localforage.min.js
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/viewer.min.js
// @connect      xunlei.com
// @connect      ja.wikipedia.org
// @connect      jdforrepam.com
// @connect      cc3001.dmm.co.jp
// @connect      cc3001.dmm.com
// @connect      www.dmm.co.jp
// @connect      www.dmm.com
// @connect      api.dmm.com
// @connect      special.dmm.co.jp
// @connect      adult.contents.fc2.com
// @connect      fc2ppvdb.com
// @connect      123av.com
// @connect      115.com
// @connect      webapi.115.com
// @connect      u3c3.com
// @connect      u9a9.com
// @connect      sukebei.nyaa.si
// @connect      javstore.net
// @connect      missav.live
// @connect      jable.tv
// @connect      jav.rs
// @connect      javtrailers.com
// @connect      javdb.com
// @connect      javbus.com
// @connect      www.123pan.com
// @connect      yun.123pan.com
// @connect      supjav.com
// @connect      translate-pa.googleapis.com
// @connect      *
// @grant        GM_xmlhttpRequest
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_deleteValue
// @grant        GM_openInTab
// @grant        unsafeWindow
// @run-at       document-idle
// ==/UserScript==

(()=>{var Io=Object.defineProperty;var Bd=(o,e,t)=>e in o?Io(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var d=(o,e)=>Io(o,"name",{value:e,configurable:!0});var lt=(o,e,t)=>Bd(o,typeof e!="symbol"?e+"":e,t);var Ri=class Ri{constructor(e,t={}){if(!e)throw new TypeError("LifecycleScope id is required");this.id=e,this.controller=new AbortController,this.cleanups=new Set,this.requestConsumers=new Set,this.observerCleanups=new Map,this.listenerCount=0,this.observerCount=0,this.disposed=!1,this.generation=0,this.onChange=t.onChange??null}get signal(){return this.controller.signal}listen(e,t,s,a){return this.assertActive(),e.addEventListener(t,s,a),this.listenerCount+=1,this.addCleanup(()=>{e.removeEventListener(t,s,a),this.listenerCount-=1})}ownObserver(e){this.assertActive();let t=this.observerCleanups.get(e);if(t)return t;this.observerCount+=1;let s=this.addCleanup(()=>{e.disconnect(),this.observerCount-=1,this.observerCleanups.delete(e)});return this.observerCleanups.set(e,s),s}releaseObserver(e){this.observerCleanups.get(e)?.()}observe(e,t,s){this.assertActive();let a=new MutationObserver(t);return a.observe(e,s),this.ownObserver(a),a}ownTimeout(e){return this.addCleanup(()=>clearTimeout(e))}ownRequestConsumer(e){return this.assertActive(),this.requestConsumers.add(e),this.emitChange(),this.addCleanup(()=>{this.requestConsumers.delete(e)&&e.release()})}addCleanup(e){this.assertActive();let t=!0,s=d(()=>{t&&(t=!1,this.cleanups.delete(s),e(),this.emitChange())},"wrapped");return this.cleanups.add(s),this.emitChange(),s}nextGeneration(){return this.assertActive(),this.generation+=1,this.generation}canCommit(e){return!this.disposed&&e===this.generation}dispose(){if(!this.disposed){this.disposed=!0,this.controller.abort();for(let e of[...this.cleanups].reverse())e();this.emitChange()}}assertActive(){if(this.disposed)throw new DOMException(`LifecycleScope ${this.id} is disposed`,"AbortError")}snapshot(){return Object.freeze({id:this.id,disposed:this.disposed,listeners:this.listenerCount,observers:this.observerCount,requestConsumers:this.requestConsumers.size,generation:this.generation})}emitChange(){this.onChange?.(this.snapshot())}};d(Ri,"LifecycleScope");var te=Ri;var ps=new WeakSet;function kt(o={},e={}){if(ps.has(o)||ps.has(o.success))return o;let{ui:t,...s}=o,a=["scroll","table","media"].includes(t?.body)?t.body:"scroll";t?.size&&e.getDialogArea&&(s.area=e.getDialogArea(t.size));let i,r=s.success,n=s.end;return s.success=function(l,c){let h=l?.nodeType===1?l:l?.[0]||globalThis.document?.getElementById(`layui-layer${c}`);if(h?.classList){h.classList.add("jhs-dialog","jhs-ui"),h.dataset.jhsDialogBody=a,i=new te(`dialog-shell-${c}`);let u=h.querySelector(".layui-layer-close");u&&(u.setAttribute("role","button"),u.setAttribute("tabindex","0"),u.setAttribute("aria-label","关闭弹窗"),i.listen(u,"keydown",g=>{let m=g.key;(m==="Enter"||m===" ")&&(g.preventDefault(),u.click())}));let p=d(()=>{if(t?.size&&e.getDialogArea){let[m,f]=e.getDialogArea(t.size);Object.assign(h.style,{width:m,height:f});let v=h.querySelector(".layui-layer-content"),b=h.querySelector("iframe");if(b&&v){let w=h.querySelector(".layui-layer-title")?.getBoundingClientRect().height||0;v.style.height=`${Math.max(0,parseFloat(f)-w)}px`,b.style.height=v.style.height}}h.style.maxWidth=`${Math.max(0,window.innerWidth-16)}px`,h.style.maxHeight=`${Math.max(0,window.innerHeight-16)}px`;let g=h.getBoundingClientRect();(t?.size||g.right>window.innerWidth-8||g.left<8)&&(h.style.left=`${h.offsetLeft+Math.max(8,(window.innerWidth-g.width)/2)-g.left}px`),(t?.size||g.bottom>window.innerHeight-8||g.top<8)&&(h.style.top=`${h.offsetTop+Math.max(8,(window.innerHeight-g.height)/2)-g.top}px`)},"resize");i.listen(window,"resize",p),p()}try{return r?.call(this,l,c)}catch(u){throw i?.dispose(),u}},s.end=function(...l){return i?.dispose(),n?.apply(this,l)},ps.add(s),ps.add(s.success),s}d(kt,"prepareDialogOptions");var Md=/^(?:[a-z0-9-]+\.)?javdb(?:[a-z0-9-]*)\.com$/i,Od=["javbus","javsee","seejav"];function Ro(o=window.location){return o instanceof URL?o:typeof o=="string"?new URL(o):new URL(o.href||`${o.protocol}//${o.hostname}${o.pathname||"/"}${o.search||""}`)}d(Ro,"normalizeLocation");function gs(o=window.location){let t=Ro(o).hostname.toLowerCase().replace(/\.$/,""),s=Md.test(t),a=Od.some((c=>t.includes(c))),i=t==="123pan.com"||t.endsWith(".123pan.com"),r=t==="javtrailers.com"||t.endsWith(".javtrailers.com"),n=t==="subtitlecat.com"||t.endsWith(".subtitlecat.com");return{site:s?"javdb":a?"javbus":i?"123pan":r?"javtrailers":n?"subtitlecat":"unknown",hostname:t,isJavDB:s,isJavBus:a,is123Pan:i,isJavTrailers:r,isSubtitleCat:n}}d(gs,"detectSite");function We(o=window.location){let e=Ro(o);return e.pathname==="/advanced_search"&&e.searchParams.get("handlePlayback")==="1"}d(We,"isHitShowPage");var zd=Object.defineProperty,Ei=d(o=>{throw TypeError(o)},"a"),A=d((o,e,t)=>((s,a,i)=>a in s?zd(s,a,{enumerable:!0,configurable:!0,writable:!0,value:i}):s[a]=i)(o,typeof e!="symbol"?e+"":e,t),"i"),Di=d((o,e,t)=>(((s,a,i)=>{a.has(s)||Ei("Cannot "+i)})(o,e,"access private method"),t),"s"),Y="",Ni={site:"unknown",hostname:"",isJavDB:!1,isJavBus:!1,is123Pan:!1,isJavTrailers:!1,isSubtitleCat:!1},N=!1,B=!1,ms=!1,ce="filter",ue="favorite",pe="hasDown",me="hasWatch",Ne="屏蔽",et="已屏蔽";var Le="收藏",tt="已收藏";var fe="已下载";var ve="已观看";var ne="no",R="yes",Be="javdb",je="javbus",Me="actor",st="actress",Je="censored",Ke="uncensored",at=[{id:"video-mhb",quality:"dmb_w",text:"旧视频源-中画质宽版 (404p)",canSelect:!1},{id:"video-mhb",quality:"sm_s",text:"旧视频源-低画质 (240p)",canSelect:!1},{id:"video-mhb",quality:"dm_s",text:"旧视频源-中画质 (360p)",canSelect:!1},{id:"video-mhb",quality:"dmb_s",text:"旧视频源-中画质 (480p)",canSelect:!1},{id:"video-mhb",quality:"mhb_w",text:"旧视频源-高画质宽版 (404p)",canSelect:!1},{id:"video-mmb",quality:"mmb",text:"中画质 (432p)",canSelect:!0},{id:"video-mhb",quality:"mhb",text:"高画质 (576p)",canSelect:!0},{id:"video-hmb",quality:"hmb",text:"HD (720p)",canSelect:!0},{id:"video-hhb",quality:"hhb",text:"FullHD (1080p)",canSelect:!0},{id:"video-hhbs",quality:"hhbs",text:"FullHD (1080p60fps)",canSelect:!0},{id:"video-4k",quality:"4k",text:"4K (2160p)",canSelect:!0},{id:"video-4ks",quality:"4ks",text:"4K (2160p60fps)",canSelect:!0}];function Eo(o=window.location){let e=gs(o);return Y=o.href,Ni=e,N=e.isJavDB,B=e.isJavBus,ms=Y.includes("/search?q")||Y.includes("/search/")||Y.includes("/users/"),e}d(Eo,"initializeRuntimeConstants");function C(o){let e=document.createElement("span");return e.textContent=o,e.innerHTML.replaceAll('"',"&quot;").replaceAll("'","&#39;")}d(C,"escapeHtml");var fs=3;function T(o){if(typeof o!="string")return null;let e=o.trim();return!e||["undefined","null"].includes(e.toLowerCase())?null:(e=e.normalize("NFKC").replace(/[‐‑‒–—―﹘﹣-]/g,"-").replace(/[\s_]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").toUpperCase(),e?Fd(e):null)}d(T,"normalizeCarNum");var Ud=new Set(["ABC","ABP","ADN","ATID","BF","CAWD","DLDSS","DVAJ","FSDSS","HEYZO","HMN","IPX","IPZZ","JUQ","JUL","JUX","MEYD","MIAA","MIDE","MIDV","MIMK","MIRD","NIMA","PRED","RBD","SDDE","SONE","SSIS","SSNI","STARS","URE","VEC","WAAA","WANZ","XVSR"]);function Fd(o){let e=String(o||"").match(/^([A-Z]{2,8})(\d{2,7})$/);return e&&Ud.has(e[1])?`${e[1]}-${e[2]}`:o}d(Fd,"tryCanonicalizeSimpleCarNum");function Do(...o){for(let e of o){let t=T(e);if(t)return t}return null}d(Do,"firstValidCarNum");function No(o){if(!o||typeof o!="object"||Array.isArray(o))throw new TypeError("getPageInfo() contract broken: expected object");return o}d(No,"assertPageInfoContract");function Lo(){return window.location.href.includes("hideNav=1")?`
         .navbar-default {
            display: none !important;
        }
        body {
            padding-top:0px!important;
        }
    `:""}d(Lo,"getJavBusHiddenNavCss");function Bo(){return window.location.href.includes("hideNav=1")?`
        .main-nav,#search-bar-container {
            display: none !important;
        }

        html {
            padding-top:0px!important;
        }
    `:""}d(Bo,"getJavDbHiddenNavCss");function Mo(o){if(o)if(o.includes("<style>"))document.head.insertAdjacentHTML("beforeend",o);else{let e=document.createElement("style");e.textContent=o,document.head.appendChild(e)}}d(Mo,"H");var J=Object.freeze({content:10,elevated:20,localPopover:30,popover:100,dropdown:1e3,fabBackdrop:12345691,fabMenu:12345692,fab:12345693,debugLow:12345678,hostNav:12345679,hostTopbar:12345689,hoverPreview:12345690,modal:12345699,sheetBackdrop:12345789,sheet:12345790,layer:999999991,dialogHoverPreview:999999992,viewer:999999993,loading:999999994,debug:999999999,tooltip:1e9});function Oo(){return`
<style>
    :root {
        /* 字体 */
        --jhs-font: system-ui, -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;

        /* 中性色 */
        --jhs-bg: #f4f6f9;
        --jhs-surface: #ffffff;
        --jhs-surface-2: #f2f4f8;
        --jhs-surface-hover: #e9edf4;
        --jhs-focus: #3b6ea5;
        --jhs-border: #e3e7ee;
        --jhs-border-strong: #8a94a6;
        --jhs-text: #1f2733;
        --jhs-text-muted: #5b6b7c;
        --jhs-text-faint: #637183;
        --jhs-input-bg: #f2f4f8;
        --jhs-placeholder: #637183;
        --jhs-disabled-bg: #f2f4f8;
        --jhs-disabled-text: #637183;

        /* 间距 / 排版 / 控件尺寸 */
        --jhs-space-1: 4px;
        --jhs-space-2: 8px;
        --jhs-space-3: 12px;
        --jhs-space-4: 16px;
        --jhs-space-5: 24px;
        --jhs-space-6: 32px;
        --jhs-font-size-xs: 12px;
        --jhs-font-size-sm: 13px;
        --jhs-font-size-md: 14px;
        --jhs-font-size-lg: 16px;
        --jhs-font-size-xl: 18px;
        --jhs-control-height-sm: 32px;
        --jhs-control-height: 36px;
        --jhs-touch-target: 44px;
        --jhs-motion-fast: 120ms;
        --jhs-motion-base: 180ms;
        --jhs-ease: cubic-bezier(.2, 0, 0, 1);

        /* 层级:业务模块只消费语义令牌,不自行发明数值 */
        --jhs-z-content: ${J.content};
        --jhs-z-elevated: ${J.elevated};
        --jhs-z-local-popover: ${J.localPopover};
        --jhs-z-popover: ${J.popover};
        --jhs-z-dropdown: ${J.dropdown};
        --jhs-z-fab-backdrop: ${J.fabBackdrop};
        --jhs-z-fab-menu: ${J.fabMenu};
        --jhs-z-fab: ${J.fab};
        --jhs-z-debug-low: ${J.debugLow};
        --jhs-z-host-nav: ${J.hostNav};
        --jhs-z-host-topbar: ${J.hostTopbar};
        --jhs-z-hover-preview: ${J.hoverPreview};
        --jhs-z-modal: ${J.modal};
        --jhs-z-sheet-backdrop: ${J.sheetBackdrop};
        --jhs-z-sheet: ${J.sheet};
        --jhs-z-layer: ${J.layer};
        --jhs-z-dialog-hover-preview: ${J.dialogHoverPreview};
        --jhs-z-viewer: ${J.viewer};
        --jhs-z-loading: ${J.loading};
        --jhs-z-debug: ${J.debug};
        --jhs-z-tooltip: ${J.tooltip};

        /* 主操作色 (中性蓝灰; 状态色仅表达数据语义) */
        --jhs-accent: #3b6ea5;
        --jhs-accent-hover: #2f5b8a;
        --jhs-accent-tint: #e7eef6;
        --jhs-accent-text-on: #ffffff;

        /* 通用反馈语义(不得代替影片状态色) */
        --jhs-danger: #c02b2b;
        --jhs-danger-tint: #fde8e8;
        --jhs-danger-text-on: #ffffff;
        --jhs-warning: #826207;
        --jhs-warning-tint: #faf3df;
        --jhs-warning-text-on: #ffffff;

        /* 状态语义色 (品牌, 保持可辨识): red=屏蔽 cyan=收藏 green=下载 amber=观看
         * -on   实色背景上的文字 (filter 用白字, 其余深字)
         * -text tint 背景上的文字 / 彩色文字落 surface 的正文色 */
        --jhs-status-filter: #de3333;
        --jhs-status-filter-tint: #fde8e8;
        --jhs-status-filter-hover: #c02b2b;
        --jhs-status-filter-text: #c02b2b;
        --jhs-status-filter-on: #ffffff;
        --jhs-status-fav: #25b1dc;
        --jhs-status-fav-tint: #e5f6fc;
        --jhs-status-fav-hover: #1e93b8;
        --jhs-status-fav-text: #15728b;
        --jhs-status-fav-on: #14181d;
        --jhs-status-down: #7bc73b;
        --jhs-status-down-tint: #eff8e6;
        --jhs-status-down-hover: #66ac2d;
        --jhs-status-down-text: #387213;
        --jhs-status-down-on: #14181d;
        --jhs-status-watch: #d7a80c;
        --jhs-status-watch-tint: #faf3df;
        --jhs-status-watch-hover: #b58b09;
        --jhs-status-watch-text: #826207;
        --jhs-status-watch-on: #14181d;

        /* 品牌色 (第三方站点来源标识, 保持可辨识) */
        --jhs-brand-javdb: #c23a85;
        --jhs-brand-javbus: #967004;

        /* 代码查看器 (终端语义, 亮暗一致, 不随主题) */
        --jhs-code-bg: #1e1e1e;
        --jhs-code-text: #ffffff;
        --jhs-code-line: #aaaaaa;

        /* 圆角: 唯一一套 */
        --jhs-radius-xs: 6px;
        --jhs-radius-sm: 8px;
        --jhs-radius-md: 12px;
        --jhs-radius-lg: 14px;
        --jhs-radius-pill: 999px;

        /* 阴影: 与背景同色相 */
        --jhs-shadow-xs: 0 1px 2px rgba(31, 39, 51, .06);
        --jhs-shadow-sm: 0 1px 3px rgba(31, 39, 51, .08), 0 1px 2px rgba(31, 39, 51, .04);
        --jhs-shadow-md: 0 4px 14px rgba(31, 39, 51, .10);
        --jhs-shadow-lg: 0 12px 32px rgba(31, 39, 51, .16);

        /* 图标 */
        --jhs-icon-color: #5b6b7c;
    }

    :root[data-jhs-theme="dark"] {
        --jhs-bg: #14181d;
        --jhs-surface: #1d232b;
        --jhs-surface-2: #262d37;
        --jhs-surface-hover: #2e3642;
        --jhs-focus: #7cb8e8;
        --jhs-border: #333c47;
        --jhs-border-strong: #64728a;
        --jhs-text: #e6ebf1;
        --jhs-text-muted: #9aa7b6;
        --jhs-text-faint: #9cacbd;
        --jhs-input-bg: #262d37;
        --jhs-placeholder: #9cacbd;
        --jhs-disabled-bg: #262d37;
        --jhs-disabled-text: #9cacbd;

        --jhs-accent: #7ca6d4;
        --jhs-accent-hover: #8db3de;
        --jhs-accent-tint: #25354a;
        --jhs-accent-text-on: #14181d;

        --jhs-danger: #e87171;
        --jhs-danger-tint: #3a2323;
        --jhs-danger-text-on: #14181d;
        --jhs-warning: #e0b32e;
        --jhs-warning-tint: #362f18;
        --jhs-warning-text-on: #14181d;

        --jhs-status-filter: #e05a5a;
        --jhs-status-filter-tint: #3a2323;
        --jhs-status-filter-hover: #f07171;
        --jhs-status-filter-text: #e87171;
        --jhs-status-filter-on: #14181d;
        --jhs-status-fav: #4dbbe0;
        --jhs-status-fav-tint: #1f3340;
        --jhs-status-fav-hover: #6fcbe8;
        --jhs-status-fav-text: #4dbbe0;
        --jhs-status-fav-on: #14181d;
        --jhs-status-down: #93d357;
        --jhs-status-down-tint: #25341a;
        --jhs-status-down-hover: #a8de73;
        --jhs-status-down-text: #93d357;
        --jhs-status-down-on: #14181d;
        --jhs-status-watch: #e0b32e;
        --jhs-status-watch-tint: #362f18;
        --jhs-status-watch-hover: #ecc347;
        --jhs-status-watch-text: #e0b32e;
        --jhs-status-watch-on: #14181d;

        /* 品牌色 */
        --jhs-brand-javdb: #e37ab6;
        --jhs-brand-javbus: #f0c040;

        /* 代码查看器 (终端语义, 亮暗一致, 不随主题) */
        --jhs-code-bg: #1e1e1e;
        --jhs-code-text: #ffffff;
        --jhs-code-line: #aaaaaa;

        --jhs-shadow-xs: 0 1px 2px rgba(0, 0, 0, .40);
        --jhs-shadow-sm: 0 1px 3px rgba(0, 0, 0, .50);
        --jhs-shadow-md: 0 4px 14px rgba(0, 0, 0, .55);
        --jhs-shadow-lg: 0 12px 36px rgba(0, 0, 0, .60);

        --jhs-icon-color: #9aa7b6;
    }

    /* JHS 表面输入框基座 + placeholder + 禁用态 (亮暗一致, 作用域限定 JHS 表面) */
    .jhs-ui input[type="text"],
    .jhs-ui input[type="number"],
    .jhs-ui textarea,
    .jhs-ui select,
    .jhs-dialog .layui-layer-content input[type="text"],
    .jhs-dialog .layui-layer-content input[type="number"],
    .jhs-dialog .layui-layer-content textarea,
    .jhs-dialog .layui-layer-content select {
        background-color: var(--jhs-input-bg);
        color: var(--jhs-text);
        border: 1px solid var(--jhs-border);
    }
    .jhs-ui ::placeholder,
    .jhs-dialog .layui-layer-content ::placeholder {
        color: var(--jhs-placeholder);
        opacity: 1;
    }
    .jhs-ui button:disabled,
    .jhs-ui input:disabled,
    .jhs-ui select:disabled,
    .jhs-dialog .layui-layer-content button:disabled,
    .jhs-dialog .layui-layer-content input:disabled,
    .jhs-dialog .layui-layer-content select:disabled {
        background-color: var(--jhs-disabled-bg);
        color: var(--jhs-disabled-text);
        border-color: var(--jhs-border);
        cursor: not-allowed;
        opacity: 1;
    }

    /* JHS 表面基础字体 */
    .jhs-ui, .jhs-dialog .layui-layer-content, .tabulator, .toastify, .jhs-fab, .menu-box {
        font-family: var(--jhs-font);
    }

    /* 焦点环 */
    :where(.jhs-ui) :focus-visible,
    :where(.jhs-dialog .layui-layer-content) :focus-visible,
    :where(.tabulator) :focus-visible {
        outline: 2px solid var(--jhs-accent);
        outline-offset: 2px;
    }

    /* 滚动条 (JHS 表面) */
    .jhs-scrollbar::-webkit-scrollbar,
    .content-panel::-webkit-scrollbar,
    .tabulator-tableholder::-webkit-scrollbar,
    .has-navbar-fixed-top::-webkit-scrollbar,
    .jhs-dialog .layui-layer-content::-webkit-scrollbar {
        width: 6px;
        height: 6px;
    }
    .jhs-scrollbar::-webkit-scrollbar-track,
    .content-panel::-webkit-scrollbar-track,
    .tabulator-tableholder::-webkit-scrollbar-track,
    .has-navbar-fixed-top::-webkit-scrollbar-track,
    .jhs-dialog .layui-layer-content::-webkit-scrollbar-track {
        background: var(--jhs-surface-2);
        border-radius: 10px;
    }
    .jhs-scrollbar::-webkit-scrollbar-thumb,
    .content-panel::-webkit-scrollbar-thumb,
    .tabulator-tableholder::-webkit-scrollbar-thumb,
    .has-navbar-fixed-top::-webkit-scrollbar-thumb,
    .jhs-dialog .layui-layer-content::-webkit-scrollbar-thumb {
        background: var(--jhs-border-strong);
        border-radius: 10px;
    }
    .jhs-scrollbar::-webkit-scrollbar-thumb:hover,
    .content-panel::-webkit-scrollbar-thumb:hover,
    .tabulator-tableholder::-webkit-scrollbar-thumb:hover,
    .has-navbar-fixed-top::-webkit-scrollbar-thumb:hover,
    .jhs-dialog .layui-layer-content::-webkit-scrollbar-thumb:hover {
        background: var(--jhs-text-faint);
    }

    @media (prefers-reduced-motion: reduce) {
        .jhs-ui, .jhs-dialog .layui-layer-content, .tabulator, .toastify, .jhs-fab, .menu-box,
        .jhs-ui *, .jhs-dialog .layui-layer-content *, .tabulator *, .toastify *, .jhs-fab *, .menu-box * {
            transition: none !important;
            animation: none !important;
        }
    }

    /* 暗色下覆盖 layui-layer 弹层 chrome (外部 layui.css 为亮色主题) */
    :root[data-jhs-theme="dark"] .jhs-dialog.layui-layer {
        background-color: var(--jhs-surface);
        color: var(--jhs-text);
        box-shadow: var(--jhs-shadow-lg);
    }
    :root[data-jhs-theme="dark"] .layui-layer-title {
        background-color: var(--jhs-surface-2);
        color: var(--jhs-text);
        border-bottom: 1px solid var(--jhs-border);
    }
    :root[data-jhs-theme="dark"] .jhs-dialog .layui-layer-content {
        color: var(--jhs-text);
    }
    :root[data-jhs-theme="dark"] .jhs-dialog .layui-layer-btn a {
        background-color: var(--jhs-surface-2);
        border: 1px solid var(--jhs-border);
        color: var(--jhs-text);
    }
    :root[data-jhs-theme="dark"] .jhs-dialog .layui-layer-btn .jhs-dialog .layui-layer-btn0 {
        background-color: var(--jhs-accent);
        border-color: transparent;
        color: var(--jhs-accent-text-on);
    }
    .jhs-dialog .layui-layer-setwin .layui-layer-close {
        width: 36px!important;
        height: 36px!important;
        background: none!important;
        color: var(--jhs-text-muted)!important;
        font-size: 0!important;
        opacity: 1!important;
    }
    .jhs-dialog .layui-layer-setwin .layui-layer-close::before,
    .jhs-dialog .layui-layer-setwin .layui-layer-close::after {
        content: "";
        position: absolute;
        top: 17px;
        left: 9px;
        width: 18px;
        height: 2px;
        border-radius: 1px;
        background: currentColor;
    }
    .jhs-dialog .layui-layer-setwin .layui-layer-close::before { transform: rotate(45deg); }
    .jhs-dialog .layui-layer-setwin .layui-layer-close::after { transform: rotate(-45deg); }
    .jhs-dialog .layui-layer-setwin .layui-layer-close:hover,
    .jhs-dialog .layui-layer-setwin .layui-layer-close:focus-visible { color: var(--jhs-text)!important; }
    :root[data-jhs-theme="dark"] .layui-input,
    :root[data-jhs-theme="dark"] .jhs-dialog .layui-layer-content input[type="text"],
    :root[data-jhs-theme="dark"] .jhs-dialog .layui-layer-content input[type="number"],
    :root[data-jhs-theme="dark"] .jhs-dialog .layui-layer-content textarea,
    :root[data-jhs-theme="dark"] .jhs-dialog .layui-layer-content select {
        background-color: var(--jhs-input-bg);
        color: var(--jhs-text);
        border: 1px solid var(--jhs-border);
    }

    /* 暗色下覆盖 Tabulator 表格 chrome (semanticui 主题为亮色) */
    :root[data-jhs-theme="dark"] .tabulator {
        background-color: var(--jhs-surface);
        color: var(--jhs-text);
        border: 1px solid var(--jhs-border);
    }
    :root[data-jhs-theme="dark"] .tabulator .tabulator-header {
        background-color: var(--jhs-surface-2);
        color: var(--jhs-text);
        border-bottom: 1px solid var(--jhs-border);
    }
    :root[data-jhs-theme="dark"] .tabulator .tabulator-header .tabulator-col {
        background-color: var(--jhs-surface-2);
        color: var(--jhs-text);
        border-right: 1px solid var(--jhs-border);
    }
    :root[data-jhs-theme="dark"] .tabulator .tabulator-row {
        background-color: var(--jhs-surface);
        color: var(--jhs-text);
        border-bottom: 1px solid var(--jhs-border);
    }
    :root[data-jhs-theme="dark"] .tabulator .tabulator-row.tabulator-row-even {
        background-color: var(--jhs-surface-2);
    }
    :root[data-jhs-theme="dark"] .tabulator .tabulator-cell {
        color: var(--jhs-text);
        border-right: 1px solid var(--jhs-border);
    }
    :root[data-jhs-theme="dark"] .tabulator .tabulator-footer {
        background-color: var(--jhs-surface-2);
        color: var(--jhs-text);
        border-top: 1px solid var(--jhs-border);
    }
    :root[data-jhs-theme="dark"] .tabulator .tabulator-responsive-collapse {
        background-color: var(--jhs-surface-2);
        color: var(--jhs-text);
        border-top: 1px solid var(--jhs-border);
    }

    /* 暗色下图标翻转为单色, 避免深色 path 在暗表面上不可见 */
    :root[data-jhs-theme="dark"] .jhs-icon path {
        fill: var(--jhs-icon-color);
    }
</style>
`}d(Oo,"buildThemeCss");function Vt(o="light"){let e="light";o==="dark"?e="dark":o==="auto"&&(e=window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"),document.documentElement.setAttribute("data-jhs-theme",e)}d(Vt,"applyThemeMode");function zo(o){let e=window.matchMedia("(prefers-color-scheme: dark)");o.listen(e,"change",()=>{let t=globalThis.settingsService?.snapshot?.().themeMode??storageManager.getSettingSync("themeMode","light");t==="auto"&&Vt(t)})}d(zo,"initializeThemeRuntime");function Uo(){return`
<style id="jhs-ui-primitives">
    :where(.jhs-ui, .jhs-dialog .layui-layer-content, .menu-box, .jhs-fab-menu) {
        color: var(--jhs-text);
        font-family: var(--jhs-font);
        font-size: var(--jhs-font-size-md);
        line-height: 1.5;
    }

    :is(.jhs-btn, .jhs-filter-btn, .site-btn, .magnet-hub-btn, .pagination-btn) {
        box-sizing: border-box;
        display: inline-flex;
        min-height: var(--jhs-control-height);
        align-items: center;
        justify-content: center;
        gap: var(--jhs-space-2);
        padding: 0 var(--jhs-space-3);
        margin: 0;
        border: 1px solid var(--jhs-border);
        border-radius: var(--jhs-radius-sm);
        background: var(--jhs-surface);
        color: var(--jhs-text);
        box-shadow: none;
        font: inherit;
        font-size: var(--jhs-font-size-sm);
        font-weight: 600;
        line-height: 1;
        text-align: center;
        text-decoration: none;
        text-shadow: none;
        white-space: nowrap;
        cursor: pointer;
        transition: background-color var(--jhs-motion-fast) var(--jhs-ease),
                    border-color var(--jhs-motion-fast) var(--jhs-ease),
                    color var(--jhs-motion-fast) var(--jhs-ease),
                    transform var(--jhs-motion-fast) var(--jhs-ease);
    }

    :is(.jhs-btn, .jhs-filter-btn, .site-btn, .magnet-hub-btn, .pagination-btn):hover {
        border-color: var(--jhs-accent);
        background: var(--jhs-surface-2);
        color: var(--jhs-accent);
        box-shadow: none;
        filter: none;
        transform: none;
    }

    :is(.jhs-btn, .jhs-filter-btn, .site-btn, .magnet-hub-btn, .pagination-btn):active {
        transform: translateY(1px);
    }

    :is(.jhs-btn, .jhs-filter-btn, .site-btn, .magnet-hub-btn, .pagination-btn):disabled,
    :is(.jhs-btn, .jhs-filter-btn, .site-btn, .magnet-hub-btn, .pagination-btn)[aria-disabled="true"] {
        border-color: var(--jhs-border);
        background: var(--jhs-disabled-bg);
        color: var(--jhs-disabled-text);
        cursor: not-allowed;
        opacity: 1;
        transform: none;
    }

    :is(.jhs-btn--primary, .jhs-btn--accent) {
        border-color: var(--jhs-accent);
        background: var(--jhs-accent);
        color: var(--jhs-accent-text-on);
    }
    :is(.jhs-btn--primary, .jhs-btn--accent):hover {
        border-color: var(--jhs-accent-hover);
        background: var(--jhs-accent-hover);
        color: var(--jhs-accent-text-on);
    }

    :is(.jhs-btn--secondary, .jhs-btn--muted, .site-btn) {
        border-color: var(--jhs-border);
        background: var(--jhs-surface);
        color: var(--jhs-text);
    }
    .jhs-btn--danger {
        border-color: var(--jhs-danger);
        background: var(--jhs-danger);
        color: var(--jhs-danger-text-on);
    }
    .jhs-btn--danger:hover {
        border-color: var(--jhs-danger);
        background: var(--jhs-danger);
        color: var(--jhs-danger-text-on);
        filter: brightness(.92);
    }
    .jhs-btn--ghost {
        border-color: transparent;
        background: transparent;
        color: var(--jhs-text-muted);
    }
    .jhs-btn--dark {
        border-color: var(--jhs-border-strong);
        background: var(--jhs-surface-2);
        color: var(--jhs-text);
    }
    .jhs-btn--dark:hover {
        background: var(--jhs-surface-hover);
    }
    /* 图片查看器的离屏临时容器(showImageViewer 字符串入口) */
    .temporary-container {
        position: absolute;
        left: -9999px;
        top: 0;
        width: 1px;
        height: 1px;
        overflow: hidden;
        opacity: 0;
        pointer-events: none;
    }
    /* 识图结果等面板内通用块容器 */
    .jhs-layout-c8be1ccb { display: block; width: 100%; min-width: 0; }
    .jhs-btn--ghost:hover {
        border-color: transparent;
        background: var(--jhs-surface-2);
        color: var(--jhs-text);
    }

    .jhs-video-player {
        display: block;
        width: 100%;
        height: 100%;
        background: #000;
    }
    .jhs-video-toolbar {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: var(--jhs-space-2);
        padding-block: var(--jhs-space-2);
    }
    .jhs-video-toolbar > .jhs-toolbar {
        margin-left: auto;
    }
    body:has(.fancybox-content #video-bottom-toolbar) #jhs-fab { visibility:hidden; }
    .jhs-video-quality-list {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: var(--jhs-space-2);
    }
    .jhs-video-quality-btn {
        min-width: 80px;
    }
    .jhs-video-quality-btn.active,
    .jhs-video-quality-btn[aria-pressed="true"] {
        border-color: var(--jhs-accent);
        background: var(--jhs-accent);
        color: var(--jhs-accent-text-on);
    }
    .jhs-btn--soft {
        border-color: transparent;
        background: var(--jhs-accent-tint);
        color: var(--jhs-accent);
    }
    .jhs-btn--filter {
        border-color: transparent;
        background: var(--jhs-status-filter-tint);
        color: var(--jhs-status-filter-text);
    }
    .jhs-btn--fav {
        border-color: transparent;
        background: var(--jhs-status-fav-tint);
        color: var(--jhs-status-fav-text);
    }
    .jhs-btn--down {
        border-color: transparent;
        background: var(--jhs-status-down-tint);
        color: var(--jhs-status-down-text);
    }
    .jhs-btn--watch {
        border-color: transparent;
        background: var(--jhs-status-watch-tint);
        color: var(--jhs-status-watch-text);
    }
    :is(.jhs-btn--filter, .jhs-btn--fav, .jhs-btn--down, .jhs-btn--watch):hover {
        border-color: var(--jhs-border-strong);
        background: var(--jhs-surface-2);
        color: var(--jhs-text);
    }
    .jhs-btn--sm {
        min-height: var(--jhs-control-height-sm);
        padding-inline: var(--jhs-space-2);
        font-size: var(--jhs-font-size-xs);
    }
    .jhs-icon-btn, .card-btn {
        width: var(--jhs-control-height);
        min-width: var(--jhs-control-height);
        height: var(--jhs-control-height);
        min-height: var(--jhs-control-height);
        padding: 0;
        border: 1px solid transparent;
        border-radius: var(--jhs-radius-sm);
        background: transparent;
        color: var(--jhs-icon-color);
        box-shadow: none;
    }
    :where(.jhs-icon-btn, .card-btn):hover {
        border-color: var(--jhs-border);
        background: var(--jhs-surface-2);
        color: var(--jhs-text);
        box-shadow: none;
        transform: none;
    }
    :where(.jhs-icon-btn, .card-btn) svg {
        width: 18px;
        height: 18px;
    }

    :where(.jhs-field, .jhs-select, .jhs-textarea,
        .jhs-ui input:not([type]), .jhs-ui input[type="text"], .jhs-ui input[type="number"], .jhs-ui input[type="url"], .jhs-ui input[type="password"],
        .jhs-ui select, .jhs-ui textarea,
        .jhs-dialog .layui-layer-content input:not([type]), .jhs-dialog .layui-layer-content input[type="text"], .jhs-dialog .layui-layer-content input[type="number"],
        .jhs-dialog .layui-layer-content input[type="url"], .jhs-dialog .layui-layer-content input[type="password"], .jhs-dialog .layui-layer-content select, .jhs-dialog .layui-layer-content textarea) {
        box-sizing: border-box;
        min-height: var(--jhs-control-height);
        padding: var(--jhs-space-2) var(--jhs-space-3);
        border: 1px solid var(--jhs-border);
        border-radius: var(--jhs-radius-sm);
        background: var(--jhs-input-bg);
        color: var(--jhs-text);
        font: inherit;
        font-size: var(--jhs-font-size-sm);
        line-height: 1.35;
        transition: background-color var(--jhs-motion-fast) var(--jhs-ease),
                    border-color var(--jhs-motion-fast) var(--jhs-ease),
                    box-shadow var(--jhs-motion-fast) var(--jhs-ease);
    }
    :where(.jhs-field, .jhs-select, .jhs-textarea,
        .jhs-ui input, .jhs-ui select, .jhs-ui textarea,
        .jhs-dialog .layui-layer-content input, .jhs-dialog .layui-layer-content select, .jhs-dialog .layui-layer-content textarea):hover:not(:disabled) {
        border-color: var(--jhs-accent);
    }
    :where(.jhs-field, .jhs-select, .jhs-textarea,
        .jhs-ui input, .jhs-ui select, .jhs-ui textarea,
        .jhs-dialog .layui-layer-content input, .jhs-dialog .layui-layer-content select, .jhs-dialog .layui-layer-content textarea):focus-visible {
        border-color: var(--jhs-accent);
        outline: 2px solid var(--jhs-accent-tint);
        outline-offset: 1px;
        box-shadow: 0 0 0 1px var(--jhs-accent);
    }
    :where(.jhs-field, .jhs-select, .jhs-textarea,
        .jhs-ui input[type="text"], .jhs-ui input[type="number"], .jhs-ui input[type="url"],
        .jhs-ui select, .jhs-ui textarea,
        .jhs-dialog .layui-layer-content input[type="text"], .jhs-dialog .layui-layer-content input[type="number"],
        .jhs-dialog .layui-layer-content input[type="url"], .jhs-dialog .layui-layer-content select, .jhs-dialog .layui-layer-content textarea):hover:not(:focus) {
        border-color: var(--jhs-border-strong);
    }
    :where(.jhs-textarea, .jhs-ui textarea, .jhs-dialog .layui-layer-content textarea) {
        min-height: 76px;
        resize: vertical;
    }

    .jhs-switch, .mini-switch {
        appearance: none;
        box-sizing: border-box;
        width: 40px;
        min-width: 40px;
        height: 22px;
        min-height: 22px;
        padding: 2px;
        border: 1px solid var(--jhs-border);
        border-radius: var(--jhs-radius-pill);
        background: var(--jhs-surface-2);
        cursor: pointer;
        transition: background-color var(--jhs-motion-fast) var(--jhs-ease), border-color var(--jhs-motion-fast) var(--jhs-ease);
    }
    :where(.jhs-switch, .mini-switch)::before {
        display: block;
        width: 16px;
        height: 16px;
        border-radius: 50%;
        background: var(--jhs-surface);
        box-shadow: var(--jhs-shadow-xs);
        content: "";
        transition: transform var(--jhs-motion-fast) var(--jhs-ease);
    }
    :where(.jhs-switch, .mini-switch):checked {
        border-color: var(--jhs-accent);
        background: var(--jhs-accent);
    }
    :where(.jhs-switch, .mini-switch):checked::before {
        transform: translateX(18px);
    }

    :where(.jhs-range, .jhs-ui input[type="range"], .jhs-dialog .layui-layer-content input[type="range"]) {
        appearance: none;
        width: 100%;
        height: 22px;
        margin: 0;
        padding: 0;
        border: 0;
        background: transparent;
        cursor: pointer;
    }
    :where(.jhs-range, .jhs-ui input[type="range"], .jhs-dialog .layui-layer-content input[type="range"])::-webkit-slider-runnable-track {
        height: 4px;
        border-radius: var(--jhs-radius-pill);
        background: var(--jhs-border);
    }
    :where(.jhs-range, .jhs-ui input[type="range"], .jhs-dialog .layui-layer-content input[type="range"])::-webkit-slider-thumb {
        appearance: none;
        width: 18px;
        height: 18px;
        margin-top: -7px;
        border: 2px solid var(--jhs-surface);
        border-radius: 50%;
        background: var(--jhs-accent);
        box-shadow: 0 0 0 1px var(--jhs-accent), var(--jhs-shadow-xs);
    }
    :where(.jhs-range, .jhs-ui input[type="range"], .jhs-dialog .layui-layer-content input[type="range"]):disabled {
        cursor: not-allowed;
        opacity: .55;
    }

    .jhs-toolbar {
        display: flex;
        align-items: center;
        gap: var(--jhs-space-2);
        flex-wrap: wrap;
        min-width: 0;
    }
    .jhs-toolbar--between {
        justify-content: space-between;
    }
    .jhs-toolbar__group {
        display: flex;
        align-items: center;
        gap: var(--jhs-space-2);
        flex-wrap: wrap;
        min-width: 0;
    }
    .jhs-section {
        display: grid;
        gap: var(--jhs-space-3);
        margin-block: 0 var(--jhs-space-4);
    }
    .jhs-section__heading {
        margin: 0;
        color: var(--jhs-text);
        font-size: var(--jhs-font-size-lg);
        font-weight: 700;
        line-height: 1.3;
    }
    .jhs-section__description, .jhs-helper-text {
        margin: 0;
        color: var(--jhs-text-muted);
        font-size: var(--jhs-font-size-xs);
        line-height: 1.5;
    }
    .jhs-card, .jhs-setting-group {
        box-sizing: border-box;
        border: 1px solid var(--jhs-border);
        border-radius: var(--jhs-radius-md);
        background: var(--jhs-surface);
        box-shadow: none;
    }
    .jhs-card {
        padding: var(--jhs-space-4);
    }
    .jhs-setting-group {
        overflow: hidden;
    }
    .jhs-setting-row {
        box-sizing: border-box;
        display: grid;
        grid-template-columns: minmax(180px, 1fr) minmax(180px, 280px);
        gap: var(--jhs-space-4);
        align-items: center;
        min-height: 52px;
        margin: 0;
        padding: var(--jhs-space-3) var(--jhs-space-4);
        border-bottom: 1px solid var(--jhs-border);
    }
    :where(.jhs-setting-group, .content-panel) > .jhs-setting-row:last-child {
        border-bottom: 0;
    }
    .jhs-setting-row__label, .setting-label {
        min-width: 0;
        margin: 0;
        color: var(--jhs-text);
        font-size: var(--jhs-font-size-sm);
        font-weight: 600;
        line-height: 1.4;
    }
    .jhs-setting-row__description {
        display: block;
        margin-top: var(--jhs-space-1);
        color: var(--jhs-text-muted);
        font-size: var(--jhs-font-size-xs);
        font-weight: 400;
    }
    .jhs-setting-row__control, .form-content {
        display: flex;
        min-width: 0;
        max-width: none;
        align-items: center;
        justify-content: flex-end;
        gap: var(--jhs-space-2);
    }
    :where(.jhs-setting-row__control, .form-content) > :where(input, select, textarea) {
        width: min(100%, 280px);
        margin: 0;
    }

    .jhs-segmented, .magnet-tabs__options {
        display: inline-flex;
        align-items: center;
        gap: var(--jhs-space-1);
        padding: var(--jhs-space-1);
        border: 1px solid var(--jhs-border);
        border-radius: var(--jhs-radius-md);
        background: var(--jhs-surface-2);
    }
    .jhs-segmented__item, .magnet-tab {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-height: var(--jhs-control-height-sm);
        padding: 0 var(--jhs-space-3);
        border: 0;
        border-radius: var(--jhs-radius-xs);
        background: transparent;
        color: var(--jhs-text-muted);
        font-size: var(--jhs-font-size-sm);
        font-weight: 600;
        line-height: 1;
        cursor: pointer;
    }
    :where(.jhs-segmented__item, .magnet-tab):hover {
        background: var(--jhs-surface);
        color: var(--jhs-text);
    }
    :where(.jhs-segmented__item, .magnet-tab).active,
    :where(.jhs-segmented__item, .magnet-tab)[aria-selected="true"] {
        background: var(--jhs-surface);
        color: var(--jhs-text);
        box-shadow: var(--jhs-shadow-xs);
    }

    .jhs-popover {
        position: absolute;
        top: calc(100% + var(--jhs-space-2));
        right: 0;
        z-index: var(--jhs-z-local-popover);
        display: none;
        min-width: 152px;
        padding: var(--jhs-space-2);
        border: 1px solid var(--jhs-border);
        border-radius: var(--jhs-radius-md);
        background: var(--jhs-surface);
        box-shadow: var(--jhs-shadow-md);
    }
    .jhs-popover.is-open { display: grid; gap: var(--jhs-space-1); }
    .jhs-popover [role="menuitem"], .jhs-popover [role="menuitemradio"] { width: 100%; justify-content: flex-start; }

    .jhs-select-control { position:relative; display:inline-flex; min-width:140px; max-width:100%; }
    .jhs-select-source-native { display:none!important; }
    .jhs-select-trigger { width:100%; justify-content:space-between; }
    .jhs-select-trigger::after { content:"▾"; margin-left:var(--jhs-space-2); color:var(--jhs-text-muted); font-size:11px; }
    .jhs-select-control.is-open .jhs-select-trigger::after { content:"▴"; }
    .jhs-select-menu { left:0; right:auto; min-width:100%; max-height:320px; overflow-y:auto; }
    .jhs-select-group { display:grid; gap:var(--jhs-space-1); }
    .jhs-select-group__label { padding:var(--jhs-space-1) var(--jhs-space-2); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-xs); font-weight:600; }
    .jhs-select-option[aria-checked="true"] { background:var(--jhs-accent-tint); color:var(--jhs-accent); }

    .jhs-task-emphasis { color:var(--jhs-status-filter-text); }
    .jhs-code-viewer { height:100%; overflow:auto; padding:15px 5px; background:var(--jhs-code-bg); color:var(--jhs-code-text); font-family:Consolas,Monaco,monospace; white-space:pre-wrap; }
    .jhs-code-line-number { color:var(--jhs-code-line); }
    .jhs-count-table__cell { padding:3px; border:1px solid var(--jhs-border); }
    .jhs-count-table__head { padding:3px; border:1px solid var(--jhs-border); font-weight:700; }
    .jhs-play-overlay { position:absolute; inset:50% auto auto 50%; transform:translate(-50%,-50%); color:#fff; font-size:40px; text-shadow:0 0 10px rgba(0,0,0,.5); }
    .jhs-image-preview { max-width:100%; max-height:300px; border-radius:var(--jhs-radius-xs); box-shadow:var(--jhs-shadow-xs); }

    .jhs-badge, .jhs-chip, .card-tag, .card-new-count-tag, .magnet-score {
        box-sizing: border-box;
        display: inline-flex;
        min-height: 24px;
        align-items: center;
        justify-content: center;
        gap: var(--jhs-space-1);
        padding: 2px var(--jhs-space-2);
        border: 1px solid transparent;
        border-radius: var(--jhs-radius-pill);
        background: var(--jhs-surface-2);
        color: var(--jhs-text-muted);
        font-size: var(--jhs-font-size-xs);
        font-weight: 600;
        line-height: 1.2;
        white-space: nowrap;
    }
    .jhs-badge--accent, .card-new-count-tag {
        background: var(--jhs-accent-tint);
        color: var(--jhs-accent);
    }
    .jhs-badge--danger, .card-tag {
        background: var(--jhs-status-filter-tint);
        color: var(--jhs-status-filter-text);
    }
    .jhs-badge--success {
        background: var(--jhs-status-down-tint);
        color: var(--jhs-status-down-text);
    }
    .jhs-badge--neutral { border-color: var(--jhs-border); background: var(--jhs-surface-2); color: var(--jhs-text-muted); }
    .jhs-badge--filter { background: var(--jhs-status-filter-tint); color: var(--jhs-status-filter-text); }
    .jhs-badge--fav { background: var(--jhs-status-fav-tint); color: var(--jhs-status-fav-text); }
    .jhs-badge--down { background: var(--jhs-status-down-tint); color: var(--jhs-status-down-text); }
    .jhs-badge--watch { background: var(--jhs-status-watch-tint); color: var(--jhs-status-watch-text); }

    .jhs-pagination, #actress-pagination, #nv-pagination-bar {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: var(--jhs-space-1);
        flex-wrap: wrap;
        padding-top: var(--jhs-space-3);
        border-top: 1px solid var(--jhs-border);
    }
    :where(.jhs-pagination, #actress-pagination, #nv-pagination-bar) .pagination-btn {
        min-width: var(--jhs-control-height-sm);
        min-height: var(--jhs-control-height-sm);
        padding-inline: var(--jhs-space-2);
    }
    :where(.jhs-pagination, #actress-pagination, #nv-pagination-bar) .pagination-btn.active,
    :where(.jhs-pagination, #actress-pagination, #nv-pagination-bar) .pagination-btn[aria-current="page"] {
        border-color: var(--jhs-accent);
        background: var(--jhs-accent);
        color: var(--jhs-accent-text-on);
    }

    .jhs-state, .magnet-loading, .magnet-error {
        box-sizing: border-box;
        display: grid;
        min-height: 120px;
        place-items: center;
        gap: var(--jhs-space-2);
        padding: var(--jhs-space-5);
        border: 1px dashed var(--jhs-border-strong);
        border-radius: var(--jhs-radius-md);
        background: var(--jhs-surface-2);
        color: var(--jhs-text-muted);
        text-align: center;
    }
    .jhs-state--error, .magnet-error {
        border-color: var(--jhs-status-filter-text);
        background: var(--jhs-status-filter-tint);
        color: var(--jhs-status-filter-text);
    }
    .jhs-state__content { display:grid; gap:var(--jhs-space-1); justify-items:center; }
    .jhs-state__title { margin:0; color:inherit; font-size:var(--jhs-font-size-md); font-weight:700; }
    .jhs-state__description { margin:0; color:var(--jhs-text-muted); font-size:var(--jhs-font-size-sm); }
    .jhs-panel-state { padding:var(--jhs-space-4) 0; color:var(--jhs-text-muted); text-align:center; }
    .jhs-task-status { padding:var(--jhs-space-2) var(--jhs-space-3); border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-sm); background:var(--jhs-surface-2); }
    .jhs-task-status__name { color:var(--jhs-text); font-weight:700; }
    .jhs-task-status__meta { display:block; margin-top:var(--jhs-space-1); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-xs); }
    .jhs-is-hidden { display: none !important; }
    .jhs-dialog-title { padding: 0 var(--jhs-space-2); }
    .jhs-pagination__summary { margin-left: var(--jhs-space-3); color: var(--jhs-text-muted); font-size: var(--jhs-font-size-sm); }
    .jhs-skeleton {
        overflow: hidden;
        border-radius: var(--jhs-radius-xs);
        background: var(--jhs-surface-2);
    }
    @media (prefers-reduced-motion: no-preference) {
        .jhs-skeleton {
            background: linear-gradient(90deg, var(--jhs-surface-2) 25%, var(--jhs-border) 50%, var(--jhs-surface-2) 75%);
            background-size: 200% 100%;
            animation: jhs-skeleton-shimmer 1.4s ease-in-out infinite;
        }
        @keyframes jhs-skeleton-shimmer {
            to { background-position-x: -200%; }
        }
    }

    .layui-layer {
        display: flex;
        flex-direction: column;
        overflow: hidden;
        border: 1px solid var(--jhs-border);
        border-radius: var(--jhs-radius-lg) !important;
        background: var(--jhs-surface);
        color: var(--jhs-text);
        box-shadow: var(--jhs-shadow-lg) !important;
    }
    /* 内容区占满标题/按钮栏以下的剩余空间,配合表格 height:100% 让尾行与分页条始终可达;
       auto 高度的 layer(消息/确认框)中 flex 退化为自然高度,不受影响 */
    .jhs-dialog .layui-layer-content {
        flex: 1 1 auto;
        min-height: 0;
        box-sizing: border-box;
    }
    /* 表格类弹窗(黑名单/历史/备份)的通用全高布局,配合 Tabulator height:100% 让尾行与分页条始终可达 */
    .jhs-table-dialog {
        display: flex;
        flex-direction: column;
        height: 100%;
        min-height: 0;
        padding: var(--jhs-space-3) var(--jhs-space-4);
    }
    .jhs-table-dialog .jhs-table-dialog__content,
    .jhs-table-dialog #table-container {
        flex: 1;
        min-height: 0;
    }
    .layui-layer-title {
        min-height: 48px;
        padding: 0 52px 0 var(--jhs-space-4);
        border-bottom: 1px solid var(--jhs-border);
        background: var(--jhs-surface);
        color: var(--jhs-text);
        font-size: var(--jhs-font-size-lg);
        font-weight: 700;
        line-height: 48px;
    }
    .layui-layer-btn {
        display: flex;
        justify-content: flex-end;
        gap: var(--jhs-space-2);
        padding: var(--jhs-space-3) var(--jhs-space-4) !important;
        border-top: 1px solid var(--jhs-border);
        background: var(--jhs-surface);
    }
    .layui-layer-btn a {
        min-height: var(--jhs-control-height);
        margin: 0 !important;
        padding: 0 var(--jhs-space-3) !important;
        border: 1px solid var(--jhs-border-strong) !important;
        border-radius: var(--jhs-radius-sm) !important;
        background: var(--jhs-surface) !important;
        color: var(--jhs-text) !important;
        line-height: var(--jhs-control-height) !important;
    }
    .layui-layer-btn .layui-layer-btn0 {
        border-color: var(--jhs-accent) !important;
        background: var(--jhs-accent) !important;
        color: var(--jhs-accent-text-on) !important;
    }

    .tabulator {
        overflow: hidden;
        border: 1px solid var(--jhs-border) !important;
        border-radius: var(--jhs-radius-md);
        background: var(--jhs-surface) !important;
        color: var(--jhs-text) !important;
        font-family: var(--jhs-font);
        font-size: var(--jhs-font-size-sm);
    }
    .tabulator .tabulator-header,
    .tabulator .tabulator-header .tabulator-col {
        min-height: 40px;
        border-color: var(--jhs-border) !important;
        background: var(--jhs-surface-2) !important;
        color: var(--jhs-text) !important;
    }
    .tabulator .tabulator-row {
        min-height: 44px;
        border-color: var(--jhs-border) !important;
        background: var(--jhs-surface) !important;
        color: var(--jhs-text) !important;
    }
    .tabulator .tabulator-row:hover {
        background: var(--jhs-surface-2) !important;
    }
    .tabulator .tabulator-cell {
        display: inline-flex;
        min-height: 44px;
        align-items: center;
        border-right: 0 !important;
        color: var(--jhs-text) !important;
    }
    .tabulator .tabulator-row { border-bottom: 1px solid var(--jhs-border) !important; }
    .tabulator .tabulator-header .tabulator-col { border-right-color: color-mix(in srgb, var(--jhs-border) 55%, transparent) !important; }
    .tabulator .tabulator-footer {
        border-color: var(--jhs-border) !important;
        background: var(--jhs-surface-2) !important;
        color: var(--jhs-text) !important;
    }

    /* 新作品列表卡保留轻边框,结构布局由插件自身样式负责。 */
    .nv-card {
        border: 1px solid var(--jhs-border) !important;
        border-radius: var(--jhs-radius-md) !important;
        background: var(--jhs-surface) !important;
        box-shadow: none !important;
        transform: none !important;
        transition: border-color var(--jhs-motion-fast) var(--jhs-ease) !important;
    }
    .nv-card:hover {
        border-color: var(--jhs-accent) !important;
        box-shadow: none !important;
        transform: none !important;
    }
    /* 磁力搜索:分段控件、紧凑结果行和明确反馈状态。 */
    .magnet-container {
        width: 100%;
        margin: var(--jhs-space-3) auto !important;
        color: var(--jhs-text);
        font-family: var(--jhs-font) !important;
    }
    .magnet-tabs {
        display: flex;
        align-items: center;
        justify-content: space-between !important;
        gap: var(--jhs-space-3);
        margin-bottom: var(--jhs-space-3) !important;
        padding: 0 !important;
        border-bottom: 0 !important;
    }
    .magnet-tabs > div {
        display: inline-flex !important;
        gap: var(--jhs-space-1);
        padding: var(--jhs-space-1);
        border: 1px solid var(--jhs-border);
        border-radius: var(--jhs-radius-md);
        background: var(--jhs-surface-2);
    }
    .magnet-tab {
        min-height: var(--jhs-control-height-sm);
        margin: 0 !important;
        padding: 0 var(--jhs-space-3) !important;
        border: 0 !important;
        border-radius: var(--jhs-radius-xs) !important;
        background: transparent !important;
        color: var(--jhs-text-muted);
        line-height: var(--jhs-control-height-sm);
    }
    .magnet-tab.active {
        margin: 0 !important;
        border: 0 !important;
        background: var(--jhs-surface) !important;
        color: var(--jhs-text);
        box-shadow: var(--jhs-shadow-xs);
    }
    .magnet-results {
        min-height: 200px;
        overflow: hidden;
        border: 1px solid var(--jhs-border);
        border-radius: var(--jhs-radius-md);
        background: var(--jhs-surface);
    }
    .magnet-result {
        min-height: 68px;
        padding: var(--jhs-space-3) 190px var(--jhs-space-3) var(--jhs-space-4) !important;
        border-bottom: 1px solid var(--jhs-border) !important;
        background: var(--jhs-surface);
    }
    .magnet-result:last-child {
        border-bottom: 0 !important;
    }
    .magnet-result:hover {
        background: var(--jhs-surface-2) !important;
    }
    .magnet-title {
        margin-bottom: var(--jhs-space-1) !important;
        padding-right: 0 !important;
        font-weight: 600 !important;
    }
    .magnet-title a {
        display: inline-block;
        max-width: calc(100% - 52px);
        overflow: hidden;
        text-overflow: ellipsis;
        vertical-align: bottom;
        white-space: nowrap;
    }
    .magnet-score { margin-right: var(--jhs-space-1); font-size: var(--jhs-font-size-sm); cursor: help; }
    .magnet-info {
        justify-content: flex-start !important;
        gap: var(--jhs-space-4);
        margin: 0 !important;
        color: var(--jhs-text-muted) !important;
    }
    .magnet-copy {
        top: 50% !important;
        right: var(--jhs-space-3) !important;
        display: flex;
        flex: 0 0 auto;
        flex-wrap: nowrap;
        gap: var(--jhs-space-2);
        transform: translateY(-50%);
    }
    .magnet-hub-btn {
        flex: 0 0 auto;
        min-height: var(--jhs-control-height-sm) !important;
        margin: 0 !important;
        padding: 0 var(--jhs-space-2) !important;
        border-radius: var(--jhs-radius-sm) !important;
        font-size: var(--jhs-font-size-xs) !important;
        white-space: nowrap;
    }
    .magnet-hub-btn.copied {
        border-color: transparent !important;
        background: var(--jhs-status-down-tint) !important;
        color: var(--jhs-status-down-text) !important;
    }

    @media (max-width: 767px) {
        :is(.jhs-btn, .jhs-filter-btn, .site-btn, .magnet-hub-btn, .pagination-btn, .jhs-icon-btn, .card-btn) {
            min-height: var(--jhs-touch-target);
        }
        :where(.jhs-icon-btn, .card-btn) {
            width: var(--jhs-touch-target);
            min-width: var(--jhs-touch-target);
            height: var(--jhs-touch-target);
        }
        .jhs-setting-row {
            grid-template-columns: 1fr;
            gap: var(--jhs-space-2);
            padding: var(--jhs-space-3);
        }
        .jhs-setting-row__control, .form-content {
            justify-content: stretch;
        }
        :where(.jhs-setting-row__control, .form-content) > :where(input, select, textarea, button, a) {
            width: 100%;
            max-width: none;
        }
        .jhs-toolbar--between {
            align-items: stretch;
            flex-direction: column;
        }
        .magnet-tabs {
            align-items: stretch;
            flex-direction: column;
        }
        .magnet-tabs > div {
            width: 100%;
            min-width: 0;
            max-width: 100%;
            box-sizing: border-box;
            overflow-x: auto;
        }
        .magnet-result {
            padding-right: var(--jhs-space-4) !important;
        }
        .magnet-copy {
            position: static !important;
            display: grid;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            margin-top: var(--jhs-space-2);
            transform: none;
        }
        .magnet-copy .magnet-hub-btn { width: 100%; min-height: var(--jhs-touch-target) !important; }
        .jhs-segmented {
            max-width: 100%;
            overflow-x: auto;
        }
    }

        /* migrated template layout utilities */

        .jhs-layout-06cf30c0 { margin-top:15px;display:flex;justify-content:center;gap:10px; }



        .jhs-layout-186f17ef { padding:18px 18px !important; }


        .jhs-layout-1b3790ef { display:flex;margin-bottom:10px; }

        .jhs-layout-1e90930a { display:flex;gap:10px;flex-wrap:wrap; }



        .jhs-layout-2100e73d { margin-left:20px; }

        .jhs-layout-21a4fe43 { margin-left:0 }

        .jhs-layout-2335597e { padding:18px 18px !important;margin-left:50px }

        .jhs-layout-27f87d75 { display:block;margin-bottom:5px; }


        .jhs-layout-294497f1 { top:-15px }


        .jhs-layout-2e003268 { margin-bottom:5px }

        .jhs-layout-31a824a2 { display:flex;gap:5px }



        .jhs-layout-3536a853 { margin-top:30px;cursor:auto }




        .jhs-layout-3b6a3a65 { cursor:pointer }


        .jhs-layout-3fed2a7e { margin-left:5px; }

        .jhs-layout-3fefafab { overflow-y:auto;height:calc(100% - 40px); }




        .jhs-layout-481ed7e7 { padding:10px; }

        .jhs-layout-53809f1e { display:flex;gap:5px; }

        .jhs-layout-583c2485 { height:100%;padding-bottom:20px }

        .jhs-layout-598afa5a { margin-bottom:25px; }




        .jhs-layout-5f3e3549 { width:140px;text-align:center;padding:8px 0; }





        .jhs-layout-66253c00 { margin-top:8px;display:none }


        .jhs-layout-6b99de8b { display:none }


        .jhs-layout-6d489fc7 { margin:0 0.75rem }

        .jhs-layout-701bf0f9 { margin-bottom:0!important; }


        .jhs-layout-761d3add { margin-bottom:10px }

        .jhs-layout-769fed37 { padding:20px }

        .jhs-layout-78fa54ea { margin-left:10px }

        .jhs-layout-7cb3f981 { padding:10px 20px;height:100%;overflow:hidden; }

        .jhs-layout-7daea5fa { margin-bottom:5px; }

        .jhs-layout-81eaab28 { height:calc(100% - 50px);overflow-x:hidden; }

        .jhs-layout-8453d189 { display:flex;align-items:center;flex-grow:1;justify-content:flex-end; }



        .jhs-layout-8896c95d { margin-right:5px }

        .jhs-layout-8cddc29a { padding:20px; }

        .jhs-layout-8cf76fd7 { width:150px;height:auto; }




        .jhs-layout-9813a0dd { margin-left:5px }

        .jhs-layout-9db87399 { margin-top:50px;cursor:auto }

        .jhs-layout-9e3c853e { margin-bottom:15px; }

        .jhs-layout-9ea2322d { margin:20px auto }

        .jhs-layout-9fe45cd8 { width:120px; }

        .jhs-layout-a38a0e50 { max-height:100%;max-width:100%;object-fit:contain }




        .jhs-layout-b12542a5 { width:100% }

        .jhs-layout-b5c4e4f7 { overflow:hidden;height:110px;text-align:center; }

        .jhs-layout-ba4750c8 { margin:30px 0 }

        .jhs-layout-bd59a2e1 { text-align:center;margin-bottom:15px; }

        .jhs-layout-c0d4a511 { margin-top:5px; }

        .jhs-layout-c4eb15bf { width:100%;padding:12px;
 cursor:pointer;
  }


        .jhs-layout-cad980f4 { width:100%; }

        .jhs-layout-cd9d5db1 { overflow:hidden;max-height:215px;text-align:center; }

        .jhs-layout-d10a577d { margin-bottom:20px;text-align:center;display:none; }

        .jhs-layout-d2c171b1 { margin-top:10px }

        .jhs-layout-d44e70c7 { height:calc(100% - 50px); }

        .jhs-layout-d4a09a0d { width:200px; }

        .jhs-layout-d4a575e8 { height:inherit;width:100%; }

        .jhs-layout-d50e4f09 { margin-top:15px;display:none; }

        .jhs-layout-d543acf8 { display:flex;justify-content:center;align-items:center;position:absolute;top:0;left:0;height:100%;width:100%;z-index:var(--jhs-z-content);overflow:hidden }




        .jhs-layout-d9caa2c0 { display:flex;align-items:center;gap:5px; }

        .jhs-layout-da303dcf { margin-bottom:15px; }

        .jhs-layout-da5a4919 { display:flex;justify-content:space-between; }

        .jhs-layout-dd5a75f6 { width:300px; }

        .jhs-layout-e2965a97 { margin:10px auto;display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:20px; }

        .jhs-layout-e32cff7f { padding:30px; }

        .jhs-layout-e5d57abb { overflow:hidden;max-height:150px;max-width:150px;text-align:center; }






        .jhs-layout-f43f0d6d { width:160px;text-align:center;padding:8px 0; }

        .jhs-layout-f4e719ae { margin:10px 0 }

        .jhs-layout-f5f47b30 { margin-left:100px;width:400px; }

    @media (prefers-reduced-motion: reduce) {
        :where(.jhs-ui, .jhs-dialog .layui-layer-content, .menu-box, .jhs-fab-menu) *,
        :where(.jhs-ui, .jhs-dialog .layui-layer-content, .menu-box, .jhs-fab-menu) *::before,
        :where(.jhs-ui, .jhs-dialog .layui-layer-content, .menu-box, .jhs-fab-menu) *::after {
            scroll-behavior: auto !important;
            transition-duration: 0.01ms !important;
            animation-duration: 0.01ms !important;
            animation-iteration-count: 1 !important;
        }
    }
    .jhs-state-actions { container:jhs-state-actions / inline-size; width:100%; min-width:0; flex:1 1 344px; }
    .jhs-state-actions__buttons { display:flex; flex-wrap:wrap; gap:var(--jhs-space-2); }
    .jhs-state-actions .jhs-state-action { min-width:80px; width:auto; padding:0 var(--jhs-space-3); }
    .jhs-state-action[aria-pressed="true"] { border-color:currentColor; box-shadow:inset 0 0 0 1px currentColor; }
    .jhs-state-actions[data-jhs-state-count="2"] { width:auto; flex:0 1 auto; container-type:normal; }
    .jhs-fc2-toolbar > .jhs-state-actions { grid-column:1 / -1; flex-basis:100%; }
    @container jhs-state-actions (max-width:479px) {
        .jhs-state-actions[data-jhs-state-count="4"] .jhs-state-actions__buttons { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); }
    }
    .jhs-detail-btn-row { gap:var(--jhs-space-4); }
    :is(.jhs-detail-owned-slot,.jhs-review-panel,.jhs-related-panel) { background:var(--jhs-surface); color:var(--jhs-text); }
    .jhs-detail-btn-row > :not(.jhs-state-actions) { gap:var(--jhs-space-2); }
    .jhs-btn[aria-busy="true"] { cursor:progress; }
    .jhs-table .tabulator-cell .jhs-btn { min-height:var(--jhs-control-height-sm); font-size:var(--jhs-font-size-xs); padding:0 var(--jhs-space-2); }
    .jhs-dialog.layui-layer { display:flex; flex-direction:column; box-sizing:border-box; overflow:hidden; border-radius:var(--jhs-radius-md); }
    .jhs-dialog > .layui-layer-title { flex:0 0 auto; padding-right:52px; }
    .jhs-dialog > .layui-layer-content { min-height:0; min-width:0; flex:1 1 auto; overflow:auto; }
    .jhs-dialog[data-jhs-dialog-body="table"] > .layui-layer-content { display:flex; flex-direction:column; overflow:hidden; }
    .jhs-dialog[data-jhs-dialog-body="media"] > .layui-layer-content { display:flex; flex-direction:column; overflow:hidden; }
    .jhs-dialog > .layui-layer-content > iframe { min-height:0; width:100%; max-width:100%; }
    .jhs-dialog > .layui-layer-btn { flex:0 0 auto; display:flex; flex-wrap:wrap; justify-content:flex-end; gap:var(--jhs-space-2); padding:var(--jhs-space-4); }
    .jhs-dialog > .layui-layer-btn > a { display:inline-flex; align-items:center; justify-content:center; box-sizing:border-box; min-height:var(--jhs-control-height); margin:0; padding:0 var(--jhs-space-3); border-radius:var(--jhs-radius-sm); font-size:var(--jhs-font-size-sm); }
    .jhs-dialog .layui-layer-setwin { top:0; right:0; }
    .jhs-dialog .layui-layer-setwin .layui-layer-close { display:block; width:44px; height:44px; margin:0; background-position:center; }
    :is(.jhs-ui,.jhs-dialog) label:has(> :is(input[type="checkbox"],.jhs-switch,.mini-switch)) { display:inline-flex; align-items:center; min-height:var(--jhs-control-height); gap:var(--jhs-space-2); }
    @media (max-width:767px), (pointer:coarse) {
        :is(.jhs-btn,.jhs-filter-btn,.jhs-select-trigger,.jhs-field,.jhs-input,.jhs-select,.jhs-icon-btn,.card-btn), .jhs-table .tabulator-cell .jhs-btn,
        .jhs-dialog > .layui-layer-btn > a { min-height:var(--jhs-touch-target); }
        :is(.jhs-ui,.jhs-dialog) label:has(> :is(input[type="checkbox"],.jhs-switch,.mini-switch)) { min-height:var(--jhs-touch-target); }
        .jhs-dialog .layui-layer-close { width:44px!important; height:44px!important; }
        .jhs-dialog .layui-layer-close::before,.jhs-dialog .layui-layer-close::after { top:21px; left:13px; }
    }
</style>`}d(Uo,"buildUiPrimitivesCss");function Oe(o,{type:e="empty",title:t="",description:s="",actionLabel:a="",onAction:i=null}={}){let r=o?.jquery?o:$(o),n=$('<div class="jhs-state"></div>').addClass(`jhs-state--${e}`).attr("role",e==="error"?"alert":"status"),l=$('<div class="jhs-state__content"></div>');return t&&l.append($('<p class="jhs-state__title"></p>').text(t)),s&&l.append($('<p class="jhs-state__description"></p>').text(s)),a&&typeof i=="function"&&l.append($('<button type="button" class="jhs-btn jhs-btn--secondary"></button>').text(a).on("click",i)),n.append(l),r.empty().append(n),n}d(Oe,"renderStateView");function Fo(o){if(!o||typeof o.observe!="function")throw new TypeError("UI accessibility requires an app LifecycleScope");let e="button.jhs-btn, a.jhs-btn[role='button'], .card-btn, .jhs-icon-btn, [class*='jhs-'] button, [class*='jhs-'] a[role='button']",t=d(r=>{let n=r.nodeType===Node.ELEMENT_NODE&&r.matches?.(e)?[r]:[],l=r.querySelectorAll?[...r.querySelectorAll(e)]:[];[...n,...l].forEach((c=>{if(c.hasAttribute("aria-label")||c.hasAttribute("aria-labelledby")||c.textContent.trim())return;let h=c.getAttribute("title")||c.getAttribute("data-tip");h&&c.setAttribute("aria-label",h)}))},"enhance");t(document);let s=new Set,a=!1,i=d(()=>{a=!1;let r=[...s],n=r.filter((l=>!r.some((c=>c!==l&&c.contains?.(l)))));s.clear(),n.forEach(t)},"flush");return o.observe(document.documentElement,(r=>{r.forEach((n=>n.addedNodes.forEach((l=>{l.nodeType===Node.ELEMENT_NODE&&s.add(l)})))),s.size&&!a&&(a=!0,queueMicrotask(i))}),{childList:!0,subtree:!0})}d(Fo,"initializeUiAccessibility");var re=class re{static _ensureGlobalClickHandler(){re._globalClickBound||(re._globalClickBound=!0,$(document).on("click.jhsSelect",(e=>{$(e.target).closest(".jhs-select-control").length||re.closeAll()})))}constructor(e){if(this.source=$(e),!this.source.length)return;let t=re.instances.get(this.source[0]);if(t)return t;let s=this.source.hasClass("jhs-is-hidden")||this.source[0].style.display==="none";this.control=$('<div class="jhs-select-control"></div>'),this.trigger=$('<button type="button" class="jhs-btn jhs-btn--secondary jhs-select-trigger" aria-haspopup="menu" aria-expanded="false"><span class="jhs-select-value"></span></button>'),this.menu=$('<div class="jhs-popover jhs-select-menu" role="menu"></div>'),this.source.wrap(this.control),this.control=this.source.parent(),this.control.append(this.trigger,this.menu),this.source.addClass("jhs-select-source-native").attr({"aria-hidden":"true",tabindex:"-1"}),s&&this.control.addClass("jhs-is-hidden"),re.instances.set(this.source[0],this),this.render(),this.bind(),this.refresh()}static enhance(e=document){let t=$(e),s=t.is("select.jhs-select-source")?t:t.find("select.jhs-select-source");return s.each(((a,i)=>new re(i))),s}static get(e){let t=$(e)[0];return t?re.instances.get(t)||new re(t):null}static setValue(e,t,s=!1){let a=re.get(e);a&&(a.source.val(t),s?a.emitChange():a.refresh())}static refresh(e){re.get(e)?.refresh()}static refreshAll(e=document){re.enhance(e),$(e).find("select.jhs-select-source").each(((t,s)=>re.refresh(s)))}static setVisible(e,t){re.get(e)?.control.toggleClass("jhs-is-hidden",!t)}static closeAll(e=null){$(".jhs-select-control.is-open").each(((t,s)=>{let a=$(s).children("select.jhs-select-source")[0],i=a&&re.instances.get(a);i&&i!==e&&i.close()}))}render(){this.menu.empty();let e=d((t,s)=>{let a=$('<button type="button" class="jhs-btn jhs-btn--ghost jhs-select-option" role="menuitemradio" tabindex="-1"></button>');a.attr({"data-value":t.value,"aria-checked":t.selected?"true":"false"}).prop("disabled",t.disabled).text(t.text),s.append(a)},"appendOption");this.source.children().each(((t,s)=>{if(s.tagName==="OPTGROUP"){let a=$('<div class="jhs-select-group" role="group"></div>').attr("aria-label",s.label),i=$('<div class="jhs-select-group__label"></div>').text(s.label);a.append(i),$(s).children("option").each(((r,n)=>e(n,a))),this.menu.append(a)}else s.tagName==="OPTION"&&e(s,this.menu)}))}bind(){this.trigger.on("click",(e=>{e.preventDefault(),e.stopPropagation(),this.source.prop("disabled")||(this.control.hasClass("is-open")?this.close():this.open())})).on("keydown",(e=>{["ArrowDown","ArrowUp","Home","End"].includes(e.key)&&(e.preventDefault(),this.open(e.key==="ArrowUp"||e.key==="End"?"last":e.key==="Home"?"first":"selected"))})),this.menu.on("click",".jhs-select-option",(e=>{e.preventDefault(),this.choose($(e.currentTarget))})).on("keydown",".jhs-select-option",(e=>{let t=this.options(),s=t.index(e.currentTarget);if(e.key==="Escape")return e.preventDefault(),e.stopPropagation(),this.close(!0);if(e.key==="Tab")return void this.close(!0);if(["Enter"," "].includes(e.key))return e.preventDefault(),this.choose($(e.currentTarget));if(!["ArrowDown","ArrowUp","Home","End"].includes(e.key))return;e.preventDefault();let a=e.key==="Home"?0:e.key==="End"?t.length-1:e.key==="ArrowDown"?(s+1)%t.length:(s-1+t.length)%t.length;t.eq(a).trigger("focus")})),this.source.on("change.jhsSelect",(()=>this.refresh())),re._ensureGlobalClickHandler()}options(){return this.menu.find(".jhs-select-option:not(:disabled)")}open(e="selected"){re.closeAll(this),this.control.addClass("is-open"),this.menu.addClass("is-open"),this.trigger.attr("aria-expanded","true");let t=this.options(),s=t.filter('[aria-checked="true"]');(e==="last"?t.last():e==="first"?t.first():s.length?s.first():t.first()).trigger("focus")}close(e=!1){this.control.removeClass("is-open"),this.menu.removeClass("is-open"),this.trigger.attr("aria-expanded","false"),e&&this.trigger.trigger("focus")}choose(e){e.prop("disabled")||(this.source.val(e.attr("data-value")),this.emitChange(),this.close(!0))}emitChange(){this.source[0]?.dispatchEvent(new Event("change",{bubbles:!0}))}refresh(){let e=this.source.find("option:selected").first(),t=this.source.val();this.trigger.find(".jhs-select-value").text(e.text()),this.trigger.prop("disabled",this.source.prop("disabled")),this.menu.find(".jhs-select-option").attr("aria-checked","false").filter(((s,a)=>$(a).attr("data-value")===String(t??""))).attr("aria-checked","true")}};d(re,"JhsSelect"),lt(re,"instances",new WeakMap),lt(re,"_globalClickBound",!1);var K=re;function Vd(){return`
<style>
    .top-bar { z-index:var(--jhs-z-host-topbar)!important; }
    ${Lo()}
    .masonry { display:grid; box-sizing:border-box; width:100%!important; height:100%!important; padding:0 15px!important; column-gap:10px; row-gap:10px; grid-template-columns:repeat(4,minmax(0,1fr)); align-items:start; }
    .masonry .item { top:initial!important; left:initial!important; float:none!important; position:relative!important; background-color:var(--jhs-surface-2); }
    .masonry .movie-box { width:100%!important; height:100%!important; margin:0!important; overflow:inherit!important; }
    .masonry .movie-box .photo-frame { height:auto!important; margin:0!important; position:relative; }
    .masonry .movie-box img { max-height:500px; height:100%!important; object-fit:contain; object-position:top; transform:none!important; transition:none!important; }
    .masonry .photo-info span { display:inline-block; max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
    .photo-frame .mheyzo, .photo-frame .mcaribbeancom2 { margin-left:0!important; }
    .avatar-box { display:flex!important; width:100%!important; margin:0!important; }
    .avatar-box .photo-info { display:flex; align-items:center; justify-content:center; gap:30px; flex-direction:row; background-color:var(--jhs-surface)!important; }
    footer { display:none!important; }
    .video-title { display:-webkit-box!important; height:75px; white-space:normal!important; -webkit-box-orient:vertical; -webkit-line-clamp:3; }
</style>`}d(Vd,"buildJavBusCss");function Hd(){return`
<style>
    ${Bo()}
    .navbar { z-index:var(--jhs-z-host-nav)!important; padding:0; }
    .navbar-link:not(.is-arrowless) { padding-right:33px; }
    .sub-header, #footer, .app-desktop-banner,
    div[data-controller="movie-tab"] .tabs, h3.main-title,
    div.video-detail > div:nth-child(4) > div > div.tabs.no-bottom > ul > li:nth-child(3),
    div.video-detail > div:nth-child(4) > div > div.tabs.no-bottom > ul > li:nth-child(2),
    div.video-detail > div:nth-child(4) > div > div.tabs.no-bottom > ul > li:nth-child(1),
    .top-meta, .float-buttons { display:none!important; }
    div.tabs.no-bottom, .tabs ul { border-bottom:none!important; }
    .movie-list .item { position:relative!important; }
    .item > a[data-jhs-fc2-primary="true"], .item > a[data-jhs-fc2-primary="true"] .cover, .item > a[data-jhs-fc2-primary="true"] .cover img { display:block!important; width:100%!important; }
    .movie-list .item .cover img { transform:none!important; transition:none!important; }
    .video-title { display:-webkit-box; height:80px; white-space:normal!important; -webkit-box-orient:vertical; -webkit-line-clamp:3; }
    .main-tabs, .tabs { overflow-x:hidden; flex-wrap:wrap; justify-content:flex-start; }
    .main-tabs ul, .tabs ul { flex-wrap:wrap; flex-grow:0; }
    .toolbar { display:flex; }
</style>`}d(Hd,"buildJavDbCss");var qd=`
<style>
    .fr-btn { float:right; margin-left:4px!important; }
    .menu-box { position:fixed; right:10px; top:50%; display:flex; flex-direction:column; gap:6px; z-index:var(--jhs-z-dropdown); transform:translateY(-50%); }
    .do-hide { display:none!important; }
    .jhs-icon { width:16px; height:16px; }
    .tool-box .jhs-icon { width:1.5rem; height:1.5rem; }
    .jhs-nav-btn { color:var(--jhs-accent)!important; font-weight:600; }
    .jhs-nav-btn:hover { color:var(--jhs-accent-hover)!important; }
    .tabulator .tabulator-row .action-cell-dropdown { overflow:visible!important; }
    .tabulator .tabulator-row.tabulator-selectable:hover { cursor:default!important; }
    .tabulator .tabulator-col.tabulator-sortable[aria-sort="ascending"] .tabulator-arrow { border-bottom-color:var(--jhs-accent)!important; }
    .tabulator .tabulator-col.tabulator-sortable[aria-sort="descending"] .tabulator-arrow { border-top-color:var(--jhs-accent)!important; }
    .tabulator-responsive-collapse { border-top:none!important; }
    .tabulator-responsive-collapse table { margin-left:50px!important; }
    .tabulator-cell { height:auto!important; }
    .tabulator .tabulator-cell { white-space:normal!important; text-overflow:clip!important; }
    .tabulator-tableholder { overflow-x:hidden!important; }
</style>`,Vo=!1;function Ho(o,e=""){if(Vo)return;let t=d((s,a)=>o?.register?o.register(s,a.replace(/^\s*<style>|<\/style>\s*$/g,"")):Mo(a),"register");t("jhs-core-theme",Oo()),B&&t("jhs-host-javbus",Vd()),N&&t("jhs-host-javdb",Hd()),t("jhs-core-layout",qd),t("jhs-ui-primitives",Uo()),e&&t("jhs-detail-panels",e),Vo=!0}d(Ho,"injectCoreCss");function qo(){return`
        .jhs-review-panel { min-width:0; }
        .jhs-panel-header { display:flex; min-height:var(--jhs-control-height); align-items:center; justify-content:space-between; gap:var(--jhs-space-3); margin-bottom:var(--jhs-space-3); }
        .jhs-panel-header h3 { margin:0; color:var(--jhs-text); font-size:var(--jhs-font-size-lg); font-weight:600; line-height:1.5; }
        .jhs-panel-toggle { flex:none; }
        .jhs-review-list { display:grid; }
        .jhs-review-item { min-width:0; padding:var(--jhs-space-4) 0; border-bottom:1px solid color-mix(in srgb,var(--jhs-border) 55%,transparent); }
        .jhs-review-item:last-child { border-bottom:0; }
        .jhs-review-meta { display:flex; flex-wrap:wrap; align-items:center; gap:var(--jhs-space-1) var(--jhs-space-3); color:var(--jhs-text-muted); font-size:14px; }
        .jhs-review-author { color:var(--jhs-text); font-size:15px; font-weight:600; }
        .jhs-review-floor { margin-left:auto; color:var(--jhs-text-faint); }
        .jhs-review-content { margin:var(--jhs-space-3) 0 0; color:var(--jhs-text); font-size:16px; line-height:1.7; overflow-wrap:anywhere; white-space:pre-wrap; }
        .jhs-review-link { display:inline-flex; align-items:center; gap:var(--jhs-space-1); margin:0 var(--jhs-space-1); padding:2px var(--jhs-space-2); border:0; border-radius:var(--jhs-radius-pill); background:var(--jhs-accent-tint); color:var(--jhs-accent); font:inherit; font-size:var(--jhs-font-size-sm); line-height:1.5; text-decoration:none; vertical-align:baseline; cursor:pointer; }
        .jhs-review-link-copy { color:var(--jhs-text-muted); }
        .jhs-review-link-wrap { display:flex; align-items:center; justify-content:space-between; gap:var(--jhs-space-2); width:100%; margin:var(--jhs-space-1) 0; }
        .jhs-review-inline-controls { display:inline-flex; align-items:center; gap:var(--jhs-space-1); margin:0 var(--jhs-space-1); }
        .jhs-review-link-main { display:inline-flex; align-items:center; flex-wrap:wrap; gap:var(--jhs-space-1); }
        .jhs-review-link-actions { display:inline-flex; align-items:center; gap:var(--jhs-space-1); margin-left:auto; flex-shrink:0; }
        .jhs-review-offline-btn { background:var(--jhs-accent) !important; color:var(--jhs-accent-text-on) !important; }
        .jhs-panel-state { padding:var(--jhs-space-4) 0; color:var(--jhs-text-muted); text-align:center; }
        .jhs-panel-footer { display:flex; justify-content:center; padding-top:var(--jhs-space-3); }
        .jhs-panel-end { color:var(--jhs-text-faint); font-size:var(--jhs-font-size-sm); }
        @media (max-width:767px) { .jhs-review-floor { width:100%; margin-left:0; } }
        .jhs-related-panel { min-width:0; }
        .jhs-related-list { display:grid; }
        .jhs-related-item { display:grid; gap:var(--jhs-space-2); padding:var(--jhs-space-3) 0; border-bottom:1px solid color-mix(in srgb,var(--jhs-border) 55%,transparent); }
        .jhs-related-item:last-child { border-bottom:0; }
        .jhs-related-heading { display:flex; min-width:0; align-items:baseline; gap:var(--jhs-space-2); }
        .jhs-related-index { flex:none; color:var(--jhs-text-faint); font-size:14px; }
        .jhs-related-title { min-width:0; overflow:hidden; color:var(--jhs-accent); font-size:16px; font-weight:600; text-overflow:ellipsis; text-decoration:none; white-space:nowrap; }
        .jhs-related-meta { display:flex; flex-wrap:wrap; gap:var(--jhs-space-2) var(--jhs-space-4); color:var(--jhs-text-muted); font-size:14px; }
        .jhs-related-time { color:var(--jhs-text-faint); font-size:14px; white-space:nowrap; }
        .jhs-detail-owned-slot :is(.jhs-review-item,.jhs-related-item) { padding:var(--jhs-space-3); border-bottom-color:var(--jhs-border); }
        .jhs-detail-owned-slot .jhs-panel-header { padding-bottom:var(--jhs-space-3); margin-bottom:0; border-bottom:1px solid var(--jhs-border); }
        .jhs-detail-owned-slot .jhs-panel-header:has(.jhs-panel-toggle[aria-expanded="false"]) { padding-bottom:0; border-bottom:0; }
        .jhs-detail-owned-slot .jhs-panel-footer { padding:var(--jhs-space-3); }
        .jhs-detail-owned-slot :is(.jhs-review-meta,.jhs-related-meta,.jhs-related-time) { font-size:var(--jhs-font-size-sm); }
        .jhs-detail-owned-slot .jhs-related-title { white-space:normal; overflow-wrap:anywhere; }
        .jhs-detail-owned-slot .jhs-related-time { white-space:normal; overflow-wrap:anywhere; }
    `}d(qo,"buildDetailPanelCss");var Wd=Object.freeze(["NETWORK_ERROR","TIMEOUT","AUTH_REQUIRED","NOT_FOUND","PARSE_ERROR","RATE_LIMITED","ABORTED","UNSUPPORTED","INVALID_RESPONSE","INVALID_URL","CF_BLOCKED","CIRCUIT_OPEN","TASK_EXISTS","OPERATION_FAILED","MISSING_DEPENDENCY","UNDECLARED_DEPENDENCY","DUPLICATE_TOKEN","BOOTSTRAP_FAILED"]),Ct=class Ct extends Error{constructor(e,t,s={}){if(super(t,{cause:s.cause}),!Wd.includes(e))throw new TypeError(`Unknown JhsError code: ${e}`);this.name="JhsError",this.code=e,this.source=s.source??"jhs",this.retryable=s.retryable??!1,this.details=s.details?Object.freeze({...s.details}):null}static from(e,t="jhs"){if(e instanceof Ct)return e;if(e instanceof DOMException&&e.name==="AbortError")return new Ct("ABORTED","请求已取消",{source:t,cause:e});let s=e instanceof Error?e.message:String(e??"未知错误");return new Ct("NETWORK_ERROR",s,{source:t,cause:e,retryable:!0})}toJSON(){return{code:this.code,message:this.message,source:this.source,retryable:this.retryable,details:this.details}}};d(Ct,"JhsError");var D=Ct;var ct=Object.freeze(["favorite","downloaded","watched","blocked"]),Li=Object.freeze({[ue]:"favorite",[pe]:"downloaded",[me]:"watched",[ce]:"blocked"});function Ht(){return{favorite:!1,downloaded:!1,watched:!1,blocked:!1}}d(Ht,"createEmptyStateFlags");function Jd(o){let e=Ht(),t=typeof o=="string"?Li[o]:void 0;return t&&(e[t]=!0),e}d(Jd,"stateFlagsFromLegacyStatus");function q(o){let e=Ht();return ct.forEach((t=>e[t]=o?.[t]===!0)),e}d(q,"normalizeStateFlags");function Kd(o){let e=q(o);return e.blocked?ce:e.watched?me:e.downloaded?pe:e.favorite?ue:""}d(Kd,"projectLegacyStatus");function vs(o){return o.stateFlags=q(o.stateFlags),o.status=Kd(o.stateFlags),o}d(vs,"syncLegacyStatus");function oe(o){let e=q(o);return ct.some((t=>e[t]))}d(oe,"hasAnyState");function ke(o){return typeof o=="string"&&Li[o]||null}d(ke,"legacyActionToFlag");function Wo(o){let e=new Map,t=[],s=[];o.filter(Boolean).forEach((i=>{let r=i.carNum,n=T(r);if(!n)return;let l={...i,carNum:n,stateFlags:i.stateFlags?q(i.stateFlags):Jd(i.status)};i.stateFlags||!i.status||Li[i.status]||s.push({carNum:n,status:i.status});let c=e.get(n)||[];c.push({original:r,item:l}),e.set(n,c)}));let a=[];for(let[i,r]of e){let n=r.map((g=>g.item)).sort(((g,m)=>String(g.updateDate||"").localeCompare(String(m.updateDate||"")))),l={},c=Ht();n.forEach((g=>{Object.entries(g).forEach((([m,f])=>f!=null&&f!==""&&m!=="stateFlags"&&m!=="status"&&(l[m]=f))),ct.forEach((m=>c[m]=c[m]||g.stateFlags[m]))}));let h=n.map((g=>g.createDate)).filter(Boolean).sort(),u=n.map((g=>g.updateDate)).filter(Boolean).sort();h.length&&(l.createDate=h[0]),u.length&&(l.updateDate=u.at(-1)),l.carNum=i,l.stateFlags=c,vs(l),a.push(l);let p=[...new Set(r.map((g=>g.original)).filter(Boolean))];p.length>1&&t.push({carNum:i,originals:p,count:r.length})}return{list:a,collisions:t,unknownStatuses:s}}d(Wo,"mergeCanonicalCarRecords");var bs=Object.freeze(["car_list","filter_keyword_title","filter_keyword_review","setting","blacklist","blacklist_car_list","favorite_actresses","highlighted_tags","activity_log","offline_history","new_video_decisions"]),Jo=Object.freeze([...bs,"third_party_ttl_cache"]),Ko=Object.freeze(["trustedLocalOrigins","webDavUrl","webDavUsername","webDavPassword"]),Go=Object.freeze(["webDavPassword"]),Gd=new Set(["car_list","filter_keyword_title","filter_keyword_review","blacklist","blacklist_car_list","favorite_actresses","highlighted_tags","offline_history"]),Qd=new Set(["setting","third_party_ttl_cache","activity_log","new_video_decisions"]);function Bi(o){let e=o&&typeof o=="object"&&!Array.isArray(o)?{...o}:{};for(let t of[...Ko,...Go])delete e[t];return e}d(Bi,"selectPortableSettings");function Qo(o,e){let t=Bi(e);for(let s of[...Ko,...Go])Object.prototype.hasOwnProperty.call(o||{},s)&&(t[s]=o[s]);return t}d(Qo,"mergePortableSettings");function Yo(o){if(!o||typeof o!="object"||Array.isArray(o))throw new TypeError("备份数据格式无效");let e=Number(o.data_version||0);if(!Number.isInteger(e)||e<0)throw new TypeError("备份数据版本无效");if(e>fs)throw new Error("数据来自更新版本的 JHS,当前版本无法安全读取");for(let t of Gd)if(o[t]!=null&&!Array.isArray(o[t]))throw new TypeError(`备份字段 ${t} 必须为数组`);for(let t of Qd)if(o[t]!=null&&(typeof o[t]!="object"||Array.isArray(o[t])))throw new TypeError(`备份字段 ${t} 必须为对象`);return e}d(Yo,"validatePortableData");async function Mi(o){for(let e of bs){let t=await o.forage.getItem(e);if(Array.isArray(t)?t.length:t&&typeof t=="object"?Object.keys(t).length:t!=null)return!0}return!1}d(Mi,"hasPortableUserData");async function Yd(o){if(!await Mi(o))return null;let e=await o._getSnapshots(),t=e.find(r=>r.kind==="migration-snapshot"&&r.targetDataVersion===2);if(t)return t;let s=await o.exportPortableData(),a={id:"migration_v2_"+Date.now(),name:"6.4.0-migration-backup",source:"migration",kind:"migration-snapshot",targetDataVersion:2,appVersion:"6.4.0",createdAt:new Date().toISOString(),time:utils.getNowStr(),itemCount:Object.values(s).reduce(((r,n)=>r+(Array.isArray(n)?n.length:n&&typeof n=="object"?1:0)),0),data:s},i=d(async()=>(e.push(a),e.length>10&&e.splice(0,e.length-10),await o._saveSnapshots(e),a),"save");return o._withCrossTabLock?await o._withCrossTabLock("jhs_snapshot_lock",i):await i()}d(Yd,"ensureV2MigrationSnapshot");async function Zd(o){await o.merge_table_name(),await o.clean_no_url_blacklist(),await o.async_merge_other(),await o.merge_blacklist(),await o.merge_favoriteActress(),await o.merge_tow_car_list_table()}d(Zd,"migrateLegacyStorage");async function Xd(o){await Yd(o);let e=await o.forage.getItem(o.car_list_key)||[],t=Wo(e);await o._setItemAndInvalidate(o.car_list_key,t.list);let a=(await o.forage.getItem(o.favorite_actresses_key)||[]).map(r=>{if(!Array.isArray(r.newVideoList))return r;let n=r.newVideoList.map(l=>typeof l=="string"?T(l):{...l,carNum:T(l.carNum)}).filter((l=>typeof l=="string"?l:l.carNum));return{...r,newVideoList:n}});await o._setItemAndInvalidate(o.favorite_actresses_key,a);let i=await o.forage.getItem("data_health_warnings")||[];t.collisions.length&&i.push({type:"canonical-collision",createdAt:new Date().toISOString(),items:t.collisions}),t.unknownStatuses.length&&i.push({type:"unknown-legacy-status",createdAt:new Date().toISOString(),items:t.unknownStatuses}),i.length&&await o.forage.setItem("data_health_warnings",i)}d(Xd,"migrateStateFlags");async function eh(o){let[e,t,s]=await Promise.all([o.forage.getItem(o.car_list_key),o.forage.getItem("new_video_decisions"),o.forage.getItem("activity_log")]),a=Array.isArray(e)?e:[],i={...t||{}},r=Array.isArray(s?.entries)?s.entries:[],n=new Map;r.filter((h=>h?.type==="new-video-remove"&&h?.commitState==="committed")).forEach((h=>(Array.isArray(h.changes)?h.changes:[]).forEach((u=>{let p=T(u?.carNum);p&&n.set(p,h)}))));let l=[],c=[];return a.forEach((h=>{let u=T(h?.carNum),p=n.get(u),g=h&&!String(h.url||"").trim()&&!String(h.names||"").trim()&&!String(h.status||"").trim()&&!oe(q(h.stateFlags));if(!u||!p||!g||(Array.isArray(p.changes)?p.changes:[]).find((b=>T(b?.carNum)===u))?.undoState==="reverted")return void c.push(h);let f=h.updateDate||h.createDate||p.createdAt||new Date().toISOString(),v=i[u];i[u]={action:"dismissed",until:null,createdAt:v?.createdAt||f,updatedAt:v?.updatedAt||f},l.push(u)})),l.length?(await o.forage.setItem("new_video_decisions",i),await o._setItemAndInvalidate(o.car_list_key,c),l):[]}d(eh,"repairNewVideoTombstones");async function th(o){await eh(o);let e=typeof o.forage.keys=="function"?await o.forage.keys():[];for(let t of e)String(t).startsWith("jhs_http_public_cache:v1:")&&await o.forage.removeItem(t)}d(th,"migrateV3");var sh=Object.freeze({1:Zd,2:Xd,3:th});async function ws(o){let e=globalThis.navigator?.locks,t=d(async()=>{let s=await o.getDataVersion();if(s>fs)throw new Error("数据来自更新版本的 JHS,当前版本无法安全读取");for(let a=s+1;a<=fs;a++){let i=sh[a];if(!i)throw new Error(`缺少数据迁移: ${a-1} → ${a}`);await i(o),await o.setDataVersion(a),s=a}return s},"run");return e?.request?e.request("jhs_data_migration",t):t()}d(ws,"runDataMigrations");var Oi=Object.freeze({ListPagePlugin:"list.core",AutoPagePlugin:"list.auto-page",Fc2Plugin:"detail.fc2-owned",FoldCategoryPlugin:"list.fold-category",ListPageButtonPlugin:"list.actions",HistoryPlugin:"library.history",SettingPlugin:"settings.core",NavBarPlugin:"identity.javdb-navigation",BusNavBarPlugin:"identity.javbus-navigation",HitShowPlugin:"discovery.hit-show",TOP250Plugin:"discovery.top250",SearchByImagePlugin:"identity.image-search",Fc2By123AvPlugin:"detail.fc2-lookup",DetailPagePlugin:"detail.javdb-native",BusDetailPagePlugin:"detail.javbus-native",DetailWorkspacePlugin:"detail.workspace",ReviewPlugin:"detail.reviews",RelatedPlugin:"detail.related",ScreenShotPlugin:"detail.screenshot",ScreenshotPlugin:"detail.screenshot",MagnetHubPlugin:"detail.external-magnets",PreviewVideoPlugin:"detail.javdb-preview",CoverButtonPlugin:"detail.cover-state-actions",DetailPageButtonPlugin:"detail.page-state-actions",HighlightMagnetPlugin:"detail.native-magnets",OtherSitePlugin:"detail.external-sites",SubTitleCatPlugin:"external-bridge.subtitle",FilterTitleKeywordPlugin:"library.keyword-filter",ActressInfoPlugin:"identity.actress-info",TranslatePlugin:"external-bridge.translation",WantAndWatchedVideosPlugin:"library.state-actions",BlacklistPlugin:"library.blacklist",FavoriteActressesPlugin:"library.favorite-actresses",NewVideoPlugin:"discovery.new-video",TaskPlugin:"discovery.scheduler",StatsPlugin:"stats.dashboard",MobileBottomBarPlugin:"responsive-shell.bottom-bar",OneOneFiveMatchPlugin:"external-bridge.115-match",UnifiedOfflinePlugin:"external-bridge.offline",CompatibilityEnhancementsPlugin:"compatibility.enhancements",BusImgPlugin:"detail.javbus-images",BusPreviewVideoPlugin:"detail.javbus-preview",OneTwoThreeOfflinePlugin:"external-bridge.123pan",JavTrailersPlugin:"external-bridge.javtrailers"}),ah=Object.freeze({"detail.subtitle":["external-bridge.subtitle"],"detail.native":["detail.javdb-native","detail.javbus-native"],"detail.state-actions":["detail.cover-state-actions","detail.page-state-actions"],"detail.gallery":["detail.javdb-preview","detail.javbus-images","detail.javbus-preview"]});function _t(o){let e=Array.isArray(o)?o:[],t=Oi,s=ah;return[...new Set(e.filter(a=>typeof a=="string").flatMap(a=>s[a]??[t[a]??a]))]}d(_t,"migrateDisabledPlugins");function $t(o){return Oi[o]??o}d($t,"disabledIdForPlugin");function Ge(o){try{let e=typeof o=="string"?JSON.parse(o):o;return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}catch{return[]}}d(Ge,"parseDisabledPlugins");var zi=class zi{constructor(e={}){this.plugins=new Map,this._errorLog=[],this._lastTimings=[],this._startedAt=performance.now(),this._registrationMs=0,this._cssMs=0,this._immediateMs=0,this._readyMs=0,this._idlePending=0,this._idleCompleted=0,this._disabledPluginsPromise=null,this._dependencyDeclarations=Object.freeze({}),this._catalogDescriptors=new Map,this.diagnostics=e.diagnostics??null}setDependencyDeclarations(e){if(this.plugins.size)throw new Error("依赖声明必须在插件注册前配置");this._dependencyDeclarations=e||Object.freeze({})}setCatalogDescriptors(e){if(this.plugins.size)throw new Error("插件目录必须在插件注册前配置");this._catalogDescriptors=new Map(e.map(t=>[t.name,Object.freeze({...t})])),this._syncDiagnostics()}register(e,t={},s={}){if(typeof e!="function")throw new Error("插件必须是一个类");let a=performance.now(),i=new e;i.pluginManager=this;let r=i.getName();if(this.plugins.has(r))throw new Error(`插件"${r}"已注册`);i.declaredDependencies=new Set(this._dependencyDeclarations[r]||[]),i.runtimeServices=Object.freeze({...t}),i.disableable=s.disableable??!0,this.plugins.set(r,i),this._registrationMs+=performance.now()-a,this._syncDiagnostics()}getBean(e){return this.plugins.get(e)}resolveDeclaredPlugin(e){return this.plugins.get(e)}recordDependencyError(e,t,s){return s.jhsDiagnosticsRecorded=!0,this._addError(e,"dependency",s),s}_addError(e,t,s){let a=s;this._errorLog.push({time:new Date().toISOString(),plugin:e,phase:t,message:a?.message||String(s),stack:a?.stack||""}),this._errorLog.length>200&&this._errorLog.shift(),this.diagnostics?.recordError({source:"legacy-plugin",plugin:e,phase:t,message:a?.message||String(s)})}getErrorLog(){return[...this._errorLog]}clearErrorLog(){this._errorLog=[],this.diagnostics?.clearErrors()}getTimings(){return[...this._lastTimings]}getPluginNames(){return Array.from(this.plugins.keys())}getPluginDescriptors(){let e=new Map(this._catalogDescriptors);for(let[t,s]of this.plugins)e.set(t,Object.freeze({name:t,disableable:s.disableable!==!1}));return[...e.values()]}getStartupReport(){return{registeredPlugins:this.plugins.size,registrationMs:this._registrationMs,cssMs:this._cssMs,immediateMs:this._immediateMs,readyMs:this._readyMs,idlePending:this._idlePending,idleCompleted:this._idleCompleted}}_syncDiagnostics(){this.diagnostics?.setLegacyRuntime(this.getPluginDescriptors(),this.getStartupReport(),this.getTimings())}async _getDisabledPlugins(){return this._disabledPluginsPromise||(this._disabledPluginsPromise=(async()=>{try{let e=await storageManager.getSetting("disabledPlugins","[]"),t=new Set(Ge(e));return new Set([...this.plugins].filter((([s,a])=>a.disableable!==!1&&t.has($t(s)))).map((([s])=>s)))}catch{return new Set}})())}async processCss(){let e=performance.now(),t=await this._getDisabledPlugins(),s=utils.isMobileMode(),i=(await Promise.all(Array.from(this.plugins).map((async([r,n])=>{try{if(t.has(r))return{name:r,status:"disabled"};if(s&&typeof n.shouldSkipOnMobile=="function"&&n.shouldSkipOnMobile())return{name:r,status:"skipped"};if(typeof n.initCss=="function"){let l=await n.initCss();return{name:r,status:"fulfilled",css:l}}return{name:r,status:"skipped"}}catch(l){return clog.error(`插件 ${r} 加载 CSS 失败`,l),this._addError(r,"initCss",l),{name:r,status:"rejected",error:l}}})))).map((r=>r.css)).filter(Boolean);i.length>0&&utils.insertStyle(i),this._cssMs=performance.now()-e,this._syncDiagnostics()}async _runPlugin(e){let t=performance.now();try{typeof e.plugin.handle=="function"&&await e.plugin.handle(),e.timing.elapsed=performance.now()-t,e.timing.status="ok"}catch(s){let a=s;e.timing.elapsed=performance.now()-t,e.timing.status="error",e.timing.error=a?.message||String(s),clog.error(`插件 ${e.name} 执行失败`,s),s?.jhsDiagnosticsRecorded||this._addError(e.name,e.mode==="idle"?"handle-idle":"handle",s)}}_scheduleIdle(e){let t=d(()=>e().catch((s=>{clog.error("[JHS] 空闲插件执行失败:",s)})),"t");typeof requestIdleCallback=="function"?requestIdleCallback(t,{timeout:1500}):setTimeout(t,100)}async _runIdlePlugins(e){for(let t of e)t.startedAt=performance.now(),await this._runPlugin(t),this._idlePending--,this._idleCompleted++;this._syncDiagnostics()}async processPlugins(){let e=await this._getDisabledPlugins(),t=utils.isMobileMode(),s=[],a=[],i=[];for(let[n,l]of this.plugins){let c=typeof l.getStartupMode=="function"&&l.getStartupMode()==="idle"?"idle":"immediate",h={name:n,elapsed:0,status:"pending",startupMode:c};if(e.has(n))h.status="disabled",i.push(h);else if(t&&typeof l.shouldSkipOnMobile=="function"&&l.shouldSkipOnMobile())h.status="skipped-mobile",i.push(h);else{if(typeof l.bindImmediateEvents=="function")try{l.bindImmediateEvents()}catch(p){clog.error(`插件 ${n} 即时事件绑定失败`,p),this._addError(n,"bind-immediate-events",p)}let u={name:n,plugin:l,mode:c,timing:h,startedAt:0};c==="idle"?(h.status="pending-idle",a.push(u)):s.push(u),i.push(h)}}this._lastTimings=i;let r=performance.now();await Promise.all(s.map((n=>(n.startedAt=performance.now(),this._runPlugin(n))))),this._immediateMs=performance.now()-r;for(let n of s)if(typeof n.plugin.afterPluginsReady=="function")try{await n.plugin.afterPluginsReady()}catch(l){clog.error(`插件 ${n.name} 完成初始化后执行失败`,l),this._addError(n.name,"after-ready",l)}this._readyMs=performance.now()-this._startedAt,this._idlePending=a.length,a.length&&this._scheduleIdle((()=>this._runIdlePlugins(a))),this._syncDiagnostics()}};d(zi,"PluginManager");var ys=zi,it=class it{constructor(...e){if(!it._sharedIcons){this.settingSvg="",this.editSvg="",this.deleteSvg="",this.checkSvg="",this.actressSvg="",this.newSvg="",this.refreshSvg="",this.blacklistSvg="",this.copySvg="",this.titleSvg="",this.carNumSvg="",this.downSvg="",this.handleSvg="",this.siteSvg="",this.videoSvg="",this.screenSvg="",this.recoveryVideoSvg="",A(this,"pluginManager",null),A(this,"settingSvg",'<svg t="1760926954860" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4947" width="200" height="200"><path d="M511.099222 365.825763c-80.7786 0-146.26579 65.482515-146.26579 146.259556 0 80.7786 65.48719 146.259556 146.26579 146.259556 80.777041 0 146.259556-65.480957 146.259556-146.259556C657.358779 431.308278 591.876263 365.825763 511.099222 365.825763L511.099222 365.825763zM511.099222 585.215097c-40.391637 0-73.136012-32.742816-73.136012-73.129778 0-40.391637 32.742816-73.129778 73.136012-73.129778 40.386962 0 73.129778 32.738141 73.129778 73.129778C584.229 552.472281 551.486184 585.215097 511.099222 585.215097L511.099222 585.215097zM511.099222 585.215097M900.893017 568.24369l-26.451395-15.268032c3.065451-27.021784 3.138697-54.472139 0.077922-81.822754l26.373473-15.225955c69.953678-40.391637 93.920921-129.844512 53.533959-199.799749-40.390079-69.95212-129.839837-93.925596-199.799749-53.533959l-26.373473 15.225955c-22.153219-16.330888-45.963059-29.99217-70.896534-40.843585l0-30.545416c0-80.777041-65.48719-146.259556-146.26579-146.259556-80.7786 0-146.259556 65.482515-146.259556 146.259556l0 30.515806c-12.377127 5.421811-24.587501 11.55583-36.562551 18.473743-11.97505 6.917913-23.396854 14.420242-34.277879 22.432179l-26.431136-15.258682c-69.958353-40.391637-159.406553-16.424395-199.79819 53.533959C27.378272 326.082437 51.343956 415.535311 121.299193 455.922273l26.449837 15.275825c-3.063892 27.020226-3.137139 54.465905-0.077922 81.822754l-26.373473 15.224397c-69.953678 40.391637-93.920921 129.841395-53.533959 199.799749 40.391637 69.95212 129.839837 93.920921 199.79819 53.533959l26.375032-15.224397c22.153219 16.32933 45.963059 29.984378 70.896534 40.843585l0 30.537624c0 80.7786 65.48719 146.26579 146.26579 146.26579 80.777041 0 146.259556-65.48719 146.259556-146.26579l0-30.515806c12.377127-5.415577 24.587501-11.55583 36.567226-18.467509 11.97505-6.917913 23.398412-14.420242 34.277879-22.432179l26.423343 15.258682c69.959912 40.391637 159.408111 16.418162 199.799749-53.533959C994.813938 698.085085 970.848254 608.635327 900.893017 568.24369L900.893017 568.24369zM891.096666 731.474653c-20.198936 34.982294-64.923035 46.962019-99.900654 26.770875l-63.331869-36.567226 0 0 0 0-7.988562-4.611422c-18.134004 18.450366-39.024886 34.787489-62.516805 48.353705-23.49971 13.559983-48.091888 23.482568-73.129778 29.964118l0 9.222846 0 0 0 65.828489 0 7.301289c0 40.391637-32.742816 73.136012-73.136012 73.136012-40.386962 0-73.129778-32.742816-73.129778-73.136012l0-7.402588 0-65.72719 0 0 0-9.300768c-50.682014-13.090892-97.855981-39.682547-135.652816-78.232109l-7.983886 4.606747 0 0-63.331869 36.567226c-34.977618 20.191144-79.706394 8.206743-99.900654-26.770875-20.192702-34.977618-8.206743-79.701718 26.770875-99.899095l6.341291-3.657657 0 0 64.972905-37.516316c-14.487254-52.005129-13.929333-106.151555 0.073247-156.593569l-8.057133-4.650384 0 0-63.331869-36.567226c-34.982294-20.192702-46.963578-64.923035-26.770875-99.900654 20.192702-34.97606 64.923035-46.962019 99.900654-26.763083l6.324148 3.649866 0 0 64.996282 37.528784c18.132445-18.450366 39.024886-34.790606 62.516805-48.353705 23.493477-13.559983 48.085654-23.485685 73.129778-29.964118l0-9.229079L437.960093 153.739276l0-7.309082c0-40.385404 32.742816-73.129778 73.129778-73.129778 40.391637 0 73.129778 32.744375 73.129778 73.129778l0 7.404147 0 65.72719 0 9.307001c50.686689 13.086217 97.862215 39.684106 135.657491 78.232109l48.487732-27.997368 22.828023-13.176607c34.977618-20.192702 79.701718-8.212977 99.89442 26.763083 20.198936 34.982294 8.212977 79.706394-26.764641 99.900654l-30.822819 17.79738-32.50905 18.769847 0 0 0 0-7.983886 4.605189c14.488813 52.009805 13.929333 106.159347-0.077922 156.599803l64.979139 37.511641 0 0 6.414537 3.701294C899.303409 651.772936 911.289368 696.498594 891.096666 731.474653L891.096666 731.474653zM891.096666 731.474653M197.330785 324.240361c-1.932465 3.232203-3.824411 6.497135-5.649343 9.785442L197.330785 324.240361 197.330785 324.240361zM197.330785 324.240361M830.515443 690.133926l-5.655577 9.804144C826.793889 696.699632 828.685835 693.433143 830.515443 690.133926L830.515443 690.133926zM830.515443 690.133926M505.297151 146.430195l11.304921 0C512.835324 146.369416 509.067017 146.374091 505.297151 146.430195L505.297151 146.430195zM505.297151 146.430195M516.898176 877.740444l-11.31583 0C509.350653 877.796547 513.125193 877.796547 516.898176 877.740444L516.898176 877.740444zM516.898176 877.740444" fill="#272636" p-id="4948"></path></svg>'),A(this,"editSvg",'<svg t="1760920692801" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3545" width="200" height="200"><path d="M1013.929675 128.26571a143.759824 143.759824 0 0 1 10.44409 53.858738 84.576649 84.576649 0 0 1-5.836403 30.308339 92.870485 92.870485 0 0 1-18.635533 29.284408 1314.726599 1314.726599 0 0 1-24.983901 24.574329c-7.372299 7.06512-13.82306 13.311095-19.249891 18.737926-6.143582 6.143582-12.082378 11.672806-17.406817 16.382886L720.266444 82.598415c9.317766-8.601015 20.478607-18.942712 33.277737-31.02509s23.448006-21.604931 31.946628-28.67005a102.085858 102.085858 0 0 1 68.193763-22.731255c11.263234 0.307179 22.116896 2.047861 32.560985 5.222045 10.546483 3.071791 19.659463 6.655547 27.441334 10.546483 16.280493 8.601015 34.301667 23.550399 54.063524 45.052936 19.864249 21.502538 35.120812 43.82422 46.076867 67.272226z m-907.20231 570.943576l32.560986-33.38013c17.099637-17.509209 38.397389-39.216533 64.098041-64.917186l84.986221-85.395793 94.303987-94.815953 250.350976-251.477299L850.817567 389.163169 600.46659 640.640468l-93.177663 94.815953c-31.02509 30.410732-58.978389 58.364031-83.859898 83.655111-24.779115 25.29108-45.360116 46.17926-61.743001 62.562146a504.797674 504.797674 0 0 1-55.804206 50.274981c-10.239304 7.884264-20.581 14.130239-31.537055 18.737926a507.152714 507.152714 0 0 1-47.715156 19.86425 1609.311367 1609.311367 0 0 1-131.063087 42.185931c-20.478607 5.426831-35.837563 8.908194-45.974474 10.546483-20.88818 2.35504-34.813633-0.819144-41.981145-9.42016-6.860333-8.601015-8.805801-22.93604-5.73401-43.312254a396.261054 396.261054 0 0 1 11.058448-47.305584c5.836403-20.683394 12.082378-42.185931 18.635532-64.40522 6.553154-22.219289 13.003916-42.697897 19.249891-61.435822 6.143582-18.635533 11.263234-31.537055 15.15417-38.602176 4.607687-10.853662 9.829732-20.785787 15.666135-29.796373a192.49891 192.49891 0 0 1 25.086294-29.796374z" fill="#FF9500" p-id="3546"></path></svg>'),A(this,"deleteSvg",'<svg t="1760921450746" class="jhs-icon icon" viewBox="0 0 1194 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4530" width="200" height="200"><path d="M761.086847 36.028779s309.754321-147.538628 424.952209 231.50509c2.047962 6.570546 71.337359 253.862013-220.838618 415.139055-12.970429 7.167869-267.515096 145.746661-370.339877 341.327076 0 0-90.963666-205.649563-393.379455-351.566888-6.399883-3.071944-304.549083-156.583796-163.751664-487.2444 3.669266-8.533177 163.666333-336.20717 466.423449-99.411511l24.575549 27.391498L387.931021 324.279495l237.648977 159.570408-109.139333 145.746661L625.579998 849.069874l-30.719437-205.820227 166.226286-169.81022-216.486698-168.103585L761.086847 36.028779z" fill="#F4382E" p-id="4531"></path></svg>'),A(this,"checkSvg",'<svg t="1760921633527" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5603" width="200" height="200"><path d="M924.928 544A413.76 413.76 0 0 1 544 924.736v3.264h-64v-3.2A413.696 413.696 0 0 1 99.072 544H96v-64h3.072A413.696 413.696 0 0 1 480 99.2V96h64v3.2a413.76 413.76 0 0 1 380.928 380.8h3.072v64h-3.072z m-64-64A350.016 350.016 0 0 0 544 163.2V288h-64V163.2A350.016 350.016 0 0 0 163.072 480H288v64H163.072A350.016 350.016 0 0 0 480 860.8V736h64v124.8a350.016 350.016 0 0 0 316.928-316.8H736v-64h124.928zM512 544a32 32 0 1 1 32-32 32 32 0 0 1-32 32z" fill="#333333" p-id="5604"></path></svg>'),A(this,"actressSvg",'<svg t="1760926744637" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1948" width="200" height="200"><path d="M265.950168 668.467036V209.809493A209.809493 209.809493 0 0 1 475.759661 0h40.949536A209.809493 209.809493 0 0 1 726.564189 209.809493v440.435" p-id="1949"></path><path d="M916.558657 825.861124a193.463804 193.463804 0 0 0-137.442564-155.83573l-186.001889-45.795231-10.487631-124.293214H424.106373L412.231008 624.025416l-170.623063 44.44162a193.452429 193.452429 0 0 0-133.666108 154.698244L76.410695 1023.192384h871.189985z" fill="#FFE7D9" p-id="1950"></path><path d="M668.472724 265.682859c68.431223-29.187919 96.140409 100.349111 5.20969 151.774902z" fill="#FFCFB5" p-id="1951"></path><path d="M676.378259 334.421203c1.137487-99.814492-38.674561-172.158671-38.674561-172.15867l-59.740822 11.920865a493.805894 493.805894 0 0 1-80.761583 9.099896 493.669396 493.669396 0 0 1-80.761583-9.099896l-59.683948-11.88674s-39.812048 72.344179-38.776934 172.15867l-1.080613 92.05683c5.209691 56.271486 92.4777 121.381247 195.022161 119.163147 61.196805 0.034125 165.59537-51.573665 165.59537-119.197272z" fill="#FFE7D9" p-id="1952"></path><path d="M322.198905 274.703131c-68.419848-29.187919-96.140409 100.349111-5.209691 151.774902z" fill="#FFCFB5" p-id="1953"></path><path d="M297.390311 812.461526H742.034014a38.458438 38.458438 0 0 1 38.458438 38.458439V1020.325917H258.931873V850.90859a38.458438 38.458438 0 0 1 38.458438-38.447064z" fill="#FFD527" p-id="1954"></path><path d="M690.539973 92.284327c-20.645391 84.287793-275.613121 235.323328-424.589805 117.525166l104.955934-95.548915 139.399042-64.529643z" p-id="1955"></path><path d="M285.321573 383.708519h33.624119v177.118114h-33.624119zM675.855015 383.708519h33.624118v177.118114h-33.624118z" fill="#FFD527" p-id="1956"></path></svg>'),A(this,"newSvg",'<svg t="1760926857487" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3954" width="200" height="200"><path d="M508.330667 733.994667c-11.008-7.338667-13.44-17.109333-7.338667-29.333334 28.117333-37.888 41.557333-98.986667 40.341333-183.317333v-165.013333c0-14.656 7.338667-23.210667 21.994667-25.664 37.888-1.216 82.496-5.504 133.845333-12.842667 13.44-2.432 21.376 3.072 23.829334 16.512 1.216 12.224-4.266667 19.562667-16.512 21.994667a1787.093333 1787.093333 0 0 1-113.664 11.008c-6.101333 0-9.173333 3.669333-9.173334 10.986666v84.330667h135.68c12.224 1.237333 18.944 7.957333 20.16 20.181333-1.216 10.986667-7.936 17.109333-20.16 18.346667h-36.672v223.658667c-1.216 12.202667-7.936 18.944-20.16 20.16-11.008-1.216-17.109333-7.957333-18.346666-20.16V501.162667h-60.48v18.346666c1.216 92.885333-13.44 161.92-44.010667 207.146667-6.101333 12.224-15.893333 14.677333-29.333333 7.338667z m-131.989334-282.325334c-1.237333 0-2.453333 0.618667-3.669333 1.834667h45.824a522.666667 522.666667 0 0 0 16.512-31.168c7.317333-12.224 12.224-20.778667 14.656-25.664 6.122667-11.008 15.274667-14.677333 27.52-11.008 9.770667 6.122667 12.202667 14.058667 7.317333 23.829333-4.906667 9.792-13.44 24.448-25.664 44.010667h49.493334c9.770667 1.216 15.274667 6.72 16.512 16.490667-1.237333 11.008-6.741333 17.109333-16.512 18.346666h-82.496a12.437333 12.437333 0 0 1 3.669333 9.173334v38.485333h69.653333c9.792 1.216 15.296 6.72 16.512 16.490667-1.216 11.008-6.72 17.130667-16.512 18.346666h-69.653333v108.16c0 34.218667-15.274667 51.946667-45.845333 53.162667h-16.490667a195.157333 195.157333 0 0 1-20.16 1.834667c-12.224 0-19.562667-6.72-22.016-20.16 1.237333-12.224 7.338667-18.944 18.346667-20.16 2.432 0 6.101333 0.597333 10.986666 1.834666h11.008c15.893333 0 23.829333-8.554667 23.829334-25.685333v-98.986667H314.026667c-11.008-1.216-17.109333-7.338667-18.346667-18.346666 1.237333-9.770667 7.338667-15.274667 18.346667-16.490667h75.157333V497.493333c0-3.669333 1.216-6.72 3.669333-9.173333h-89.813333c-11.029333-1.216-17.130667-7.317333-18.346667-18.325333 1.216-9.770667 7.317333-15.274667 18.346667-16.490667h56.810667c-3.669333-1.216-6.72-4.266667-9.173334-9.173333-1.216-1.216-3.050667-4.266667-5.482666-9.173334a758.336 758.336 0 0 0-14.677334-23.829333c-4.885333-9.770667-3.050667-17.706667 5.504-23.829333 11.008-3.669333 19.562667-1.216 25.664 7.338666 2.453333 2.432 6.122667 7.338667 11.008 14.656 6.101333 8.554667 9.770667 14.08 10.986667 16.512 4.906667 9.770667 2.453333 18.346667-7.317333 25.664z m-60.501333-71.509333c-9.792-1.216-15.274667-7.317333-16.512-18.346667 1.237333-9.749333 6.72-15.253333 16.512-16.490666h75.157333c-3.669333-12.202667-7.338667-21.973333-10.986666-29.333334-1.237333-12.202667 3.648-19.541333 14.656-21.973333 12.224-2.453333 21.397333 1.216 27.52 10.986667 0 1.216 0.597333 3.669333 1.813333 7.338666 4.906667 15.872 9.173333 26.88 12.842667 32.981334h60.48c11.008 1.237333 17.130667 6.741333 18.346666 16.512-1.216 11.008-7.338667 17.109333-18.346666 18.346666h-181.482667z m-14.677333 311.68c-8.533333-6.122667-10.986667-14.08-7.338667-23.829333a1659.648 1659.648 0 0 0 33.002667-66.005334c4.906667-9.792 12.224-12.842667 22.016-9.173333 9.770667 4.906667 13.44 12.224 10.986666 21.994667-3.669333 6.122667-9.173333 17.728-16.490666 34.837333-8.554667 15.893333-14.677333 27.52-18.346667 34.837333-4.885333 8.554667-12.821333 11.008-23.829333 7.338667z m201.664-25.664c-9.770667 4.885333-18.346667 2.432-25.664-7.338667a1138.56 1138.56 0 0 1-27.498667-44.010666c-4.885333-8.533333-3.050667-16.490667 5.504-23.829334 9.770667-3.669333 18.346667-1.216 25.664 7.338667l14.677333 21.994667c6.101333 9.770667 10.389333 17.109333 12.821334 21.994666 4.906667 8.554667 3.050667 16.512-5.504 23.850667z" fill="#333333" p-id="3955"></path><path d="M675.328 117.717333A425.429333 425.429333 0 0 0 512 85.333333C276.352 85.333333 85.333333 276.352 85.333333 512s191.018667 426.666667 426.666667 426.666667 426.666667-191.018667 426.666667-426.666667c0-56.746667-11.093333-112-32.384-163.328a21.333333 21.333333 0 0 0-39.402667 16.341333A382.762667 382.762667 0 0 1 896 512c0 212.074667-171.925333 384-384 384S128 724.074667 128 512 299.925333 128 512 128c51.114667 0 100.8 9.984 146.986667 29.12a21.333333 21.333333 0 0 0 16.341333-39.402667z" fill="#333333" p-id="3956"></path></svg>'),A(this,"refreshSvg",'<svg t="1760926993643" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5942" width="200" height="200"><path d="M511.966722 0a511.966722 511.966722 0 1 0 179.828311 32.445891l-22.46254 59.964102A447.970882 447.970882 0 1 1 511.966722 63.99584a31.99792 31.99792 0 0 0 0-63.99584z" fill="#333333" p-id="5943"></path><path d="M649.2378 9.151405A30.909991 30.909991 0 0 1 671.316364 0h193.267438a31.99792 31.99792 0 0 1 31.357962 31.99792c0 17.662852-13.759106 31.99792-31.357962 31.99792H703.954243v160.629559a31.99792 31.99792 0 0 1-31.99792 31.357962 31.485953 31.485953 0 0 1-31.99792-31.357962V31.357962c0-8.511447 3.647763-16.318939 9.343392-21.950573z" fill="#333333" p-id="5944"></path></svg>'),A(this,"blacklistSvg",'<svg t="1761386375897" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1936" width="200" height="200"><path d="M513.199827 65.667605c-246.537999 0-446.399933 199.861934-446.399933 446.399933 0 246.553349 199.861934 446.399933 446.399933 446.399933 246.553349 0 446.399933-199.846584 446.399933-446.399933C959.599759 265.529539 759.753175 65.667605 513.199827 65.667605zM513.199827 894.697075c-211.320916 0-382.629537-171.322947-382.629537-382.628514 0-94.183056 34.029024-180.417069 90.461291-247.080352l165.389818 165.389818c4.320399 39.651069 26.816762 73.840752 58.981323 94.068446-72.189136 27.369348-123.517151 97.156784-123.517151 178.936345l337.541643 0 100.846826 100.846826C693.608709 860.664981 607.375719 894.697075 513.199827 894.697075zM805.362956 759.14175 697.264982 651.0448c-16.556071-58.332547-60.10082-105.306394-116.275213-126.601396 35.888372-22.570042 59.752896-62.511729 59.752896-108.032482 0-70.436212-57.108672-127.542838-127.542838-127.542838-48.218188 0-90.184999 26.765597-111.865787 66.245773L266.120498 219.900316c66.663282-56.432267 152.897296-90.461291 247.079328-90.461291 211.304544 0 382.628514 171.308621 382.628514 382.629537C895.82834 606.244454 861.796246 692.476421 805.362956 759.14175z" fill="#272636" p-id="1937"></path></svg>'),A(this,"copySvg",'<svg t="1749017229420" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9184" width="200" height="200"><path d="M512 74.666667C270.933333 74.666667 74.666667 270.933333 74.666667 512S270.933333 949.333333 512 949.333333 949.333333 753.066667 949.333333 512 753.066667 74.666667 512 74.666667z m0 810.666666c-204.8 0-373.333333-168.533333-373.333333-373.333333S307.2 138.666667 512 138.666667 885.333333 307.2 885.333333 512 716.8 885.333333 512 885.333333z" fill="#666666" p-id="9185"></path><path d="M512 512m-42.666667 0a42.666667 42.666667 0 1 0 85.333334 0 42.666667 42.666667 0 1 0-85.333334 0Z" fill="#666666" p-id="9186"></path><path d="M341.333333 512m-42.666666 0a42.666667 42.666667 0 1 0 85.333333 0 42.666667 42.666667 0 1 0-85.333333 0Z" fill="#666666" p-id="9187"></path><path d="M682.666667 512m-42.666667 0a42.666667 42.666667 0 1 0 85.333333 0 42.666667 42.666667 0 1 0-85.333333 0Z" fill="#666666" p-id="9188"></path></svg>'),A(this,"titleSvg",'<svg t="1747553289744" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7507" width="200" height="200"><path d="M959.8 150.8c0-2.3-1.9-4.2-4.2-4.2H253.3c-2.3 0-4.2 1.9-4.2 4.2v115.9c0 2.3 1.9 4.2 4.2 4.2h702.3c2.3 0 4.2-1.9 4.2-4.2V150.8z" fill="" p-id="7508"></path><path d="M126.4 208.8m-62.2 0a62.2 62.2 0 1 0 124.4 0 62.2 62.2 0 1 0-124.4 0Z" fill="" p-id="7509"></path><path d="M851.5 453.7c0-2.1-1.8-3.9-3.9-3.9H252.9c-2.1 0-3.9 1.7-3.9 3.9v116.6c0 2.1 1.7 3.9 3.9 3.9h594.7c2.1 0 3.9-1.7 3.9-3.9V453.7z" fill="" p-id="7510"></path><path d="M126.4 512m-62.2 0a62.2 62.2 0 1 0 124.4 0 62.2 62.2 0 1 0-124.4 0Z" fill="" p-id="7511"></path><path d="M851.5 756.9c0-2.1-1.8-3.9-3.9-3.9H252.9c-2.1 0-3.9 1.8-3.9 3.9v116.6c0 2.1 1.7 3.9 3.9 3.9h594.7c2.1 0 3.9-1.7 3.9-3.9V756.9z" fill="" p-id="7512"></path><path d="M126.4 815.2m-62.2 0a62.2 62.2 0 1 0 124.4 0 62.2 62.2 0 1 0-124.4 0Z" fill="" p-id="7513"></path></svg>'),A(this,"carNumSvg",'<svg t="1747552574854" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3539" width="200" height="200"><path d="M920.337035 447.804932c-6.067182-6.067182-10.918677-11.643178-16.985859-17.71036l48.536436-30.334889-42.469254-109.207238-121.340579 12.134365c-6.067182-6.067182-6.067182-12.134365-12.134365-18.201547-12.134365-12.134365-18.201547-24.267706-24.267706-30.334889-24.26873-36.402071-30.334889-42.469254-54.603619-42.469254H339.116511c-18.201547 0-24.267706 6.067182-54.603619 42.469254-6.067182 6.067182-12.134365 18.201547-24.267706 30.334889 0 0-6.067182 6.067182-12.134365 18.201547l-115.27442-12.134365-48.536436 109.207238 51.090608 24.378223c-6.067182 6.067182-30.334889 34.660404-30.334889 34.660405l-15.542998 22.280446-12.282744 17.018605c-6.067182 12.134365-5.064342 10.868535-5.064342 29.070082v224.480635c0 36.402071 18.201547 60.670801 54.603618 60.670801h115.273397c36.402071 0 54.603619-24.267706 54.603619-54.603619v-18.201547h424.693562v18.201547c0 30.334889 18.201547 54.603619 54.603618 54.603619h115.273397c36.402071 0 60.670801-24.267706 60.670801-60.670801V539.300786c0-42.469254 0.685615-46.662763-11.44875-64.863287-4.731768-6.744611-11.94403-16.196891-20.101827-26.632567z m-35.186383-78.381161l-30.334889 18.201547-12.134365-12.134365c-6.067182-8.899694-12.134365-12.134365-12.134365-18.201547l42.469254-6.067183 12.134365 18.201548z m-533.899776-97.072873h339.755054l78.871325 103.140055H272.378527l78.872349-103.140055zM175.305655 357.290429h36.402071c-6.067182 6.067182-6.067182 12.134365-12.134365 18.201547l-18.201547 6.067183-18.201547-12.134365 12.135388-12.134365z m667.375743 394.35765h-54.603619V678.843936H242.043638v72.804143H132.837424V527.167444c0-12.134365-0.041956-20.662599 1.216711-23.556508 1.258667-2.89391 9.955746-16.924461 21.193695-29.173437l35.722596-38.276768h639.576607l21.917172 20.938891c6.067182 6.067182 21.847587 21.366633 25.712615 28.732392 7.621585 9.996678 6.973832 10.999518 13.041014 23.133883v242.682182h-48.536436zM242.043638 533.234627h133.474944v60.670801H242.043638v-60.670801z m412.559197 0h133.474944v60.670801H654.602835v-60.670801z" p-id="3540"></path></svg>'),A(this,"downSvg",'<svg t="1747552626242" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4551" width="200" height="200"><path d="M641.6 660l-8.64-64 32-4.32a211.2 211.2 0 0 0-26.72-420.32 215.36 215.36 0 0 0-213.12 192 94.56 94.56 0 0 0 0 11.52v41.28h-64V384v-7.04a153.12 153.12 0 0 1 0-19.52A279.84 279.84 0 0 1 636.16 108H640A275.2 275.2 0 0 1 673.28 656z" fill="#333333" p-id="4552"></path><path d="M490.4 446.24l-7.52-39.84a182.4 182.4 0 0 1 107.52-162.88l29.12-13.28L646.08 288l-29.12 13.28a117.92 117.92 0 0 0-70.08 101.28l6.24 30.4zM392.96 652.32h-78.72A202.24 202.24 0 0 1 256 256l30.72-9.12 18.24 61.28-30.72 9.12a138.24 138.24 0 0 0 39.68 270.72h78.72zM479.2 512h64v320h-64z" fill="#333333" p-id="4553"></path><path d="M510.4 908l-156.32-147.68 43.84-46.4 112.48 106.08 112.8-106.08 43.84 46.56-156.64 147.52z" fill="#333333" p-id="4554"></path></svg>'),A(this,"handleSvg",'<svg t="1749106236917" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2628" width="200" height="200"><path d="M838 989.48a32 32 0 0 1-22.5-9.22L519.3 687.6 207.48 980.8a32 32 0 0 1-54-23.32V136.52A98.54 98.54 0 0 1 252 38.1h519.6A98.52 98.52 0 0 1 870 136.52v820.96a32 32 0 0 1-32 32zM252 102.1a34.46 34.46 0 0 0-34.42 34.42v746.96L498 619.84a32 32 0 0 1 44.42 0.56L806 880.88V136.52a34.46 34.46 0 0 0-34.4-34.42z" p-id="2629"></path><path d="M648 604.92a28 28 0 0 1-16.46-5.34l-112.84-82-112.84 82a28 28 0 0 1-43.08-31.32l43.1-132.64-112.84-82a28 28 0 0 1 16.46-50.66h139.48L492 170.34a28 28 0 0 1 53.26 0l43.1 132.64h139.48a28 28 0 0 1 16.46 50.66l-112.84 82 43.1 132.64A28 28 0 0 1 648 604.92z m-129.3-150a27.86 27.86 0 0 1 16.46 5.36l59.58 43.28-22.76-70a28 28 0 0 1 10.02-31.28l59.58-43.3H568a28 28 0 0 1-26.64-19.34l-22.76-70-22.76 70a28 28 0 0 1-26.62 19.34h-73.64l59.58 43.3a28 28 0 0 1 10.16 31.3l-22.76 70 59.58-43.28a28 28 0 0 1 16.46-5.32z" p-id="2630"></path></svg>'),A(this,"siteSvg",'<svg t="1749107903569" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12439" width="200" height="200"><path d="M882.758621 133.674884C882.758621 59.84828 822.91034 0 749.083736 0 675.25715 0 615.40887 59.84828 615.40887 133.674884 615.40887 163.358402 625.152318 191.656395 642.813352 214.773283L670.872117 193.336726 648.314739 166.170836 253.911693 493.666092 276.469054 520.831982 302.371681 496.834595C277.256669 469.725608 241.995388 453.990153 204.295574 453.990153 130.46897 453.990153 70.62069 513.838433 70.62069 587.66502 70.62069 661.491624 130.46897 721.339904 204.295574 721.339904 255.555319 721.339904 301.619094 692.208675 324.036714 647.136344L276.646223 663.002394 706.082022 877.440106 721.856794 845.849335 690.37312 829.861888C680.932829 848.452414 675.940882 869.068818 675.940882 890.325116 675.940882 964.15172 735.789162 1024 809.615766 1024 883.442353 1024 943.290633 964.15172 943.290633 890.325116 943.290633 874.050807 940.36533 858.125365 934.723584 843.16446L868.645076 868.0826C871.294817 875.109252 872.669943 882.595452 872.669943 890.325116 872.669943 925.14899 844.439623 953.37931 809.615766 953.37931 774.791892 953.37931 746.561571 925.14899 746.561571 890.325116 746.561571 880.245089 748.902894 870.575616 753.340487 861.836782L769.436089 830.140063 737.631567 814.258564 308.195769 599.820853 276.554929 584.02108 260.805279 615.686903C250.212352 636.984797 228.494795 650.719214 204.295574 650.719214 169.4717 650.719214 141.241379 622.488894 141.241379 587.66502 141.241379 552.841163 169.4717 524.610842 204.295574 524.610842 222.12269 524.610842 238.680594 531.99985 250.566444 544.829369L273.29589 569.363385 299.026432 547.997855 693.429478 220.502616 719.514606 198.84265 698.930882 171.900169C690.596687 160.991373 686.029559 147.727007 686.029559 133.674884 686.029559 98.85101 714.25988 70.62069 749.083736 70.62069 783.90761 70.62069 812.137931 98.85101 812.137931 133.674884 812.137931 148.208022 807.249885 161.899255 798.379608 172.996785L853.543883 217.089695C872.331935 193.584128 882.758621 164.379366 882.758621 133.674884ZM749.083736 196.729062C729.149334 196.729062 710.818745 187.460449 698.930882 171.900169L642.813352 214.773283C667.922573 247.639305 706.904064 267.349751 749.083736 267.349751 790.225902 267.349751 828.357809 248.599782 853.543883 217.089695L798.379608 172.996785C786.455411 187.915034 768.530291 196.729062 749.083736 196.729062ZM337.970441 587.66502C337.970441 553.551854 325.093782 521.360666 302.371681 496.834595L250.566444 544.829369C261.309069 556.424898 267.349751 571.526356 267.349751 587.66502 267.349751 597.565263 265.091478 607.069184 260.805279 615.686903L324.036714 647.136344C333.156105 628.801148 337.970441 608.540036 337.970441 587.66502ZM809.615766 756.650249C758.753986 756.650249 712.986006 785.330865 690.37312 829.861888L753.340487 861.836782C764.027215 840.791658 785.603302 827.270938 809.615766 827.270938 836.08553 827.270938 859.461862 843.730308 868.645076 868.0826L934.723584 843.16446C915.252259 791.529949 865.714547 756.650249 809.615766 756.650249Z" fill="#389BFF" p-id="12440"></path></svg>'),A(this,"videoSvg",'<svg t="1749003664455" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1952" width="200" height="200"><path d="M825.6 153.6H198.4C124.5 153.6 64 214.1 64 288v448c0 73.9 60.5 134.4 134.4 134.4h627.2c73.9 0 134.4-60.5 134.4-134.4V288c0-73.9-60.5-134.4-134.4-134.4z m-138.2 44.8l112 112H706l-112-112h93.4z m-156.8 0l112 112H526.7l-112-112h115.9z m-179.2 0l112 112H347.5l-112-112h115.9zM108.8 288c0-41.4 28.4-76.1 66.7-86.3l108.7 108.7H108.8V288z m806.4 448c0 49.4-40.2 89.6-89.6 89.6H198.4c-49.4 0-89.6-40.2-89.6-89.6V355.2h806.4V736z m0-425.6h-52.5l-112-112h74.9c49.4 0 89.6 40.2 89.6 89.6v22.4z" p-id="1953"></path><path d="M454 687.2l149.3-77.6c27.5-13.8 27.5-53 0-66.8L468 472.2c-31.2-15.6-68 7.1-68 42v139.6c0 27.8 29.2 45.8 54 33.4zM444.8 512l134.4 67.2-134.4 67.2V512z" p-id="1954"></path></svg>'),A(this,"screenSvg",'<svg t="1750691468062" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2693" width="200" height="200"><path d="M288 160a64 64 0 0 0-64 64v576a64 64 0 0 0 64 64h448a64 64 0 0 0 64-64v-576a64 64 0 0 0-64-64h-448m0-64h448a128 128 0 0 1 128 128v576a128 128 0 0 1-128 128h-448a128 128 0 0 1-128-128v-576a128 128 0 0 1 128-128z" fill="#4078FD" p-id="2694"></path><path d="M416 352m-64 0a64 64 0 1 0 128 0 64 64 0 1 0-128 0Z" fill="#FE9C23" p-id="2695"></path><path d="M352 732.448a32 32 0 0 1-32-32v-160a32 32 0 0 1 44.224-29.568l130.112 53.632 153.952-169.984a32 32 0 0 1 55.712 21.472v284.448a32 32 0 0 1-32 32z m0-32h320z" fill="#4078FD" opacity=".2" p-id="2696"></path><path d="M672 416l-169.088 186.656-150.912-62.208v160h320V416m0-32a32 32 0 0 1 32 32v284.448a32 32 0 0 1-32 32h-320a32 32 0 0 1-32-32v-160a32 32 0 0 1 44.192-29.6l130.112 53.632 153.984-169.984a32 32 0 0 1 23.712-10.496z" fill="#4078FD" p-id="2697"></path></svg>'),A(this,"recoveryVideoSvg",'<svg t="1749003779161" class="jhs-icon icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8204" width="200" height="200"><path d="M938.666667 553.92V768c0 64.8-52.533333 117.333333-117.333334 117.333333H202.666667c-64.8 0-117.333333-52.533333-117.333334-117.333333V256c0-64.8 52.533333-117.333333 117.333334-117.333333h618.666666c64.8 0 117.333333 52.533333 117.333334 117.333333v297.92z m-64-74.624V256a53.333333 53.333333 0 0 0-53.333334-53.333333H202.666667a53.333333 53.333333 0 0 0-53.333334 53.333333v344.48A290.090667 290.090667 0 0 1 192 597.333333a286.88 286.88 0 0 1 183.296 65.845334C427.029333 528.384 556.906667 437.333333 704 437.333333c65.706667 0 126.997333 16.778667 170.666667 41.962667z m0 82.24c-5.333333-8.32-21.130667-21.653333-43.648-32.917333C796.768 511.488 753.045333 501.333333 704 501.333333c-121.770667 0-229.130667 76.266667-270.432 188.693334-2.730667 7.445333-7.402667 20.32-13.994667 38.581333-7.68 21.301333-34.453333 28.106667-51.370666 13.056-16.437333-14.634667-28.554667-25.066667-36.138667-31.146667A222.890667 222.890667 0 0 0 192 661.333333c-14.464 0-28.725333 1.365333-42.666667 4.053334V768a53.333333 53.333333 0 0 0 53.333334 53.333333h618.666666a53.333333 53.333333 0 0 0 53.333334-53.333333V561.525333zM320 480a96 96 0 1 1 0-192 96 96 0 0 1 0 192z m0-64a32 32 0 1 0 0-64 32 32 0 0 0 0 64z" fill="#000000" p-id="8205"></path></svg>');let t=["settingSvg","editSvg","deleteSvg","checkSvg","actressSvg","newSvg","refreshSvg","blacklistSvg","copySvg","titleSvg","carNumSvg","downSvg","handleSvg","siteSvg","videoSvg","screenSvg","recoveryVideoSvg"];it._sharedIcons=Object.fromEntries(t.map((s=>[s,this[s]]))),Object.assign(it.prototype,it._sharedIcons),t.forEach((s=>delete this[s]))}this.pluginManager=null,this.declaredDependencies=new Set,this.runtimeServices=Object.freeze({})}getName(){throw new Error(`${this.constructor.name} 未显示getName()`)}getDependency(e){if(!this.declaredDependencies.has(e)){let s=new Error(`${this.getName()} 未声明依赖 ${e}`);throw this.pluginManager?.recordDependencyError(this.getName(),e,s)||s}let t=this.pluginManager.resolveDeclaredPlugin(e);if(!t){let s=new Error(`Missing dependency: ${this.getName()} -> ${e}`);throw this.pluginManager?.recordDependencyError(this.getName(),e,s)||s}return t}getOptionalDependency(e){if(!this.declaredDependencies.has(e)){let t=new Error(`${this.getName()} 未声明依赖 ${e}`);throw this.pluginManager?.recordDependencyError(this.getName(),e,t)||t}return this.pluginManager.resolveDeclaredPlugin(e)}getRuntimeService(e){if(!Object.prototype.hasOwnProperty.call(this.runtimeServices,e))throw new Error(`${this.getName()} 未声明运行时依赖 ${e}`);return this.runtimeServices[e]}initCss(){return""}handle(){}getStartupMode(){return"immediate"}shouldSkipOnMobile(){return!1}getPageInfo(){let e=null,t,s,a,i,r=window.location.href;if(N){let n=new URL(r).searchParams,l=T(n.get("jhsCarNum")),c=T($('.column-video-info a[data-clipboard-text][title*="番"], .video-detail a[data-clipboard-text][title*="番"]').first().attr("data-clipboard-text"))||T($('a[title="複製番號"]').attr("data-clipboard-text")),h=null;$(".column-video-info .panel-block, .video-detail .panel-block").each((p,g)=>{let m=$(g),f=m.find("strong, .label").first().text().trim();h||!/(?:番号|番號|^ID)\s*[::]?/i.test(f)||(h=T(m.find("[data-clipboard-text]").first().attr("data-clipboard-text"))||T(m.find(".value").first().text()))});let u=T($("#video_id, .video-id, .video-title strong").first().text());e=Do(l,c,h,u),t=r.split("?")[0].split("#")[0],s=$(".female").prev().map(((p,g)=>$(g).text())).get().join(" "),a=$(".male").prev().map(((p,g)=>$(g).text())).get().join(" "),i=$('strong:contains("日期:")').parent(".panel-block").find(".value").text().trim()}return B&&(t=r.split("?")[0],e=T((t.split("/").filter(Boolean).pop()||"").replace(/_\d{4}-\d{2}-\d{2}$/,"")),s=$('span[onmouseover*="star_"] a').map(((n,l)=>$(l).text())).get().join(" "),a="",i=$('span.header:contains("發行日期:")').parent("p").text().trim().replace("發行日期:","").trim()),No({carNum:e,url:t,actress:s,actors:a,publishTime:i})}getActressId(){let e=Y.match(/\/actors\/([^/?]+)/);return e&&e.length>1?e[1]:null}getActressPageInfo(){let e=window.location.href;if(!e.includes("/actors/")&&!e.includes("/star/"))throw new Error("接口调用错误, 非演员详情页");let t=[],s=N?$(".actor-section-name"):$(".avatar-box .photo-info .pb10");s.length&&s.text().trim().split(",").forEach(h=>{t.push(h.trim())});let a=$(".section-meta:not(:contains('影片'))");a.length&&a.text().trim().split(",").forEach(h=>{t.push(h.trim())});let i=$(".section-meta:contains('男優')").length>0?Me:st,r=Je;t.some(h=>h.includes("無碼"))&&(r=Ke),e.includes("uncensored")&&(r=Ke);let n=null,l=null,c=new URL(e);if(N){l=c.pathname.split("/").filter(u=>u.trim()!=="").pop();let h=c.searchParams;h.delete("sort_type"),h.delete("page"),n=c.toString()}else if(B){let h="/star/",u=e.split(h);if(u.length<2)throw new Error("提取演员url失败");let p=u[0];l=u[1].split("/")[0],n=p+h+l}return{starId:l,name:t[0],allName:t,role:i,movieType:r,blacklistUrl:n}}getSelector(e){let t=e||(N?Be:B?je:null),s={javdb:{boxSelector:".movie-list",itemSelector:".movie-list .item",coverImgSelector:".cover img",requestDomItemSelector:".movie-list .item",nextPageSelector:".pagination-next"},javbus:{boxSelector:".masonry",itemSelector:".masonry .item",coverImgSelector:".masonry .movie-box .photo-frame img",requestDomItemSelector:"#waterfall .item",nextPageSelector:"#next"}},a=t;if(!a||!s[a])throw new Error("类型错误: 无法确定选择器类型 (JavDb 或 JavBus)");return s[a]}parseMovieId(e){return(e.split("/").pop()||"").split(/[?#]/)[0]}getBoxCarInfo(e){var t,s,a;let i=e.find("a"),r=i.attr("href"),n=null,l=null,c=null,h=e.find(".video-title");if(h.length>0){let u=h.find("strong");if(u.length>0&&(n=u.text().trim()),l=(t=i.attr("title"))==null?void 0:t.trim(),!l){let p=h.text().trim();l=n&&p.includes(n)?p.replace(n,"").trim():p}c=e.find(".meta").text().trim()}if(!n){let u=e.find("img");u.length>0&&(l=((s=u.attr("title"))==null?void 0:s.trim())||((a=u.attr("data-title"))==null?void 0:a.trim()));let p=e.find("date").map(((m,f)=>$(f).text().trim())).get(),g=d(m=>/^\d{4}-\d{1,2}-\d{1,2}$/.test(m),"s");c=p.find(g)||null,n=p.find(m=>!g(m))||null}if(!n){let u="提取番号信息失败: carNum 为空";throw clog.error("Error in getBoxCarInfo:",u,"Box Element:",e.get(0)),show.error(u),new Error(u)}return{carNum:n,url:r||"",title:l||"",publishTime:c||""}}getBoxCarInfoList(e=null){let t=e||$(this.getSelector().itemSelector);if(t.length===0)return clog.error("获取当前列表页所有item的番号信息失败!"),[];let s=[];return t.each(((a,i)=>{let r=$(i);try{let n=this.getBoxCarInfo(r);s.push(n)}catch(n){let l=n;clog.error("[getBoxCarInfoList] 提取单个 boxCar 信息失败:",l?.message||String(n),"元素索引:",a)}})),s}checkDuplicateCarNumbers(e,t){if(!e||e.length===0||!t||t.length===0)return!1;let s=new Set(e.map((i=>i.carNum)).filter((i=>i)));if(s.size===0)return!1;let a=0;for(let i=0;i<t.length;i++){let r=t[i]?t[i].carNum:null;if(r&&s.has(r)){if(a++,a>=2)return clog.warn("警告: 检测到连续番号信息重复, 该类别可能已被限制页码。"),!0}else a=0}return!1}};d(it,"BasePlugin"),lt(it,"_sharedIcons",null);var I=it;var Ui=class Ui{constructor({utils:e,storageManager:t}){this.utils=e,this.storageManager=t,this._circuitBreakers=new Map,this._domainStats=new Map}_getDomain(e){try{return new URL(e).hostname}catch{return"unknown"}}_isCloudflareChallenge(e,t=0){if(typeof e!="string"||!e)return!1;let s=e.toLowerCase(),a=/<title[^>]*>\s*just a moment(?:\.\.\.)?\s*<\/title>/i.test(e),i=/id=["']challenge-form["']/i.test(e),r=s.includes("cf-chl-")||s.includes("cf_chl_opt"),n=s.includes("/cdn-cgi/challenge-platform/")||s.includes("challenge-platform");return a||i&&(r||n)||(t===403||t===429||t===503)&&r&&n}_checkCircuitBreaker(e){let t=this._circuitBreakers.get(e);if(!t)return null;if(t.state==="open"){let s=Date.now()-t.openTime;return s<t.cooldownMs?{state:"open",remaining:Math.ceil((t.cooldownMs-s)/1e3)}:(t.state="half-open",t.failCount=0,t.probing=!1,null)}return t.state==="half-open"&&t.probing?{state:"half-open",remaining:0}:null}isDomainCircuitBroken(e){return this._checkCircuitBreaker(this._getDomain(e))}_recordSuccess(e){let t=this._circuitBreakers.get(e);t&&(t.state="closed",t.failCount=0,t.probing=!1);let s=this._domainStats.get(e);s||(s={count:0,errors:0,lastUsed:0},this._domainStats.set(e,s)),s.count++,s.lastUsed=Date.now()}_recordFailure(e,{affectsBreaker:t=!0}={}){let s=this._circuitBreakers.get(e);s&&t&&(s.failCount++,(s.state==="half-open"||s.failCount>=(s.threshold||3))&&(s.state="open",s.openTime=Date.now(),s.probing=!1,clog.warn(`[熔断] ${e} 连续失败 ${s.failCount} 次,已熔断 ${s.cooldownMs/1e3} 秒`)));let a=this._domainStats.get(e);a||(a={count:0,errors:0,lastUsed:0},this._domainStats.set(e,a)),a.count++,a.errors++,a.lastUsed=Date.now()}getCircuitBreakerStatus(){let e={};return this._circuitBreakers.forEach(((t,s)=>{e[s]={...t}})),e}resetCircuitBreaker(e){this._circuitBreakers.delete(e)}resetAllCircuitBreakers(){this._circuitBreakers.clear()}getDomainStats(){let e={};return this._domainStats.forEach(((t,s)=>{e[s]={...t}})),e}clearDomainStats(){this._domainStats.clear()}async get(e,t={},s={},a,i={}){return this.gmRequest("GET",e,null,t,s,a,i)}post(e,t={},s={}){s={"Content-Type":"application/json",...s};let a=JSON.stringify(t);return this.gmRequest("POST",e,a,null,s)}async gmRequest(e,t,s={},a={},i={},r=!1,n={}){if(a&&Object.keys(a).length){let b=new URLSearchParams(a).toString();t+=(t.includes("?")?"&":"?")+b}let l=this._getDomain(t),[c,h,u,p]=await Promise.all([this.storageManager.getSetting("httpTimeout",5e3),this.storageManager.getSetting("httpRetryCount",3),this.storageManager.getSetting("circuitBreakerThreshold",3),this.storageManager.getSetting("circuitBreakerCooldown",6e4)]),g=this._circuitBreakers.get(l);g||(g={state:"closed",failCount:0,openTime:0,cooldownMs:p,threshold:u,probing:!1},this._circuitBreakers.set(l,g)),g.threshold=Math.max(1,Number(u)||3),g.cooldownMs=Math.max(1e3,Number(p)||6e4);let m=this._checkCircuitBreaker(l);if(m){let b=new Error(`站点 ${l} 已熔断,${m.remaining}秒后重试`);throw b._circuitBroken=!0,b}let f=!1,v=d(b=>{b&&!f?(f=!0,this._recordFailure(l,{affectsBreaker:!0})):this._recordFailure(l,{affectsBreaker:!1})},"recordBreakerFailure");return s||(s=void 0),await this.utils.retry(()=>{let b=this._checkCircuitBreaker(l);if(b){let w=new Error(`站点 ${l} 已熔断,${b.remaining}秒后重试`);return w._circuitBroken=!0,Promise.reject(w)}return g.state==="half-open"&&(g.probing=!0),new Promise((w,S)=>{globalThis.GM_xmlhttpRequest({method:e,url:t,headers:i,timeout:c,data:s,...n.cookiePartitionTopLevelSite?{cookiePartition:{topLevelSite:n.cookiePartitionTopLevelSite}}:{},onload:d(j=>{try{if(j.status===404&&n.ignoreNotFound)return void w(null);if(this._isCloudflareChallenge(j.responseText,j.status)){v(!0);let k=new Error(`Cloudflare challenge blocked: ${t}`);return k._cfBlocked=!0,k.status=j.status,k.requestUrl=t,k.finalUrl=j.finalUrl,k.cfDiagnostics={status:j.status,requestUrl:t,finalUrl:j.finalUrl,contentLength:j.responseText?.length||0},void S(k)}if(r&&j.finalUrl!==t&&S("请求被重定向了,URL是:"+j.finalUrl),j.status>=200&&j.status<300)if(this._recordSuccess(l),j.responseText)try{w(JSON.parse(j.responseText))}catch{w(j.responseText)}else w(j.responseText||j);else if(clog.error("请求失败,状态码:",j.status,t),v(j.status>=500),j.responseText)try{let k=JSON.parse(j.responseText);k.status=j.status,S(k)}catch{let k=new Error(j.responseText||`请求发生错误 ${j.status}`);k.status=j.status,S(k)}else{let k=new Error(`请求发生错误 ${j.status}`);k.status=j.status,S(k)}}catch(k){v(!0),S(k)}},"onload"),onerror:d(j=>{clog.error("网络错误:",t),v(!0),S(new Error(j.error||"网络错误"))},"onerror"),ontimeout:d(()=>{v(!0),S(new Error("请求超时: "+t))},"ontimeout")})})},h)}};d(Ui,"GmHttp");var js=Ui;var ih=1e3,Zo=1e4,rh=30*864e5;function le(o){return o==null?o:JSON.parse(JSON.stringify(o))}d(le,"cloneStateValue");function Se(o){return o===null||typeof o!="object"?JSON.stringify(o):Array.isArray(o)?`[${o.map(Se).join(",")}]`:`{${Object.keys(o).sort().map((e=>`${JSON.stringify(e)}:${Se(o[e])}`)).join(",")}}`}d(Se,"stableStateValue");async function nh(o){let e=globalThis.crypto?.subtle;if(!e)throw new Error("当前环境不支持状态冲突归档哈希");let t=new TextEncoder().encode(Se(o)),s=await e.digest("SHA-256",t);return Array.from(new Uint8Array(s),(a=>a.toString(16).padStart(2,"0"))).join("")}d(nh,"hashState");function Fi(o,e){return e.split(".").reduce(((t,s)=>t?.[s]),o)}d(Fi,"getStatePath");function oh(o,e,t){let s=e.split("."),a=s.pop(),i=s.reduce(((r,n)=>r[n]||(r[n]={})),o);a&&(t===void 0?delete i[a]:i[a]=le(t))}d(oh,"setStatePath");function qt(o){return[...new Set(o.filter((e=>typeof e=="string"&&!!e)))]}d(qt,"uniqueStateKeys");function Vi(o,e,t){let s=T(t),a=[];return o.forEach(((i,r)=>(i.newVideoList||[]).forEach(((n,l)=>{T(typeof n=="string"?n:n.carNum)===s&&a.push({actressIndex:r,itemIndex:l,item:le(n)})})))),{actressItems:a,decision:le(e[s]||null)}}d(Vi,"captureNewVideoEffect");function lh(o,e,t,s,a=null){let i=T(t);return Se(e[i]||null)!==Se(a)?!1:s.actressItems.every((r=>!(o[r.actressIndex]?.newVideoList||[]).some(n=>T(typeof n=="string"?n:n.carNum)===i)))}d(lh,"canRestoreNewVideoEffect");function Xo(o,e,t,s){s.actressItems.forEach((i=>{let r=o[i.actressIndex];if(!r)return;let n=[...r.newVideoList||[]],l=Math.min(i.itemIndex,n.length);n.splice(l,0,le(i.item)),r.newVideoList=n}));let a=T(t);s.decision?e[a]=le(s.decision):delete e[a]}d(Xo,"restoreNewVideoEffect");function Ss(o,e=Date.now()){let t={entries:Array.isArray(o?.entries)?o.entries:[],trackingStartedAt:o?.trackingStartedAt||new Date(e).toISOString(),coverageStart:o?.coverageStart||null,truncatedAt:o?.truncatedAt||null},s=e-rh,a=[],i=[];t.entries.forEach((n=>(Date.parse(n.createdAt)>=s||n.commitState==="pending"?a:i).push(n))),i.sort(((n,l)=>String(n.createdAt).localeCompare(String(l.createdAt)))),a.sort(((n,l)=>String(n.createdAt).localeCompare(String(l.createdAt))));let r=Math.max(0,ih-a.length);if(t.entries=[...i.slice(-r),...a].sort(((n,l)=>String(n.createdAt).localeCompare(String(l.createdAt)))),t.entries.length>Zo){let n=t.entries.filter((h=>h.commitState==="pending")),l=t.entries.filter((h=>h.commitState!=="pending")),c=Math.max(0,Zo-n.length);t.entries=[...c?l.slice(-c):[],...n].sort(((h,u)=>String(h.createdAt).localeCompare(String(u.createdAt)))),t.truncatedAt=new Date(e).toISOString(),t.coverageStart=t.entries[0]?.createdAt||t.truncatedAt}return t}d(Ss,"pruneActivityLog");var Hi=class Hi{constructor(e,t){this.storage=e,this.eventBus=t,this._queue=Promise.resolve(),this._recovering=!1}_withLock(e){let t=globalThis.navigator?.locks;if(t)return t.request("jhs_state_mutation",e);let s=this._queue.then(e,e);return this._queue=s.catch((()=>{})),s}async getActivityLog(){return Ss(await this.storage.forage.getItem("activity_log"))}async getOfflineHistory(){return await this.storage.forage.getItem("offline_history")||[]}async appendOfflineHistory(e){return this._withLock(async()=>{let t=await this.getOfflineHistory(),s={id:e.id||globalThis.crypto?.randomUUID?.()||`offline_${Date.now()}`,createdAt:e.createdAt||new Date().toISOString(),...e,carNum:T(e.carNum)};t.push(s),t.length>1e3&&t.splice(0,t.length-1e3),await this.storage.forage.setItem("offline_history",t);try{await this.eventBus.emit("offline-history-changed",{ids:[s.id]})}catch{globalThis.console?.warn("[JHS] 离线历史已保存,通知失败")}return s})}async removeOfflineHistory(e){return this._withLock(async()=>{let t=new Set(Array.isArray(e)?e:[e]),s=await this.getOfflineHistory(),a=s.filter((i=>!t.has(i.id)));return a.length===s.length?!1:(await this.storage.forage.setItem("offline_history",a),await this.eventBus.emit("offline-history-changed",{ids:[...t],removed:!0}),!0)})}async getNewVideoDecisions(){return await this.storage.forage.getItem("new_video_decisions")||{}}async getState(e){let t=T(e);if(!t)return null;let s=await this.storage.getCar(t);return s?le(s):null}async _readDomains(e=null){let t=new Set(e??["carList","actresses","decisions","activity"]),s=d((l,c,h)=>t.has(l)?this.storage.forage.getItem(c):Promise.resolve(h),"read"),[a,i,r,n]=await Promise.all([s("carList",this.storage.car_list_key,[]),s("actresses",this.storage.favorite_actresses_key,[]),s("decisions","new_video_decisions",{}),s("activity","activity_log",null)]);return{carList:a||[],actresses:i||[],decisions:r||{},activity:Ss(n)}}_removeHandledNewVideos(e,t,s){let a=new Set(qt(s.map(T))),i={...t};return a.forEach((n=>delete i[n])),{actresses:e.map((n=>{if(!Array.isArray(n.newVideoList))return n;let l=n.newVideoList.filter((c=>!a.has(T(typeof c=="string"?c:c.carNum))));return l.length===n.newVideoList.length?n:{...n,newVideoList:l}})),decisions:i}}async _writeActivity(e){await this.storage.forage.setItem("activity_log",Ss(e))}async _commit(e,t,s,a=["carList","activity"]){let i=le(s),r={...e.activity,entries:[...e.activity.entries,i]},n=[...new Set([...a,"activity"])],l=d((h,u=!1)=>Object.fromEntries(n.map(p=>[p,le(p==="activity"&&u?r:h[p])])),"select"),c={schema:2,id:s.id,state:"prepared",createdAt:s.createdAt,touchedDomains:n,before:l(e),after:l(t,!0)};await this.storage.forage.setItem("mutation_journal",c);try{n.includes("carList")&&await this.storage._setItemAndInvalidate(this.storage.car_list_key,t.carList),n.includes("activity")&&await this._writeActivity(r),n.includes("actresses")&&await this.storage._setItemAndInvalidate(this.storage.favorite_actresses_key,t.actresses),n.includes("decisions")&&await this.storage.forage.setItem("new_video_decisions",t.decisions),s.commitState="committed",r.entries=r.entries.map((h=>h.id===s.id?s:h)),await this._writeActivity(r),await this.storage.forage.removeItem("mutation_journal"),this.storage._invalidateCache()}catch(h){throw await this._recoverJournal(c),h}}async _recoverJournal(e){let t=await this.getActivityLog(),s=t.entries.find((i=>i.id===e.id)),a=Array.isArray(e.touchedDomains)?e.touchedDomains:["carList","actresses","decisions","activity"];if(s?.commitState==="committed")a.includes("carList")&&await this.storage._setItemAndInvalidate(this.storage.car_list_key,e.after.carList),a.includes("actresses")&&await this.storage._setItemAndInvalidate(this.storage.favorite_actresses_key,e.after.actresses),a.includes("decisions")&&await this.storage.forage.setItem("new_video_decisions",e.after.decisions);else{let i=await this._readDomains(a),r=a.filter(l=>l!=="activity");if(r.some((l=>{let c=Se(i[l]);return c!==Se(e.before[l])&&c!==Se(e.after[l])}))){let l={journal:le(e),detectedAt:new Date().toISOString(),currentStateHash:await nh(Object.fromEntries(r.map(c=>[c,i[c]])))};try{let c=await this.storage.forage.getItem("mutation_journal_conflicts")||[];c.push(l),c.length>20&&c.splice(0,c.length-20),await this.storage.forage.setItem("mutation_journal_conflicts",c),await this.storage.forage.removeItem("mutation_journal"),this.storage._invalidateCache()}catch(c){throw clog.error("[状态] 冲突事务归档失败,保留原事务日志",c),c}clog.warn("[状态] 检测到未完成状态事务且数据已变化,已归档证据并保留当前数据"),show.info("检测到未完成的状态事务,已保留当前数据并归档冲突证据");return}a.includes("carList")&&await this.storage._setItemAndInvalidate(this.storage.car_list_key,e.before.carList),a.includes("actresses")&&await this.storage._setItemAndInvalidate(this.storage.favorite_actresses_key,e.before.actresses),a.includes("decisions")&&await this.storage.forage.setItem("new_video_decisions",e.before.decisions),e.before.activity?await this._writeActivity(e.before.activity):(t.entries=t.entries.filter((l=>l.id!==e.id)),await this._writeActivity(t))}await this.storage.forage.removeItem("mutation_journal"),this.storage._invalidateCache()}async _recoverWithoutLock(){let e=await this.storage.forage.getItem("mutation_journal");return e?(await this._recoverJournal(e),!0):!1}async recoverPendingTransaction(){return this._withLock((()=>this._recoverWithoutLock()))}async patch(e,t,s={}){let a=qt((Array.isArray(e)?e:[e]).map(T));if(!a.length)throw new Error("番号为空");let i=Object.keys(t).find((r=>!ct.includes(r)||typeof t[r]!="boolean"));if(i)throw new TypeError(`无效状态字段: ${i}`);return this._withLock((()=>this._patchWithoutLock(a,t,s)))}async _patchWithoutLock(e,t,s){await this._recoverWithoutLock();let a=await this._readDomains(),i=new Map(a.carList.map((u=>[T(u.carNum),u]))),r=[],n=[],l=Array.isArray(s.records)?new Map(s.records.map((u=>[T(u.carNum),u]))):new Map;if(e.forEach((u=>{let p=i.get(u),g=l.get(u)||s.record||{},m=utils.getNowStr(),f=p?le(p):null,v=p?{...p,stateFlags:q(p.stateFlags)}:{carNum:u,url:g.url||window.location.href,names:g.names||"",createDate:m,stateFlags:Ht()},b=[];["url","names","publishTime","starId","remark","fc2Source"].forEach((w=>{w==="fc2Source"&&!["fc2","123av"].includes(g[w])||!Object.prototype.hasOwnProperty.call(g,w)||g[w]==null||!s.replaceMetadata&&g[w]===""||v[w]===g[w]||(v[w]=g[w],b.push(w))})),ct.forEach((w=>Object.prototype.hasOwnProperty.call(t,w)&&v.stateFlags[w]!==t[w]&&(t[w]&&n.push(u),v.stateFlags[w]=t[w],b.push(`stateFlags.${w}`)))),!(!b.length&&p)&&(v.updateDate=m,vs(v),i.set(u,v),r.push({carNum:u,operation:p?"patch":"create",fields:b,before:f,after:le(v),undoState:"pending"}))})),!r.length)return{changed:[],transactionId:null};r.forEach((u=>n.includes(u.carNum)&&(u.newVideoEffect=Vi(a.actresses,a.decisions,u.carNum))));let c=this._removeHandledNewVideos(a.actresses,a.decisions,n),h={id:globalThis.crypto?.randomUUID?.()||`activity_${Date.now()}`,type:s.type||"state-patch",commitState:"pending",changes:r,createdAt:new Date().toISOString(),undoAttemptedAt:null};return await this._commit(a,{carList:[...i.values()],...c},h,n.length?["carList","actresses","decisions","activity"]:["carList","activity"]),await this.eventBus.emit("car-state-changed",{carNums:r.map((u=>u.carNum)),transactionId:h.id}),n.length&&await this.eventBus.emit("new-video-changed",{carNums:[...new Set(n)],reason:"state-handled"}),await this.eventBus.emit("activity-log-changed",{transactionId:h.id}),{changed:r.map((u=>u.carNum)),transactionId:h.id}}async toggle(e,t,s={}){if(!ct.includes(t))throw new TypeError(`无效状态字段: ${t}`);let a=T(e);if(!a)throw new Error("番号为空");return this._withLock(async()=>{await this._recoverWithoutLock();let i=await this.storage.getCar(a),r=q(i?.stateFlags);return this._patchWithoutLock([a],{[t]:!r[t]},s)})}async remove(e){let t=new Set(qt((Array.isArray(e)?e:[e]).map(T)));return this._withLock(async()=>{await this._recoverWithoutLock();let s=await this._readDomains(),a=s.carList.filter(r=>t.has(T(r.carNum))).map(r=>({carNum:T(r.carNum),operation:"delete",fields:["record"],before:le(r),after:null,undoState:"pending"}));if(!a.length)return{changed:[],transactionId:null};let i={id:globalThis.crypto?.randomUUID?.()||`activity_${Date.now()}`,type:"record-delete",commitState:"pending",changes:a,createdAt:new Date().toISOString(),undoAttemptedAt:null};return await this._commit(s,{carList:s.carList.filter(r=>!t.has(T(r.carNum))),actresses:s.actresses,decisions:s.decisions},i,["carList","activity"]),await this.eventBus.emit("car-records-removed",{carNums:a.map(r=>r.carNum),transactionId:i.id}),await this.eventBus.emit("activity-log-changed",{transactionId:i.id}),{changed:a.map(r=>r.carNum),transactionId:i.id}})}async setNewVideoDecision(e,t,s=null){if(!["ignored","snoozed","dismissed",null].includes(t))throw new TypeError("无效新作决策");let a=qt((Array.isArray(e)?e:[e]).map(T));return this._withLock(async()=>{await this._recoverWithoutLock();let i=await this._readDomains(),r={...i.decisions},n=new Date().toISOString(),l=[];if(a.forEach((u=>{let p=le(r[u]||null),g=t?{action:t,until:t==="snoozed"?s:null,createdAt:p?.createdAt||n,updatedAt:n}:null;Se(p)===Se(g)||(g?r[u]=g:delete r[u],l.push({carNum:u,operation:"new-video-decision",fields:["decision"],before:p,after:g,undoState:"pending"}))})),!l.length)return{changed:[],transactionId:null};let c={id:globalThis.crypto?.randomUUID?.()||`activity_${Date.now()}`,type:"new-video-decision",commitState:"pending",changes:l,createdAt:n,undoAttemptedAt:null},h=l.map((u=>u.carNum));return await this._commit(i,{carList:i.carList,actresses:i.actresses,decisions:r},c,["decisions","activity"]),await this.eventBus.emit("new-video-changed",{carNums:h,reason:t||"decision-restored"}),await this.eventBus.emit("activity-log-changed",{transactionId:c.id}),{changed:h,transactionId:c.id}})}async removeFromNewVideoList(e,t="manual"){let s=qt((Array.isArray(e)?e:[e]).map(T));return this._withLock(async()=>{await this._recoverWithoutLock();let a=await this._readDomains(),i=s.filter((u=>{let p=Vi(a.actresses,a.decisions,u);return p.actressItems.length>0||!!p.decision&&p.decision.action!=="dismissed"}));if(!i.length)return{changed:[],transactionId:null};let r=new Date().toISOString(),n={...a.decisions},l=i.map((u=>{let p=Vi(a.actresses,a.decisions,u),g={action:"dismissed",until:null,createdAt:p.decision?.createdAt||r,updatedAt:r};return n[u]=g,{carNum:u,operation:"new-video-remove",fields:["newVideoList","decision"],before:null,after:{removed:!0,reason:t},newVideoEffect:p,afterDecision:g,undoState:"pending"}})),c=this._removeHandledNewVideos(a.actresses,a.decisions,i),h={id:globalThis.crypto?.randomUUID?.()||`activity_${Date.now()}`,type:"new-video-remove",commitState:"pending",changes:l,createdAt:r,undoAttemptedAt:null};return await this._commit(a,{carList:a.carList,actresses:c.actresses,decisions:n},h,["actresses","decisions","activity"]),await this.eventBus.emit("new-video-changed",{carNums:i,reason:t}),await this.eventBus.emit("activity-log-changed",{transactionId:h.id}),{changed:i,transactionId:h.id}})}async undoTransaction(e){return this._withLock(async()=>{await this._recoverWithoutLock();let t=await this._readDomains(),s=le(t),a=s.activity.entries.find((v=>v.id===e&&v.commitState==="committed"));if(!a)throw new Error("操作记录不存在或尚未提交");let i=new Map(s.carList.map((v=>[T(v.carNum),le(v)]))),r={...s.decisions},n=le(s.actresses),l=[],c=[],h=new Set(["activity"]);for(let v of a.changes){if(v.undoState==="reverted")continue;let b=i.get(v.carNum);if(v.newVideoEffect&&!lh(n,r,v.carNum,v.newVideoEffect,v.afterDecision??null)){v.undoState="conflict",c.push(v.carNum);continue}if(v.operation==="delete"){b?(v.undoState="conflict",c.push(v.carNum)):(i.set(v.carNum,le(v.before)),v.undoState="reverted",l.push(v.carNum),h.add("carList"));continue}if(v.operation==="new-video-decision"){let w=r[v.carNum]||null;Se(w)!==Se(v.after)?(v.undoState="conflict",c.push(v.carNum)):(v.before?r[v.carNum]=le(v.before):delete r[v.carNum],v.undoState="reverted",l.push(v.carNum),h.add("decisions"));continue}if(v.operation==="new-video-remove"){Xo(n,r,v.carNum,v.newVideoEffect),v.undoState="reverted",l.push(v.carNum),h.add("actresses"),h.add("decisions");continue}if(!["patch","create"].includes(v.operation)||!b||v.fields.some((w=>Se(Fi(b,w))!==Se(Fi(v.after,w))))){v.undoState="conflict",c.push(v.carNum);continue}v.operation==="create"&&!v.before?i.delete(v.carNum):(v.fields.forEach((w=>oh(b,w,Fi(v.before,w)))),vs(b),i.set(v.carNum,b)),h.add("carList"),v.newVideoEffect&&(Xo(n,r,v.carNum,v.newVideoEffect),h.add("actresses"),h.add("decisions")),v.undoState="reverted",l.push(v.carNum)}a.undoAttemptedAt=new Date().toISOString();let u=Ss(s.activity),p=[...i.values()],g=[...h],m=d(v=>Object.fromEntries(g.map(b=>[b,le(v[b])])),"select"),f={schema:2,id:`undo_${e}`,state:"prepared",createdAt:a.undoAttemptedAt,touchedDomains:g,before:m(t),after:m({carList:p,actresses:n,decisions:r,activity:u})};try{await this.storage.forage.setItem("mutation_journal",f),h.has("carList")&&await this.storage._setItemAndInvalidate(this.storage.car_list_key,p),h.has("actresses")&&await this.storage._setItemAndInvalidate(this.storage.favorite_actresses_key,n),h.has("decisions")&&await this.storage.forage.setItem("new_video_decisions",r),await this._writeActivity(u),await this.storage.forage.removeItem("mutation_journal"),this.storage._invalidateCache()}catch(v){throw await this._recoverWithoutLock(),v}return l.length&&await this.eventBus.emit("car-state-changed",{carNums:l,undoOf:e}),await this.eventBus.emit("activity-log-changed",{transactionId:e,undo:!0}),{reverted:l,conflicts:c}})}};d(Hi,"StateService");var xs=Hi;function el(o,e){e.stateService=o}d(el,"attachStateServiceCompatibility");function qi(o,e){return new Map(o.filter((t=>t&&t[e])).map((t=>[t[e],t])))}d(qi,"createIndexedMap");function tl(o){let e={[ce]:new Set,[ue]:new Set,[pe]:new Set,[me]:new Set};return o.forEach((t=>{if(!t?.carNum)return;let s=q(t.stateFlags);s.blocked&&e[ce].add(t.carNum),s.favorite&&e[ue].add(t.carNum),s.downloaded&&e[pe].add(t.carNum),s.watched&&e[me].add(t.carNum)})),e}d(tl,"createStatusMap");function sl(o,e){let t=new Map;return o.forEach((s=>{let a=s&&s[e];a&&t.set(a,(t.get(a)||0)+1)})),Array.from(t.entries()).filter((s=>s[1]>1))}d(sl,"groupDuplicateItems");function al(o,e){let t=new Map,s=[],a=!1;for(let i of o){let r=i&&i[e];if(!r){s.push(i);continue}let n=t.get(r);n?(Object.assign(n,i),a=!0):(t.set(r,i),s.push(i))}return{list:s,changed:a}}d(al,"dedupeByKey");var Wi="filter_keyword_review",Ji="review_filter_keyword",il=Promise.resolve();function Wt(o,e){let t=d(async()=>{let a=await o.get(Wi),i=await o.get(Ji),r=[...new Set([...Array.isArray(a)?a.map(String):[],...Array.isArray(i)?i.map(String):[],...e==null?[]:[e]])];if(JSON.stringify(a??[])!==JSON.stringify(r)&&(await o.set(Wi,r),JSON.stringify(await o.get(Wi))!==JSON.stringify(r)))throw new Error("评论关键词回读失败");return Array.isArray(i)&&JSON.stringify(await o.get(Ji))===JSON.stringify(i)&&await o.remove?.(Ji),r},"write"),s=il.then(async()=>{let a=globalThis.navigator?.locks;return a?.request?await a.request("jhs_keyword_lock",t):await t()});return il=s.then(()=>{},()=>{}),s}d(Wt,"readReviewKeywords");var Ki=new WeakSet,rl=d(async function(o,e,t){let s,a=globalThis.navigator?.locks,i=d(async()=>{if(Array.isArray(o))s=[...o];else{let r=await this.forage.getItem(e)||[];if(r.includes(o)){let n=`${o} ${t}已存在`;throw show.error(n),new Error(n)}r.push(o),s=r}return await this._setItemAndInvalidate(e,s),s},"write");return a?.request?a.request("jhs_keyword_lock",i):i()},"t"),Jt=class Jt{constructor(){this.stateService=globalThis.stateService??null;var e,t,s;if(e=this,(t=Ki).has(e)?Ei("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,s),A(this,"car_list_key","car_list"),A(this,"filter_keyword_title_key","filter_keyword_title"),A(this,"filter_keyword_review_key","filter_keyword_review"),A(this,"setting_key","setting"),A(this,"blacklist_key","blacklist"),A(this,"blacklist_car_list_key","blacklist_car_list"),A(this,"third_party_cache_key","third_party_ttl_cache"),A(this,"favorite_actresses_key","favorite_actresses"),A(this,"highlighted_tags_key","highlighted_tags"),A(this,"_actressLock",Promise.resolve()),A(this,"forage",localforage.createInstance({driver:localforage.INDEXEDDB,name:"JAV-JHS",version:1,storeName:"appData"})),A(this,"cacheCarList",null),A(this,"cacheBlacklist",null),A(this,"cacheTitleFilterKeyword",null),A(this,"cacheFavoriteActresses",null),A(this,"cache_filter_actor_actress_car_list",null),A(this,"cacheSettingObj",null),A(this,"cacheCarMap",null),A(this,"cacheStatusMap",null),A(this,"cacheBlacklistMap",null),A(this,"_pendingReads",new Map),A(this,"_cacheGenerations",new Map),A(this,"_cacheStats",{hits:0,misses:0}),Jt.instance)throw new Error("StorageManager已被实例化过了!");Jt.instance=this}async getDataVersion(){return await this.forage.getItem("data_version")||0}async setDataVersion(e){await this.forage.setItem("data_version",e)}_getCacheGeneration(e){return this._cacheGenerations.get(e)||0}_invalidateRead(e){this._cacheGenerations.set(e,this._getCacheGeneration(e)+1),this._pendingReads.delete(e)}async _readCached(e,t,s){if(this[e]!==null)return this[e];let a=this._pendingReads.get(t);if(a)return a;let i=this._getCacheGeneration(t),r=this.forage.getItem(t).then(n=>{let l=n||s;return i===this._getCacheGeneration(t)&&this[e]===null&&(this[e]=l),l}).finally(()=>{this._pendingReads.get(t)===r&&this._pendingReads.delete(t)});return this._pendingReads.set(t,r),r}_invalidateCache(e=null){let t=[this.car_list_key,this.blacklist_key,this.filter_keyword_title_key,this.favorite_actresses_key,this.blacklist_car_list_key,this.setting_key];(e===null?t:t.includes(e)?[e]:[]).forEach((s=>this._invalidateRead(s))),(!e||e===this.car_list_key)&&(this.cacheCarList=null,this.cacheCarMap=null,this.cacheStatusMap=null),(!e||e===this.blacklist_key)&&(this.cacheBlacklist=null,this.cacheBlacklistMap=null),(!e||e===this.filter_keyword_title_key)&&(this.cacheTitleFilterKeyword=null),(!e||e===this.favorite_actresses_key)&&(this.cacheFavoriteActresses=null),(!e||e===this.blacklist_car_list_key)&&(this.cache_filter_actor_actress_car_list=null),(!e||e===this.setting_key)&&(this.cacheSettingObj=null)}async _setItemAndInvalidate(e,t){await this.forage.setItem(e,t),this._invalidateCache(e)}async _withCrossTabLock(e,t){let s=globalThis.navigator?.locks;return s?.request?s.request(e,t):t()}async withActressLock(e){return this._withCrossTabLock("jhs_actress_lock",async()=>{let t,s=new Promise(i=>t=i),a=this._actressLock;this._actressLock=this._actressLock.then(()=>s),await a;try{return await e()}finally{t()}})}async _rawUpdateFavoriteActress(e){let t=await this.getFavoriteActressList(),{starId:s,name:a,allName:i,avatar:r,lastCheckTime:n,newVideoList:l,lastPublishTime:c,actressType:h,remark:u}=e;if(!s)throw new Error("缺失starId");let p=t.find((g=>g.starId===s));return p?(a&&(p.name=a),i&&(p.allName=i),r&&(p.avatar=r),h!=null&&(p.actressType=h),n&&(p.lastCheckTime=n),l&&(p.newVideoList=l),c&&(p.lastPublishTime=c),u&&(p.remark=u),p.updateDate=utils.getNowStr(),await this._setItemAndInvalidate(this.favorite_actresses_key,t),!0):(clog.error("未找到演员信息",s,a),!1)}async getCarList(){return this._readCached("cacheCarList",this.car_list_key,[])}async getCarMap(){if(this.cacheCarMap===null){let e=await this.getCarList();this.cacheCarMap=qi(e,"carNum")}return this.cacheCarMap}async getStatusMap(){if(this.cacheStatusMap===null){let e=await this.getCarList();this.cacheStatusMap=tl(e)}return this.cacheStatusMap}async getCar(e){return(await this.getCarMap()).get(T(e))}_saveSingleCar(e,t){let{carNum:s,url:a,names:i,actionType:r,publishTime:n,starId:l}=e;if(!s)throw show.error("番号为空!"),new Error("番号为空!");if(!a)throw show.error("url为空!"),new Error("url为空!");a.includes("http")||(a=window.location.origin+a),i&&(i=i.trim());let c=t.find((h=>h.carNum===s));if(c)i&&(c.names=i),a&&(c.url=a),n&&(c.publishTime=n),c.updateDate=utils.getNowStr();else{let h=utils.getNowStr();c={carNum:s,url:a,names:i,status:"",createDate:h,updateDate:h,publishTime:n},l&&(c.starId=l),t.push(c)}switch(r){case ce:if(c.status===ce){let u=`${s} 已在屏蔽列表中`;throw show.error(u),new Error(u)}c.status=ce;break;case ue:if(c.status===ue){let u=`${s} 已在收藏列表中`;throw show.error(u),new Error(u)}c.status=ue;break;case pe:if(c.status===pe){let u=`${s} 已标记为已下载`;throw show.error(u),new Error(u)}c.status=pe;break;case me:if(c.status===me){let u=`${s} 已标记为已观看`;throw show.error(u),new Error(u)}c.status=me;break;default:let h="actionType错误, 请联系作者更正: "+r;throw show.error(h),new Error(h)}}async saveCar(e){let t=T(e.carNum),s=ke(e.actionType);if(!t)throw show.error("番号为空!"),new Error("番号为空!");if(!e.url)throw show.error("url为空!"),new Error("url为空!");if(!s)throw show.error("actionType错误, 请联系作者更正: "+e.actionType),new Error("actionType错误, 请联系作者更正: "+e.actionType);let a=await this.getCar(t);if(q(a?.stateFlags)[s]){let i={blocked:"已在屏蔽列表中",favorite:"已在收藏列表中",downloaded:"已标记为已下载",watched:"已标记为已观看"},r=`${t} ${i[s]}`;throw show.error(r),new Error(r)}return this.stateService.patch(t,{[s]:!0},{type:"legacy-save",record:{...e,carNum:t}})}async updateCarInfo(e){let{carNum:t,url:s,names:a,actionType:i,publishTime:r,remark:n}=e;if(!t)throw show.error("番号为空!"),new Error("番号为空!");if(!s)throw show.error("url为空!"),new Error("url为空!");if(a&&(a=a.trim()),t=T(t),!await this.getCar(t)){let h="数据不存在: "+t;throw show.error(h),new Error(h)}let c=ke(i);if(!c){let h="actionType错误, 请联系作者更正: "+i;throw show.error(h),new Error(h)}return this.stateService.patch(t,{[c]:!0},{type:"legacy-update",record:{carNum:t,names:a,url:s,remark:n,publishTime:r}})}async saveCarList(e){if(!e||!Array.isArray(e)||e.length===0)throw show.error("记录列表为空!"),new Error("记录列表为空!");let t=await this.getCarMap(),s=new Set,a=new Map;for(let i of e){let r=T(i.carNum),n=ke(i.actionType);if(!r)throw show.error("番号为空!"),new Error("番号为空!");if(!i.url)throw show.error("url为空!"),new Error("url为空!");if(!n)throw new Error("actionType错误, 请联系作者更正: "+i.actionType);let l=`${r}:${n}`;if(s.has(l)||q(t.get(r)?.stateFlags)[n])throw new Error(`${r} 状态已存在`);s.add(l);let c=a.get(n)||[];c.push({...i,carNum:r}),a.set(n,c)}for(let[i,r]of a)await this.stateService.patch(r.map((n=>n.carNum)),{[i]:!0},{type:"legacy-batch-save",records:r})}async removeNewVideoList(e){return this.withActressLock(async()=>{let t=new Set((Array.isArray(e)?e:[e]).map(T).filter(Boolean)),s=await this.getFavoriteActressList(),a=new Set,i=s.map((r=>{if(!r.newVideoList||!Array.isArray(r.newVideoList))return r;let n=r.newVideoList.filter((l=>{let c=T(typeof l=="string"?l:l.carNum),h=t.has(c);return h&&(clog.log("移除关联女优新作品",l.name,c),a.add(c)),!h}));return{...r,newVideoList:n}}));return a.size&&await this._setItemAndInvalidate(this.favorite_actresses_key,i),{changed:[...a]}})}async removeCar(e){return(await this.stateService.remove(e)).changed.length?!0:(show.error(`${e} 不存在`),!1)}async batchRemoveCars(e){return(await this.stateService.remove(e)).changed.length||!1}async getBlacklist(){return this._readCached("cacheBlacklist",this.blacklist_key,[])}async getBlacklistMap(){if(this.cacheBlacklistMap===null){let e=await this.getBlacklist();this.cacheBlacklistMap=qi(e,"starId")}return this.cacheBlacklistMap}async addBlacklistItem(e){return this._withCrossTabLock("jhs_blacklist_lock",()=>this._addBlacklistItemWithoutLock(e))}async _addBlacklistItemWithoutLock(e){let{starId:t,name:s,allName:a,role:i,movieType:r,url:n}=e;if(!t)throw new Error("缺失starId");if(!s)throw new Error("缺失name");if(!i)throw new Error("缺失role");let l=await this.getBlacklist(),c=l.find((h=>h.starId===t));if(c)c.url=n,c.role=i,c.movieType=r,clog.log("更新黑名单演员信息",c);else{let h={starId:t,name:s,allName:a||[s],createTime:utils.getNowStr(),role:i,movieType:r,url:n};l.push(h),clog.log("增加黑名单演员信息",h)}await this._setItemAndInvalidate(this.blacklist_key,l)}async updateBlacklistItem(e){return this._withCrossTabLock("jhs_blacklist_lock",()=>this._updateBlacklistItemWithoutLock(e))}async _updateBlacklistItemWithoutLock(e){if(!e||!e.starId)throw new Error("参数不全");let t=await this.getBlacklist(),s=t.find((a=>a.starId===e.starId));if(!s)throw new Error(`未找到黑名单演员信息:${e.name} ${e.starId}`);e.checkTime&&(s.checkTime=e.checkTime),e.lastPublishTime&&(s.lastPublishTime=e.lastPublishTime),await this._setItemAndInvalidate(this.blacklist_key,t)}async deleteBlacklistItem(e){return this._withCrossTabLock("jhs_blacklist_lock",async()=>{let t=await this.getBlacklist(),s=t.filter((a=>a.starId!==e));t.length!==s.length&&await this._setItemAndInvalidate(this.blacklist_key,s)})}async getBlacklistCarList(){return this._readCached("cache_filter_actor_actress_car_list",this.blacklist_car_list_key,[])}async batchSaveBlacklistCarList(e){return this._withCrossTabLock("jhs_blacklist_lock",async()=>{let t=await this.getBlacklistCarList(),s=JSON.parse(JSON.stringify(t)),a=!1,i=[];for(let r of e)s.find((n=>n.carNum===r.carNum))||(this._saveSingleCar(r,s),clog.html(`屏蔽演员番号: <span class="jhs-layout-eeefd8c8">${C(r.names)} ${C(r.carNum)}</span>`),a=!0,i.push(r.carNum));if(a){await this._setItemAndInvalidate(this.blacklist_car_list_key,s);let r=await this.removeNewVideoList(i);r.changed.length&&await window.jhsEventBus?.emit?.("new-video-changed",{reason:"blacklist-car-removed",carNums:r.changed}),await window.cleanCache_filter_actor_actress_car_list()}return{changed:i.map(T).filter(Boolean)}})}async removeBlacklistCarList(e){let t=await this.getBlacklistCarList(),s=t.filter((a=>a.starId!==e));s.length!==t.length&&(await this._setItemAndInvalidate(this.blacklist_car_list_key,s),window.cleanCache_filter_actor_actress_car_list())}async getFavoriteActressList(){return this._readCached("cacheFavoriteActresses",this.favorite_actresses_key,[])}async addFavoriteActressList(e){return this.withActressLock(async()=>{let t=await this.getFavoriteActressList(),s=0;for(let a of e){let{starId:i,name:r,allName:n,avatar:l,lastCheckTime:c,lastPublishTime:h,actressType:u}=a;if(!i)throw new Error("缺失starId");if(!r)throw new Error("缺失name");n||(n=[r]);let p="(無碼)";u||(u=r.includes(p)||n.some((f=>f.includes(p)))?Ke:Je),r=r.replace(p,""),n=n.map((f=>f.replace(p,"")));let g=t.find((f=>f.starId===i));if(g){g.avatar&&g.avatar.includes("https")||l&&(clog.log(l),g.avatar=l,clog.html(`<span class="jhs-layout-eeefd8c8">补全女优头像: ${C(r)}</span>`),s++),!g.actressType&&u&&(g.actressType=u,clog.html(`<span class="jhs-layout-eeefd8c8">补全女优类别: ${C(r)} ${C(u)}</span>`),s++),g.name.includes(p)&&(g.name=r,g.allName=n,clog.html(`<span class="jhs-layout-eeefd8c8">更正女优名字: ${C(r)} ${C(n)}</span>`),s++);continue}let m=utils.getNowStr();t.push({starId:i,name:r,allName:n,avatar:l,lastCheckTime:c,lastPublishTime:h,createDate:m,updateDate:m,actressType:u}),clog.html(`<span class="jhs-layout-eeefd8c8">同步JavDB已收藏的演员: ${C(r)}</span>`),s++}return s>0?await this._setItemAndInvalidate(this.favorite_actresses_key,t):clog.log("信息已记录, 无需要进行同步收藏的演员"),s})}async removeFavoriteActress(e){return this.withActressLock(async()=>{let t=await this.getFavoriteActressList(),s=t.length,a=t.filter((i=>i.starId!==e));return a.length===s?(clog.error(`移除演员失败, ${e} 不存在`),!1):(await this._setItemAndInvalidate(this.favorite_actresses_key,a),!0)})}async updateFavoriteActress(e){return this.withActressLock(()=>this._rawUpdateFavoriteActress(e))}async getHighlightedTags(){return await this.forage.getItem(this.highlighted_tags_key)||[]}async setHighlightedTags(e){return await this.forage.setItem(this.highlighted_tags_key,e)}async saveTitleFilterKeyword(e){return await Di(this,Ki,rl).call(this,e,this.filter_keyword_title_key,"标题关键词"),Array.isArray(e)?null:this.withActressLock(async()=>{let t=await this.getFavoriteActressList(),s=!1,a=t.map((i=>{if(!i.newVideoList||!Array.isArray(i.newVideoList))return i;let r=i.newVideoList.filter((n=>{let l=typeof n=="string"?n:n.carNum,c=l.startsWith(e);return c&&(clog.log("移除关联女优新作品",i.name,l),s=!0),!c}));return{...i,newVideoList:r}}));s&&await this._setItemAndInvalidate(this.favorite_actresses_key,a)})}async getTitleFilterKeyword(){return this._readCached("cacheTitleFilterKeyword",this.filter_keyword_title_key,[])}async getReviewFilterKeywordList(){return Wt({get:d(e=>this.forage.getItem(e),"get"),set:d((e,t)=>this._setItemAndInvalidate(e,t),"set"),remove:d(e=>this.forage.removeItem(e),"remove")})}async saveReviewFilterKeyword(e){return Di(this,Ki,rl).call(this,e,this.filter_keyword_review_key,"评论关键词")}async getSetting(e=null,t){let s=await this._readCached("cacheSettingObj",this.setting_key,{});if(e===null)return s;if(!Object.prototype.hasOwnProperty.call(s,e))return t;let a=s[e];return a==="true"||a==="false"?a.toLowerCase()==="true":typeof a!="string"||a.trim()===""||isNaN(Number(a))?a:Number(a)}getSettingSync(e,t){if(!this.cacheSettingObj||!Object.prototype.hasOwnProperty.call(this.cacheSettingObj,e))return t;let s=this.cacheSettingObj[e];return s==="true"||s==="false"?s.toLowerCase()==="true":typeof s!="string"||s.trim()===""||isNaN(Number(s))?s:Number(s)}async saveSetting(e){if(globalThis.settingsService?.replace)return globalThis.settingsService.replace(e);e?(await this._setItemAndInvalidate(this.setting_key,e),await window.clean_cacheSettingObj()):show.error("设置对象为空")}invalidateSettingCache(){this._invalidateCache(this.setting_key)}async saveSettingItem(e,t){if(!e)return void show.error("key 不能为空");if(globalThis.settingsService?.set)return globalThis.settingsService.set(e,t);let s=globalThis.navigator?.locks,a=d(async()=>{let i=await this.getSetting();i[e]=t,await this.saveSetting(i)},"write");return s?.request?s.request("jhs_setting_lock",a):a()}async updateSetting(e){if(globalThis.settingsService?.update)return globalThis.settingsService.update(e);let t=globalThis.navigator?.locks,s=d(async()=>{let a=await this.getSetting();e(a),await this.saveSetting(a)},"write");return t?.request?t.request("jhs_setting_lock",s):s()}async importData(e){Yo(e),await Mi(this)&&await this.createSnapshot("导入前自动备份","auto-import");let t={...e};t.setting&&typeof t.setting=="object"&&!Array.isArray(t.setting)&&(t.setting=Qo(await this.getSetting(),t.setting));let s=new Set([...Jo,"data_version"]);await this._withCrossTabLock("jhs_state_mutation",async()=>{let a=[];for(let i in t){if(!s.has(i)){clog.warn(`[导入] 跳过未知数据键: ${i}`);continue}i!=="third_party_ttl_cache"&&a.push(i==="data_version"?this.setDataVersion(t[i]):this._setItemAndInvalidate(i,t[i]))}await Promise.all(a),this._invalidateCache(),await ws(this)}),await window.stateService?.recoverPendingTransaction()}async exportPortableData(){let e={data_version:await this.getDataVersion()};for(let t of bs){let s=await this.forage.getItem(t);s!=null&&(e[t]=t===this.setting_key?Bi(s):s)}return e}async exportData(){let e=await this.exportPortableData();if(Object.keys(e).length<=1)throw new Error("没有可导出的数据");return e}async getThirdPartyCache(){return await this.forage.getItem(this.third_party_cache_key)||{}}async setThirdPartyCache(e){await this.forage.setItem(this.third_party_cache_key,e||{})}async clearThirdPartyCache(){await this.forage.removeItem(this.third_party_cache_key)}async deleteCachedRequest(e){let t=await this.getThirdPartyCache();Object.prototype.hasOwnProperty.call(t,e)&&(delete t[e],await this.setThirdPartyCache(t))}async cachedRequest(e,t,s){let a=Date.now(),i=await this.getThirdPartyCache(),r=i[e];if(r&&r.time&&a-r.time<(r.ttl||t))return this._cacheStats.hits++,r.data;this._cacheStats.misses++;let n=await s(),l=n&&typeof n=="object"&&"__jhsCacheTtl"in n?n.__jhsCacheTtl:t,c=n&&typeof n=="object"&&"__jhsCacheTtl"in n?n.data:n;return c==null?c:(i[e]={time:a,ttl:l,data:c},this._pruneThirdPartyCache(i,a),await this._withCrossTabLock("jhs_ttl_cache_lock",async()=>{let h=await this.getThirdPartyCache();h[e]=i[e],this._pruneThirdPartyCache(h,a),await this.setThirdPartyCache(h)}),c)}async cacheSet(e,t,s){let a=Date.now();return this._withCrossTabLock("jhs_ttl_cache_lock",async()=>{let i=await this.getThirdPartyCache();i[e]={time:a,ttl:s,data:t},this._pruneThirdPartyCache(i,a),await this.setThirdPartyCache(i)})}_pruneThirdPartyCache(e,t){for(let r of Object.keys(e)){let n=e[r];(!n||n.time&&t-n.time>Math.max(n.ttl||0,2592e6))&&delete e[r]}let i=Object.keys(e);if(i.length>500){i.sort(((r,n)=>(e[r].time||0)-(e[n].time||0)));for(let r of i.slice(0,i.length-500))delete e[r]}}getCacheHitStats(){let e=this._cacheStats.hits+this._cacheStats.misses;return{hits:this._cacheStats.hits,misses:this._cacheStats.misses,total:e,rate:e>0?(this._cacheStats.hits/e*100).toFixed(1)+"%":"N/A"}}_groupDuplicateItems(e,t){return sl(e,t)}_dedupeByKey(e,t){return al(e,t)}async inspectDataHealth(){let[e,t,s,a]=await Promise.all([this.getCarList(),this.getFavoriteActressList(),this.getBlacklist(),this.getBlacklistCarList()]),i=await this.getCarMap(),r={checkedAt:utils.getNowStr(),totals:{carList:e.length,favoriteActresses:t.length,blacklist:s.length,blacklistCarList:a.length},fixable:[],readonly:[]},n=d((x,_,E)=>r.fixable.push({type:x,message:_,count:E}),"o"),l=d((x,_,E)=>r.readonly.push({type:x,message:_,count:E}),"r"),c=this._groupDuplicateItems(e,"carNum"),h=this._groupDuplicateItems(t,"starId"),u=this._groupDuplicateItems(s,"starId");c.length&&n("duplicate-car","重复番号记录",c.length),h.length&&n("duplicate-actress","重复收藏演员",h.length),u.length&&n("duplicate-blacklist","重复黑名单演员",u.length);let p=e.filter((x=>x&&x.actress)).length,g=a.filter((x=>x&&x.actress)).length,m=t.filter((x=>x&&Object.prototype.hasOwnProperty.call(x,"dbId"))).length,f=s.filter((x=>x&&("key"in x||"recordTime"in x||"isActor"in x))).length;p+g+m+f>0&&n("legacy-fields","旧字段残留",p+g+m+f);let v=t.filter((x=>x&&x.name&&!Array.isArray(x.allName))).length+s.filter((x=>x&&x.name&&!Array.isArray(x.allName))).length;v&&n("invalid-all-name","演员别名不是数组",v);let b=0;t.forEach((x=>{Array.isArray(x?.newVideoList)&&(b+=x.newVideoList.filter((_=>{let E=typeof _=="string"?_:_.carNum;return i.has(E)})).length)})),b&&n("stored-new-video","新作品列表中已有鉴定记录",b);let w=e.filter((x=>x&&x.carNum&&!x.url)).length;w&&l("missing-url","番号记录缺失 url,需要人工确认来源",w);let S=t.filter((x=>x&&!x.starId)).length+s.filter((x=>x&&!x.starId)).length;S&&l("missing-star-id","演员缺失 starId,需要人工确认身份",S);let j=new Set(s.map((x=>x&&x.starId)).filter(Boolean)),k=a.filter((x=>x&&x.starId&&!j.has(x.starId))).length;return k&&l("orphan-blacklist-car","黑名单作品找不到关联演员",k),r}async repairDataHealth(){let e=0,t=await this.getCarList(),s=await this.getFavoriteActressList(),a=await this.getBlacklist(),i=await this.getBlacklistCarList(),r=this._dedupeByKey(t,"carNum");r.changed&&(t=r.list,e++);let n=this._dedupeByKey(s,"starId");n.changed&&(s=n.list,e++);let l=this._dedupeByKey(a,"starId");l.changed&&(a=l.list,e++),t=t.map((h=>{if(!h)return h;let u=!1;return h.actress!==void 0&&(h.names=h.actress,delete h.actress,u=!0),u&&e++,h})),i=i.map((h=>{if(!h)return h;let u=!1;return h.actress!==void 0&&(h.names=h.actress,delete h.actress,u=!0),Object.prototype.hasOwnProperty.call(h,"type")&&(delete h.type,u=!0),u&&e++,h})),s=s.map((h=>{if(!h)return h;let u=!1;return Object.prototype.hasOwnProperty.call(h,"dbId")&&(h.starId||(h.starId=h.dbId),delete h.dbId,u=!0),h.name&&!Array.isArray(h.allName)&&(h.allName=h.allName?[h.allName]:[h.name],u=!0),u&&e++,h})),a=a.map((h=>{if(!h)return h;let u=!1;return Object.prototype.hasOwnProperty.call(h,"isActor")&&(h.role||(h.role=h.isActor?Me:st),delete h.isActor,u=!0),Object.prototype.hasOwnProperty.call(h,"recordTime")&&(h.createTime||(h.createTime=h.recordTime),delete h.recordTime,u=!0),Object.prototype.hasOwnProperty.call(h,"key")&&(delete h.key,u=!0),h.name&&!Array.isArray(h.allName)&&(h.allName=h.allName?[h.allName]:[h.name],u=!0),u&&e++,h}));let c=new Set(t.filter((h=>h&&h.carNum)).map((h=>h.carNum)));return s=s.map((h=>{if(!Array.isArray(h?.newVideoList))return h;let u=h.newVideoList.filter((p=>{let g=typeof p=="string"?p:p.carNum;return!c.has(g)}));return u.length!==h.newVideoList.length&&(h={...h,newVideoList:u},e++),h})),await this._setItemAndInvalidate(this.car_list_key,t),await this._setItemAndInvalidate(this.favorite_actresses_key,s),await this._setItemAndInvalidate(this.blacklist_key,a),await this._setItemAndInvalidate(this.blacklist_car_list_key,i),{fixedGroups:e,report:await this.inspectDataHealth()}}async merge_table_name(){let e="filter_actor_actress_info_list",t=await this.forage.getItem(e)||[];t&&t.length>0&&(clog.debug("更正",e),await this._setItemAndInvalidate(this.blacklist_key,t)),await this.forage.removeItem(e),e="favorite_actresses_info_list",t=await this.forage.getItem(e)||[],t&&t.length>0&&(clog.debug("更正",e),await this._setItemAndInvalidate(this.favorite_actresses_key,t)),await this.forage.removeItem(e),e="car_list_filter_actor_actress",t=await this.forage.getItem(e)||[],t&&t.length>0&&(clog.debug("更正",e),await this._setItemAndInvalidate(this.blacklist_car_list_key,t)),await this.forage.removeItem(e),e="title_filter_keyword",t=await this.forage.getItem(e)||[],t&&t.length>0&&(clog.debug("更正",e),await this._setItemAndInvalidate(this.filter_keyword_title_key,t)),await this.forage.removeItem(e),await this.getReviewFilterKeywordList(),e="highlightedTags",t=await this.forage.getItem(e)||[],t&&t.length>0&&(clog.debug("更正",e),await this._setItemAndInvalidate(this.highlighted_tags_key,t)),await this.forage.removeItem(e)}async clean_no_url_blacklist(){let[e,t]=await Promise.all([this.getBlacklistCarList(),this.getBlacklist()]);if(e.length&&!e[0].actress)return;let s=new Set(t.map((n=>n.name))),a=e.filter((n=>!n.actress||s.has(n.actress)));e.length!==a.length&&(clog.debug("清理 blacklistCarList 前",e.length),clog.debug("清理 blacklistCarList 后",a.length),await this._setItemAndInvalidate(this.blacklist_car_list_key,a));let i=new Set(a.map((n=>n.actress))),r=t.filter((n=>i.has(n.name)));r=r.map((n=>{let{key:l,recordTime:c,...h}=n,u=h;return c!==void 0&&(u.createTime=c),u})),(t.length!==r.length||t.some((n=>"key"in n||"recordTime"in n)))&&(clog.debug("清理 Blacklist 前",t.length),clog.debug("清理 Blacklist 后",r.length),await this._setItemAndInvalidate(this.blacklist_key,r))}async async_merge_other(){let e=!1,t={enableCheckFilterActorActress:"enableCheckBlacklist",checkIntervalTime_filterActorActress:"checkBlacklist_intervalTime",checkIntervalTime_ruleTime:"checkNewVideo_ruleTime",checkIntervalTime_newVideo:"checkNewVideo_intervalTime",checkIntervalTime_favoriteActress:"checkFavoriteActress_IntervalTime"};await this.updateSetting(s=>{for(let a in t){let i=t[a];Object.prototype.hasOwnProperty.call(s,a)&&(s[i]=s[a],delete s[a],e=!0)}s.checkFilterTime&&(delete s.checkFilterTime,e=!0),s.checkFilterConcurrencyCount&&(delete s.checkFilterConcurrencyCount,e=!0),s.checkFilterSleep&&(delete s.checkFilterSleep,e=!0)}),e&&clog.debug("配置数据已更正")}async merge_blacklist(){let e=await this.getBlacklist();if(!e||e.length===0)return;let t=!1,s=e.map((r=>{let n=!1;if(Object.prototype.hasOwnProperty.call(r,"isActor")&&!r.role&&(r.role=r.isActor?Me:st,delete r.isActor,n=!0),!r.starId&&r.url)try{let l=new URL(r.url).pathname,c=l.split("/").filter((h=>h.trim()!=="")).pop();r.starId!==c&&(r.starId=c,n=!0)}catch(l){clog.error("提取url-starId发生错误",r.url,l)}if(r.allName||(r.allName=r.name?[r.name]:[],n=!0),r.movieType||(r.movieType=Je,n=!0),r.url&&r.url.includes("sort_type")){let l=new URL(r.url);l.searchParams.delete("sort_type"),r.url=l.toString(),clog.debug("去除黑名单地址sort_type参数")}return n&&(t=!0),r}));t&&(clog.debug("更正 Blacklist 数据结构"),await this._setItemAndInvalidate(this.blacklist_key,s));let a=await this.getBlacklistCarList();t=!1;let i=a.map((r=>{if(!r.starId){let n=e.find((l=>l.name===r.actress));n&&(r.starId=n.starId),t=!0}return r.type&&(delete r.type,t=!0),r}));t&&(clog.debug("更正 blacklistCarList 数据结构"),await this._setItemAndInvalidate(this.blacklist_car_list_key,i))}async merge_favoriteActress(){let e=await this.getFavoriteActressList();if(!e||e.length===0)return;let t=!1,s=e.map((a=>{let i=!1;return a.dbId&&(a.starId=a.dbId,delete a.dbId,i=!0),i&&(t=!0),a}));t&&(clog.debug("更正 favoriteActressesInfoList 数据结构"),await this._setItemAndInvalidate(this.favorite_actresses_key,s))}async merge_tow_car_list_table(){let e=await this.getBlacklistCarList(),t=await this.getCarList(),s=!1,a=e.map((r=>{let n=!1;return r.actress!==void 0&&(r.names=r.actress,delete r.actress,n=!0),n&&(s=!0),r}));s&&(clog.debug("更正 blacklistCarList 数据结构 actress->names"),await this._setItemAndInvalidate(this.blacklist_car_list_key,a)),s=!1;let i=t.map((r=>{let n=!1;return r.actress!==void 0&&(r.names=r.actress,delete r.actress,n=!0),n&&(s=!0),r}));s&&(clog.debug("更正 carList 数据结构 actress->names"),await this._setItemAndInvalidate(this.car_list_key,i))}_snapshotKey(){return"snapshots"}_snapshotMetaKeys(){return["snapshots","data_version"]}async _getSnapshots(){return await this.forage.getItem(this._snapshotKey())||[]}async _saveSnapshots(e){await this._setItemAndInvalidate(this._snapshotKey(),e)}async _withSnapshotLock(e){return await navigator.locks.request("jhs_snapshot_lock",async()=>await e())}async createSnapshot(e="",t="manual"){return this._withSnapshotLock(async()=>{let s=await this._getSnapshots(),a=await this.exportData();for(let n of this._snapshotMetaKeys())delete a[n];let i=0;for(let n of Object.values(a))Array.isArray(n)?i+=n.length:typeof n=="object"&&n&&i++;let r={id:"snap_"+Date.now()+"_"+Math.random().toString(36).slice(2,8),name:e||utils.getNowStr(),source:t,time:utils.getNowStr(),itemCount:i,data:a,kind:"snapshot"};return s.push(r),s.length>10&&s.splice(0,s.length-10),await this._saveSnapshots(s),clog.log(`创建快照: ${r.name} (${t})`),r})}async getSnapshotList(){return(await this._getSnapshots()).map((e=>({id:e.id,name:e.name,source:e.source,time:e.time,itemCount:e.itemCount,kind:e.kind||"snapshot",targetDataVersion:e.targetDataVersion,appVersion:e.appVersion})))}async getSnapshot(e){return(await this._getSnapshots()).find((t=>t.id===e))||null}async deleteSnapshot(e){return this._withSnapshotLock(async()=>{let t=await this._getSnapshots(),s=t.filter((a=>a.id!==e));if(s.length===t.length)return void clog.warn("删除快照失败, ID不存在: "+e);await this._saveSnapshots(s),clog.log("删除快照: "+e)})}async restoreSnapshot(e){let t=await this.getSnapshot(e);if(!t)throw new Error("快照不存在: "+e);if(!t.data||typeof t.data!="object")throw new Error("快照数据损坏");let s={...t.data};for(let a of this._snapshotMetaKeys())delete s[a];return await this.importData(s),clog.log("已恢复快照: "+t.name),t}_stableStringify(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?"["+e.map((t=>this._stableStringify(t))).join(",")+"]":"{"+Object.keys(e).sort().map((t=>JSON.stringify(t)+":"+this._stableStringify(e[t]))).join(",")+"}"}diffData(e,t){let s=new Set([...Object.keys(e),...Object.keys(t)]),a={},i={added:0,removed:0,modified:0,unchanged:0};for(let r of s){let n=e[r],l=t[r];if(!(n===void 0&&l===void 0))if(n===void 0){let c=Array.isArray(l)?l.length:1;a[r]={status:"added",oldCount:0,newCount:c,added:Array.isArray(l)?l:[],removed:[],modified:[]},i.added++}else if(l===void 0){let c=Array.isArray(n)?n.length:1;a[r]={status:"removed",oldCount:c,newCount:0,added:[],removed:Array.isArray(n)?n:[],modified:[]},i.removed++}else if(Array.isArray(n)&&Array.isArray(l)){let c=this._diffArrays(n,l,r);a[r]={status:c.status,oldCount:n.length,newCount:l.length,...c},i[c.status]++}else if(typeof n=="object"&&typeof l=="object"&&!Array.isArray(n)&&!Array.isArray(l)){let c=this._diffObjects(n,l);a[r]={status:c.status,oldCount:Object.keys(n).length,newCount:Object.keys(l).length,added:[],removed:[],modified:c.changes},i[c.status]++}else n===l?(a[r]={status:"unchanged",oldCount:1,newCount:1,added:[],removed:[],modified:[]},i.unchanged++):(a[r]={status:"modified",oldCount:1,newCount:1,added:[],removed:[],modified:[{key:r,changes:{_value:[n,l]}}]},i.modified++)}return{summary:i,stores:a}}_getArrayKey(e){return e==="car_list"||e==="blacklist_car_list"?"carNum":e==="blacklist"||e==="favorite_actresses"?"starId":null}_diffArrays(e,t,s){let a=this._getArrayKey(s);if(!a){let u=this._stableStringify(e),p=this._stableStringify(t);if(u===p)return{status:"unchanged",added:[],removed:[],modified:[]};let g=new Set(e.map((f=>this._stableStringify(f)))),m=new Set(t.map((f=>this._stableStringify(f))));return{status:"modified",added:t.filter((f=>!g.has(this._stableStringify(f)))),removed:e.filter((f=>!m.has(this._stableStringify(f)))),modified:[]}}let i=new Map(e.map((u=>[u[a],u]))),r=new Map(t.map((u=>[u[a],u]))),n=[],l=[],c=[];for(let[u,p]of r){let g=i.get(u);if(!g)n.push(p);else{let m=this._diffObjects(g,p);m.status!=="unchanged"&&c.push({key:u,changes:m.changes})}}for(let[u]of i)r.has(u)||l.push(i.get(u));return{status:n.length+l.length+c.length===0?"unchanged":"modified",added:n,removed:l,modified:c}}_diffObjects(e,t){let s=new Set([...Object.keys(e),...Object.keys(t)]),a={},i=0;for(let r of s){let n=e[r],l=t[r];this._stableStringify(n)!==this._stableStringify(l)&&(a[r]=[n,l],i++)}return{status:i===0?"unchanged":"modified",changes:a}}};d(Jt,"StorageManager");var ks=Jt;var Tt=class Tt{constructor(){return A(this,"intervalContainer",{}),A(this,"waitSequence",0),A(this,"mimeTypes",{txt:"text/plain",html:"text/html",css:"text/css",csv:"text/csv",json:"application/json",xml:"application/xml",jpg:"image/jpeg",jpeg:"image/jpeg",png:"image/png",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",pdf:"application/pdf",doc:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xls:"application/vnd.ms-excel",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",ppt:"application/vnd.ms-powerpoint",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",zip:"application/zip",rar:"application/x-rar-compressed","7z":"application/x-7z-compressed",mp3:"audio/mpeg",wav:"audio/wav",mp4:"video/mp4",webm:"video/webm",ogg:"audio/ogg"}),A(this,"timers",new Map),A(this,"insertStyle",(e=>{let t=(Array.isArray(e)?e:[e]).filter(Boolean);if(t.length===0)return;let s=t.map((i=>i.replace(/^\s*<style[^>]*>/i,"").replace(/<\/style>?\s*$/i,""))).filter(Boolean).join(`
`),a=document.createElement("style");s&&(a.textContent=s,document.head.append(a))})),A(this,"layerIndexStack",[]),Tt.instance||(Tt.instance=this),Tt.instance}importResource(e){let t;e.indexOf("css")>=0?(t=document.createElement("link"),t.setAttribute("rel","stylesheet"),t.href=e):(t=document.createElement("script"),t.setAttribute("type","text/javascript"),t.src=e);let s=t.href||t.src;[...document.head.querySelectorAll("link[href], script[src]")].some((a=>(a.href||a.src)===s))||document.head.appendChild(t)}openPage(e,t,s,a){s=s??!0;let i=a&&(Object.prototype.hasOwnProperty.call(a,"event")||Object.prototype.hasOwnProperty.call(a,"newTab"))?a:{event:a},r=i.event,n=new URL(e,window.location.origin),l=T(t);if(/^\/v\/[^/]+/.test(n.pathname)&&l&&n.searchParams.set("jhsCarNum",l),i.newTab||r&&(r.ctrlKey||r.metaKey||r.button===1))return void GM_openInTab(n.href,{insert:0});n.pathname.includes("/actors/")||n.pathname.includes("/star/")||n.searchParams.set("hideNav","1");let h=null;layer.open(kt({type:2,zIndex:J.layer,ui:{size:"workspace",body:"media"},title:t,content:n.href,scrollbar:!1,shadeClose:s,area:this.getDialogArea("workspace"),isOutAnim:!1,anim:-1,success:d((u,p)=>{h=p,this.setupEscClose(p)},"success"),end:d(()=>{h!=null&&this.releaseEscClose(h)},"end")},this))}_handleGlobalEscKey(e){if(e.key!=="Escape"&&e.keyCode!==27||e.defaultPrevented||e.isDefaultPrevented?.()||this.layerIndexStack.length===0)return;for(;this.layerIndexStack.length&&!document.getElementById(`layui-layer${this.layerIndexStack[this.layerIndexStack.length-1]}`);)this.layerIndexStack.pop();let t=this.layerIndexStack[this.layerIndexStack.length-1];if(t==null)return;let s=$(`#layui-layer${t}`),a=!1,i=d(r=>$(r).find(".viewer-container:visible, .fancybox-container.fancybox-is-open:visible, .fancybox-container.fancybox-is-closing:visible").filter((n,l)=>{let c=$(l).closest(".layui-layer");return!c.length||c.attr("id")===`layui-layer${t}`}).length>0,"hasPreview");if(i(document))a=!0;else{let r=s.find(`#layui-layer-iframe${t}`)[0];if(r)try{r.contentDocument&&i(r.contentDocument)&&(a=!0)}catch{clog.warn("无法检查跨域 iframe 内的预览容器")}}a||(this.layerIndexStack.pop(),layer.close(t))}setupEscClose(e){var t;this._boundHandler||(this._boundHandler=this._handleGlobalEscKey.bind(this),$(document).off("keydown.globalLayerEsc"),$(document).on("keydown.globalLayerEsc",this._boundHandler)),this.layerIndexStack.indexOf(e)===-1&&this.layerIndexStack.push(e);let s=$(`#layui-layer-iframe${e}`),a=`keydown.layerEsc${e}`;try{let i=(t=s[0])==null?void 0:t.contentDocument;if(i){if(s.attr("data-esc-bound")==="yes")return;$(i).off(a),$(i).on(a,this._boundHandler),s.attr("data-esc-bound","yes")}}catch(i){clog.error("iframe监听失败 (跨域或未加载完毕):",i)}}releaseEscClose(e){let t=e??this.layerIndexStack[this.layerIndexStack.length-1];t!=null&&(this.layerIndexStack=this.layerIndexStack.filter((s=>s!==t)))}trapFocus(e){if(!e)return()=>{};let t=document.activeElement,s='a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])',a=d(()=>[...e.querySelectorAll(s)].filter((r=>!r.hidden&&r.getAttribute("aria-hidden")!=="true"&&r.offsetParent!==null)),"visible"),i=d(r=>{if(r.key!=="Tab")return;let n=a();if(!n.length)return void r.preventDefault();let l=n[0],c=n[n.length-1];r.shiftKey&&document.activeElement===l?(r.preventDefault(),c.focus()):!r.shiftKey&&document.activeElement===c&&(r.preventDefault(),l.focus())},"handleKeydown");return e.addEventListener("keydown",i),queueMicrotask((()=>a()[0]?.focus())),()=>{e.removeEventListener("keydown",i),t?.isConnected&&typeof t.focus=="function"&&t.focus()}}getOwningLayerIndex(e={}){let t=d(i=>{let r=i?.id||"",n=/^layui-layer(\d+)$/.exec(r);return n?Number(n[1]):null},"parseIndex"),s=Number.isInteger(e?.layerIndex)?e.layerIndex:null;try{s===null&&window.frameElement&&(s=t(window.frameElement.closest?.(".layui-layer")))}catch{}let a=e?.root;if(s===null&&a){let i=a.jquery?a[0]:a.nodeType?a:null,r=i?.matches?.(".layui-layer")?i:i?.closest?.(".layui-layer");s=t(r)}return s}async closePage(e={}){let t=globalThis.settingsService?.snapshot?.(),s=t&&Object.prototype.hasOwnProperty.call(t,"needClosePage")?t.needClosePage:await storageManager.getSetting("needClosePage","yes");if(s!=="yes"&&s!==!0)return!1;let a=this.getOwningLayerIndex(e);if(a!==null&&window.parent&&window.parent!==window)try{let n=globalThis.unsafeWindow?.parent?.utils;if(n&&n!==this&&typeof n.closePage=="function")return!!await n.closePage({layerIndex:a})}catch{}let i=window.parent&&window.parent!==window?window.parent:window,r=i.layer||globalThis.layer;return a!==null&&typeof r?.close=="function"?(r.close(a),!0):(window.close(),!0)}loopDetector(e,t,s=20,a=1e4,i=!0,r=null){let n=++this.waitSequence,l=null,c=null,h=null,u=!1,p=d(()=>{l&&(r?.releaseObserver?r.releaseObserver(l):l.disconnect()),clearTimeout(c),clearTimeout(h),clearInterval(this.intervalContainer[n]?.fallback),delete this.intervalContainer[n]},"d"),g=d(b=>{u||(u=!0,p(),b&&t&&t())},"h"),m=d(()=>{u||e()&&g(!0)},"g"),f=d(()=>{u||(clearTimeout(c),c=setTimeout(m,Math.max(0,s)))},"p"),v=d(()=>{u=!0,p()},"cancel");return this.intervalContainer[n]={},e()?(g(!0),v):(r?.observe&&document.documentElement?l=r.observe(document.documentElement,f,{childList:!0,subtree:!0,characterData:!0}):this.intervalContainer[n].fallback=setInterval(m,Math.max(100,s)),h=setTimeout((()=>{if(u)return;let b=!1;try{b=e()}catch(w){clog.error("DOM 等待条件执行失败",w)}g(b||i)}),Math.max(0,a)),v)}rightClick(e,t,s){let a;typeof e=="string"?a=document.querySelector(e):e instanceof HTMLElement&&(a=e),a||(clog.warn("rightClick(), 容器无效或未提供,将使用 document.body 进行全局委托。"),a=document.body),typeof t=="string"&&t.trim()!==""?a.addEventListener("contextmenu",(i=>{let r=i.target.closest(t);r&&s(i,r)})):clog.error("rightClick(), 必须提供有效的 targetSelector。")}q(e,t,s,a){let i;if(this.isMobileMode())i=layer.confirm(t,{title:"提示",btn:["确定","取消"],shade:0,zIndex:J.layer},(function(){s&&s(),layer.close(i)}),(function(){a&&a()}));else{let r,n;e?(r=e.clientX-130,n=e.clientY-120):(r=window.innerWidth/2-120,n=window.innerHeight/2-120),i=layer.confirm(t,{offset:[n,r],title:"提示",btn:["确定","取消"],shade:0,zIndex:J.layer},(function(){s&&s(),layer.close(i)}),(function(){a&&a()}))}}getNowStr(e="-",t=":",s=null){let a;if(a=s?new Date(s):new Date,isNaN(a.getTime()))return"";let i=a.getFullYear(),r=String(a.getMonth()+1).padStart(2,"0"),n=String(a.getDate()).padStart(2,"0"),l=String(a.getHours()).padStart(2,"0"),c=String(a.getMinutes()).padStart(2,"0"),h=String(a.getSeconds()).padStart(2,"0");return`${[i,r,n].join(e)} ${[l,c,h].join(t)}`}formatDate(e,t="-",s=":"){let a;if(e instanceof Date)a=e;else{if(typeof e!="string")throw new Error("Invalid date input: must be Date object or date string");if(a=new Date(e),isNaN(a.getTime()))throw new Error("Invalid date string")}let i=a.getFullYear(),r=String(a.getMonth()+1).padStart(2,"0"),n=String(a.getDate()).padStart(2,"0"),l=String(a.getHours()).padStart(2,"0"),c=String(a.getMinutes()).padStart(2,"0"),h=String(a.getSeconds()).padStart(2,"0");return`${[i,r,n].join(t)} ${[l,c,h].join(s)}`}getHourDifference(e,t){let s=e.getTime(),a=t.getTime(),i=Math.abs(a-s)/36e5;return Math.floor(i)}download(e,t){show.info("开始请求下载...");let s=t.split(".").pop().toLowerCase(),a,i=this.mimeTypes[s]||"application/octet-stream";if(e instanceof Blob)a=e;else if(e instanceof ArrayBuffer||ArrayBuffer.isView(e))a=new Blob([e],{type:i});else if(typeof e=="string"&&e.startsWith("data:")){let l=atob(e.split(",")[1]),c=new ArrayBuffer(l.length),h=new Uint8Array(c);for(let u=0;u<l.length;u++)h[u]=l.charCodeAt(u);a=new Blob([h],{type:i})}else a=new Blob([e],{type:i});let r=URL.createObjectURL(a),n=document.createElement("a");n.href=r,n.download=t,document.body.appendChild(n),n.click(),setTimeout((()=>{document.body.removeChild(n),URL.revokeObjectURL(r)}),100)}smoothScrollToTop(e=500){return new Promise((t=>{let s=performance.now(),a=window.pageYOffset;window.requestAnimationFrame(d((function i(r){let n=r-s,l=Math.min(n/e,1),c=l<.5?4*l*l*l:1-Math.pow(-2*l+2,3)/2;window.scrollTo(0,a*(1-c)),l<1?window.requestAnimationFrame(i):t()}),"i"))}))}isUrl(e){try{return new URL(e),!0}catch{return!1}}setHrefParam(e,t){let s=new URL(window.location.href);s.searchParams.set(e,t),window.history.pushState({},"",s.toString())}getUrlParam(e,t){let s=e.split("?")[1];if(!s)return null;let a=new RegExp(`(?:^|&)${t}=([^&]*)`),i=s.match(a),r="";return i&&i[1]&&(r=decodeURIComponent(i[1].replace(/\+/g," "))),r&&(r==="true"||r==="false"?r.toLowerCase()==="true":typeof r!="string"||r.trim()===""||isNaN(Number(r))?r:Number(r))}getResponsiveArea(e){let t=window.innerWidth;return this.isMobileMode()?["100%","90%"]:t>=1200?e||this.getDefaultArea():["70%","90%"]}getDialogArea(e="md"){let t={sm:[480,640],md:[720,700],lg:[1040,760],xl:[1320,860],workspace:[1440,960]},s=t[e]||t.md,a=window.innerWidth<=768?16:e==="workspace"?32:64,i=Math.max(320,Math.min(s[0],window.innerWidth-a)),r=Math.max(320,Math.min(s[1],window.innerHeight-a));return[`${i}px`,`${r}px`]}getDefaultArea(){return["85%","90%"]}isMobile(){let e=navigator.userAgent.toLowerCase();return["iphone","ipod","ipad","android","blackberry","windows phone","nokia","webos","opera mini","mobile","mobi","tablet"].some((t=>e.includes(t)))}isMobileMode(){let t=globalThis.settingsService?.snapshot?.()?.mobileMode??storageManager.getSettingSync("mobileMode","auto");return t==="on"||t!=="off"&&(this.isMobile()||window.innerWidth<768)}async copyToClipboard(e,t){let s=String(t??""),a=!1;try{if(navigator.clipboard?.writeText)await navigator.clipboard.writeText(s),a=!0;else throw new Error("Clipboard API unavailable")}catch(i){let r=document.createElement("textarea"),n=document.activeElement;r.value=s,r.setAttribute("readonly",""),r.style.position="fixed",r.style.opacity="0",document.body.appendChild(r),r.select();try{if(a=document.execCommand("copy")===!0,!a)throw i}catch(l){clog.error("复制失败:",l),show.error("复制失败,请手动复制")}finally{r.remove(),n?.focus?.()}}return a&&show.info(`${e}已复制到剪贴板, ${s}`),a}htmlTo$dom(e){let t=new DOMParser;return $(t.parseFromString(e,"text/html"))}isHidden(e){let t=e.jquery?e[0]:e;return!t||t.offsetWidth<=0&&t.offsetHeight<=0||window.getComputedStyle(t).display==="none"}time(e="default",t="s",s=2){if(this.timers.has(e)){let a=this.timers.get(e),i=performance.now()-a.startTime,r,n;return a.unit==="s"?(r=(i/1e3).toFixed(a.precision),n="秒"):(r=i.toFixed(a.precision),n="毫秒"),this.timers.delete(e),`${e}: ${r}${n}`}this.timers.set(e,{startTime:performance.now(),unit:t,precision:s})}sleep(e=1e3){return new Promise((t=>setTimeout(t,e)))}debounce(e,t=200){let s=null,a=d(function(...i){let r=this;clearTimeout(s),s=setTimeout((()=>{s=null,e.apply(r,i)}),Math.max(0,t))},"debounced");return a.cancel=()=>{clearTimeout(s),s=null},a}genericSort(e,t,s=!0){if(!Array.isArray(e)||e.length===0)return[];if(!Array.isArray(t)||t.length===0)return[...e];let a=d(l=>{if(l instanceof Date)return l;if(typeof l=="string"){let c=new Date(l);if(!isNaN(c.getTime()))return c}return l},"i"),i=d((l,c)=>c!=null?typeof c=="function"?c(l):l&&typeof l=="object"?l[c]:void 0:l,"getVal"),r=[],n=[];for(let l of e){let c=!1;for(let h of t){let u=i(l,h.key);if(u==null||u===void 0){c=!0;break}}c?r.push(l):n.push(l)}return n.sort(((l,c)=>{for(let h of t){let{key:u,order:p="asc"}=h,g=i(l,u),m=i(c,u),f=a(g),v=a(m),b=f instanceof Date&&v instanceof Date?f.getTime()-v.getTime():typeof g=="number"&&typeof m=="number"?g-m:typeof g=="string"&&typeof m=="string"?g.localeCompare(m):String(g).localeCompare(String(m));if(p==="desc"&&(b*=-1),b!==0)return b}return 0})),s?[...n,...r]:[...r,...n]}async retry(e,t=3){let s=0;for(;s<t;)try{let a=await e();return s>0&&clog.debug(`[重试] 请求成功,共发起 ${s+1} 次。`),a}catch(a){let i=a instanceof Error?a.message:typeof a=="object"?JSON.stringify(a):String(a);if(a?._cfBlocked||a?._circuitBroken||i.includes("Just a moment")||i.includes("重定向")||i.toLowerCase().includes("404 not found"))throw a;if(s++,s===t)throw clog.debug(`[重试] 达到最大重试次数 (${t}),最终失败:`,a),a;await this.sleep(500*s),clog.debug(`[重试] 请求失败,准备第 ${s+1} 次重试, 错误信息: ${i}`)}}};d(Tt,"Utils");var Cs=Tt;function nl(o){let e=globalThis.utils??new Cs,t=globalThis.storageManager??new ks,s=new js({utils:e,storageManager:t}),a=new xs(t,o);return el(a,t),Object.freeze({utils:e,gmHttp:s,storageManager:t,stateService:a})}d(nl,"createLegacyRuntime");var Qi=class Qi{constructor(e="channel-refresh",t={}){this.originId=globalThis.crypto?.randomUUID?.()||`tab_${Date.now()}_${Math.random().toString(36).slice(2)}`,this.listeners=new Map,this.seen=new Set,this.channel=new BroadcastChannel(e),this.errorReporter=t.errorReporter??null,this.channel.addEventListener("message",(s=>this._receive(s.data)))}_reportHandlerError(e){if(this.errorReporter)try{this.errorReporter(e)}catch{}else try{globalThis.clog?.error?.("[JHS] event listener failed:",e)}catch{}}on(e,t){let s=this.listeners.get(e)||new Set;return s.add(t),this.listeners.set(e,s),()=>s.delete(t)}async _dispatch(e){for(let t of[...this.listeners.get(e.type)||[]])try{await t(e.payload,e)}catch(s){this._reportHandlerError(s)}}_remember(e){this.seen.add(e),this.seen.size>256&&this.seen.delete(this.seen.values().next().value)}async emit(e,t={},s={}){let a={eventId:globalThis.crypto?.randomUUID?.()||`event_${Date.now()}_${Math.random().toString(36).slice(2)}`,originId:this.originId,type:e,payload:t,timestamp:Date.now()};this._remember(a.eventId);try{await this._dispatch(a)}finally{s.broadcast!==!1&&this.channel.postMessage(a)}return a}async _receive(e){if(!(!e||e.originId===this.originId||e.eventId&&this.seen.has(e.eventId))){if(!e.eventId){let t=e.type==="refresh"?"legacy-refresh":e.type;return this._dispatch({...e,type:t,payload:e.payload||{},eventId:`legacy_${Date.now()}_${Math.random()}`,originId:"legacy",timestamp:Date.now()})}this._remember(e.eventId),await this._dispatch(e)}}};d(Qi,"JhsEventBus");var Gi=Qi,F;function ol(){if(F)return F;F=new Gi;let o=window;return o.refresh=()=>F?.emit("legacy-refresh"),o.cleanCache_filter_actor_actress_car_list=()=>F?.emit("blacklist-rules-changed"),o.clean_cacheSettingObj=()=>F?.emit("settings-changed",{source:"legacy"}),F}d(ol,"initializeEventBus");var dt;function ll(o,{clogMsgCount:e=2e3}={}){if(dt)return dt;let t=Math.min(3e3,Math.max(100,Number(e)||2e3)),s;document.head.insertAdjacentHTML("beforeend",`
        <style>
            .loading-container {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                display: flex;
                justify-content: center;
                align-items: center;
                background-color: rgba(0, 0, 0, 0.1);
                z-index: var(--jhs-z-loading);
            }

            .loading-animation {
                position: relative;
                width: 60px;
                height: 12px;
                background: linear-gradient(90deg, #4facfe 0%, #00f2fe 100%);
                border-radius: 6px;
                animation: loading-animate 1.8s ease-in-out infinite;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
            }

            .loading-animation:before,
            .loading-animation:after {
                position: absolute;
                display: block;
                content: "";
                animation: loading-animate 1.8s ease-in-out infinite;
                height: 12px;
                border-radius: 6px;
                box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
            }

            .loading-animation:before {
                top: -20px;
                left: 10px;
                width: 40px;
                background: linear-gradient(90deg, #ff758c 0%, #ff7eb3 100%);
            }

            .loading-animation:after {
                bottom: -20px;
                width: 35px;
                background: linear-gradient(90deg, #ff9a9e 0%, #fad0c4 100%);
            }

            @keyframes loading-animate {
                0% {
                    transform: translateX(40px);
                }
                50% {
                    transform: translateX(-30px);
                }
                100% {
                    transform: translateX(40px);
                }
            }
        </style>
    `),document.head.insertAdjacentHTML("beforeend","<style>@media (prefers-reduced-motion:reduce){.loading-animation,.loading-animation:before,.loading-animation:after{animation:none}}</style>"),window.loading=function(){let r=document.createElement("div");r.className="loading-container",r.setAttribute("role","status"),r.setAttribute("aria-live","polite"),r.setAttribute("aria-label","处理中"),r.setAttribute("aria-busy","true");let n=document.createElement("div");return n.className="loading-animation",r.appendChild(n),document.body.appendChild(r),{close:d(()=>{r&&r.parentNode&&r.parentNode.removeChild(r)},"close")}},(function(){let r=d((n,l,c,h,u)=>{let p;typeof c=="object"?(p=c,p.gravity||(p.gravity="top"),p.position||(p.position="center")):(p=typeof h=="object"?h:u||{},p.gravity=c||"top",p.position=typeof h=="string"?h:"center"),p.gravity&&p.gravity!=="center"||(p.offset={y:"calc(50vh - 150px)"});let g="var(--jhs-status-fav)",m="var(--jhs-status-fav-tint)",f="var(--jhs-status-down)",v="var(--jhs-status-down-tint)",b="var(--jhs-status-filter)",w="var(--jhs-status-filter-tint)",S={borderRadius:"12px",padding:"12px 16px",boxShadow:"0 4px 6px rgba(0,0,0,0.1)",minWidth:"150px",textAlign:"center",zIndex:J.debug},j={text:n,duration:2500,close:!1,gravity:"top",position:"center",style:{info:{...S,background:`${g}`,color:"var(--jhs-status-fav-on)"},success:{...S,background:`${f}`,color:"var(--jhs-status-down-on)"},error:{...S,background:`${b}`,color:"var(--jhs-status-filter-on)"}}[l],stopOnFocus:!0,oldestFirst:!1,...p};j.duration===-1&&(j.close=!0);let k=Toastify(j);return k.showToast(),k.closeShow=()=>{k.toastElement.remove()},k},"e");window.show={ok:d((n,l="center",c,h)=>r(n,"success",l,c,h),"ok"),error:d((n,l="center",c,h)=>r(n,"error",l,c,h),"error"),info:d((n,l="center",c,h)=>r(n,"info",l,c,h),"info")}})(),(function(){let r=null;document.head.insertAdjacentHTML("beforeend",`<style>
        .jhs-image-viewer-owner { position:relative; overflow:hidden!important; }
        .jhs-image-viewer-host { position:absolute; inset:0; overflow:hidden; }
        .jhs-fc2-image-viewer .viewer-canvas { overflow:hidden!important; }
        .jhs-fc2-image-viewer .viewer-footer { padding:8px; box-sizing:border-box; background:var(--jhs-surface); }
        .jhs-image-viewer-toolbar { display:flex; align-items:center; justify-content:center; flex-wrap:wrap; gap:8px; }
        .jhs-fc2-image-viewer .jhs-btn { min-width:44px; min-height:44px; }
        .jhs-image-viewer-nav,.jhs-image-viewer-close { position:absolute; z-index:var(--jhs-z-local-popover); padding:0; width:44px; height:44px; font-size:28px; }
        .jhs-image-viewer-nav { top:calc(50% - 22px); }
        .jhs-image-viewer-prev { left:8px; }
        .jhs-image-viewer-next { right:8px; }
        .jhs-image-viewer-close { right:8px; top:8px; }
        .jhs-image-viewer-count { min-width:48px; color:var(--jhs-text-muted); font-size:var(--jhs-font-size-sm); }
    </style>`),document.head.insertAdjacentHTML("beforeend",`
        <style>
            .viewer-canvas {
                overflow: auto !important;
            }

            .viewer-close {
                background: rgba(222, 51, 51, 0.6) !important; /* 状态红 --jhs-status-filter 半透明弱化 */
            }
            .viewer-close:hover {
                background: rgba(222, 51, 51, 0.8) !important;
            }
        </style>
    `),window.showImageViewer=function(n,l="",c={}){let h=null,u=!1;if(typeof n=="string"||n instanceof String){let U=document.createElement("div"),X=document.createElement("img");U.className="temporary-container jhs-layout-c8be1ccb",X.src=String(n),X.alt=String(l),U.appendChild(X),document.body.appendChild(U),h=$(U),u=!0}else h=$(n);let p=h.is("img")?h[0]:h.find("img")[0],g=p?.closest(".jhs-fc2-workspace"),m=g?.querySelector('[data-jhs-slot="gallery"]'),f=m?.contains(p)?$(m):c.galleryRoot?$(c.galleryRoot):null,v=f?.length?f:h,b=v.find("img").addBack("img").toArray(),w=Math.max(0,b.indexOf(p)),S=b.length>1;if(!p||!v.length||!p.isConnected||o.disposed)return void(u&&h.remove());r?.close(!1);let j=p.closest(".layui-layer"),k=p.closest("button,a,[tabindex]")||document.activeElement,x=g&&j?.querySelector(".layui-layer-content"),_=new te("ui:image-viewer"),E=document.documentElement.style.overflow,L=document.body.style.overflow,M,P,z,O,H=g?.inert,Q=x?.classList.contains("jhs-image-viewer-owner"),se={close(U=!0){if(!_.disposed){_.dispose(),P?.();try{M?.destroy()}finally{z?.remove(),x&&(x.classList.toggle("jhs-image-viewer-owner",Q),g.inert=H),u&&h.remove(),r===se&&(r=null,document.documentElement.style.overflow=document.querySelector(".layui-layer-shade")?"hidden":j?"":E,document.body.style.overflow=L,U&&k?.isConnected&&k.focus?.({preventScroll:!0}))}}}};r=se,P=o.addCleanup(()=>se.close(!1));let ge=[...document.querySelectorAll(".layui-layer")].reduce((U,X)=>{let ie=window.getComputedStyle(X),xt=Number(ie.zIndex);return ie.display!=="none"&&Number.isFinite(xt)?Math.max(U,xt+1):U},J.viewer);if(x){z=document.createElement("div"),z.className="jhs-image-viewer-host",z.style.zIndex=String(ge);let U=document.createElement("div");U.hidden=!0,b.forEach(X=>{let ie=document.createElement("img");ie.src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1' height='1'/%3E",ie.setAttribute("data-jhs-viewer-source",X.currentSrc||X.src),ie.alt=X.alt,U.appendChild(ie)}),z.appendChild(U),x.classList.add("jhs-image-viewer-owner"),x.appendChild(z),g.inert=!0,v=$(U)}let Ee=d(U=>U<0?M?.prev(!!g):M?.next(!!g),"navigate"),De={zIndex:ge,...g?{className:`jhs-fc2-image-viewer jhs-ui${x?" viewer-in":""}`,inline:!!x,zIndexInline:ge,minWidth:0,minHeight:0,button:!1,transition:!1,initialCoverage:.9,ready:d(()=>{if(_.disposed||!M?.viewer)return;let U=M.viewer,X=document.createElement("div");X.className="jhs-image-viewer-toolbar",U.setAttribute("role","dialog"),U.setAttribute("aria-label","图片预览");let ie=d((ye,Ed,Dd,Nd,Ld=U)=>{let ot=document.createElement("button");return ot.type="button",ot.className=`jhs-btn jhs-btn--secondary ${Dd}`,ot.setAttribute("aria-label",ye),ot.textContent=Ed,_.listen(ot,"click",Po=>{Po.preventDefault(),Po.stopPropagation(),Nd()}),Ld.appendChild(ot),ot},"button"),xt=ie("关闭图片","×","jhs-image-viewer-close",()=>se.close());S&&(ie("上一张","‹","jhs-image-viewer-nav jhs-image-viewer-prev",()=>Ee(-1)),ie("下一张","›","jhs-image-viewer-nav jhs-image-viewer-next",()=>Ee(1))),ie("放大图片","放大","",()=>M.zoom(.1),X),ie("缩小图片","缩小","",()=>M.zoom(-.1),X),ie("适应窗口","适应","",()=>M.reset(),X),O=document.createElement("span"),O.className="jhs-image-viewer-count",O.setAttribute("aria-live","polite"),X.appendChild(O),M.footer.appendChild(X);let us=-1/0;if(_.listen(U,"wheel",ye=>{!S||ye.ctrlKey||!ye.deltaY||(ye.preventDefault(),ye.stopPropagation(),!(ye.timeStamp-us<180)&&(us=ye.timeStamp,Ee(Math.sign(ye.deltaY))))},{passive:!1}),x&&typeof ResizeObserver<"u"){let ye=new ResizeObserver(()=>{M?.ready&&!_.disposed&&M.resize()});ye.observe(z),_.ownObserver(ye)}xt.focus({preventScroll:!0})},"bindFc2Controls")}:{},...x?{url:"data-jhs-viewer-source"}:{},navbar:!1,initialViewIndex:w,zoomOnWheel:!1,zoomRatio:.1,toggleOnDblclick:!1,toolbar:g?!1:{prev:S?1:0,zoomIn:1,zoomOut:1,reset:1,next:S?1:0,rotateLeft:0,rotateRight:0,flipHorizontal:0,flipVertical:0},title:!1,keyboard:!1,viewed(){if(_.disposed)return;if(g){M.resize(),O&&(O.textContent=`${M.index+1} / ${b.length}`);return}M.zoomTo(1.4);let U=(M.viewerData.width-M.imageData.width)/2,X=(M.viewerData.height-M.imageData.height)/2;M.moveTo(U,X)},shown(){_.disposed||(document.documentElement.style.overflow="hidden",document.body.style.overflow="hidden")},hidden(){se.close()}};try{_.listen(document,"keydown",U=>{if(S&&U.key==="ArrowLeft")return U.preventDefault(),U.stopPropagation(),void Ee(-1);if(S&&U.key==="ArrowRight")return U.preventDefault(),U.stopPropagation(),void Ee(1);if(g&&U.key==="Tab"&&M?.viewer){let X=[...M.viewer.querySelectorAll("button")],ie=X.indexOf(document.activeElement);U.preventDefault(),X[(ie+(U.shiftKey?-1:1)+X.length)%X.length]?.focus();return}(U.key==="Escape"||!g&&U.key===" ")&&(U.preventDefault(),U.stopPropagation(),se.close())},!0),_.observe(document.body,()=>{(!p.isConnected||j&&!j.isConnected)&&se.close(!1)},{childList:!0,subtree:!0}),M=new Viewer(v[0],De),M.show()}catch(U){throw se.close(!1),U}}})(),window.ImageHoverPreview=class{constructor(r={}){this.scope=new te(`ui:image-hover:${Date.now()}`),this.config={selector:".hover-preview",dataAttribute:"data-full",maxWidth:1e3,maxHeight:1e3,offsetX:20,offsetY:20,zIndex:J.hoverPreview,owner:null,resolveOwner:null,zIndexStrategy:"fixed",transition:.2,hideDelay:100,loadedUrlLimit:128,autoAdjustPosition:!0,...r},this.config.loadedUrlLimit=Math.max(1,Number(this.config.loadedUrlLimit)||128),this.preview=null,this.currentTarget=null,this.timer=null,this.imgElement=null,this.pendingImage=null,this.placement=null,this.pointer=null,this.animationFrame=null,this.loadGeneration=0,this.destroyed=!1,this.currentUrl=null,this.pendingUrl=null,this.loadedUrls=new Map,this.eventsBound=!1,this.overlayObserver=null,this.onMouseEnter=n=>this.handleMouseEnter(n),this.onMouseLeave=n=>this.handleMouseLeave(n),this.onMouseMove=n=>this.handleMouseMove(n),this.onDocumentOver=n=>this.handleDocumentOver(n),this.onDocumentOut=n=>this.handleDocumentOut(n),this.onDocumentMove=n=>this.handleDocumentMove(n),this.onDocumentScroll=()=>this.handleDocumentScroll(),this.suppressUntilMouseMove=!1,this.init()}init(){utils.isMobileMode()||(this.injectStyles(),this.createPreviewElement(),this.bindEvents())}injectStyles(){if(document.getElementById("jhs-image-hover-preview-style"))return;let r=document.createElement("style");r.id="jhs-image-hover-preview-style",r.textContent=`
            .image-hover-preview {
                position: fixed;
                display: block;
                visibility: hidden;
                overflow: hidden;
                pointer-events: none;
                opacity: 0;
                border-radius: var(--jhs-radius-xs);
                background-color: var(--jhs-surface);
                box-shadow: var(--jhs-shadow-lg);
                transition: opacity var(--jhs-hover-transition, .2s) ease;
            }
            .image-hover-preview.active { visibility: visible; opacity: 1; }
            .image-hover-preview img { display: block; width: 100%; height: 100%; object-fit: contain; }
            .image-hover-preview::after {
                position: absolute;
                inset: 0;
                pointer-events: none;
                background: rgba(0, 0, 0, .03);
                content: "";
            }
            .image-hover-preview.loading { min-width: 120px; min-height: 72px; }
            .image-hover-preview.loading::before {
                position: absolute;
                top: 50%;
                left: 50%;
                color: var(--jhs-text-muted);
                font-size: var(--jhs-font-size-md);
                content: "加载中...";
                transform: translate(-50%, -50%);
            }
            .image-hover-preview__error { padding: var(--jhs-space-3); color: var(--jhs-danger); }
        `,document.head.appendChild(r)}createPreviewElement(){this.preview=document.createElement("div"),this.preview.className="image-hover-preview",this.preview.style.zIndex=String(this.resolvePreviewZIndex()),this.preview.style.setProperty("--jhs-hover-transition",`${this.config.transition}s`),document.body.appendChild(this.preview)}resolveOwnerElement(){let r=typeof this.config.resolveOwner=="function"?this.config.resolveOwner():this.config.owner;return r?.jquery?r[0]:r}resolvePreviewZIndex(){let r=Number(this.config.zIndex)||J.hoverPreview;if(this.config.zIndexStrategy!=="owner"&&!this.resolveOwnerElement())return r;let n=this.resolveOwnerElement();for(;n;){let l=typeof getComputedStyle=="function"?getComputedStyle(n).zIndex:"",c=Number(n.style?.zIndex||l);if(Number.isFinite(c)&&c>0){r=c+1;break}n=n.parentElement}return r}refreshOwnerZIndex(){if(this.preview&&(this.config.zIndexStrategy==="owner"||this.resolveOwnerElement())){let r=String(this.resolvePreviewZIndex());this.preview.style.zIndex!==r&&(this.preview.style.zIndex=r)}}isOwnerUncovered(){let r=this.resolveOwnerElement();if(!r)return this.config.zIndexStrategy!=="owner";if(!r.isConnected||!this.currentTarget?.isConnected||!r.contains(this.currentTarget))return!1;let n=r.closest(".layui-layer"),l=Number(n&&window.getComputedStyle(n).zIndex)||0;return![...document.querySelectorAll(".layui-layer, .viewer-container, .fancybox-container, .loading-container")].some(c=>{if(c===n||c.contains(r))return!1;let h=window.getComputedStyle(c);return!c.getClientRects().length||h.display==="none"||h.visibility==="hidden"?!1:!c.matches(".layui-layer")||Number(h.zIndex)>=l})}watchOwnerOverlays(){!this.resolveOwnerElement()||this.overlayObserver||(this.overlayObserver=this.scope.observe(document.body,()=>{this.isOwnerUncovered()?this.refreshOwnerZIndex():this.hidePreview()},{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","hidden"]}))}bindEvents(){this.eventsBound||this.destroyed||(this.scope.listen(document,"mouseover",this.onDocumentOver),this.scope.listen(document,"mouseout",this.onDocumentOut),this.scope.listen(document,"mousemove",this.onDocumentMove),this.scope.listen(document,"scroll",this.onDocumentScroll,{capture:!0,passive:!0}),this.scope.listen(document,"wheel",this.onDocumentScroll,{passive:!0}),this.eventsBound=!0)}handleDocumentScroll(){this.destroyed||!this.currentTarget||(this.suppressUntilMouseMove=!0,clearTimeout(this.timer),this.timer=null,this.hidePreview())}findTarget(r){let n=r.target;return n?.closest?n.closest(this.config.selector):null}handleDocumentOver(r){if(this.suppressUntilMouseMove)return;let n=this.findTarget(r);n&&(!r.relatedTarget||!n.contains(r.relatedTarget))&&this.handleMouseEnter(r,n)}handleDocumentOut(r){let n=this.findTarget(r);n&&(!r.relatedTarget||!n.contains(r.relatedTarget))&&this.handleMouseLeave()}handleDocumentMove(r){this.suppressUntilMouseMove=!1,this.currentTarget&&(r.target===this.currentTarget||this.currentTarget.contains(r.target))&&this.handleMouseMove(r)}handleMouseEnter(r,n=r.currentTarget){if(this.destroyed||!this.preview)return;if(this.refreshOwnerZIndex(),clearTimeout(this.timer),this.timer=null,this.currentTarget=n,!this.isOwnerUncovered())return this.hidePreview();this.watchOwnerOverlays(),this.pointer={x:r.clientX,y:r.clientY},this.placement=null;let l=this.currentTarget.getAttribute(this.config.dataAttribute)||this.currentTarget.src;if(!l)return;if(l===this.currentUrl&&this.imgElement)return this.showCurrentPreview();if(l===this.pendingUrl)return void this.preview.classList.add("active");let c=this.loadedUrls.get(l);if(c)return++this.loadGeneration,this.pendingImage&&(this.pendingImage.onload=null,this.pendingImage.onerror=null),this.pendingImage=null,this.pendingUrl=null,this.loadedUrls.delete(l),this.loadedUrls.set(l,c),void this.commitPreview(l,c);let h=++this.loadGeneration;this.pendingImage&&(this.pendingImage.onload=null,this.pendingImage.onerror=null),this.pendingUrl=l,this.currentUrl?this.showCurrentPreview():(this.preview.replaceChildren(),this.preview.classList.add("loading","active"));let u=new Image;this.pendingImage=u,u.onload=()=>{if(this.destroyed||h!==this.loadGeneration||!this.preview)return;let{width:p,height:g}=this.calculateImageSize(u),m={width:p,height:g};for(this.loadedUrls.set(l,m);this.loadedUrls.size>this.config.loadedUrlLimit;)this.loadedUrls.delete(this.loadedUrls.keys().next().value);this.pendingImage=null,this.pendingUrl=null,this.commitPreview(l,m)},u.onerror=()=>{if(this.destroyed||h!==this.loadGeneration||!this.preview)return;if(this.pendingImage=null,this.pendingUrl=null,this.currentUrl)return void this.preview.classList.add("active");let p=document.createElement("div");p.className="image-hover-preview__error",p.textContent="图片加载失败",this.preview.replaceChildren(p),this.preview.classList.remove("loading"),this.preview.classList.add("active")},u.src=l}commitPreview(r,n){if(!this.preview)return;let l=document.createElement("img");l.src=r,l.alt="预览图",this.preview.replaceChildren(l),this.imgElement=l,this.currentUrl=r,this.preview.style.width=`${n.width}px`,this.preview.style.height=`${n.height}px`,this.preview.classList.remove("loading"),this.showCurrentPreview()}showCurrentPreview(){if(!this.preview||!this.pointer||!this.imgElement)return;if(!this.isOwnerUncovered())return this.hidePreview();let r=this.preview.offsetWidth,n=this.preview.offsetHeight;this.placement=this.choosePlacement(this.pointer.x,this.pointer.y,r,n),this.preview.classList.add("active"),this.schedulePosition()}calculateImageSize(r){let l=Math.max(1,window.innerWidth-2*(8+this.config.offsetX)),c=Math.max(1,window.innerHeight-2*(8+this.config.offsetY)),h=Math.min(this.config.maxWidth,l),u=Math.min(this.config.maxHeight,c),p=Math.min(1,h/r.naturalWidth,u/r.naturalHeight);return{width:Math.max(1,Math.round(r.naturalWidth*p)),height:Math.max(1,Math.round(r.naturalHeight*p))}}choosePlacement(r,n,l,c){if(!this.config.autoAdjustPosition)return{horizontal:"right",vertical:"bottom"};let h=window.innerWidth-r-this.config.offsetX,u=r-this.config.offsetX,p=window.innerHeight-n-this.config.offsetY,g=n-this.config.offsetY;return{horizontal:h>=l||h>=u?"right":"left",vertical:p>=c||p>=g?"bottom":"top"}}handleMouseMove(r){!this.currentTarget||!this.preview?.classList.contains("active")||(this.pointer={x:r.clientX,y:r.clientY},this.schedulePosition())}schedulePosition(){this.animationFrame||!this.pointer||!this.placement||(this.animationFrame=requestAnimationFrame((()=>{this.animationFrame=null,this.applyPosition()})))}applyPosition(){if(!this.preview||!this.pointer||!this.placement)return;let r=8,n=this.preview.offsetWidth,l=this.preview.offsetHeight,c=this.placement.horizontal==="right"?this.pointer.x+this.config.offsetX:this.pointer.x-n-this.config.offsetX,h=this.placement.vertical==="bottom"?this.pointer.y+this.config.offsetY:this.pointer.y-l-this.config.offsetY;c=Math.min(Math.max(r,c),Math.max(r,window.innerWidth-n-r)),h=Math.min(Math.max(r,h),Math.max(r,window.innerHeight-l-r)),this.preview.style.left=`${c}px`,this.preview.style.top=`${h}px`}handleMouseLeave(){this.preview&&(clearTimeout(this.timer),this.timer=setTimeout((()=>this.hidePreview()),this.config.hideDelay))}hidePreview(){this.preview&&(clearTimeout(this.timer),this.overlayObserver&&(this.scope.releaseObserver(this.overlayObserver),this.overlayObserver=null),++this.loadGeneration,this.pendingImage&&(this.pendingImage.onload=null,this.pendingImage.onerror=null),this.pendingImage=null,this.pendingUrl=null,this.preview.classList.remove("active","loading"),this.currentTarget=null,this.pointer=null,this.placement=null,this.timer=null)}destroy(){this.destroyed||(this.destroyed=!0,++this.loadGeneration,clearTimeout(this.timer),this.animationFrame&&cancelAnimationFrame(this.animationFrame),this.animationFrame=null,this.pendingImage&&(this.pendingImage.onload=null,this.pendingImage.onerror=null),this.pendingImage=null,this.eventsBound&&(this.scope.dispose(),this.eventsBound=!1),this.overlayObserver=null,this.loadedUrls.clear(),this.preview?.remove(),this.preview=null,this.currentTarget=null)}},(function(){document.head.insertAdjacentHTML("beforeend",`
        <style>
            .console-logger-container {
                position: fixed;
                bottom: 0;
                right: 0;
                z-index: var(--jhs-z-loading);
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                display: flex;
                flex-direction: column;
                align-items: flex-end;
                width: fit-content;
            }

            .console-logger-toggle {
                width: 40px;
                height: 30px;
                background: var(--jhs-accent);
                border-radius: 120px 10px 0 0;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1);
                transition: all 0.3s ease;
                color: var(--jhs-accent-text-on);
                font-size: 16px;
            }

            .console-logger-toggle:hover {
                background: var(--jhs-accent-hover);
            }

            .console-logger-toggle::after {
                content: '▼';
                transition: transform 0.3s ease;
            }

            .console-logger-toggle.collapsed::after {
                content: '▲';
            }

            .console-logger-window {
                width: 400px;
                height: 400px;
                background: var(--jhs-surface);
                border-radius: 10px 0 10px 10px;
                box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
                display: flex;
                flex-direction: column;
                overflow: hidden;
                transform: translateY(0);
                opacity: 1;
                /* 简化过渡属性 */
                transition: width 0.3s ease, height 0.3s ease, opacity 0.3s ease, transform 0.3s ease;
            }

            .console-logger-window.maximized {
                width: 600px !important;
                height: 85vh !important;
                border-radius: 10px 0 0 10px; /* 调整圆角以匹配右下角 */
            }

            .console-logger-window.collapsed {
                height: 0 !important;
                min-height: 0 !important;
                opacity: 0;
            }

            .console-logger-header {
                background: var(--jhs-accent);
                color: var(--jhs-accent-text-on);
                padding: 12px 15px;
                display: flex;
                justify-content: space-between;
                align-items: center;
                flex-shrink: 0;
            }

            .console-logger-title {
                font-weight: 600;
                font-size: 16px;
            }

            .console-logger-controls {
                display: flex;
                gap: 10px;
            }

            .console-logger-controls button {
                background: transparent;
                border: 1px solid rgba(255, 255, 255, 0.3);
                padding: 5px 10px;
                font-size: 12px;
                color: var(--jhs-accent-text-on);
                border-radius: 4px;
                cursor: pointer;
                transition: background 0.3s;
            }

            .console-logger-controls button:hover {
                background: rgba(255, 255, 255, 0.1);
            }

            /* 新增的按钮样式 */
            .console-logger-maximize-toggle {
                line-height: 1;
                font-size: 14px !important; /* 使箭头看起来更大 */
                padding: 5px 8px !important;
            }
            .console-logger-maximize-toggle::before {
                content: '⇱'; /* Unicode symbol for maximized */
            }
            .console-logger-maximize-toggle.active::before {
                content: '⇲'; /* Unicode symbol for minimized */
            }


            .console-logger-filters {
                display: flex;
                align-items: center;
                gap: 5px;
                padding: 10px;
                background: var(--jhs-surface-2);
                border-bottom: 1px solid var(--jhs-border);
                flex-shrink: 0;
                overflow-x: hidden;
            }

            /* 新增: 过滤器按钮组的容器,负责滚动 */
            .console-logger-filter-group {
                display: flex;
                gap: 5px;
                overflow-x: auto; /* 允许过滤器按钮滚动 */
                flex-grow: 1; /* 占据剩余空间 */
                padding-right: 10px; /* 避免滚动条影响按钮 */
            }

            .console-logger-filter {
                padding: 5px 10px;
                font-size: 12px;
                border-radius: 15px;
                background: var(--jhs-input-bg);
                color: var(--jhs-text-muted);
                border: 1px solid var(--jhs-border);
                cursor: pointer;
                transition: all 0.3s;
                white-space: nowrap;
                flex-shrink: 0; /* 确保不被压缩 */
            }

            .console-logger-filter.active {
                background: var(--jhs-accent);
                color: var(--jhs-accent-text-on);
                border-color: var(--jhs-accent);
            }

            /* 新增: 滚动到底部按钮的样式 (位于 filtersContainer 内部右侧) */
            .console-logger-scroll-to-bottom {
                background: var(--jhs-accent);
                border: none;
                padding: 5px 10px;
                font-size: 12px;
                color: var(--jhs-accent-text-on);
                border-radius: 4px;
                cursor: pointer;
                transition: background 0.3s;
                line-height: 1;
                height: fit-content;
                white-space: nowrap;
                margin-left: auto; /* 将按钮推到最右侧 */
                flex-shrink: 0; /* 确保不被压缩 */
            }

            .console-logger-scroll-to-bottom:hover {
                background: var(--jhs-accent-hover);
            }


            .console-logger-content {
                flex: 1;
                overflow-y: auto;
                padding: 10px;
                background: var(--jhs-surface);
                word-wrap: break-word;
                text-align: left;
            }

            .console-logger-entry {
                padding: 8px 10px;
                margin-bottom: 3px;
                border-radius: 4px;
                font-size: 12px;
                line-height: 1.4;
                /*animation: consoleFadeIn 0.3s ease;*/
                border-left: 3px solid transparent;
            }

            @keyframes consoleFadeIn {
                from { opacity: 0; transform: translateY(5px); }
                to { opacity: 1; transform: translateY(0); }
            }

            .console-logger-timestamp {
                color: var(--jhs-text-muted);
                font-size: 11px;
                margin-right: 2px;
            }

            @media (max-width: 767px) {
                .console-logger-container {
                    right: 10px;
                    bottom: 10px;
                }

                .console-logger-window {
                    width: calc(100vw - 20px);
                    height: 300px;
                }
            }

            .console-logger-message[data-type="json"] {
                white-space: pre-wrap;
            }
        </style>
    `),document.head.insertAdjacentHTML("beforeend",`<style>
        .console-logger-container { font-family:inherit; z-index:var(--jhs-z-debug); }
        .console-logger-toggle { border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md) var(--jhs-radius-md) 0 0; box-shadow:var(--jhs-shadow-sm); transition:background-color var(--jhs-motion-fast) ease; }
        .console-logger-toggle::after { transition:transform var(--jhs-motion-fast) ease; }
        .console-logger-window { border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md) 0 var(--jhs-radius-md) var(--jhs-radius-md); box-shadow:var(--jhs-shadow-lg); transition:width var(--jhs-motion-fast) ease,height var(--jhs-motion-fast) ease,opacity var(--jhs-motion-fast) ease,transform var(--jhs-motion-fast) ease; }
        .console-logger-window.maximized { border-radius:var(--jhs-radius-md) 0 0 var(--jhs-radius-md); }
        .console-logger-controls button,.console-logger-filter,.console-logger-scroll-to-bottom,.console-logger-entry { border-radius:var(--jhs-radius-sm); }
        .console-logger-controls button,.console-logger-scroll-to-bottom { transition:background-color var(--jhs-motion-fast) ease; }
        .console-logger-filter { transition:background-color var(--jhs-motion-fast) ease,border-color var(--jhs-motion-fast) ease; }
        @media (prefers-reduced-motion:reduce) { .console-logger-toggle,.console-logger-toggle::after,.console-logger-window,.console-logger-controls button,.console-logger-filter,.console-logger-scroll-to-bottom { transition:none; } }
    </style>`);let r={base:{label:"信息",background:"var(--jhs-status-fav-tint)",borderLeftColor:"var(--jhs-accent)"},warn:{label:"警告",background:"var(--jhs-status-watch-tint)",borderLeftColor:"var(--jhs-status-watch)"},error:{label:"错误",background:"var(--jhs-status-filter-tint)",borderLeftColor:"var(--jhs-status-filter)"},debug:{label:"调试",background:"var(--jhs-surface-2)",borderLeftColor:"var(--jhs-border-strong)"}},n={base:["base","warn","error"],warn:["warn"],error:["error"],debug:["base","warn","error","debug"]},l=t,c="jhs_clog_maximize",h="jhs_clog_expand",u="jhs_clog_filter",g=class g{constructor(){let f=localStorage.getItem(u);this.currentFilter=f&&r[f]?f:"base",this.logs=[],this.isInitialized=!1,this.userScrolledUp=!1}tryInitialize(){return document.readyState!=="loading"&&(this.isInitialized||(this.init(),this.isInitialized=!0),!0)}init(){this.createContainer(),this.bindEvents(),this.checkInitialMaximizeState(),this.checkInitialCollapseState()}createContainer(){this.container=document.createElement("div"),this.container.className="console-logger-container jhs-ui",this.container.style.display="none",this.toggleBtn=document.createElement("button"),this.toggleBtn.type="button",this.toggleBtn.setAttribute("aria-label","展开或收起运行日志"),this.toggleBtn.className="console-logger-toggle collapsed",this.container.appendChild(this.toggleBtn),window.matchMedia?.("(max-width: 767px)").matches&&(this.toggleBtn.hidden=!0,this.toggleBtn.style.display="none"),this.window=document.createElement("div"),this.window.className="console-logger-window collapsed";let f=document.createElement("div");f.className="console-logger-header";let v=document.createElement("div");v.className="console-logger-title",v.textContent="JHS Console";let b=document.createElement("div");b.className="console-logger-controls",this.maximizeBtn=document.createElement("button"),this.maximizeBtn.textContent="",this.maximizeBtn.classList.add("console-logger-maximize-toggle"),b.appendChild(this.maximizeBtn);let w=document.createElement("button");w.textContent="清空",w.addEventListener("click",(()=>this.clear())),b.appendChild(w),f.appendChild(v),f.appendChild(b),this.filtersContainer=document.createElement("div"),this.filtersContainer.className="console-logger-filters",this.filterButtonGroup=document.createElement("div"),this.filterButtonGroup.className="console-logger-filter-group",this.filtersContainer.appendChild(this.filterButtonGroup),this.scrollToBottomBtn=document.createElement("button"),this.scrollToBottomBtn.className="console-logger-scroll-to-bottom",this.scrollToBottomBtn.textContent="到底部",this.filtersContainer.appendChild(this.scrollToBottomBtn),this.content=document.createElement("div"),this.content.className="console-logger-content jhs-scrollbar",this.window.appendChild(f),this.window.appendChild(this.filtersContainer),this.window.appendChild(this.content),this.container.appendChild(this.window),document.body.appendChild(this.container),Object.keys(r).forEach((S=>{let j=document.createElement("button");j.type="button",j.className="jhs-btn console-logger-filter",S===this.currentFilter&&j.classList.add("active"),j.textContent=r[S].label,j.dataset.type=S,j.addEventListener("click",(()=>this.setFilter(S))),this.filterButtonGroup.appendChild(j)}))}bindEvents(){this.toggleBtn.addEventListener("click",(()=>{this.toggleExpandCollapsed()})),this.maximizeBtn.addEventListener("click",(()=>this.toggleMaximize())),this.scrollToBottomBtn.addEventListener("click",(()=>{this.content.scrollTop=this.content.scrollHeight,this.userScrolledUp=!1})),this.content.addEventListener("scroll",(()=>{let f=this.content.scrollHeight-this.content.clientHeight<=this.content.scrollTop+5;this.userScrolledUp=!f})),this.content.addEventListener("wheel",(f=>{let v=this.content.scrollTop===0,b=this.content.scrollHeight-this.content.clientHeight<=this.content.scrollTop+1;(v&&f.deltaY<0||b&&f.deltaY>0)&&(f.preventDefault(),f.stopPropagation())}),{passive:!1})}toggleExpandCollapsed(){let f=this.window.classList.toggle("collapsed");this.toggleBtn.classList.toggle("collapsed"),f?localStorage.setItem(h,"no"):(localStorage.setItem(h,"yes"),this.reRenderAllLogs())}checkInitialCollapseState(){let f=localStorage.getItem(h);f&&f!=="no"?(this.window.classList.toggle("collapsed"),this.toggleBtn.classList.toggle("collapsed"),setTimeout((()=>{this.content.scrollTop=this.content.scrollHeight}),0)):(this.window.classList.add("collapsed"),this.toggleBtn.classList.add("collapsed"))}checkInitialMaximizeState(){localStorage.getItem(c)==="maximized"&&(this.window.classList.add("maximized"),this.maximizeBtn.classList.add("active"))}toggleMaximize(){let f=this.window.classList.toggle("maximized");this.maximizeBtn.classList.toggle("active",f),f?localStorage.setItem(c,"maximized"):localStorage.setItem(c,"minimized"),this.window.classList.contains("collapsed")||(this.content.scrollTop=this.content.scrollHeight)}addLog(f,v="base",...b){return this._appendLog(!1,f,v,...b)}addHtmlLog(f,v="base",...b){return this._appendLog(!0,f,v,...b)}_appendLog(f,v,b="base",...w){let S=this.tryInitialize(),j,k=[];r[b]?(j=b,k=w):(j="base",k=[b,...w]),j=r[j]?j:"base";let x=[v,...k],_="msg",E=[];x.forEach((P=>{if(Object.prototype.toString.call(P)==="[object Error]")E.push(String(P));else if(typeof P=="object"&&P!==null)try{E.push("<br/>"+JSON.stringify(P,null,2)),_="json"}catch{E.push(String(P)),_="msg"}else E.push(String(P))}));let L=E.join("  ");f&&(L=L.replace(/(?:(?:https?|ftp):\/\/|www\.|(?:\/\/))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]/gi,(P=>{let z=P.startsWith("http")||P.startsWith("ftp"),O=P.startsWith("//"),H=P.startsWith("www."),Q=P;return O?Q=`http:${P}`:!z&&H&&(Q=`http://${P}`),`<a href="${C(Q)}" target="_blank">${C(P)}</a>`})));let M={message:L,messageType:_,type:j,html:f,timestamp:new Date,id:Date.now()+Math.random()};if(this.logs.push(M),this.logs.length>l){this.logs.shift();let P=this.content.querySelector(".console-logger-entry");P&&P.remove()}S&&this.renderLog(M)}log(...f){let[v,...b]=f;setTimeout((()=>{this.addLog(v,"base",...b)}),0)}html(...f){let[v,...b]=f;setTimeout((()=>{this.addHtmlLog(v,"base",...b)}),0)}htmlDebug(...f){let[v,...b]=f;setTimeout((()=>{this.addHtmlLog(v,"debug",...b)}),0)}error(...f){let[v,...b]=f;console.error(...f),setTimeout((()=>{this.addLog(v,"error",...b)}),0)}warn(...f){let[v,...b]=f;setTimeout((()=>{this.addLog(v,"warn",...b)}),0)}debug(...f){let[v,...b]=f;setTimeout((()=>{this.addLog(v,"debug",...b)}),0)}renderLog(f){if(this.container.style.display==="none"||this.window.classList.contains("collapsed")||!(n[this.currentFilter]||[]).includes(f.type))return;let v=this._createLogElement(f);this.content.appendChild(v),this.window.classList.contains("collapsed")||this.userScrolledUp||(this.content.scrollTop=this.content.scrollHeight)}reRenderAllLogs(){this.container.style.display!=="none"&&(this.window.classList.contains("collapsed")||setTimeout((()=>{if(this.content.innerHTML="",this.logs.length===0)return;let f=n[this.currentFilter]||[],v=document.createDocumentFragment();this.logs.forEach((b=>{if(f.includes(b.type)){let w=this._createLogElement(b);v.appendChild(w)}})),this.content.appendChild(v),this.content.scrollTop=this.content.scrollHeight}),0))}_createLogElement(f){let v=document.createElement("div");v.className="console-logger-entry",v.dataset.type=f.type,v.dataset.id=f.id;let b=r[f.type]||r.base;v.style.borderLeft="3px solid "+b.borderLeftColor,v.style.background=b.background;let w=(f.timestamp instanceof Date?f.timestamp:new Date(f.timestamp)).toTimeString().split(" ")[0],S=document.createElement("span");S.className="console-logger-timestamp",S.textContent=`[${w}]`;let j=document.createElement("span");if(j.className="console-logger-message",j.dataset.type=f.messageType,f.html)j.innerHTML=f.message;else{let k=f.message.replace(/<br\s*\/?>/gi,`
`),x=/(?:(?:https?|ftp):\/\/|www\.|(?:\/\/))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]/gi,_=0,E;for(;E=x.exec(k);){E.index>_&&j.appendChild(document.createTextNode(k.slice(_,E.index)));let L=E[0],M=L;L.startsWith("//")?M=`http:${L}`:L.startsWith("www.")&&(M=`http://${L}`);let P=document.createElement("a");P.href=M,P.target="_blank",P.textContent=L,j.appendChild(P),_=E.index+E[0].length}_<k.length&&j.appendChild(document.createTextNode(k.slice(_)))}return v.append(S,j),v}setFilter(f){this.currentFilter!==f&&(this.currentFilter=f,localStorage.setItem(u,f),this.filterButtonGroup.querySelectorAll(".console-logger-filter").forEach((v=>{v.dataset.type===f?v.classList.add("active"):v.classList.remove("active")})),this.reRenderAllLogs())}clear(){this.logs=[],this.content.innerHTML=""}openDialog(){if(!this.tryInitialize()||!this.window||typeof layer>"u")return;let f=document.createElement("div"),v=this.window.parentNode,b=this.window.getAttribute("style");f.className="jhs-ui jhs-logger-dialog",f.style.height="100%",this.window.classList.remove("collapsed","maximized"),Object.assign(this.window.style,{width:"100%",height:"100%",border:"0",borderRadius:"0",boxShadow:"none"}),this.reRenderAllLogs(),layer.open({type:1,title:"JHS 运行日志",content:f.outerHTML,area:utils.getDialogArea("md"),anim:-1,success:d(w=>{$(w).find(".jhs-logger-dialog")[0]?.appendChild(this.window),this.content.scrollTop=this.content.scrollHeight},"success"),end:d(()=>{v?.appendChild(this.window),b==null?this.window.removeAttribute("style"):this.window.setAttribute("style",b),this.window.classList.add("collapsed"),this.toggleBtn.classList.add("collapsed")},"end")})}show(){(this.isInitialized&&this.container||this.tryInitialize()&&this.container)&&(this.container.style.display="",this.reRenderAllLogs())}hide(){this.isInitialized&&this.container&&(this.container.style.display="none")}lowZIndex(){this.isInitialized&&this.container&&(this.container.style.zIndex=String(J.debugLow))}highZIndex(){this.isInitialized&&this.container&&(this.container.style.zIndex=String(J.debug))}};d(g,"o");let p=g;try{unsafeWindow.parent!==unsafeWindow&&unsafeWindow.parent.clog&&typeof unsafeWindow.parent.clog.log=="function"?s=unsafeWindow.parent.clog:s=new p}catch(m){console.error("创建日志控制台出现异常",m),s=new p}(function(){let m=d(()=>window.clog||console,"resolveClog");o.listen(window,"error",(function(f){let v=f.filename,b=f.message;typeof v=="string"&&(v.includes("javdb")||v.includes("javbus"))||m().error(`[全局 Error 异常捕获] ${b} 来源: ${v??"未知"}`)})),o.listen(window,"unhandledrejection",(function(f){let v=m(),b=f.reason,w=b?.message??"";if(["NotAllowedError","AbortError","NotSupportedError"].includes(b?.name)||w.includes("play()")||w.includes("The element has no supported sources"))return v.warn("[全局媒体播放异常] 当前媒体源无法播放",b),void f.preventDefault();if(w.includes("<span>1005</span>")&&w.includes("fc2ppvdb"))return;let S=`[全局 Promise 异常捕获] ${b.message||b}`;v.error(S,b),f.preventDefault()}))})(),o.listen(document,"mousedown",(m=>{let f=window.clog;if(!f.isInitialized||!f.container)return;let v=m.target,b=[".console-logger-container",".layui-layer-shade",".loading-container"].join(",");v.closest(b)?f.highZIndex():f.lowZIndex()}))})(),(function(){function r(l,c,h){let u=(function(E){let L=document.createElement("div");L.classList.add("js-tooltip");let M=document.createElement("div");return M.innerHTML=C(E),L.appendChild(M),document.body.appendChild(L),L})(c);u.style.display="block";let p=l.getBoundingClientRect(),g=u.getBoundingClientRect();u.style.display="none";let m=window.innerWidth,f=window.innerHeight,v,b,w=h,S=d(E=>E>=8&&E+g.height<=f-8,"h"),j=d(E=>E>=8&&E+g.width<=m-8,"g"),k=p.left+p.width/2-g.width/2,x=p.top+p.height/2-g.height/2;switch(h){case"top":b=p.top-g.height-0,b<8&&S(p.bottom+0)&&(b=p.bottom+0,w="bottom");break;case"bottom":b=p.bottom+0,b+g.height>f-8&&S(p.top-g.height-0)&&(b=p.top-g.height-0,w="top");break;case"left":v=p.left-g.width-0,v<8&&j(p.right+0)&&(v=p.right+0,w="right");break;case"right":v=p.right+0,v+g.width>m-8&&j(p.left-g.width-0)&&(v=p.left-g.width-0,w="left")}w==="top"||w==="bottom"?(v=k,v<8?v=8:v+g.width>m-8&&(v=m-g.width-8)):(w==="left"||w==="right")&&(b=x,b<8?b=8:b+g.height>f-8&&(b=f-g.height-8)),u.style.left=`${v}px`,u.style.top=`${b}px`,u.classList.add("is-active"),l.tooltipElement=u}d(r,"e"),document.head.insertAdjacentHTML("beforeend",`
        <style>
            .js-tooltip {
                position: fixed;
                padding: 8px 12px;
                border: 1px solid var(--jhs-border);
                border-radius: var(--jhs-radius-sm);
                white-space: normal;
                max-width: 600px;
                pointer-events: none;
                font-size: 14px;
                line-height: 1.5;
                z-index: var(--jhs-z-tooltip);
                background: var(--jhs-surface-2);
                color: var(--jhs-text);
                box-shadow: var(--jhs-shadow-md);
                display: none;
            }
            .js-tooltip.is-active {
                display: block !important;
            }
        </style>
    `);let n="[data-tip-top], [data-tip-bottom], [data-tip-left], [data-tip-right], [data-tip]";o.listen(document,"mouseover",(l=>{let c=l.target.closest(n);if(c&&!c.tooltipElement){let h,u="top";if(c.hasAttribute("data-tip-bottom")?(h=c.getAttribute("data-tip-bottom"),u="bottom"):c.hasAttribute("data-tip-left")?(h=c.getAttribute("data-tip-left"),u="left"):c.hasAttribute("data-tip-right")?(h=c.getAttribute("data-tip-right"),u="right"):c.hasAttribute("data-tip-top")?(h=c.getAttribute("data-tip-top"),u="top"):c.hasAttribute("data-tip")&&(h=c.getAttribute("data-tip"),u="top"),!h)return;c.hoverTimeout=setTimeout((()=>{c.matches(":hover")&&!c.tooltipElement&&r(c,h,u)}),50)}})),o.listen(document,"mouseout",(l=>{let c=l.target.closest(n);var h;c&&(c.hoverTimeout&&(clearTimeout(c.hoverTimeout),c.hoverTimeout=null),c.contains(l.relatedTarget)||c.tooltipElement&&((h=c.tooltipElement)&&h.parentNode&&h.remove(),c.tooltipElement=null))}))})();let a=window.loading,i=window.show;return dt=Object.freeze({loading:a,show:i,clog:s}),window.loading=dt.loading,window.show=dt.show,window.clog=dt.clog,dt}d(ll,"initializeLoggerRuntime");function cl(o=window){let e={$:o.jQuery,Tabulator:o.Tabulator,layer:o.layer,md5:o.md5,Toastify:o.Toastify,localforage:o.localforage,Viewer:o.Viewer},t=Object.entries(e).filter(([,s])=>s==null).map(([s])=>s);if(t.length)throw new Error(`Missing userscript vendor runtime: ${t.join(", ")}`);return Object.freeze(e)}d(cl,"getVendorRuntime");var ch=new Set(["star","genre","maker","actress","series","tag","search","director","studio","label"]),Yi=class Yi{constructor(e=document,t=window.location){this.site="javbus",this.document=e,this.location=t}resolveFirstPageUrl(e){try{let t=new URL(e),s=t.pathname.split("/").filter(Boolean),a=s[s.length-1],i=s[s.length-2];if(s.length>=2&&/^\d+$/.test(a)&&(i==="page"||s.length>=3&&ch.has(s[s.length-3]))){let n=i==="page"?s.slice(0,-2):s.slice(0,-1);t.pathname=n.length?"/"+n.join("/"):"/"}return t.href}catch{return e}}detectRoute(){return this.locateNativeMagnets()?"detail":this.locateListRoot()?"list":"other"}readMovieRef(){let e=this.document.querySelector(".info p span, [data-car-number]")?.textContent?.trim()??null;return e?Object.freeze({carNum:e,url:this.location.href,site:"javbus"}):null}locateListRoot(){return this.document.querySelector(".masonry")}locateListItems(){return[...this.locateListRoot()?.querySelectorAll(":scope > .item, :scope > .movie-box")??[]]}getListContainer(){return this.locateListRoot()?.parentElement??null}getListLayoutContainer(){return this.document.querySelector(".container-fluid .row")}createOwnedListRoot(e=[]){let t=this.document.createElement("div");return t.classList.add("masonry",...e),t}locateDetailRoot(){return this.locateNativeMagnets()?.closest(".container")??this.document.querySelector(".container .row.movie")?.parentElement??null}locateDetailSlots(){let e=this.locateDetailRoot();return Object.freeze({summary:e?.querySelector('[data-jhs-slot="summary-actions"]')??e?.querySelector(".row.movie")??null,resources:this.locateNativeMagnets(),reviews:e?.querySelector('[data-jhs-slot="reviews"]')??this.document.querySelector("#reviews"),related:e?.querySelector('[data-jhs-slot="related"]')})}locateNativeGallery(){return this.document.querySelector("#sample-waterfall, .sample-box")}locateNativeMagnets(){return this.document.querySelector("#magnet-table")}getDetailResourceBoundary(){let e=this.locateNativeMagnets(),t=this.locateDetailRoot();return!t||!e?null:Object.freeze({site:"javbus",hostRoot:t,controller:e,observeRoot:e.parentElement,resourceRoot:e,resourceRegion:[...t.children].find(s=>s===e||s.contains(e))||e,rows:d(()=>[...e.querySelectorAll("tr")].filter(s=>s.querySelector('td a[href^="magnet:"],td a[href^="ed2k:"]')),"rows"),sortSelect:null,getResource:d(s=>s.querySelector('td a[href^="magnet:"],td a[href^="ed2k:"]')?.getAttribute("href")||"","getResource"),getTitleTarget:d(s=>s.querySelector("td:first-child a:first-child"),"getTitleTarget"),hasSubtitleTag:d(s=>[...s.querySelectorAll("td:first-child a")].slice(1).some(a=>a.textContent?.includes("字幕")),"hasSubtitleTag"),getActionTarget(s){let a=[...s.querySelectorAll(".buttons,.actions,.btn-group")].filter(n=>n.closest("td")).at(-1);return a||s.querySelector('td a[href^="magnet:"],td a[href^="ed2k:"]')?.closest("td")||null},actionTargetRequiresWrapper:d(s=>![...s.querySelectorAll(".buttons,.actions,.btn-group")].some(a=>a.closest("td")),"actionTargetRequiresWrapper")})}};d(Yi,"JavBusHostAdapter");var _s=Yi;var dh=new Set(["ABC","ABP","ADN","ATID","BF","CAWD","DLDSS","DVAJ","FSDSS","HEYZO","HMN","IPX","IPZZ","JUQ","JUL","JUX","MEYD","MIAA","MIDE","MIDV","MIMK","MIRD","NIMA","PRED","RBD","SDDE","SONE","SSIS","SSNI","STARS","URE","VEC","WAAA","WANZ","XVSR"]);function ee(o){if(typeof o!="string")return null;let e=o.trim();if(!e||["undefined","null"].includes(e.toLowerCase()))return null;e=e.normalize("NFKC").replace(/[‐‑‒–—―﹘﹣-]/g,"-").replace(/[\s_]+/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").toUpperCase();let t=e.match(/^([A-Z]{2,8})(\d{2,7})$/);return t&&dh.has(t[1])?`${t[1]}-${t[2]}`:e||null}d(ee,"normalizeMovieCarNum");function dl(o,e="https://javdb.com"){try{return new URL(String(o||""),e).pathname.match(/^\/v\/([^/]+)\/?$/)?.[1]||null}catch{return null}}d(dl,"extractJavDbMovieId");var Zi=class Zi{constructor(e=document,t=window.location){this.site="javdb",this.document=e,this.location=t}resolveFirstPageUrl(e){try{let t=new URL(e);return t.searchParams.delete("page"),t.href}catch{return e}}detectRoute(){return this.location.pathname.startsWith("/v/")||this.location.pathname.startsWith("/movies/")?"detail":this.location.pathname==="/users/collection_codes"?"owned-detail":this.location.pathname==="/advanced_search"&&["handlePlayback","handleTop"].some((e=>new URLSearchParams(this.location.search).get(e)==="1"))||this.locateListRoot()?"list":"other"}readMovieRef(){let e=this.document.querySelector(".panel-block.first-block .value, [data-car-number]")?.textContent?.trim()??null;return e?Object.freeze({carNum:e,url:this.location.href,site:"javdb"}):null}locateListRoot(){return this.document.querySelector(".movie-list")}locateListItems(){return[...this.locateListRoot()?.querySelectorAll(":scope > .item")??[]]}getListContainer(){return this.locateListRoot()?.parentElement??null}getListLayoutContainer(){return this.document.querySelector("section .container")}createOwnedListRoot(e=[]){let t=this.document.createElement("div");return t.classList.add("movie-list","h","cols-4","vcols-8",...e),t}mountOwnedListRoot(e,t){for(let s of[...e.children])s.matches(".movie-list, nav.pagination")&&s.remove();e.append(t)}locateDetailRoot(){return this.document.querySelector(".video-detail")??this.document.querySelector(".movie-panel-info")?.closest(".container")??this.document.querySelector("main")}locateDetailSlots(){let e=this.locateDetailRoot();return Object.freeze({summary:e?.querySelector('[data-jhs-slot="summary-actions"]')??this.document.querySelector(".movie-panel-info"),resources:this.document.querySelector("#magnets-content"),reviews:e?.querySelector('[data-jhs-slot="reviews"]')??this.document.querySelector("#reviews"),related:e?.querySelector('[data-jhs-slot="related"]')})}locateNativeGallery(){return this.document.querySelector(".tile-images, .preview-images")}locateNativeMagnets(){return this.document.querySelector("#magnets-content")}getDetailResourceBoundary(){let e=this.locateNativeMagnets(),t=e?.closest('[data-controller="magnet-sort"]'),s=this.locateDetailRoot();if(!s||!t||!e)return null;let a=[...s.children].find(i=>i===t||i.contains(t))||t;return Object.freeze({site:"javdb",hostRoot:s,controller:t,observeRoot:t,resourceRoot:e,resourceRegion:a,rows:d(()=>[...e.children].filter(i=>i.matches(".item")),"rows"),sortSelect:t.querySelector('select[data-action*="magnet-sort#sort"]'),prepareLayout(){e.setAttribute("data-jhs-magnets","true"),a.setAttribute("data-jhs-host-region","resources");let i=e.closest(".message.video-panel, .video-panel")||t;i.setAttribute("data-jhs-resource-surface","true");let r=e.closest(".message-body");r&&i.contains(r)&&r.setAttribute("data-jhs-resource-body","true");for(let n of e.children){if(!n.matches(".item"))continue;let l=n.querySelector(":scope > .magnet-name"),c=n.querySelector(":scope > .date"),h=n.querySelector(":scope > .buttons");!l||!h||(n.setAttribute("data-jhs-magnet-row","true"),l.setAttribute("data-jhs-magnet-part","info"),c?.setAttribute("data-jhs-magnet-part","date"),h.setAttribute("data-jhs-magnet-part","actions"))}},getResource(i){return i.querySelector('.copy-to-clipboard[data-clipboard-text^="magnet:"]')?.getAttribute("data-clipboard-text")||i.querySelector('.magnet-name a[href^="magnet:"]')?.getAttribute("href")||""},getActionTarget:d(i=>i.querySelector(":scope > .buttons"),"getActionTarget"),actionTargetRequiresWrapper:d(()=>!1,"actionTargetRequiresWrapper"),getTitleTarget:d(i=>i.querySelector(".name"),"getTitleTarget"),hasSubtitleTag:d(()=>!1,"hasSubtitleTag")})}parseActorMovies(e,t){if(typeof e!="string")throw new TypeError("JavDB actor page must be HTML text");let s=new DOMParser().parseFromString(e,"text/html"),a=s.querySelector("title")?.textContent??s.body?.textContent??"";if(/Just a moment|cf-chl-|Cloudflare/i.test(a))throw new TypeError("JavDB actor page is a challenge page");let i=[...s.querySelectorAll(".movie-list .item")];return Object.freeze(i.flatMap(r=>{let n=r.querySelector(".video-title"),l=n?.querySelector("strong")?.textContent?.trim()??"",c=ee(l);if(!c)return[];let h=r.querySelector("img")?.getAttribute("src")??"",u=r.querySelector("a[href]")?.getAttribute("href")??"",p=r.querySelector(".score .value, .score")?.textContent?.trim()??"",g=r.querySelector(".score .count, .meta .count")?.textContent?.trim()??"";return[Object.freeze({carNum:c,title:(n?.textContent??"").replace(l,"").trim(),coverUrl:h?new URL(h,t).href.replace("thumbs","covers"):null,url:u?new URL(u,t).href:null,publishTime:r.querySelector(".meta")?.textContent?.trim()||null,score:Number.parseFloat(p)||0,voteCount:Number.parseInt(g.replace(/[^\d]/g,""))||0})]}))}parseActorCollection(e,t){if(typeof e!="string")throw new TypeError("JavDB actor collection must be HTML text");let s=new DOMParser().parseFromString(e,"text/html"),a=s.querySelector("title")?.textContent??s.body?.textContent??"";if(/Just a moment|cf-chl-|Cloudflare/i.test(a))return Object.freeze({state:"challenge",isEmpty:!1,actors:Object.freeze([]),nextUrl:null});let i=s.querySelector("#actors");if(!i)return Object.freeze({state:"invalid",isEmpty:!1,actors:Object.freeze([]),nextUrl:null});try{let r=[...i.querySelectorAll(".actor-box")],n=r.map(h=>{let u=h.querySelector("a[title][href]"),p=u?.getAttribute("title")??"",g=u?.getAttribute("href")??"",m=u?.querySelector("img")?.getAttribute("src")??"",f=p.split(",").map(w=>w.trim()).filter(Boolean),v=new URL(g,t),b=v.pathname.split("/").filter(Boolean).pop()??"";if(!b||!f.length)throw new TypeError("演员卡身份字段无效");return Object.freeze({starId:b,name:f[0],allName:Object.freeze(f),avatar:m?new URL(m,t).href:null,actressType:u?.querySelector(".info")?.textContent?.trim().includes("無碼")?"uncensored":"censored",lastCheckTime:null,lastUpdateTime:null})}),l=s.querySelector(".pagination-next")?.getAttribute("href"),c=l?new URL(l,t).href:null;return Object.freeze({state:"valid",isEmpty:r.length===0,actors:Object.freeze(n),nextUrl:c})}catch{return Object.freeze({state:"invalid",isEmpty:!1,actors:Object.freeze([]),nextUrl:null})}}};d(Zi,"JavDbHostAdapter");var $s=Zi;var hh=new Set(["system","feature"]),uh=new Set(["eager","idle","on-command","on-demand"]),ph=new Set(["builtin-public","custom-public","user-local"]),gh=new Set(["bronze","silver"]);function ht(o,e){if(typeof o!="string"||o.trim()==="")throw new TypeError(`${e} must be a non-empty string`)}d(ht,"requireNonEmptyString");function hl(o,e){if(!Array.isArray(o))throw new TypeError(`${e} must be an array`)}d(hl,"requireArray");function At(o,e){hl(o,e);let t=o;for(let s of t)ht(s,`${e} item`);if(new Set(t).size!==t.length)throw new TypeError(`${e} cannot contain duplicates`)}d(At,"requireUniqueStrings");function Xi(o,e){hl(o,e);let t=o;if(t.some(s=>typeof s!="symbol"))throw new TypeError(`${e} must contain dependency tokens`);if(new Set(t).size!==t.length)throw new TypeError(`${e} cannot contain duplicate tokens`)}d(Xi,"requireUniqueTokens");function Ie(o){if(ht(o.id,"Feature id"),!hh.has(String(o.kind)))throw new TypeError("Feature kind must be system or feature");if(!uh.has(String(o.startup)))throw new TypeError("Feature startup mode is invalid");for(let e of["sites","routes","contributes","providesCommands"])At(o[e],e);if(Xi(o.requires,"requires"),typeof o.activate!="function")throw new TypeError("Feature activate must be a function");if(typeof o.disableable!="boolean")throw new TypeError("Feature disableable must be explicit");if(o.kind==="system"&&o.disableable!==!1)throw new TypeError("System features cannot be disableable");return Object.freeze({...o})}d(Ie,"defineFeature");function ul(o){if(ht(o.id,"Contribution id"),ht(o.featureId,"Contribution featureId"),ht(o.legacyPluginId,"Contribution legacyPluginId"),At(o.sites,"sites"),At(o.routes,"routes"),At(o.surfaces,"surfaces"),Xi(o.requires,"requires"),typeof o.plugin!="function")throw new TypeError("Contribution plugin must be a class");if(!o.order||typeof o.order!="object")throw new TypeError("Contribution order must be explicit");return Object.freeze({...o,sites:Object.freeze([...o.sites]),routes:Object.freeze([...o.routes]),surfaces:Object.freeze([...o.surfaces]),order:Object.freeze({...o.order})})}d(ul,"defineContribution");function W(o){if(ht(o.id,"Integration id"),!ph.has(String(o.trustClass)))throw new TypeError("Integration trustClass is invalid");if(!gh.has(String(o.quality)))throw new TypeError("Integration quality is invalid");At(o.hosts,"hosts"),At(o.capabilities,"capabilities"),Xi(o.requires,"requires");let e=o.hosts,t=o.capabilities;if(e.length===0||t.length===0)throw new TypeError("Integration hosts and capabilities cannot be empty");for(let s of e){let a=String(s);if(a!==a.toLowerCase()||new URL(`https://${a}`).hostname!==a)throw new TypeError(`Integration host is invalid: ${a}`)}if(o.cachePolicy===void 0)throw new TypeError("Integration cachePolicy must be explicit");if(o.cachePolicy!=="none"){if(!o.cachePolicy||typeof o.cachePolicy!="object"||Array.isArray(o.cachePolicy))throw new TypeError("Integration cachePolicy must be none or a capability map");let s=o.cachePolicy,a=t.filter(r=>!Object.hasOwn(s,String(r))),i=Object.keys(s).filter(r=>!t.includes(r));if(a.length||i.length)throw new TypeError(`Integration cachePolicy mismatch (missing: ${a.join(", ")||"none"}; extra: ${i.join(", ")||"none"})`);for(let[r,n]of Object.entries(s))ht(n,`cachePolicy.${r}`)}if(typeof o.createClient!="function"||typeof o.createAdapter!="function")throw new TypeError("Integration client and adapter factories are required");if(o.createHostAdapter!==null&&typeof o.createHostAdapter!="function")throw new TypeError("Integration createHostAdapter must be a function or explicit null");return Object.freeze({...o})}d(W,"defineIntegration");function G(o,e){return Symbol.for(`jhs.${o}.${e}`)}d(G,"createToken");var Z=Object.freeze({navigation:G("port","navigation"),http:G("port","http"),storage:G("port","storage"),dialog:G("port","dialog"),style:G("port","style"),host:G("port","host"),javdbHost:G("port","javdb-host"),javbusHost:G("port","javbus-host")}),y=Object.freeze({diagnostics:G("service","diagnostics"),urlPolicy:G("service","url-policy"),navigation:G("service","navigation"),http:G("service","http"),storage:G("service","storage"),webdav:G("service","webdav"),credential:G("service","credential"),dialog:G("service","dialog"),settings:G("service","settings"),movie:G("service","movie"),actressInfo:G("service","actress-info"),imageSearch:G("service","image-search"),review:G("service","review"),related:G("service","related"),magnet:G("service","magnet"),screenshot:G("service","screenshot"),translation:G("service","translation"),subtitle:G("service","subtitle"),account:G("service","account"),offline:G("service","offline"),cache:G("service","cache"),state:G("service","state"),profile:G("service","profile")}),Qe=Object.freeze({command:G("registry","command"),feature:G("registry","feature"),provider:G("registry","provider"),settings:G("registry","settings"),integration:G("registry","integration")}),xe=Object.freeze({externalDetail:"external-detail-v1"});var er=class er{constructor(e){this.hostAdapter=e,this.root=null,this.slots=Object.freeze({}),this.mounted=new Map,this.created=new Set}mount(){return this.root=this.hostAdapter.locateDetailRoot(),this.root&&this.ensureOwnedSlots(),this.slots=Object.freeze({...this.hostAdapter.locateDetailSlots()}),this}ensureOwnedSlots(){if(!this.root)return;let e=this.root.ownerDocument,t=this.root.querySelector(':scope > [data-jhs-slot="summary-actions"]');t||(t=e.createElement("div"),t.className="jhs-detail-owned-slot jhs-detail-owned-slot--summary-actions",t.setAttribute("data-jhs-slot","summary-actions"),this.root.append(t),this.created.add(t));let s=this.root.querySelector(':scope > [data-jhs-slot-group="post-resource"]');s||(s=e.createElement("div"),s.className="jhs-detail-post-resource",s.setAttribute("data-jhs-slot-group","post-resource"),this.root.append(s),this.created.add(s));for(let a of["reviews","related"]){if(s.querySelector(`[data-jhs-slot="${a}"]`))continue;let i=e.createElement("section");i.className=`jhs-detail-owned-slot jhs-detail-owned-slot--${a}`,i.setAttribute("data-jhs-slot",a),s.append(i),this.created.add(i)}}mountPanel(e,t){let s=this.slots[e];return s?(s.append(t),this.mounted.set(e,t),!0):!1}dispose(){for(let e of this.mounted.values())e.remove();for(let e of this.created)e.remove();this.mounted.clear(),this.created.clear(),this.root=null,this.slots=Object.freeze({})}};d(er,"HostedDetailSurface");var Ts=er;var tr=class tr{constructor(e){this.hostAdapter=e.hostAdapter,this.scope=e.scope,this.enabledContributions=new Set(e.enabledContributions),this.surface=new Ts(this.hostAdapter),this.movieRef=null}start(){return this.scope.assertActive(),this.surface.mount(),this.movieRef=this.hostAdapter.readMovieRef(),Object.freeze({movieRef:this.movieRef,contributions:[...this.enabledContributions]})}dispose(){this.surface.dispose(),this.scope.dispose()}};d(tr,"DetailController");var As=tr;var pl=Ie({id:"detail",kind:"feature",disableable:!0,sites:["javdb","javbus"],routes:["detail","owned-detail"],startup:"eager",requires:[Z.host,y.movie,y.review,y.related,y.magnet,y.screenshot],contributes:["detail.javdb-native","detail.javbus-native","detail.workspace","detail.fc2-owned","detail.fc2-navigation","detail.fc2-lookup","detail.cover-state-actions","detail.page-state-actions","detail.javdb-preview","detail.javbus-images","detail.javbus-preview","detail.reviews","detail.related","detail.native-magnets","detail.external-magnets","detail.screenshot","detail.external-sites"],providesCommands:[],activate:d((o,e)=>{if(e.route==="owned-detail")return{dispose:d(()=>{},"dispose")};let t=new As({hostAdapter:o[Z.host],scope:e.scope,enabledContributions:e.enabledContributions});return t.start(),{dispose:d(()=>t.dispose(),"dispose")}},"activate")});var Pt=d((o,e,t)=>Ie({id:o,kind:"feature",disableable:!0,sites:e,routes:[],startup:"eager",requires:[],contributes:t,providesCommands:[],activate:d(()=>({}),"activate")}),"feature"),gl=Object.freeze([Pt("list",["javdb","javbus"],["list.core","list.auto-page","list.fold-category","list.actions"]),Pt("library",["javdb","javbus"],["library.history","library.keyword-filter","library.state-actions","library.blacklist","library.favorite-actresses"]),Pt("discovery",["javdb","javbus"],["discovery.hit-show","discovery.top250","discovery.new-video","discovery.scheduler"]),Pt("external-bridge",["javdb","javbus","123pan","javtrailers","subtitlecat"],["external-bridge.translation","external-bridge.115-match","external-bridge.offline","external-bridge.123pan","external-bridge.javtrailers","external-bridge.subtitle"]),Pt("identity",["javdb","javbus"],["identity.javdb-navigation","identity.javbus-navigation","identity.image-search","identity.actress-info"]),Pt("compatibility",["javdb","javbus"],["compatibility.enhancements"])]);var ut=null;function ml(o){if(typeof o!="function")throw new TypeError("Settings UI owner must be a function");if(ut&&ut!==o)throw new Error("Settings UI owner is already registered");return ut=o,()=>{ut===o&&(ut=null)}}d(ml,"registerSettingsUiOwner");function fl(o){if(!ut)throw new Error("Settings UI owner is not ready");return ut(o)}d(fl,"openSettingsUi");var vl=Object.freeze([Ie({id:"settings",kind:"system",disableable:!1,sites:[],routes:[],startup:"on-command",requires:[y.diagnostics,y.profile],contributes:["settings.core"],providesCommands:["settings.open"],activate:d(()=>({commands:{"settings.open":d(()=>fl(),"settings.open")}}),"activate")}),Ie({id:"diagnostics",kind:"system",disableable:!1,sites:[],routes:[],startup:"eager",requires:[y.diagnostics],contributes:[],providesCommands:["diagnostics.export"],activate:d(o=>({commands:{"diagnostics.export":d(()=>o[y.diagnostics].exportSnapshot(),"diagnostics.export")}}),"activate")}),Ie({id:"responsive-shell",kind:"system",disableable:!1,sites:[],routes:[],startup:"eager",requires:[y.profile],contributes:["responsive-shell.bottom-bar"],providesCommands:[],activate:d(o=>({profile:o[y.profile].current()}),"activate")}),Ie({id:"stats",kind:"system",disableable:!1,sites:["javdb","javbus"],routes:[],startup:"idle",requires:[y.diagnostics],contributes:["stats.dashboard"],providesCommands:[],activate:d(o=>({diagnostics:o[y.diagnostics]}),"activate")})]);var bl=Object.freeze([...vl,pl,...gl]);var wl=Object.freeze({AutoPagePlugin:["ListPagePlugin"],BlacklistPlugin:["TaskPlugin","SettingPlugin","ListPagePlugin"],BusNavBarPlugin:["SearchByImagePlugin"],CompatibilityEnhancementsPlugin:["ListPagePlugin"],CoverButtonPlugin:["ListPagePlugin","ScreenShotPlugin"],DetailPageButtonPlugin:["DetailWorkspacePlugin","MagnetHubPlugin","HighlightMagnetPlugin"],Fc2NavigationPlugin:["Fc2Plugin"],Fc2Plugin:["DetailPageButtonPlugin","MagnetHubPlugin","FilterTitleKeywordPlugin","OtherSitePlugin","Fc2By123AvPlugin","TOP250Plugin","ScreenShotPlugin"],HistoryPlugin:["UnifiedOfflinePlugin","ListPagePlugin","Fc2Plugin"],HitShowPlugin:["ListPageButtonPlugin","ListPagePlugin","CoverButtonPlugin"],ListPageButtonPlugin:["NewVideoPlugin","BlacklistPlugin","ListPagePlugin"],ListPagePlugin:["HistoryPlugin","ListPageButtonPlugin","CoverButtonPlugin","AutoPagePlugin","BusImgPlugin","Fc2Plugin"],MobileBottomBarPlugin:["ListPagePlugin","DetailPageButtonPlugin","ListPageButtonPlugin","NewVideoPlugin","BlacklistPlugin","SettingPlugin","HighlightMagnetPlugin","MagnetHubPlugin","HistoryPlugin"],NavBarPlugin:["SearchByImagePlugin"],NewVideoPlugin:["TaskPlugin","SettingPlugin"],PreviewVideoPlugin:["DetailPageButtonPlugin"],SettingPlugin:["CoverButtonPlugin","TaskPlugin","OtherSitePlugin","ListPagePlugin","TranslatePlugin","ActressInfoPlugin","ScreenShotPlugin","NewVideoPlugin","BlacklistPlugin","BusImgPlugin"],StatsPlugin:["NewVideoPlugin","ListPagePlugin"],TaskPlugin:["BlacklistPlugin"],TranslatePlugin:["ListPagePlugin"],TOP250Plugin:["HitShowPlugin","ListPageButtonPlugin"],UnifiedOfflinePlugin:["OneTwoThreeOfflinePlugin"]});var sr=class sr extends I{constructor(){super(...arguments),this._generation=0}getName(){return"ActressInfoPlugin"}async handle(){let e=this.getRuntimeService("settings"),t=await this.getRuntimeService("scope")(),s=d(a=>{a.detail?.names?.includes("enableLoadActressInfo")&&(e.snapshot().enableLoadActressInfo==="no"?this.unmount():this.mount().catch((r=>clog.error("演员信息重新挂载失败",r))))},"onSettingsChanged");e.addEventListener("settings.changed",s),t.addCleanup((()=>e.removeEventListener("settings.changed",s))),await this.mount()}async mount(){if(this.getRuntimeService("settings").snapshot().enableLoadActressInfo==="no")return;this._generation++;let e=window.location.pathname;e.startsWith("/v/")||e.startsWith("/movies/")?await this.handleDetailPage():e.startsWith("/actors/")&&await this.handleStarPage()}unmount(){this._generation++,$(".actress-info").remove()}isStillActive(e){return e===this._generation&&this.getRuntimeService("settings").snapshot().enableLoadActressInfo!=="no"}async initCss(){return`<style>
            .info-tag { background-color:var(--jhs-status-fav-tint); display:inline-block; height:32px; padding:0 10px; line-height:30px; font-size:12px; color:var(--jhs-status-fav); border:1px solid var(--jhs-status-fav-tint); border-radius:4px; box-sizing:border-box; white-space:nowrap; }
        </style>`}async handleDetailPage(){if($(".actress-info").length>0)return;let e=this._generation,t=$(".female"),s=t.prev().map(((n,l)=>$(l).text().trim())).get();if(!s.length)return;let a=[];for(let n of s){let l=null;try{l=await this.searchInfo(n)}catch(h){clog.error("演员资料查询失败",n,h)}if(!this.isStillActive(e))return;let c=$('<div class="panel-block actress-info"></div>');if(l){c.append($("<strong></strong>").text(`${n}:`));let h=$("<a></a>").attr({href:l.url,target:"_blank",rel:"noopener noreferrer"}).addClass("jhs-layout-9813a0dd");h.append($("<span></span>").addClass("info-tag").text(`${l.birthday} ${l.age}`.trim()),$("<span></span>").addClass("info-tag").text(`${l.height} ${l.weight}`.trim()),$("<span></span>").addClass("info-tag").text(`${l.threeSizeText} ${l.braSize}`.trim())),c.append(h)}else{let h=this.getRuntimeService("actressInfo").profileUrl(n);c.append($("<a></a>").attr({href:h,target:"_blank",rel:"noopener noreferrer"}).append($("<strong></strong>").text(`${n}:`)))}a.push(c)}if(!this.isStillActive(e))return;let i=$("strong").filter(((n,l)=>/^(?:演員|演员)\s*:?$/.test($(l).text().trim()))).first().parent(),r=t.first().closest(".panel-block");i.length?i.after(...a):r.after(...a)}async handleStarPage(){if($(".actress-info").length>0)return;let e=this._generation,t=[],s=$(".actor-section-name");s.length&&s.text().trim().split(",").forEach((l=>t.push(l.trim())));let a=$(".section-meta:not(:contains('影片'))");if(a.length&&a.text().trim().split(",").forEach((l=>t.push(l.trim()))),!t.length)return;let i=null;for(let l of t){try{i=await this.searchInfo(l)}catch(c){clog.error("演员资料查询失败",l,c)}if(!this.isStillActive(e))return;if(i)break}let r=$('<div class="jhs-layout-c0d4a511"></div>');if(!i)r.text("无此相关演员信息");else{let l=$('<div class="jhs-layout-1b3790ef"></div>'),c=$('<div class="jhs-layout-1b3790ef"></div>');l.append($("<span></span>").addClass("jhs-layout-dd5a75f6").text(`出生日期: ${i.birthday}`),$("<span></span>").addClass("jhs-layout-d4a09a0d").text(`年龄: ${i.age}`),$("<span></span>").addClass("jhs-layout-d4a09a0d").text(`身高: ${i.height}`)),c.append($("<span></span>").addClass("jhs-layout-dd5a75f6").text(`体重: ${i.weight}`),$("<span></span>").addClass("jhs-layout-d4a09a0d").text(`三围: ${i.threeSizeText}`),$("<span></span>").addClass("jhs-layout-d4a09a0d").text(`罩杯: ${i.braSize}`)),r.append(l,c)}if(!this.isStillActive(e))return;let n=i?$("<a></a>").addClass("actress-info").attr({href:i.url,target:"_blank",rel:"noopener noreferrer"}).append(r):r.addClass("actress-info");s.parent().append(n)}async searchInfo(e){let t=await this.getRuntimeService("scope")();return this.getRuntimeService("actressInfo").lookup(e,{scope:t})}};d(sr,"ActressInfoPlugin");var Ps=sr;var ar=class ar extends I{constructor(){super(...arguments),A(this,"isUploading",!1)}getName(){return"SearchByImagePlugin"}async initCss(){return`
            <style>
                #upload-area {
                    border: 2px dashed var(--jhs-status-down);
                    border-radius: 8px;
                    padding: 40px;
                    text-align: center;
                    margin-bottom: 20px;
                    transition: all 0.3s;
                    background-color: var(--jhs-surface-2);
                }
                #upload-area:hover {
                    border-color: var(--jhs-status-down-hover);
                    background-color: var(--jhs-surface-2);
                }
                /* 拖拽进入 */
                #upload-area.highlight {
                    border-color: var(--jhs-status-fav);
                    background-color: var(--jhs-status-fav-tint);
                }


                #select-image-btn {
                    background-color: var(--jhs-status-down);
                    color: var(--jhs-status-down-on);
                    border: none;
                    padding: 10px 20px;
                    border-radius: var(--jhs-radius-sm);
                    cursor: pointer;
                    font-size: 16px;
                    transition: background-color 0.3s;
                }
                #select-image-btn:hover {
                    background-color: var(--jhs-status-down-hover);
                }


                #handle-btn, #cancel-btn {
                    padding: 8px 16px;
                    border-radius: var(--jhs-radius-sm);
                    cursor: pointer;
                    font-size: 14px;
                    border: none;
                    transition: opacity 0.3s;
                }
                #handle-btn {
                    background-color: var(--jhs-status-fav);
                    color: var(--jhs-status-fav-on);
                }
                #handle-btn:hover {
                    filter: brightness(0.94);
                }
                #cancel-btn {
                    background-color: var(--jhs-status-filter);
                    color: var(--jhs-status-filter-on);
                }
                #cancel-btn:hover {
                    filter: brightness(0.94);
                }

                .search-img-site-btns-container {
                    display: flex;
                    flex-wrap: wrap;
                    gap: 10px;
                    margin-top: 15px;
                }
                .search-img-site-btn {
                    display: flex;
                    align-items: center;
                    padding: 8px 12px;
                    background-color: var(--jhs-surface-2);
                    border-radius: var(--jhs-radius-sm);
                    text-decoration: none;
                    color: var(--jhs-text);
                    transition: all 0.2s;
                    font-size: 14px;
                    border: 1px solid var(--jhs-border);
                }
                .search-img-site-btn:hover {
                    background-color: var(--jhs-border);
                    transform: translateY(-2px);
                    box-shadow: 0 2px 5px rgba(0,0,0,0.1);
                }
                .search-img-site-btn img {
                    width: 16px;
                    height: 16px;
                    margin-right: 6px;
                }
                .search-img-site-btn span {
                    white-space: nowrap;
                }
            </style>
        `}open(e){this.getRuntimeService("dialog").open({type:1,title:"以图识图",content:`
            <div class="jhs-layout-769fed37">
                <div id="upload-area">
                    <div class="jhs-layout-9e3c853e">
                        <p>拖拽图片到此处 或 点击按钮选择图片</p>
                        <p>也可以直接 Ctrl+V 粘贴图片或 图片URL</p>
                    </div>
                    <button class="jhs-btn" id="select-image-btn">选择图片</button>
                    <input type="file" id="image-file" accept="image/*" class="jhs-layout-6b99de8b">
                </div>

                <div id="url-input-container" class="jhs-layout-d50e4f09">
                    <input type="text" id="image-url" placeholder="粘贴图片URL地址..." class="jhs-field">
                </div>

                <div id="preview-area" class="jhs-layout-d10a577d">
                    <img id="preview-image" alt="" src="" class="jhs-image-preview">
                    <div id="action-btns" class="jhs-layout-06cf30c0">
                        <button class="jhs-btn" id="handle-btn">搜索图片</button>
                        <button class="jhs-btn" id="cancel-btn">取消</button>
                    </div>

                    <div id="search-results" class="jhs-layout-c8be1ccb">
                        <p class="jhs-layout-9ea2322d">请选择识图网站:<button type="button" id="openAll" class="jhs-btn jhs-btn--ghost">全部打开</button></p>
                        <div class="search-img-site-btns-container" id="search-img-site-btns-container"></div>
                    </div>
                </div>

            </div>
        `,area:utils.isMobileMode()?utils.getResponsiveArea():["40%","80%"],success:d(async t=>{this.initEventListeners(),e&&e()},"success"),end:d(()=>{$(document).off("paste.searchImg")},"end")})}initEventListeners(){let e=$("#upload-area"),t=$("#image-file"),s=$("#select-image-btn"),a=$("#preview-area"),i=$("#preview-image"),r=$("#action-btns"),n=$("#handle-btn"),l=$("#cancel-btn"),c=$("#url-input-container"),h=$("#image-url"),u=$("#search-results"),p=$("#search-img-site-btns-container");e.on("dragover",(g=>{g.preventDefault(),e.addClass("highlight")})).on("dragleave",(()=>{e.removeClass("highlight")})).on("drop",(g=>{g.preventDefault(),e.removeClass("highlight"),g.originalEvent.dataTransfer.files&&g.originalEvent.dataTransfer.files[0]&&(this.handleImageFile(g.originalEvent.dataTransfer.files[0]),this.resetSearchUI())})),s.on("click",(()=>{t.trigger("click")})),t.on("change",(g=>{let m=g.target;m.files&&m.files[0]&&(this.handleImageFile(m.files[0]),this.resetSearchUI())})),$(document).on("paste.searchImg",(async g=>{let m=g.originalEvent.clipboardData.items;for(let v=0;v<m.length;v++)if(m[v].type.indexOf("image")!==-1){let b=m[v].getAsFile();return this.handleImageFile(b),void this.resetSearchUI()}let f=g.originalEvent.clipboardData.getData("text");f&&utils.isUrl(f)&&(c.show(),h.val(f),i.attr("src",f),a.show(),this.resetSearchUI())})),n.on("click",(async()=>{let g=i.attr("src");if(g){if(!this.isUploading){this.isUploading=!0;try{let m=await this.searchByImage(g);if(!m)return;r.hide(),u.show(),p.empty();let f=this.getRuntimeService("storage"),v="jhs_selectedSites",b=JSON.parse(f.getLocal(v)||"{}");m.targets.forEach((w=>{let S=b[w.name]!==!1,j=$('<a class="search-img-site-btn" target="_blank" rel="noopener noreferrer"></a>').attr({href:w.url,title:w.name}),k=$('<input type="checkbox" class="site-checkbox jhs-layout-8896c95d">').attr("data-site-name",w.name).prop("checked",S);j.append(k,$("<img>").attr({src:w.iconUrl,alt:w.name}),$("<span></span>").text(w.name)),p.append(j)})),p.on("change",".site-checkbox",(w=>{let S=$(w.currentTarget),j=S.data("site-name");b[j]=S.is(":checked"),f.setLocal(v,JSON.stringify(b))})),p.show()}finally{this.isUploading=!1}}}else show.info("请粘贴或上传图片")})),l.on("click",(()=>{a.hide(),c.hide(),t.val(""),h.val("")})),h.on("change",(()=>{utils.isUrl(h.val())&&(i.attr("src",h.val()),a.show())})),$("#openAll").on("click",(()=>{$(".search-img-site-btn").each(((g,m)=>{$(m).find(".site-checkbox").is(":checked")&&window.open($(m).attr("href"))}))}))}resetSearchUI(){$("#action-btns").show(),$("#search-results").hide(),$("#search-img-site-btns-container").hide().empty()}handleImageFile(e){let t=document.getElementById("preview-image"),s=document.getElementById("preview-area"),a=document.getElementById("url-input-container");if(!t||!s||!a)return;if(!e.type.match("image.*"))return void show.info("请选择图片文件");let i=new FileReader;i.onload=r=>{t.src=String(r.target?.result||""),s.style.display="block",a.style.display="none",$("#handle-btn")[0]?.click()},i.readAsDataURL(e)}async searchByImage(e){let t=loading();try{e.startsWith("data:")&&show.info("开始上传图片...");let s=await this.getRuntimeService("scope")();return await this.getRuntimeService("imageSearch").resolve(e,{scope:s})}catch(s){show.error(`搜索失败: ${s instanceof Error?s.message:String(s)}`),clog.error("搜索失败:",s)}finally{t.close()}}};d(ar,"SearchByImagePlugin");var Is=ar;async function $e(o,e=4,t){let s=new Array(o.length),a=0,i=d(async()=>{for(;a<o.length;){let r=a++;s[r]=await t(o[r],r)}},"worker");return await Promise.all(Array.from({length:Math.min(Math.max(1,e),o.length)},i)),s}d($e,"mapLimit");function be(o,e=!1){return o==null?e:o===!0||o==="true"||o==="yes"||o===1||o==="1"?!0:o===!1||o==="false"||o==="no"||o===0||o==="0"?!1:e}d(be,"parseBooleanSetting");function ae(o,e,{min:t=-1/0,max:s=1/0}={}){if(o==null||String(o).trim()==="")return e;let a=Number(o);return Number.isFinite(a)&&a>=t&&a<=s?a:e}d(ae,"parseNumberSetting");function _e(o){if(o instanceof Date)return Number.isFinite(o.getTime())?o.getTime():null;if(typeof o=="number")return Number.isFinite(o)&&o>=0?o:null;if(typeof o!="string")return null;let e=o.trim();if(!e)return null;if(/^\d{13,16}$/.test(e)){let a=Number(e);return Number.isFinite(a)?a:null}let t=e.match(/^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2}):(\d{2})$/);if(t){let a=t.slice(1).map(Number),i=new Date(a[0],a[1]-1,a[2],a[3],a[4],a[5]);return i.getFullYear()===a[0]&&i.getMonth()===a[1]-1&&i.getDate()===a[2]&&i.getHours()===a[3]&&i.getMinutes()===a[4]&&i.getSeconds()===a[5]?i.getTime():null}let s=new Date(e).getTime();return Number.isFinite(s)?s:null}d(_e,"parseTaskTimestamp");function pt(o,e,t=Date.now()){let s=ae(e,0,{min:0}),a=_e(o),i=_e(t);return s>0&&a!=null&&i!=null&&i>=a&&i-a>=36e5*s}d(pt,"shouldSkipStopped");function Kt(o){let e=null,t=-1/0;for(let s of o){let a=_e(s);a!=null&&a>t&&(t=a,e=s)}return e}d(Kt,"selectLatestPublishTime");function gt(o,e=window.location.href){if(!o)return null;try{let t=new URL(String(o),e);return["http:","https:"].includes(t.protocol)?t.href:null}catch(t){return clog.debug("外部 URL 无效,已忽略",t),null}}d(gt,"normalizeHttpUrl");function ir(o,e=window.location.href){return gt(o,e)?.replace(/^https:\/\/[^/]+\/rhe951l4q(?=\/)/i,"https://c0.jdbstatic.com")??null}d(ir,"normalizeJavdbMediaUrl");function yl(o){let e=String(o||"").trim();return/^(?:[a-f\d]{40}|[a-z2-7]{32})$/i.test(e)?e.toUpperCase():null}d(yl,"normalizeBtihHash");function jl(o){let e=String(o||"").split(/[\s,,;;]+/).map((s=>T(s))).filter((s=>typeof s=="string")),t=e.filter((s=>/^(?:FC2-)?[A-Z\d]+(?:-[A-Z\d]+)+$/i.test(s)));return{recognized:e.length,values:[...new Set(t.map((s=>s.toUpperCase())))],invalid:e.filter((s=>!t.includes(s)))}}d(jl,"parseCarNumberText");function Sl(o,e="https://javdb.com"){return`${e}/search?q=${encodeURIComponent(String(o??""))}`}d(Sl,"buildFallbackCarUrl");async function de(o,{context:e="视频",notify:t=!1,message:s="当前视频源无法播放"}={}){if(!o||typeof o.play!="function")return clog.warn(`${e}播放失败:媒体元素不可用`),t&&show.error(s),!1;try{return await o.play(),!0}catch(a){clog.warn(`${e}播放失败`,a);let i=a&&typeof a=="object"&&"name"in a?String(a.name):"";return t&&!["NotAllowedError","AbortError"].includes(i)&&show.error(s),!1}}d(de,"safePlay");var Re=Object.freeze({all:"全部",waitCheck:"待鉴定",favorite:"收藏",hasDown:"下载",hasWatch:"已看",blockedItems:"屏蔽项",favoriteUndownloaded:"收藏未下载",favoriteUnwatched:"收藏未观看",downloadedUnwatched:"下载未观看",recent7d:"最近 7 天"}),mt=Object.freeze(["all","waitCheck","favorite","hasDown","hasWatch"]),Gt=Object.freeze(["blockedItems","favoriteUndownloaded","favoriteUnwatched","downloadedUnwatched","recent7d"]),mh=new Set([...mt,...Gt]);function Te(o){return o==="filter"?"blockedItems":typeof o=="string"&&mh.has(o)?o:"waitCheck"}d(Te,"normalizeQuickFilterKey");function ft(o,e={}){return!!(o.blocked||e.keyword||e.actorBlacklist||e.actressBlacklist)}d(ft,"isHardHidden");function rr(o,e,{visibilityReasons:t={},recent:s=!1}={}){let a=Te(o),i=ft(e,t);return a==="all"?!0:a==="blockedItems"?i:i?!1:a==="waitCheck"?!oe(e):a==="favorite"?!!e.favorite:a==="hasDown"?!!e.downloaded:a==="hasWatch"?!!e.watched:a==="favoriteUndownloaded"?!!e.favorite&&!e.downloaded:a==="favoriteUnwatched"?!!e.favorite&&!e.watched:a==="downloadedUnwatched"?!!e.downloaded&&!e.watched:a==="recent7d"&&s}d(rr,"matchesQuickFilter");function xl({filter:o,flags:e,visibilityReasons:t,recent:s}){return rr(o,e,{visibilityReasons:t,recent:s})}d(xl,"shouldShowItem");var kl=Object.freeze(["native-javdb","native-javbus","u9a9","u3c3","sukebei","btsow"]);function nr(o,e){return!o||!String(o.magnet||"").startsWith("magnet:")?null:{title:String(o.title||""),magnet:o.magnet,size:o.size||"",date:o.date||"",seeders:Number(o.seeders)||0,leechers:Number(o.leechers)||0,source:e,files:Array.isArray(o.files)?o.files:[]}}d(nr,"normalizeMagnetResult");function Cl(o){let e=new URL(o).searchParams.get("xt")?.match(/^urn:btih:([a-z2-7]{32}|[a-f\d]{40})$/i)?.[1];return e?e.toUpperCase():null}d(Cl,"extractInfoHash");function Es(o){let e=new Map;return o.forEach((t=>{let s=Cl(t.magnet)||`${t.source}:${t.magnet}`,a=e.get(s);a?a.sources=[...new Set([...a.sources||[a.source],t.source])]:e.set(s,{...t,sources:[t.source]})})),[...e.values()]}d(Es,"deduplicateMagnetResults");var cr=class cr{constructor(e=[]){this.sources=new Map,e.forEach((t=>this.register(t)))}register(e){if(!e?.id||!e.name||typeof e.search!="function"||typeof e.targetUrl!="function")throw new TypeError("Invalid magnet provider");return this.sources.set(e.id,{enabled:!0,priority:100,...e}),this}get(e){return this.sources.get(e)||null}getEnabledSources(){return[...this.sources.values()].filter((e=>e.enabled)).sort(((e,t)=>e.priority-t.priority))}};d(cr,"MagnetSourceRegistry");var Qt=cr;function Rs(o){let e=new URL(o);if(e.protocol!=="https:")throw new TypeError("Source URL must use https");return e.origin}d(Rs,"validateHttpsBaseUrl");function bt(o){let e=["id","name","enabled","priority","searchUrlTemplate","targetUrlTemplate","parserType","rowSelector","titleSelector","magnetSelector","sizeSelector","dateSelector","seedersSelector","leechersSelector","resultsPath","titlePath","hashPath","magnetPath","sizePath","datePath","seedersPath"];if(Object.keys(o).some((t=>!e.includes(t))))throw new TypeError("Unsupported custom source field");if(!["torrent-table","magnet-links","json"].includes(o.parserType))throw new TypeError("Unsupported parser type");if(!String(o.name||"").trim())throw new TypeError("Source name is required");if(Rs(o.searchUrlTemplate.replace("{keyword}","test")),Rs((o.targetUrlTemplate||o.searchUrlTemplate).replace("{keyword}","test")),o.parserType==="torrent-table"&&(!o.rowSelector?.trim()||!o.magnetSelector?.trim()))throw new TypeError("表格来源必须填写结果行选择器和磁力选择器");if(o.parserType==="json"&&(!o.resultsPath?.trim()||!o.magnetPath?.trim()&&!o.hashPath?.trim()))throw new TypeError("JSON 来源必须填写结果数组路径,并填写磁力路径或哈希路径");return{...o,name:o.name.trim(),targetUrlTemplate:o.targetUrlTemplate||o.searchUrlTemplate}}d(bt,"validateCustomMagnetSource");function _l(o,e=[],t=[],s=[]){let a=`${o.title||""} ${(o.files||[]).join(" ")}`,i=d((u,p)=>u.type==="regex"?new RegExp(u.pattern,"i").test(p):p.toLowerCase().includes(u.pattern.toLowerCase()),"matches"),r=e.filter((u=>u.enabled&&i(u,a))),n=!1,l=0,c=[];return[...t.map((u=>({...u,value:o.title||""}))),...s.map((u=>({...u,value:(o.files||[]).join(" ")})))].filter((u=>u.enabled)).forEach((u=>{i(u,u.value)&&(c.push(u.id||u.pattern),u.action==="hide"?n=!0:l+=Number(u.penalty)||0)})),{...o,tags:r.map((u=>u.name)),customTagWeight:r.reduce(((u,p)=>u+(Number(p.weight)||0)),0),hidden:n,filterPenalty:l,filteredReasons:c}}d(_l,"applyMagnetRules");function or(o,e){let t=new Map;return $(o).find('a[href^="magnet:"],[data-clipboard-text^="magnet:"]').each(((s,a)=>{let i=$(a),r=i.attr("href")||i.attr("data-clipboard-text");if(!r)return;let n=i.closest(".item, .magnet-name, tr, .panel-block"),l=n.find(".name, .magnet-name, .title").first().text().trim()||i.text().trim()||"本站磁力",c=nr({title:l,magnet:r,size:n.find(".meta, .size").first().text().trim()},e);c&&t.set(Cl(r)||r,c)})),[...t.values()]}d(or,"parseNativeMagnets");function vt(o,e){return String(e||"").split(".").filter(Boolean).reduce(((t,s)=>t?.[s]),o)}d(vt,"readJsonPath");function lr(o,e,t){if(o=bt(o),o.parserType==="json")return(vt(e,o.resultsPath)||[]).map((i=>nr({title:vt(i,o.titlePath),magnet:o.magnetPath?vt(i,o.magnetPath):`magnet:?xt=urn:btih:${vt(i,o.hashPath)}`,size:vt(i,o.sizePath),date:vt(i,o.datePath),seeders:vt(i,o.seedersPath)},`custom:${t}`))).filter(Boolean);let s=utils.htmlTo$dom(e);return(o.parserType==="magnet-links"?s.find('a[href^="magnet:"]'):s.find(o.rowSelector)).map(((i,r)=>{let n=$(r),l=o.parserType==="magnet-links"?n:n.find(o.magnetSelector).first();return nr({title:o.parserType==="magnet-links"?n.text().trim():n.find(o.titleSelector).first().text().trim(),magnet:l.attr("href")||l.attr("data-magnet"),size:n.find(o.sizeSelector).text().trim(),date:n.find(o.dateSelector).text().trim(),seeders:n.find(o.seedersSelector).text().trim(),leechers:n.find(o.leechersSelector).text().trim()},`custom:${t}`)})).get().filter(Boolean)}d(lr,"parseCustomMagnetResponse");var Ns=Object.freeze([{id:"native-javdb",name:"JavDB 本站",type:"本站资源",domain:"javdb.com",priority:10,enabled:!0},{id:"native-javbus",name:"JavBus 本站",type:"本站资源",domain:"javbus.com",priority:11,enabled:!0}]);function It(o){if(!o.name?.trim()||!o.pattern?.trim())throw new TypeError("规则名称和匹配内容不能为空");if(o.type==="regex")try{new RegExp(o.pattern)}catch{throw new TypeError("正则表达式无效")}return{...o,name:o.name.trim(),pattern:o.pattern.trim()}}d(It,"validateRule");function $l(o,e=null){let t=o.parserType||"magnet-links",s={id:e?.id||`source-${Date.now()}`,name:String(o.name||"").trim(),enabled:!!o.enabled,priority:Number(o.priority)||100,searchUrlTemplate:String(o.searchUrlTemplate||"").trim(),targetUrlTemplate:String(o.targetUrlTemplate||o.searchUrlTemplate||"").trim(),parserType:t};if(!s.name)throw new TypeError("来源名称不能为空");return t==="torrent-table"&&Object.assign(s,{rowSelector:o.rowSelector,titleSelector:o.titleSelector,magnetSelector:o.magnetSelector,sizeSelector:o.sizeSelector,dateSelector:o.dateSelector,seedersSelector:o.seedersSelector,leechersSelector:o.leechersSelector}),t==="json"&&Object.assign(s,{resultsPath:o.resultsPath,titlePath:o.titlePath,magnetPath:o.magnetPath,hashPath:o.hashPath,sizePath:o.sizePath,datePath:o.datePath,seedersPath:o.seedersPath}),bt(s)}d($l,"buildCustomMagnetSource");function Yt(o,e=!1){return be(o,e)}d(Yt,"parseBooleanSetting");function Ds(o,e,t={}){let s=Number(o);if(!Number.isFinite(s))return e;let a=Math.round(s);return t.min!=null&&a<t.min?t.min:t.max!=null&&a>t.max?t.max:a}d(Ds,"parseFiniteNumberSetting");function Ye(o,e){if(["enable123Offline","enable115Offline","enable115Match","enable115LoginRedirect"].includes(o))return Yt(e,!1);if(o==="offlineProviderMode")return["ask","123","115"].includes(String(e))?String(e):"ask";if(o==="oneOneFiveConcurrency")return Ds(e,4,{min:1,max:10});if(o==="oneOneFiveCacheMinutes")return Ds(e,60,{min:1,max:1440});throw new TypeError(`未知云盘设置: ${o}`)}d(Ye,"normalizeCloudSetting");var dr=class dr{constructor(e=storageManager){this.storage=e}async getArray(e){let t=await this.storage.getSetting(e,"[]");if(Array.isArray(t))return t;try{let s=JSON.parse(t||"[]");return Array.isArray(s)?s:[]}catch{return[]}}async saveArray(e,t){if(!Array.isArray(t))throw new TypeError("配置必须是数组");return await this.storage.saveSettingItem(e,JSON.stringify(t)),t}async updateArray(e,t){if(typeof this.storage.updateSetting=="function"){let i;return await this.storage.updateSetting(r=>{let n=r[e],l;if(Array.isArray(n))l=n;else try{let c=JSON.parse(n||"[]");l=Array.isArray(c)?c:[]}catch{l=[]}if(i=t(l),!Array.isArray(i))throw new TypeError("配置必须是数组");r[e]=JSON.stringify(i)}),i}let s=await this.getArray(e),a=t(s);return await this.saveArray(e,a),a}getMagnetSources(){return this.getArray("customMagnetSources")}saveMagnetSources(e){return e.forEach(bt),this.saveArray("customMagnetSources",e)}getMagnetTagRules(){return this.getArray("magnetTagRules")}saveMagnetTagRules(e){return e.forEach(It),this.saveArray("magnetTagRules",e)}getMagnetFilterRules(){return this.getArray("magnetFilterRules")}saveMagnetFilterRules(e){return e.forEach(It),this.saveArray("magnetFilterRules",e)}async getBuiltInSources(){return await this.getArray("magnetBuiltInSources")}saveBuiltInSources(e){return e.forEach((t=>{if(!kl.includes(t.id))throw new TypeError("未知的内置磁力源");if(t.baseUrl&&Rs(t.baseUrl),t.priority!=null&&(!Number.isFinite(Number(t.priority))||Number(t.priority)<1))throw new TypeError("来源优先级无效")})),this.saveArray("magnetBuiltInSources",e)}async getScreenshotSettings(){return{mode:await this.storage.getSetting("screenshotMode","auto"),providers:await this.getArray("screenshotProviders")}}async saveScreenshotMode(e){return await this.storage.saveSettingItem("screenshotMode",e),e}async saveScreenshotProviders(e){return this.saveArray("screenshotProviders",e)}async saveScreenshotSettings(e){return typeof this.storage.patch=="function"?this.storage.patch({screenshotMode:e.mode,screenshotProviders:JSON.stringify(e.providers)}):(await this.saveScreenshotMode(e.mode),await this.saveScreenshotProviders(e.providers),e)}async getCloudSettings(){return{enable123Offline:Yt(await this.storage.getSetting("enable123Offline",!0),!0),enable115Offline:Yt(await this.storage.getSetting("enable115Offline",!1),!1),enable115Match:Yt(await this.storage.getSetting("enable115Match",!1),!1),enable115LoginRedirect:Yt(await this.storage.getSetting("enable115LoginRedirect",!1),!1),providerMode:Ye("offlineProviderMode",await this.storage.getSetting("offlineProviderMode","ask")),concurrency:Ds(await this.storage.getSetting("oneOneFiveConcurrency",4),4,{min:1,max:10}),cacheMinutes:Ds(await this.storage.getSetting("oneOneFiveCacheMinutes",60),60,{min:1,max:1440})}}async saveCloudSetting(e,t){let a={enable123Offline:"enable123Offline",enable115Offline:"enable115Offline",enable115Match:"enable115Match",enable115LoginRedirect:"enable115LoginRedirect",offlineProviderMode:"offlineProviderMode",oneOneFiveConcurrency:"oneOneFiveConcurrency",oneOneFiveCacheMinutes:"oneOneFiveCacheMinutes"}[e];if(!a)throw new TypeError(`未知云盘设置: ${e}`);let i=Ye(e,t);return await this.storage.saveSettingItem(a,i),i}async saveCloudSettings(e){let t={enable123Offline:Ye("enable123Offline",e.enable123Offline),enable115Offline:Ye("enable115Offline",e.enable115Offline),enable115Match:Ye("enable115Match",e.enable115Match),enable115LoginRedirect:Ye("enable115LoginRedirect",e.enable115LoginRedirect),offlineProviderMode:Ye("offlineProviderMode",e.providerMode||"ask"),oneOneFiveConcurrency:Ye("oneOneFiveConcurrency",e.concurrency),oneOneFiveCacheMinutes:Ye("oneOneFiveCacheMinutes",e.cacheMinutes)};if(typeof this.storage.patch=="function")return this.storage.patch(t);for(let[s,a]of Object.entries(t))await this.storage.saveSettingItem(s,a);return t}async exportConfig(){return{customMagnetSources:await this.getMagnetSources(),magnetTagRules:await this.getMagnetTagRules(),magnetFilterRules:await this.getMagnetFilterRules(),magnetBuiltInSources:await this.getBuiltInSources(),screenshot:await this.getScreenshotSettings()}}async importConfig(e){let t;try{t=JSON.parse(e)}catch(a){throw new TypeError(`配置格式错误:${a instanceof Error?a.message:String(a)}`)}if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("配置格式错误:根节点必须是对象");let s=[];if(Object.hasOwn(t,"customMagnetSources")){if(!Array.isArray(t.customMagnetSources))throw new TypeError("自定义磁力源必须是数组");t.customMagnetSources.forEach(bt),s.push(()=>this.saveMagnetSources(t.customMagnetSources))}if(Object.hasOwn(t,"magnetTagRules")){if(!Array.isArray(t.magnetTagRules))throw new TypeError("标签规则必须是数组");t.magnetTagRules.forEach(It),s.push(()=>this.saveMagnetTagRules(t.magnetTagRules))}if(Object.hasOwn(t,"magnetFilterRules")){if(!Array.isArray(t.magnetFilterRules))throw new TypeError("过滤规则必须是数组");t.magnetFilterRules.forEach(It),s.push(()=>this.saveMagnetFilterRules(t.magnetFilterRules))}if(Object.hasOwn(t,"magnetBuiltInSources")){if(!Array.isArray(t.magnetBuiltInSources))throw new TypeError("内置磁力源配置必须是数组");s.push(()=>this.saveBuiltInSources(t.magnetBuiltInSources))}if(Object.hasOwn(t,"screenshot")){if(!t.screenshot||!["auto","manual"].includes(t.screenshot.mode)||!Array.isArray(t.screenshot.providers))throw new TypeError("截图配置无效");s.push(()=>this.saveScreenshotSettings(t.screenshot))}for(let a of s)await a();return t}};d(dr,"ResourceSettingsService");var rt=dr;var Ls=Object.freeze([Object.freeze({id:"javstore",name:"JavStore",domain:"javstore.net",priority:10,enabled:!0}),Object.freeze({id:"projectjav",name:"ProjectJav",domain:"projectjav.com",priority:20,enabled:!1,implemented:!1}),Object.freeze({id:"18av",name:"18AV",domain:"18av.mm-cg.com",priority:30,enabled:!1,implemented:!1})]);var hr="x7k9p3",Tl="jhs_credential_install_secret",Al="AES:",Pl="";function ur(){let o=globalThis.localStorage?.getItem?.(Tl)||Pl;if(o)return o;let e=crypto.getRandomValues(new Uint8Array(32));return o=Rl(e.buffer),Pl=o,globalThis.localStorage?.setItem?.(Tl,o),o}d(ur,"getInstallationSecret");async function Il(o){let e=new TextEncoder,t=await crypto.subtle.importKey("raw",e.encode(`${o}.jhs.v1`),{name:"PBKDF2"},!1,["deriveKey"]);return crypto.subtle.deriveKey({name:"PBKDF2",salt:e.encode("jhs-backup"),iterations:1e5,hash:"SHA-256"},t,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}d(Il,"getEncryptionKey");function Rl(o){let e=new Uint8Array(o),t=32768,s="";for(let a=0;a<e.length;a+=t)s+=String.fromCharCode(...e.subarray(a,a+t));return btoa(s)}d(Rl,"arrayBufferToBase64");function fh(o){let e=atob(o),t=new Uint8Array(e.length);for(let s=0;s<e.length;s++)t[s]=e.charCodeAt(s);return t}d(fh,"base64ToArrayBuffer");async function Zt(o,e=ur()){let t=await Il(e),s=crypto.getRandomValues(new Uint8Array(12)),a=await crypto.subtle.encrypt({name:"AES-GCM",iv:s},t,new TextEncoder().encode(o)),i=new Uint8Array(s.length+a.byteLength);return i.set(s),i.set(new Uint8Array(a),s.length),Rl(i.buffer)}d(Zt,"encryptData");async function El(o){return Zt(o,hr)}d(El,"encryptPortableBackup");async function Ze(o,e=ur(),t=!0){let s=fh(o),a=s.slice(0,12),i=s.slice(12),r=d(async n=>new TextDecoder().decode(await crypto.subtle.decrypt({name:"AES-GCM",iv:a},await Il(n),i)),"decrypt");try{return await r(e)}catch(n){if(!t||e===hr)throw n;return r(hr)}}d(Ze,"decryptData");async function Xt(o){return Ze(o)}d(Xt,"decryptPortableBackup");async function Dl(o,e=ur()){if(!o||!o.startsWith(Al))return o;try{return await Ze(o.slice(Al.length),e)}catch{return console?.warn?.("[凭证] 凭证解密失败,按原文返回"),o}}d(Dl,"decryptCredential");var vh="zh-cn",bh=Object.freeze({"zh-cn":Object.freeze({pagination:Object.freeze({first:"首页",first_title:"首页",last:"尾页",last_title:"尾页",prev:"上一页",prev_title:"上一页",next:"下一页",next_title:"下一页",all:"全部",page_size:"每页行数"})})});function ze(o,e,t){if(typeof o!="function")throw new TypeError("Tabulator runtime is required");(typeof e=="string"?globalThis.document?.querySelector(e):e)?.classList?.add("jhs-table");let a=(t.paginationSizeSelector??[20,50,100,1e3]).filter(i=>Number.isInteger(i)&&i>0);return new o(e,{layout:"fitColumns",responsiveLayout:"collapse",pagination:!0,paginationMode:"local",height:"100%",paginationSize:a[0]??20,...t,paginationSizeSelector:a,locale:t.locale??vh,langs:t.langs??bh})}d(ze,"createJhsTable");var Ue=d(o=>o instanceof Error?o.message:String(o),"errorMessage");async function Nl(o){if(typeof o?.getProfile=="function")return o.getProfile();let e=await storageManager.getSetting();return{url:e.webDavUrl,username:e.webDavUsername,password:await Dl(e.webDavPassword||"")}}d(Nl,"resolveWebDavProfile");async function Ll(o){try{let e=document.createElement("input");e.type="file",e.accept=".json";let t=d(()=>e.remove(),"cleanup");e.onchange=async s=>{let a=s.currentTarget.files?.[0];if(!a)return void t();let i=new FileReader;i.onload=async r=>{t();try{let n=String(r.currentTarget.result||""),l=JSON.parse(n);if(!l||typeof l!="object"||Array.isArray(l))throw new Error("文件内容不是有效的数据对象");let c=loading();try{let h=await storageManager.exportData(),u=await storageManager.diffData(h,l);c.close(),o(u,l,null)}catch(h){c.close(),clog.error(h),show.error("差异分析失败: "+Ue(h))}}catch(n){clog.error(n),show.error("导入失败:文件内容不是有效的JSON格式 "+Ue(n))}},i.onerror=()=>{t(),show.error("读取文件时出错")},i.readAsText(a)},document.body.appendChild(e),e.click(),setTimeout(t,3e5)}catch(e){clog.error(e),show.error("导入数据时出错: "+Ue(e))}}d(Ll,"importSettingData");async function Bl(o,e){let t=await Nl(e),s=t.url;if(!s)return void show.error("请填写webDav服务地址并保存后, 再试此功能");let a=t.username;if(!a)return void show.error("请填写webDav用户名并保存后, 再试此功能");if(!t.password)return void show.error("请填写webDav密码并保存后, 再试此功能");let i=loading();try{let r=t.password,n=utils.getNowStr("_","_")+".json",l=JSON.stringify(await storageManager.exportData());l=await El(l),await e.createClient({url:s,username:a,password:r}).backup(o,n,l),show.ok("备份完成")}catch(r){clog.error(r),show.error(Ue(r))}finally{i.close()}}d(Bl,"backupDataByWebDav");async function Ml(o,e,t){let s=await Nl(t),a=s.url;if(!a)return void show.error("请填写webDav服务地址并保存后, 再试此功能");let i=s.username;if(!i)return void show.error("请填写webDav用户名并保存后, 再试此功能");if(!s.password)return void show.error("请填写webDav密码并保存后, 再试此功能");let r=loading();try{let n=s.password,l=t.createClient({url:a,username:i,password:n}),c=await l.getBackupList(o);e(c,l,"WebDav")}catch(n){clog.error(n),show.error(`发生错误: ${Ue(n)}`)}finally{r.close()}}d(Ml,"backupListBtnByWebDav");function wh(o,e,t,s,a,i){let r=d(c=>{let h=["B","KB","MB","GB","TB","PB"],u=0,p=c;for(;p>=1024&&u<h.length-1;)p/=1024,u++;return`${p%1==0?p.toFixed(0):p.toFixed(2)} ${h[u]}`},"formatSize"),n=d(c=>!c||c.length===0?'<div class="jhs-backup-empty">暂无数据</div>':c.map((h,u)=>`
                <div class="jhs-backup-card" data-idx="${u}">
                    <div class="jhs-backup-card-name">${C(h.name)}</div>
                    <div class="jhs-backup-card-meta">${r(h.size)} · ${utils.getNowStr("-",":",h.createTime)}</div>
                    <div class="jhs-backup-card-actions">
                        <button class="jhs-btn jhs-backup-btn jhs-backup-btn-danger" data-action="delete" data-idx="${u}">删除</button>
                        <button class="jhs-btn jhs-backup-btn jhs-backup-btn-primary" data-action="download" data-idx="${u}">下载</button>
                        <button class="jhs-btn jhs-backup-btn jhs-backup-btn-success" data-action="import" data-idx="${u}">导入</button>
                    </div>
                </div>
            `).join(""),"renderCards"),l="jhs-backup-card-list";i.open({type:1,title:t+"备份文件",content:`<div id="${l}" class="jhs-backup-cards">${n(o)}</div>`,area:utils.getResponsiveArea(["800px","70%"]),anim:-1,success:d(c=>{let h=$(c).find(`#${l}`);h.on("click",".jhs-backup-btn",async u=>{let p=$(u.currentTarget),g=p.data("action"),m=p.data("idx"),f=o[m];if(f){if(g==="delete")i.confirm(`是否删除 ${f.name} ?`,{icon:3,title:"提示",btn:["确定","取消"]},async v=>{i.close(v);let b=loading();try{await e.deleteFile(f.fileId),o=await e.getBackupList(s),h.html(n(o)),i.alert("删除成功")}catch(w){clog.error(w),show.error(`发生错误: ${Ue(w)}`)}finally{b.close()}});else if(g==="download"){let v=loading();try{let b=await Xt(await e.getFileContent(f.fileId));utils.download(b,f.name)}catch(b){clog.error(b),show.error("下载失败: "+b)}finally{v.close()}}else if(g==="import"){let v=loading();try{let b=await e.getFileContent(f.fileId);b=await Xt(b);let w=JSON.parse(b),S=await storageManager.exportData(),j=await storageManager.diffData(S,w);v.close(),a(j,null,w)}catch(b){v.close(),clog.error(b),show.error("预览失败: "+Ue(b))}}}})},"success")})}d(wh,"openFileListDialogMobile");function Ol(o,e,t,s,a,i){if(utils.isMobileMode()){wh(o,e,t,s,a,i);return}i.open({type:1,title:t+"备份文件",content:`
                <div class="jhs-table-dialog">
                    <div id="table-container" class="jhs-table-dialog__content"></div>
                </div>
            `,area:utils.getResponsiveArea(["800px","70%"]),anim:-1,success:d(r=>{let n=$(r).find(".jhs-table-dialog__content").get(0)||$(r).find("#table-container").get(0),l=ze(globalThis.Tabulator,n,{pagination:!1,layout:"fitColumns",placeholder:"暂无数据",virtualDom:!0,data:o,responsiveLayout:"collapse",responsiveLayoutCollapse:!0,columnDefaults:{headerHozAlign:"center",hozAlign:"center"},columns:[{title:"文件名",field:"name",width:200,headerSort:!1,responsive:0},{title:"文件大小",field:"size",responsive:1,headerSort:!1,formatter:d((c,h,u)=>{let p=["B","KB","MB","GB","TB","PB"],g=0,m=c.getData().size;for(;m>=1024&&g<p.length-1;)m/=1024,g++;return`${m%1==0?m.toFixed(0):m.toFixed(2)} ${p[g]}`},"formatter")},{title:"备份日期",field:"createTime",responsive:2,headerSort:!1,formatter:d((c,h,u)=>{let p=c.getData();return`${utils.getNowStr("-",":",p.createTime)}`},"formatter")},{title:"操作",minWidth:250,responsive:0,headerSort:!1,formatter:d((c,h,u)=>{let p=c.getData();return u((()=>{let g=c.getElement().querySelector(".backup-delete"),m=c.getElement().querySelector(".backup-download"),f=c.getElement().querySelector(".backup-import");g&&g.addEventListener("click",(v=>{i.confirm(`是否删除 ${p.name} ?`,{icon:3,title:"提示",btn:["确定","取消"]},(async b=>{i.close(b);let w=loading();try{await e.deleteFile(p.fileId);let S=await e.getBackupList(s);l.replaceData(S),i.alert("删除成功")}catch(S){clog.error(S),show.error(`发生错误: ${Ue(S)}`)}finally{w.close()}}))})),m&&m.addEventListener("click",(async v=>{let b=loading();try{let w=await Xt(await e.getFileContent(p.fileId));utils.download(w,p.name)}catch(w){clog.error(w),show.error("下载失败: "+w)}finally{b.close()}})),f&&f.addEventListener("click",(async v=>{let b=loading();try{let w=await e.getFileContent(p.fileId);w=await Xt(w);let S=JSON.parse(w),j=await storageManager.exportData(),k=await storageManager.diffData(j,S);b.close(),a(k,null,S)}catch(w){b.close(),clog.error(w),show.error("预览失败: "+Ue(w))}}))})),`
                                    <button type="button" class="jhs-btn jhs-btn--danger backup-delete">删除</button>
                                    <button type="button" class="jhs-btn jhs-btn--secondary backup-download">下载</button>
                                    <button type="button" class="jhs-btn jhs-btn--primary backup-import">导入</button>
                                `},"formatter")}]})},"success")})}d(Ol,"openFileListDialog");async function zl(){try{let o=JSON.stringify(await storageManager.exportData()),e=`${utils.getNowStr("_","_")}.json`;utils.download(o,e),show.ok("数据导出成功")}catch(o){clog.error(o),show.error("导出数据时出错: "+Ue(o))}}d(zl,"exportSettingData");function Ul(o,e,t,s){let a;return t?a=`
                .container-fluid .row{
                    max-width: 1000px !important;
                    min-width: ${o}%;
                    margin: auto auto;
                }

                .container {
                    max-width: 1000px !important;
                    min-width: 80%;
                    margin: auto auto;
                }

                .masonry {
                    grid-template-columns: repeat(${e}, minmax(0, 1fr));
                }
            `:a=`
            section .container{
                max-width: 1000px !important;
                min-width: ${o}%;
            }
            .movie-list, .movie-list.v{
                grid-template-columns: repeat(${e}, minmax(0, 1fr));
            }
        `,`
            <style>
                ${a}
                .nav-btn::after {
                    content:none !important;
                }

                #cache-data-display pre {
                    font-family: Consolas, Monaco, 'Andale Mono', monospace;
                    white-space: pre-wrap;
                    word-wrap: break-word;
                    line-height: 1.5;
                    color: var(--jhs-text);
                    border: 1px solid var(--jhs-border);
                }

                .cache-item {
                    transition: all 0.2s ease;
                }
                .cache-item:hover {
                    box-shadow: var(--jhs-shadow-sm);
                    transform: translateY(-2px);
                }
                .cache-item { padding:var(--jhs-space-3); border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); }
                .cache-item__title { margin-bottom:var(--jhs-space-2); color:var(--jhs-text); font-weight:700; }
                .cache-item__actions, .jhs-inline-fields { display:flex; gap:var(--jhs-space-2); }
                .cache-item__actions > * { flex:1; text-align:center; }
                .jhs-setting-label-inline { display:flex; align-items:center; gap:var(--jhs-space-1); }
                .jhs-setting-toggle-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--jhs-space-2); }
                .jhs-setting-toggle-grid label { display:flex; align-items:center; gap:var(--jhs-space-2); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-xs); }
                .jhs-cache-preview { max-height:400px; padding:var(--jhs-space-3); overflow:auto; border-radius:var(--jhs-radius-sm); background:var(--jhs-surface-2); }

                .keyword-label {
                    display: inline-flex;
                    align-items: center;
                    padding: 4px 8px;
                    border-radius: var(--jhs-radius-sm);
                    font-size: 14px;
                    position: relative;
                    margin-left: 8px;
                    margin-bottom: 5px;
                }
                .keyword-remove {
                    margin-left: 6px;
                    cursor: pointer;
                    font-size: 12px;
                    line-height: 1;
                }
                .keyword-input {
                    padding: 6px 12px;
                    border: 1px solid var(--jhs-border);
                    border-radius: var(--jhs-radius-sm);
                    font-size: 14px;
                    float:right;
                }
                .add-tag-btn {
                    padding: 6px 12px;
                    background-color: var(--jhs-surface-2);
                    color: var(--jhs-text);
                    border: none;
                    border-radius: var(--jhs-radius-sm);
                    cursor: pointer;
                    font-size: 14px;
                    margin-left: 8px;
                    float:right;
                }
                .add-tag-btn:hover {
                    background-color: var(--jhs-border-strong);
                }
                .tag-box {
                    margin-top:15px;
                }


                .simple-setting, .mini-simple-setting {
                    display: none;
                    background: var(--jhs-surface);
                    position: absolute;
                    top: ${s?"35px":"25px"};
                    right: 0;
                    z-index: var(--jhs-z-dropdown);
                    border: 1px solid var(--jhs-border);
                    border-radius: var(--jhs-radius-sm);
                    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
                    padding: 0;
                    margin-top: 5px;
                    color: var(--jhs-text);
                    width: min(360px, calc(100vw - 16px));
                    max-height: min(720px, calc(100vh - 16px));
                }
                .simple-setting__panel { display:flex; max-height:inherit; flex-direction:column; }
                .jhs-quick-setting { color:var(--jhs-text); background:var(--jhs-surface); }
                .jhs-quick-setting .simple-setting__panel { max-height:min(720px, calc(100vh - 96px)); }
                .jhs-quick-setting-backdrop { position:fixed; inset:0; z-index:var(--jhs-z-sheet-backdrop); background:rgba(0,0,0,.45); backdrop-filter:blur(2px); }
                .jhs-quick-setting-sheet { position:fixed; right:0; bottom:0; left:0; z-index:var(--jhs-z-sheet); max-height:calc(100dvh - 16px); border:1px solid var(--jhs-border); border-bottom:0; border-radius:var(--jhs-radius-lg) var(--jhs-radius-lg) 0 0; background:var(--jhs-surface); box-shadow:var(--jhs-shadow-lg); overflow:hidden; }
                .jhs-quick-setting__header { display:flex; min-height:52px; align-items:center; justify-content:space-between; padding:0 var(--jhs-space-3) 0 var(--jhs-space-4); border-bottom:1px solid var(--jhs-border); }
                .jhs-quick-setting__header h2 { margin:0; color:var(--jhs-text); font-size:var(--jhs-font-size-lg); }
                .jhs-quick-setting__close { min-width:40px; padding:0; font-size:24px; }
                .simple-setting__scroll { min-height:0; padding:var(--jhs-space-2) var(--jhs-space-3); overflow-y:auto; }
                .simple-setting__footer { display:flex; justify-content:flex-end; gap:var(--jhs-space-2); padding:var(--jhs-space-3); border-top:1px solid var(--jhs-border); }
                .simple-setting__list { display:grid; }
                .simple-setting .jhs-setting-row, .mini-simple-setting .jhs-setting-row, .jhs-quick-setting .jhs-setting-row { grid-template-columns:minmax(0,1fr) auto; gap:var(--jhs-space-3); min-height:48px; padding:var(--jhs-space-2) 0; border-bottom:1px solid var(--jhs-border); }
                .simple-setting .jhs-setting-row:last-child, .mini-simple-setting .jhs-setting-row:last-child, .jhs-quick-setting .jhs-setting-row:last-child { border-bottom:0; }
                .simple-setting .jhs-setting-row__control, .mini-simple-setting .jhs-setting-row__control, .jhs-quick-setting .jhs-setting-row__control { width:auto; justify-self:end; }
                .simple-setting .jhs-setting-row__description, .mini-simple-setting .jhs-setting-row__description, .jhs-quick-setting .jhs-setting-row__description { display:-webkit-box; overflow:hidden; -webkit-box-orient:vertical; -webkit-line-clamp:2; line-height:1.35; }
                @media (max-width:767px) { .simple-setting .jhs-setting-row__description, .mini-simple-setting .jhs-setting-row__description, .jhs-quick-setting .jhs-setting-row__description { -webkit-line-clamp:unset; white-space:normal; } }
                .jhs-setting-nav-item { position:relative; }
                .jhs-nav-button { padding-right:15px !important; }
                .jhs-mini-setting-box { position:relative; margin-left:auto; }
                .jhs-mini-setting-trigger { padding-left:0 !important; padding-right:0 !important; }
                .jhs-setting-anchor { position:relative; display:flex; flex-grow:1; justify-content:flex-end; z-index:var(--jhs-z-host-nav) !important; }
                .jhs-setting-detail-anchor { margin-top:var(--jhs-space-5); }
                .jhs-more-tools-panel { display:none; }
                .jhs-backup-cards { padding:0 var(--jhs-space-1); }
                .jhs-table-dialog { height:100%; overflow:hidden; }
                .jhs-table-dialog__content { margin:auto !important; }
                .jhs-help-title { margin:0 0 var(--jhs-space-5); padding-bottom:var(--jhs-space-3); border-bottom:1px solid var(--jhs-border); color:var(--jhs-accent); font-size:22px; }
                .jhs-list-btn-row { display:flex; flex-wrap:wrap; align-items:center; gap:var(--jhs-space-2); margin:var(--jhs-space-2) 0; }

                .jhs-setting-layout {
                    display: grid;
                    grid-template-columns: 180px minmax(0, 1fr);
                    height: 100%;
                    min-height: 0;
                    background: var(--jhs-surface);
                }

                .jhs-mobile-sidebar {
                    display: flex;
                    min-width: 0;
                    flex-direction: column;
                    gap: 2px;
                    padding: var(--jhs-space-3) var(--jhs-space-2);
                    border-right: 1px solid var(--jhs-border);
                    background: var(--jhs-surface-2);
                    overflow-y: auto;
                }

                .side-menu-item {
                    width: 100%;
                    min-height: 36px;
                    padding: 0 var(--jhs-space-3);
                    border: 0;
                    border-radius: var(--jhs-radius-sm);
                    background: transparent;
                    cursor: pointer;
                    color: var(--jhs-text);
                    display: flex;
                    align-items: center;
                    gap: 5px;
                    font: inherit;
                    font-size: var(--jhs-font-size-sm);
                    text-align: left;
                    transition: background-color var(--jhs-motion-fast) var(--jhs-ease), color var(--jhs-motion-fast) var(--jhs-ease);
                }

                .side-menu-item .icon {
                     height: 24px;
                     width: 24px;
                }

                .side-menu-item:hover {
                    background-color: var(--jhs-surface);
                }

                .side-menu-item.active {
                    background-color: var(--jhs-accent-tint);
                    color: var(--jhs-accent);
                    font-weight: 700;
                }

                .jhs-setting-main {
                    display: flex;
                    min-width: 0;
                    min-height: 0;
                    flex-direction: column;
                    height: 100%;
                }

                .jhs-setting-body {
                    flex: 1;
                    min-height: 0;
                    padding: 0 var(--jhs-space-4);
                    overflow: hidden;
                }

                .jhs-setting-body-inner {
                    width: min(100%, 880px);
                    height: 100%;
                    margin-inline: auto;
                }

                .content-panel {
                    display: none;
                    box-sizing: border-box;
                    margin: 0;
                    padding: var(--jhs-space-4) 0;
                    height: 100%;
                    overflow-x: hidden;
                    overflow-y: auto;
                }

                .content-panel.active {
                    display: block;
                }

                .jhs-setting-section + .jhs-setting-section {
                    margin-top: var(--jhs-space-5);
                }
                .jhs-setting-section > .jhs-setting-group { overflow:visible; border:0; border-radius:0; }

                .jhs-setting-section__header {
                    margin-bottom: var(--jhs-space-2);
                }

                .jhs-setting-section__header h3 {
                    margin: 0;
                    color: var(--jhs-text);
                    font-size: var(--jhs-font-size-lg);
                }

                .jhs-setting-section__header p {
                    margin: var(--jhs-space-1) 0 0;
                    color: var(--jhs-text-muted);
                    font-size: var(--jhs-font-size-sm);
                }

                .jhs-setting-row__copy {
                    min-width: 0;
                }

                .jhs-setting-row__description {
                    display: block;
                    margin-top: var(--jhs-space-1);
                    color: var(--jhs-text-muted);
                    font-size: var(--jhs-font-size-sm);
                    font-weight: 400;
                    line-height: 1.45;
                }

                .jhs-setting-row__control {
                    width: min(100%, 360px);
                    justify-self: end;
                }
                .keyword-label { background:var(--jhs-surface-2); color:var(--jhs-text); }
                .keyword-label--link { color:var(--jhs-accent); }

                .jhs-setting-output {
                    max-height: 360px;
                    padding: var(--jhs-space-3);
                    overflow: auto;
                    border: 0;
                    border-radius: var(--jhs-radius-sm);
                    background: var(--jhs-surface-2);
                }
                .jhs-setting-output:empty { display:none; }
                .jhs-setting-output--compact { max-height:250px; }
                .jhs-setting-help { margin: 0 0 var(--jhs-space-3); color: var(--jhs-text-muted); font-size: var(--jhs-font-size-sm); }
                .jhs-setting-subheading { margin:var(--jhs-space-5) 0 var(--jhs-space-2); color:var(--jhs-text); font-size:var(--jhs-font-size-md); }
                .jhs-setting-rows { border:0; padding:0; }
                .jhs-setting-subtitle { margin:0; padding:var(--jhs-space-2) var(--jhs-space-4); border-bottom:1px solid var(--jhs-border); background:var(--jhs-surface-2); color:var(--jhs-text); font-size:var(--jhs-font-size-sm); }
                .jhs-setting-metrics { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); margin-bottom:var(--jhs-space-3); }
                .jhs-setting-metric { display:grid; gap:var(--jhs-space-1); padding:var(--jhs-space-2) var(--jhs-space-3); border-right:1px solid var(--jhs-border); text-align:center; }
                .jhs-setting-metric:last-child { border-right:0; }
                .jhs-setting-metric strong { color: var(--jhs-text); font-size: var(--jhs-font-size-xl); }
                .jhs-setting-metric span { color: var(--jhs-text-muted); font-size: var(--jhs-font-size-xs); }
                .jhs-plugin-group { margin-bottom:var(--jhs-space-4); }
                .jhs-plugin-group__title { margin:0; padding:var(--jhs-space-2) 0; border-bottom:1px solid var(--jhs-border); color:var(--jhs-text); font-size:var(--jhs-font-size-sm); }
                .jhs-plugin-row { display:flex; min-height:48px; align-items:center; justify-content:space-between; gap:var(--jhs-space-3); padding:var(--jhs-space-2) 0; border-bottom:1px solid var(--jhs-border); }
                .jhs-plugin-row:last-child { border-bottom:0; }
                .jhs-plugin-copy { display:grid; min-width:0; gap:2px; }
                .jhs-plugin-copy strong { color:var(--jhs-text); font-size:var(--jhs-font-size-sm); }
                .jhs-data-table { width:100%; border-collapse:collapse; color:var(--jhs-text); font-size:var(--jhs-font-size-sm); }
                .jhs-data-table th { padding:var(--jhs-space-2); border-bottom:1px solid var(--jhs-border); background:var(--jhs-surface-2); text-align:left; }
                .jhs-data-table td { padding:var(--jhs-space-1) var(--jhs-space-2); border-bottom:1px solid var(--jhs-border); }
                .jhs-data-table .is-center { text-align:center; }
                .jhs-data-table .is-right { text-align:right; }
                .jhs-data-table .is-danger { color:var(--jhs-danger); }
                .jhs-data-table .is-warning { color:var(--jhs-warning); }
                .jhs-data-table .is-success { color:var(--jhs-status-down); }
                .jhs-data-table .is-muted { color:var(--jhs-text-faint); }
                .jhs-data-table .is-slow { color:var(--jhs-danger); font-weight:700; }
                .jhs-diagnostics { margin-top:var(--jhs-space-5); border-top:1px solid var(--jhs-border); }
                .jhs-diagnostics > summary { display:flex; min-height:var(--jhs-control-height); align-items:center; justify-content:space-between; padding:var(--jhs-space-3) 0; color:var(--jhs-text); font-size:var(--jhs-font-size-md); font-weight:600; cursor:pointer; }
                .jhs-diagnostics > summary::after { color:var(--jhs-text-muted); content:"展开"; font-size:var(--jhs-font-size-sm); font-weight:400; }
                .jhs-diagnostics[open] > summary::after { content:"收起"; }
                .jhs-diagnostics__content { padding-bottom:var(--jhs-space-3); }
                .jhs-empty-note { padding:var(--jhs-space-5); color:var(--jhs-text-faint); font-size:var(--jhs-font-size-sm); text-align:center; }
                .jhs-caption { margin:var(--jhs-space-2) 0 0; color:var(--jhs-text-faint); font-size:var(--jhs-font-size-xs); }
                .jhs-inline-metrics { display:flex; flex-wrap:wrap; gap:var(--jhs-space-3); margin-bottom:var(--jhs-space-2); font-size:var(--jhs-font-size-sm); }
                .jhs-summary-grid { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:var(--jhs-space-2); margin-bottom:var(--jhs-space-3); }
                .jhs-summary-card { padding:var(--jhs-space-3); border-radius:var(--jhs-radius-md); background:var(--jhs-surface-2); text-align:center; }
                .jhs-summary-card strong { display:block; font-size:var(--jhs-font-size-xl); }
                .jhs-summary-card--success { background:var(--jhs-status-down-tint); color:var(--jhs-status-down); }
                .jhs-summary-card--danger { background:var(--jhs-status-filter-tint); color:var(--jhs-status-filter); }
                .jhs-summary-card--warning { background:var(--jhs-status-watch-tint); color:var(--jhs-status-watch); }
                .jhs-scroll-frame { max-height:350px; overflow:auto; border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); }
                .jhs-dialog-content { padding:var(--jhs-space-4); }
                .jhs-warning-note { margin-top:var(--jhs-space-3); color:var(--jhs-status-filter); font-size:var(--jhs-font-size-xs); }
                .jhs-health-summary { margin-bottom:var(--jhs-space-2); }
                .jhs-health-columns { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--jhs-space-3); }
                .jhs-health-columns h4 { margin:0 0 var(--jhs-space-1); }

                .jhs-setting-footer {
                    display: flex;
                    flex-shrink: 0;
                    justify-content: flex-end;
                    gap: var(--jhs-space-2);
                    padding: var(--jhs-space-3) var(--jhs-space-4);
                    border-top: 1px solid var(--jhs-border);
                    background: var(--jhs-surface);
                }

                .jhs-cache-grid {
                    display: grid;
                    grid-template-columns: repeat(2, minmax(0, 1fr));
                    gap: var(--jhs-space-3);
                    margin-top: var(--jhs-space-4);
                }

                .jhs-resource-card-list { display:grid; gap:var(--jhs-space-3); min-width:0; }
                .jhs-resource-card { min-width:0; overflow:hidden; }
                .jhs-resource-card .jhs-setting-row { align-items:flex-start; }
                .jhs-resource-card small { display:block; margin-top:var(--jhs-space-1); color:var(--jhs-text-muted); overflow-wrap:anywhere; }
                .jhs-resource-card .jhs-badge { margin-left:var(--jhs-space-2); }
                .jhs-resource-form, .jhs-resource-form label, .jhs-parser-fields { display:grid; gap:var(--jhs-space-2); min-width:0; }
                .jhs-resource-form { padding:var(--jhs-space-4); max-height:70vh; overflow-y:auto; overflow-x:hidden; }
                .jhs-resource-advanced > summary { cursor:pointer; font-weight:600; }
                #advanced-resource-json { width:100%; box-sizing:border-box; margin-top:var(--jhs-space-3); }

                @media (max-width: 767px) {
                    .jhs-setting-layout {
                        grid-template-columns: minmax(0, 1fr);
                        grid-template-rows: auto minmax(0, 1fr);
                    }
                    .jhs-mobile-sidebar {
                        flex-direction: row;
                        padding: var(--jhs-space-2);
                        border-right: 0;
                        border-bottom: 1px solid var(--jhs-border);
                        overflow-x: auto;
                        overflow-y: hidden;
                    }
                    .side-menu-item {
                        width: auto;
                        min-width: max-content;
                        min-height: var(--jhs-touch-target);
                    }
                    .jhs-setting-body {
                        padding-inline: var(--jhs-space-3);
                    }
                    .jhs-cache-grid {
                        grid-template-columns: minmax(0, 1fr);
                    }
                    .jhs-summary-grid, .jhs-health-columns { grid-template-columns:minmax(0,1fr); }
                    .jhs-resource-card .jhs-setting-row { align-items:stretch; }
                    .jhs-resource-card .jhs-toolbar { flex-wrap:wrap; }
                }

                input[type="checkbox"]:disabled {
                    opacity: 0.6;
                    cursor: default !important;
                }
            </style>
        `}d(Ul,"buildSettingCss");async function yh(o=null,e){if($("#verticalImgStyle").remove(),(e===void 0?await storageManager.getSetting("enableVerticalModel",ne):e)===R){let s="100% 50% !important";window.location.href.includes("/advanced_search?type=100")&&(s="50% 50% !important");let a=`
                .cover {
                    aspect-ratio: 3 / 4.26;
                    overflow: hidden !important;
                }

                .cover img {
                    width: 100%;
                    height: 100%;
                    object-fit: cover !important;
                    object-position: ${s};
                }

                /* bus的 */
                .masonry .movie-box img {
                    aspect-ratio: 3 / 4.26;
                    object-fit: cover !important;
                    object-position: top right;
                }
            `;$("<style>").attr("id","verticalImgStyle").text(a).appendTo("head")}else $("<style>").attr("id","verticalImgStyle").text(`
                .cover {
                    min-height:auto !important;
                    padding-top: 67% !important;
                }
                .cover img {
                    object-fit: contain !important;
                    object-position: 50% 50% !important
                }

                /* bus的 */
                 .masonry .movie-box img {
                    min-height:auto !important;
                    object-fit: contain !important;
                    object-position: top;
                }
            `).appendTo("head")}d(yh,"applyImageMode");async function pr(o={},{busImgPlugin:e=null,hostAdapter:t=null}={}){let s=o.enableVerticalModel===void 0?ne:o.enableVerticalModel;await yh(e,s);let a=globalThis.utils?.isMobileMode?.()??!1,i=a?1:Number(o.containerColumns??5)||5,r=a?100:Number(o.containerWidth??100)||100;if(B&&e?.logImageHeightsByRow&&await e.logImageHeightsByRow({vertical:s,columns:i}),t){let n=t.locateListRoot?.();n&&(n.style.gridTemplateColumns=`repeat(${i}, minmax(0, 1fr))`);let l=t.getListLayoutContainer?.();l&&(l.style.minWidth=`${r}%`)}}d(pr,"applyLayoutFromSettings");var gr=new WeakMap;function fr(o){let e=gr.get(o);return e||(e=new mr(o),gr.set(o,e)),e}d(fr,"getSettingBindingHub");function Fl({root:o,selector:e,key:t,getValue:s,setValue:a,fallback:i=void 0,label:r=t,settings:n,onChange:l=null}){let c=fr(n),h=o.find(e);if(!h.length)return null;let u={setValue(p,g){p===t&&a(g)},dispose(){h.off(".jhsSettingBinding"),c._dropBinding(u)}};return c.bindings.add(u),h.off(".jhsSettingBinding").on("change.jhsSettingBinding",()=>{let p=s();l?.(t,p),c.userChanged(t,p,i,r)}),u.setValue(t,c.desiredValue(t,n.snapshot()[t]??i)),{sync(p){Object.prototype.hasOwnProperty.call(p,t)&&a(p[t])},flush:d(p=>c.flush(p),"flush"),dispose:d(()=>u.dispose(),"dispose")}}d(Fl,"bindSettingControl");function Fe({settings:o,key:e,fallback:t=void 0,apply:s,onError:a=d(()=>{},"onError")}){let i=0;return async r=>{let n=++i;s(r);try{await o.set(e,r)}catch(l){n===i&&(s(o.snapshot()[e]??t),a(l))}}}d(Fe,"createLatestSettingWriter");var vr=class vr{constructor(e){this.settings=e,this.bindings=new Set,this.pending=new Map,this.revision=0,this._onSettingsChanged=this._onSettingsChanged.bind(this),this.settings.addEventListener("settings.changed",this._onSettingsChanged)}_onSettingsChanged(e){let t=e.detail||{},s=t.snapshot??this.settings.snapshot(),a=Array.isArray(t.names)?t.names:Object.keys(s);for(let i of a){let r=this.pending.get(i);this.syncAll(i,r?r.value:s[i])}}syncAll(e,t){for(let s of this.bindings)s.setValue(e,t)}desiredValue(e,t){let s=this.pending.get(e);return s?s.value:t}userChanged(e,t,s,a){this.syncAll(e,t);let r={token:++this.revision,value:t,promise:Promise.resolve()},n=this.settings.set(e,t).then(()=>{this.pending.get(e)===r&&(this.pending.delete(e),this._maybeDispose())},l=>{if(this.pending.get(e)===r){this.pending.delete(e),r.error=l;let c=this.settings.snapshot()[e]??s;this.syncAll(e,c),this._maybeDispose(),typeof globalThis.show?.error=="function"?globalThis.show.error(`${a||e}保存失败,已恢复原设置`):typeof globalThis.clog?.error=="function"&&globalThis.clog.error(`${a||e}保存失败,已恢复原设置`,l)}});return r.promise=n,this.pending.set(e,r),n}async flush({throwOnFailure:e=!1}={}){let t=[...this.pending.values()];if(await Promise.all(t.map(s=>s.promise)),await this.settings.waitForIdle(),e){let s=t.filter(a=>a.error).map(a=>a.error);if(s.length>0){let a=new Error("部分实时设置保存失败");throw a.cause=s[0],a.liveSettingFailures=s,a}}}_dropBinding(e){this.bindings.delete(e),this._maybeDispose()}_maybeDispose(){this.bindings.size===0&&this.pending.size===0&&(this.settings.removeEventListener("settings.changed",this._onSettingsChanged),gr.delete(this.settings))}};d(vr,"SettingBindingHub");var mr=vr;function br(o,e){return be(e,!1)}d(br,"normalizeBooleanValue");function Vl(o,e={}){let t=globalThis.$,s=e.value??o.defaultValue,a=e.onChange??null,i;if(o.type==="boolean")return i=t('<input type="checkbox" class="mini-switch">').prop("checked",br(o.key,s)),i.on("change",()=>{a?.(i.is(":checked")?"yes":"no")}),{root:i,getValue:d(()=>i.is(":checked")?"yes":"no","getValue"),setValue:d(r=>i.prop("checked",br(o.key,r)),"setValue")};if(o.type==="select"){let r=Array.isArray(o.options)?o.options:[];return i=t('<select class="jhs-select-source"></select>'),r.forEach(n=>{let l=n&&typeof n=="object"?n:{value:n,label:String(n)};i.append(t("<option></option>").attr("value",l.value).text(l.label??String(l.value)))}),i.val(String(s??"")),i.on("change",()=>a?.(i.val())),{root:i,getValue:d(()=>i.val(),"getValue"),setValue:d(n=>i.val(String(n??"")),"setValue")}}return o.type==="number"?(i=t('<input type="number" class="jhs-field">').val(s==null?"":String(s)),i.on("change",()=>a?.(Number(i.val())||0)),{root:i,getValue:d(()=>Number(i.val())||0,"getValue"),setValue:d(r=>i.val(r==null?"":String(r)),"setValue")}):(i=t('<input type="text" class="jhs-field">').val(s==null?"":String(s)),i.on("change",()=>a?.(i.val())),{root:i,getValue:d(()=>i.val(),"getValue"),setValue:d(r=>i.val(r==null?"":String(r)),"setValue")})}d(Vl,"renderSettingControl");function Bs(o,e={}){let t=globalThis.$,s=Vl(o,{value:e.value,onChange:e.onChange}),a=t('<span class="jhs-setting-row__copy"></span>').append(t('<span class="jhs-setting-row__label"></span>').text(o.label)).append(t('<span class="jhs-setting-row__description"></span>').text(o.description||"")),i=t('<span class="jhs-setting-row__control"></span>').append(s.root);return{row:t('<label class="jhs-setting-row"></label>').attr("data-jhs-setting",o.key).attr("data-jhs-setting-effect",o.effect||"live").toggleClass("jhs-setting-row--indent",o.indent===!0).append(a,i),root:s.root,getValue:s.getValue,setValue:s.setValue}}d(Bs,"renderSettingRow");function Hl(o,e={}){let t=globalThis.$,s=t('<div class="simple-setting__list"></div>');for(let a of o.list({surfaces:["quick"],disabledContributions:e.disabledContributions})){let{row:i}=Bs(a);s.append(i)}return s}d(Hl,"buildQuickSettingsHtml");function es(o,e,{settings:t,onChanged:s=null}){let a=fr(t),i=new wr(o,e,{settings:t,hub:a,onChanged:s});return{sync:d(r=>i.sync(r),"sync"),flush:d(r=>a.flush(r),"flush"),dispose:d(()=>i.dispose(),"dispose"),setters:i.setters}}d(es,"bindSettingRows");var yr=class yr{constructor(e,t,{settings:s,hub:a,onChanged:i=null}){this.root=e,this.settings=s,this.hub=a,this.onChanged=i,this.setters={},this.controls=new Map,a.bindings.add(this);for(let r of t)this._bindDescriptor(r)}_bindDescriptor(e){let t=e.key,s=this.root.find(`[data-jhs-setting="${t}"]`).first();if(!s.length)return;let a=s.find(".jhs-setting-row__control"),i=a.children().first();if(!i.length){let h=Vl(e);a.append(h.root),i=h.root}let r=e.type||(i.is("select")?"select":i.is('input[type="checkbox"]')?"boolean":i.is('input[type="number"]')?"number":"text"),n=jh(r,i),l=Sh(r,i),c=e.defaultValue;i.off(".jhsSettingBinding").on("change.jhsSettingBinding",()=>{let h=l(),u=typeof e.normalize=="function"?e.normalize(h):h;n(u),this.onChanged?.(t,u),(e.effect||"live")==="live"&&this.hub.userChanged(t,u,c,e.label||t)}),this.controls.set(t,{element:i,setValue:n}),this.setters[t]=n,this.setValue(t,this.hub.desiredValue(t,this.settings.snapshot()[t]??c))}setValue(e,t){let s=this.controls.get(e);s&&s.setValue(t)}sync(e){for(let t of this.controls.keys()){let s=Object.prototype.hasOwnProperty.call(e,t)?e[t]:this.settings.snapshot()[t];this.setValue(t,s)}}dispose(){for(let e of this.controls.values())e.element.off(".jhsSettingBinding");this.hub._dropBinding(this)}};d(yr,"RowBinding");var wr=yr;function jh(o,e){return o==="boolean"?t=>e.prop("checked",br("",t)):o==="select"?t=>{e.val(String(t??"")),K.refresh(e)}:o==="number"?t=>e.val(t==null?"":String(t)):t=>e.val(t==null?"":String(t))}d(jh,"makeSetValue");function Sh(o,e){return o==="boolean"?()=>e.is(":checked")?"yes":"no":o==="select"?()=>e.val():o==="number"?()=>{let t=e.val();if(t==null||String(t).trim()==="")return Number.NaN;let s=Number(t);return Number.isFinite(s)?s:Number.NaN}:()=>e.val()}d(Sh,"makeGetValue");var jr=Object.freeze(["videoQuality","reviewCount","tagPosition","waitCheckCount","highlightedTagNumber","highlightedTagColor","checkConcurrencyCount","checkRequestSleep","enableCheckBlacklist","checkBlacklist_intervalTime","checkBlacklist_ruleTime","enableCheckFavoriteActress","checkFavoriteActress_IntervalTime","enableCheckNewVideo","checkNewVideo_intervalTime","checkNewVideo_ruleTime","httpTimeout","httpRetryCount","circuitBreakerThreshold","circuitBreakerCooldown","clogMsgCount","webDavUrl","webDavUsername","webDavPassword","missAvUrl","jableUrl","avgleUrl","javTrailersUrl","av123Url","javDbUrl","javBusUrl","supJavUrl","enableTitleSelectFilter","enableFavoriteActresses","enableSaveActressCarInfo","autoRemoveNewVideoMarkAfterBrowse"]),xh=Object.freeze({videoQuality:"#videoQuality",reviewCount:"#reviewCount",tagPosition:"#tagPosition",waitCheckCount:"#waitCheckCount",highlightedTagNumber:"#highlightedTagNumber",highlightedTagColor:"#highlightedTagColor",checkConcurrencyCount:"#checkConcurrencyCount",checkRequestSleep:"#checkRequestSleep",enableCheckBlacklist:"#enableCheckBlacklist",checkBlacklist_intervalTime:"#checkBlacklist_intervalTime",checkBlacklist_ruleTime:"#checkBlacklist_ruleTime",enableCheckFavoriteActress:"#enableCheckFavoriteActress",checkFavoriteActress_IntervalTime:"#checkFavoriteActress_IntervalTime",enableCheckNewVideo:"#enableCheckNewVideo",checkNewVideo_intervalTime:"#checkNewVideo_intervalTime",checkNewVideo_ruleTime:"#checkNewVideo_ruleTime",httpTimeout:"#httpTimeout",httpRetryCount:"#httpRetryCount",circuitBreakerThreshold:"#circuitBreakerThreshold",circuitBreakerCooldown:"#circuitBreakerCooldownSec",clogMsgCount:"#clogMsgCount",webDavUrl:"#webDavUrl",webDavUsername:"#webDavUsername",webDavPassword:"#webDavPassword",missAvUrl:"#missAvUrl",jableUrl:"#jableUrl",avgleUrl:"#avgleUrl",javTrailersUrl:"#javTrailersUrl",av123Url:"#av123Url",javDbUrl:"#javDbUrl",javBusUrl:"#javBusUrl",supJavUrl:"#supJavUrl",enableTitleSelectFilter:"#enableTitleSelectFilter",enableFavoriteActresses:"#enableFavoriteActresses",enableSaveActressCarInfo:"#enableSaveActressCarInfo",autoRemoveNewVideoMarkAfterBrowse:"#autoRemoveNewVideoMarkAfterBrowse"});function kh(o){let e=new Set;o.data("jhsDirtyManualKeys",e);for(let t of jr){let s=xh[t];s&&o.find(s).off(".jhsDirty").on("change.jhsDirty",()=>e.add(t))}}d(kh,"bindManualDirtyTracking");function Wl(o){return o?globalThis.$(o):globalThis.$(document)}d(Wl,"formRoot");async function Jl(o,e=null){let t=Wl(e),s=o.settings.snapshot();t.find("#videoQuality").val(s.videoQuality),t.find("#reviewCount").val(s.reviewCount||20),t.find("#tagPosition").val(s.tagPosition||"rightTop"),t.find("#autoRemoveNewVideoMarkAfterBrowse").prop("checked",!!s.autoRemoveNewVideoMarkAfterBrowse&&s.autoRemoveNewVideoMarkAfterBrowse===R),t.find("#waitCheckCount").val(s.waitCheckCount||5),t.find("#checkConcurrencyCount").val(ae(s.checkConcurrencyCount,2,{min:2,max:5})),t.find("#checkRequestSleep").val(ae(s.checkRequestSleep,100,{min:0,max:3e3})),t.find("#enableCheckBlacklist").val(s.enableCheckBlacklist||R),t.find("#checkBlacklist_intervalTime").val(s.checkBlacklist_intervalTime||12),t.find("#checkBlacklist_ruleTime").val(ae(s.checkBlacklist_ruleTime,8760,{min:0})),t.find("#enableCheckFavoriteActress").val(s.enableCheckFavoriteActress||R),t.find("#checkFavoriteActress_IntervalTime").val(s.checkFavoriteActress_IntervalTime||24),t.find("#enableCheckNewVideo").val(s.enableCheckNewVideo||R),t.find("#checkNewVideo_intervalTime").val(s.checkNewVideo_intervalTime||12),t.find("#checkNewVideo_ruleTime").val(ae(s.checkNewVideo_ruleTime,8760,{min:0}));let a=s.highlightedTagNumber||1,i=s.highlightedTagColor||"#ce2222";t.find("#highlightedTagNumber").val(s.highlightedTagNumber||1),t.find("#highlightedTagColor").val(s.highlightedTagColor||"#ce2222"),t.find("#highlightedTagLabel").css("border",`${a}px solid ${i}`),t.find("#clogMsgCount").val(s.clogMsgCount||2e3),t.find("#httpTimeout").val(s.httpTimeout||5e3),t.find("#httpRetryCount").val(s.httpRetryCount||3),t.find("#webDavUrl").val(s.webDavUrl||""),t.find("#webDavUsername").val(s.webDavUsername||"");let r=o.webdav,n=r?.getProfile?await r.getProfile():{url:s.webDavUrl,username:s.webDavUsername,password:""};t.find("#webDavUrl").val(n.url||""),t.find("#webDavUsername").val(n.username||""),t.find("#webDavPassword").val(n.password||""),t.find("#enableTitleSelectFilter").prop("checked",!s.enableTitleSelectFilter||s.enableTitleSelectFilter===R),t.find("#enableFavoriteActresses").prop("checked",!s.enableFavoriteActresses||s.enableFavoriteActresses===R),t.find("#enableSaveActressCarInfo").prop("checked",!!s.enableSaveActressCarInfo&&s.enableSaveActressCarInfo===R);let l=o.movie;t.find("#missAvUrl").val(l.externalSiteOrigin("missAvBtn",s)),t.find("#jableUrl").val(l.externalSiteOrigin("jableBtn",s)),t.find("#avgleUrl").val(l.externalSiteOrigin("avgleBtn",s)),t.find("#javTrailersUrl").val(l.externalSiteOrigin("javTrailersBtn",s)),t.find("#av123Url").val(l.providerOrigin("av123")||""),t.find("#javDbUrl").val(l.externalSiteOrigin("javDbBtn",s)),t.find("#javBusUrl").val(l.externalSiteOrigin("javBusBtn",s)),t.find("#supJavUrl").val(l.externalSiteOrigin("supJavBtn",s));let c=await storageManager.getReviewFilterKeywordList(),h=await storageManager.getTitleFilterKeyword();["#reviewKeywordContainer","#filterKeywordContainer"].forEach(u=>{t.find(`${u} .tag-box`).empty(),t.find(`${u} .add-tag-btn`).off(".jhsKeywordBind"),t.find(`${u} .keyword-input`).off(".jhsKeywordBind")}),c&&c.forEach(u=>{Sr("#reviewKeywordContainer",u,t)}),h&&h.forEach(u=>{Sr("#filterKeywordContainer",u,t)}),["#reviewKeywordContainer","#filterKeywordContainer"].forEach(u=>{t.find(`${u} .add-tag-btn`).on("click.jhsKeywordBind",(p=>ql(p,u,t))),t.find(`${u} .keyword-input`).on("keypress.jhsKeywordBind",(p=>{p.key==="Enter"&&ql(p,u,t)}))}),kh(t),_h(t),Ch(t,o.busImg,o.host,o.settings)}d(Jl,"loadSettingForm");function Ch(o,e,t,s){o.find("#containerColumns").off(".jhsSetting").on("input.jhsSetting",(()=>{ts(o,t,"containerColumns",o.find("#containerColumns").val())})),o.find("#containerWidth").off(".jhsSetting").on("input.jhsSetting",(a=>{ts(o,t,"containerWidth",parseInt($(a.target).val())+70)}))}d(Ch,"bindLayoutRangeEvents");function ts(o,e,t,s){if(t==="containerColumns"){let n=Math.min(10,Math.max(2,Math.round(Number(s)||5)));o.find("#containerColumns").val(String(n)),o.find("#showContainerColumns").text(String(n));let l=e?.locateListRoot?.();l&&(l.style.gridTemplateColumns=`repeat(${n}, minmax(0, 1fr))`);return}let a=Math.min(100,Math.max(70,Math.round(Number(s)||100))),i=`${a}%`;o.find("#containerWidth").val(String(a-70)),o.find("#showContainerWidth").text(i);let r=e?.getListLayoutContainer?.();r&&(r.style.minWidth=i)}d(ts,"applyLayoutRangeValue");function Xe(o){let e=$(o);e.data("jhsQuickSettingBinding")?.dispose?.(),e.removeData("jhsQuickSettingBinding"),e.empty().hide()}d(Xe,"disposeQuickSettingHost");async function Ms(o,e,t,s){let a=$(s);if(!a.length)throw new Error("Quick setting root is required");let i=o.settingsRegistry;if(!i)return;let r=i.list({surfaces:["quick"]}),n=es(a,r,{settings:o.settings});a.data("jhsQuickSettingBinding",n),a.find("#moreBtn").off(".jhsQuickSetting").on("click.jhsQuickSetting",(async l=>{l.preventDefault(),l.stopPropagation(),await a.data("jhsQuickSettingBinding")?.flush?.(),Xe(a),await t("base-panel")}))}d(Ms,"initQuickSettingForm");async function Kl(o,e=null){let t=Wl(e),s=t.data("jhsDirtyManualKeys")||null,a=null,i=null;if(!s||s.has("webDavUrl")){if(a=String(t.find("#webDavUrl").val()||"").trim(),a)try{let g=new URL(a);if(!["http:","https:"].includes(g.protocol))throw new Error("protocol");i=g.origin}catch{throw new Error("WebDAV 地址必须是有效的 HTTP/HTTPS URL")}let p=new Set(Array.isArray(o.settings.snapshot().trustedLocalOrigins)?o.settings.snapshot().trustedLocalOrigins:[]);if(i&&!p.has(i)&&!await new Promise(m=>utils.q(null,`仅授权 WebDAV 精确来源:${i},是否继续?`,()=>m(!0),()=>m(!1))))return{canceled:!0}}(!s||["webDavUrl","webDavUsername","webDavPassword"].some(p=>s.has(p)))&&o.webdav?.saveProfile&&await o.webdav.saveProfile({...!s||s.has("webDavUrl")?{url:String(t.find("#webDavUrl").val()||"").trim()}:{},...!s||s.has("webDavUsername")?{username:String(t.find("#webDavUsername").val()||"")}:{},...!s||s.has("webDavPassword")?{password:String(t.find("#webDavPassword").val()||"")}:{}});let n=await $h(t,s);await o.settings.update(p=>{if(Object.assign(p,n),i){let g=new Set(Array.isArray(p.trustedLocalOrigins)?p.trustedLocalOrigins:[]);g.add(i),p.trustedLocalOrigins=[...g]}}),t.data("jhsDirtyManualKeys",new Set);let l=[],c=t.data("jhsDirtyReviewKeywords")===!0,h=t.data("jhsDirtyTitleKeywords")===!0;if(c)try{let p=[...new Set(t.find("#reviewKeywordContainer .keyword-label").toArray().map(g=>$(g).text().replaceAll("×","").replace(/[\r\n]+/g," ").replace(/\s{2,}/g," ").trim()).filter(Boolean))];await storageManager.saveReviewFilterKeyword(p)}catch(p){l.push(p)}if(h)try{let p=[...new Set(t.find("#filterKeywordContainer .keyword-label").toArray().map(g=>$(g).text().replaceAll("×","").replace(/[\r\n]+/g," ").replace(/\s{2,}/g," ").trim()).filter(Boolean))];await storageManager.saveTitleFilterKeyword(p)}catch(p){l.push(p)}if(l.length){let p=new Error("部分设置保存失败,请重试");throw p.partialFailure=!0,p.cause=l[0],p}t.data("jhsDirtyReviewKeywords",!1),t.data("jhsDirtyTitleKeywords",!1);let u=[["filter rules",async()=>{if(!F)throw new Error("EventBus 尚未初始化");await F.emit("filter-rules-changed",{scope:"title-keyword"})}],["new-video status",()=>o.newVideo?.resetBtnTip?.()],["blacklist status",()=>o.blacklist?.resetBtnTip?.()],["blacklist table",()=>o.blacklist?.reloadTable?.()]];for(let[p,g]of u)try{await g()}catch(m){typeof globalThis.clog?.error=="function"&&globalThis.clog.error(`设置保存后 ${p} 刷新失败(已忽略)`,m)}return{ok:!0}}d(Kl,"saveSettingForm");function _h(o){o.data("jhsDirtyReviewKeywords",!1),o.data("jhsDirtyTitleKeywords",!1)}d(_h,"bindKeywordDirtyTracking");async function $h(o,e=null){let t=d((n,l,c,h)=>Math.min(h,Math.max(c,Number(n)||l)),"clamp"),s=d((n,{allowLocalHttp:l=!1}={})=>{let c=String(n||"").trim().replace(/\/$/,"");if(!c)return"";let h;try{h=new URL(c)}catch{throw new TypeError(`无效 URL:${c}`)}let u=["localhost","127.0.0.1","[::1]"].includes(h.hostname);if(h.protocol!=="https:"&&!(l&&u&&h.protocol==="http:"))throw new TypeError(`仅允许 HTTPS URL${l?"(本机地址可使用 HTTP)":""}:${c}`);return h.href.replace(/\/$/,"")},"configuredUrl"),a={videoQuality:d(()=>o.find("#videoQuality").val(),"videoQuality"),reviewCount:d(()=>o.find("#reviewCount").val(),"reviewCount"),tagPosition:d(()=>o.find("#tagPosition").val(),"tagPosition"),autoRemoveNewVideoMarkAfterBrowse:d(()=>o.find("#autoRemoveNewVideoMarkAfterBrowse").is(":checked")?R:ne,"autoRemoveNewVideoMarkAfterBrowse"),waitCheckCount:d(()=>o.find("#waitCheckCount").val(),"waitCheckCount"),highlightedTagNumber:d(()=>o.find("#highlightedTagNumber").val(),"highlightedTagNumber"),highlightedTagColor:d(()=>o.find("#highlightedTagColor").val(),"highlightedTagColor"),checkConcurrencyCount:d(()=>o.find("#checkConcurrencyCount").val(),"checkConcurrencyCount"),checkRequestSleep:d(()=>o.find("#checkRequestSleep").val(),"checkRequestSleep"),enableCheckBlacklist:d(()=>o.find("#enableCheckBlacklist").val(),"enableCheckBlacklist"),checkBlacklist_intervalTime:d(()=>o.find("#checkBlacklist_intervalTime").val(),"checkBlacklist_intervalTime"),checkBlacklist_ruleTime:d(()=>o.find("#checkBlacklist_ruleTime").val(),"checkBlacklist_ruleTime"),enableCheckFavoriteActress:d(()=>o.find("#enableCheckFavoriteActress").val(),"enableCheckFavoriteActress"),checkFavoriteActress_IntervalTime:d(()=>o.find("#checkFavoriteActress_IntervalTime").val(),"checkFavoriteActress_IntervalTime"),enableCheckNewVideo:d(()=>o.find("#enableCheckNewVideo").val(),"enableCheckNewVideo"),checkNewVideo_intervalTime:d(()=>o.find("#checkNewVideo_intervalTime").val(),"checkNewVideo_intervalTime"),checkNewVideo_ruleTime:d(()=>o.find("#checkNewVideo_ruleTime").val(),"checkNewVideo_ruleTime"),httpTimeout:d(()=>t(o.find("#httpTimeout").val(),5e3,1e3,12e4),"httpTimeout"),httpRetryCount:d(()=>t(o.find("#httpRetryCount").val(),3,1,10),"httpRetryCount"),circuitBreakerThreshold:d(()=>t(o.find("#circuitBreakerThreshold").val(),3,1,20),"circuitBreakerThreshold"),circuitBreakerCooldown:d(()=>t(Number(o.find("#circuitBreakerCooldownSec").val())*1e3,6e4,1e3,36e5),"circuitBreakerCooldown"),clogMsgCount:d(()=>o.find("#clogMsgCount").val(),"clogMsgCount"),webDavUrl:d(()=>s(o.find("#webDavUrl").val(),{allowLocalHttp:!0}),"webDavUrl"),webDavUsername:d(()=>String(o.find("#webDavUsername").val()||""),"webDavUsername"),missAvUrl:d(()=>s(o.find("#missAvUrl").val()),"missAvUrl"),jableUrl:d(()=>s(o.find("#jableUrl").val()),"jableUrl"),avgleUrl:d(()=>s(o.find("#avgleUrl").val()),"avgleUrl"),javTrailersUrl:d(()=>s(o.find("#javTrailersUrl").val()),"javTrailersUrl"),av123Url:d(()=>s(o.find("#av123Url").val()),"av123Url"),javDbUrl:d(()=>s(o.find("#javDbUrl").val()),"javDbUrl"),javBusUrl:d(()=>s(o.find("#javBusUrl").val()),"javBusUrl"),supJavUrl:d(()=>s(o.find("#supJavUrl").val()),"supJavUrl"),enableTitleSelectFilter:d(()=>o.find("#enableTitleSelectFilter").is(":checked")?R:ne,"enableTitleSelectFilter"),enableFavoriteActresses:d(()=>o.find("#enableFavoriteActresses").is(":checked")?R:ne,"enableFavoriteActresses"),enableSaveActressCarInfo:d(()=>o.find("#enableSaveActressCarInfo").is(":checked")?R:ne,"enableSaveActressCarInfo")},i=e instanceof Set?jr.filter(n=>e.has(n)).filter(n=>!["webDavUrl","webDavUsername","webDavPassword"].includes(n)):jr.filter(n=>!["webDavUrl","webDavUsername","webDavPassword"].includes(n)),r={};for(let n of i){let l=a[n];l&&(r[n]=await l())}return r}d($h,"collectManualSettingPatch");function Sr(o,e,t){let s=t.find(`${o} .tag-box`),a=String(e),i;/^[a-z]{2,}-/i.test(a)&&N?i=$("<a>").addClass("keyword-label keyword-label--link").attr("data-keyword",a).attr("href",`/video_codes/${a.replace("-","")}`).attr("target","_blank"):i=$("<div>").addClass("keyword-label").attr("data-keyword",a),i.append(document.createTextNode(a)),i.append($("<span>").addClass("keyword-remove").text("×"));let r=o==="#reviewKeywordContainer"?"jhsDirtyReviewKeywords":"jhsDirtyTitleKeywords";i.find(".keyword-remove").click((n=>{n.stopPropagation(),n.preventDefault();let l=$(n.currentTarget),c=l.closest(".keyword-label").attr("data-keyword").split(" ")[0];utils.q(n,`是否移除屏蔽词  ${C(c)}?`,(async()=>{l.parent().remove(),t.data(r,!0)}))})),s.append(i)}d(Sr,"addLabelTag");function ql(o,e,t){let s=t.find(`${e} .keyword-input`),a=s.val().trim();if(!a)return;t.find(`${e} .keyword-label`).toArray().some((r=>$(r).text().replaceAll("×","").trim()===a))||Sr(e,a,t),s.val(""),t.data(e==="#reviewKeywordContainer"?"jhsDirtyReviewKeywords":"jhsDirtyTitleKeywords",!0)}d(ql,"addKeyword");function Gl(){let o={SettingPlugin:["设置中心","core"],StatsPlugin:["统计中心","core"],MobileBottomBarPlugin:["工具栏与移动操作","core"],ListPagePlugin:["列表状态处理","list"],NavBarPlugin:["JavDB 导航","list"],BusNavBarPlugin:["JavBus 导航","list"],ListPageButtonPlugin:["列表操作","list"],HighlightMagnetPlugin:["磁力标记","list"],FoldCategoryPlugin:["分类折叠","list"],AutoPagePlugin:["自动翻页","list"],HitShowPlugin:["热播榜单","list"],TOP250Plugin:["TOP 250","list"],DetailPagePlugin:["JavDB 详情页","detail"],BusDetailPagePlugin:["JavBus 详情页","detail"],DetailPageButtonPlugin:["详情操作","detail"],ReviewPlugin:["评论","detail"],RelatedPlugin:["相关影片","detail"],TranslatePlugin:["标题翻译","detail"],WantAndWatchedVideosPlugin:["想看与看过","detail"],CoverButtonPlugin:["封面快捷操作","media"],PreviewVideoPlugin:["JavDB 预览视频","media"],BusPreviewVideoPlugin:["JavBus 预览视频","media"],ScreenShotPlugin:["剧照","media"],BusImgPlugin:["JavBus 图片适配","media"],ActressInfoPlugin:["演员资料","media"],SearchByImagePlugin:["以图搜图","media"],HistoryPlugin:["鉴定记录","data"],BlacklistPlugin:["黑名单","data"],FilterTitleKeywordPlugin:["关键词筛选","data"],FavoriteActressesPlugin:["演员收藏","data"],NewVideoPlugin:["新作品检测","data"],TaskPlugin:["定时任务","data"],OtherSitePlugin:["外部站点","network"],Fc2Plugin:["FC2 详情","network"],Fc2By123AvPlugin:["FC2 123AV","network"],MagnetHubPlugin:["磁力聚合","network"],JavTrailersPlugin:["预告片","network"],SubTitleCatPlugin:["字幕搜索","network"],OneTwoThreeOfflinePlugin:["123 云盘离线","network"]},e=d((t,s)=>({label:s,plugins:Object.entries(o).filter((a=>a[1][1]===t)).map((a=>a[0]))}),"group");return{categories:{core:e("core","基础核心"),list:e("list","列表页"),detail:e("detail","详情页"),media:e("media","媒体"),data:e("data","数据"),network:e("network","网络")},pluginMeta:o}}d(Gl,"getPluginCategories");function Th(o){return o.map(e=>`
            <div class="cache-item">
                <div class="cache-item__title">${e.text}</div>
                <div class="cache-item__actions">
                    <button type="button" class="jhs-btn jhs-btn--secondary clean-btn" data-key="${e.key}" title="${e.title}">
                        <span>清理</span>
                    </button>
                    <button type="button" class="jhs-btn jhs-btn--secondary view-btn" data-key="${e.key}" >
                        <span>查看</span>
                    </button>
                </div>
            </div>
        `).join("")}d(Th,"buildCacheItemsHtml");function Ah(){let o="";return at.forEach(e=>{e.canSelect&&(o+=`<option value="${e.quality}">${e.text}</option>`)}),o}d(Ah,"buildVideoQualityOptions");function Ql(o,e){let t=Th(e),s=Ah();return`
            <div class="jhs-setting-layout jhs-ui">
                <nav class="jhs-mobile-sidebar" aria-label="设置分类">
                    <button type="button" class="jhs-btn side-menu-item ${o==="backup-panel"?"active":""}" data-panel="backup-panel" aria-controls="backup-panel">数据备份</button>
                    <button type="button" class="jhs-btn side-menu-item ${o==="base-panel"?"active":""}" data-panel="base-panel" aria-controls="base-panel">基础配置</button>
                    <button type="button" class="jhs-btn side-menu-item ${o==="filter-panel"?"active":""}" data-panel="filter-panel" aria-controls="filter-panel">屏蔽配置</button>
                    <button type="button" class="jhs-btn side-menu-item ${o==="task-panel"?"active":""}" data-panel="task-panel" aria-controls="task-panel">定时任务</button>
                    <button type="button" class="jhs-btn side-menu-item ${o==="domain-panel"?"active":""}" data-panel="domain-panel" aria-controls="domain-panel" title="第三方视频资源域名配置">外部网站</button>

                    <button type="button" class="jhs-btn side-menu-item ${o==="cache-panel"?"active":""}" data-panel="cache-panel" aria-controls="cache-panel">清理缓存</button>
                </nav>

                <div class="jhs-setting-main">
                    <div class="jhs-setting-body">


                        <div id="backup-panel" class="content-panel ${o==="backup-panel"?"active":""}" role="region">
                            <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>数据备份</h3><p>导入、导出和远程备份 JHS 数据。</p></header><div class="jhs-setting-group">
                            <div class="jhs-toolbar">
                                <button type="button" id="importBtn" class="jhs-btn jhs-btn--secondary"><span>导入数据</span></button>
                                <button type="button" id="exportBtn" class="jhs-btn jhs-btn--primary"><span>导出数据</span></button>
                            </div>

                            <div class="jhs-setting-row">
                                <span class="setting-label">WebDav备份</span>
                                <div>
                                    <button type="button" id="webdavBackupListBtn" class="jhs-btn jhs-btn--secondary"><span>查看备份</span></button>
                                    <button type="button" id="webdavBackupBtn" class="jhs-btn jhs-btn--primary"><span>备份数据</span></button>
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">服务地址:</span>
                                <div class="form-content">
                                    <input type="url" id="webDavUrl" class="jhs-field">
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">用户名:</span>
                                <div class="form-content">
                                    <input type="text" id="webDavUsername" class="jhs-field">
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">密码:</span>
                                <div class="form-content">
                                    <input type="password" id="webDavPassword" class="jhs-field">
                                </div>
                            </div>
                        </div></section>
                        </div>


                        <div id="base-panel" class="content-panel ${o==="base-panel"?"active":""}" role="region">
                            <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>基础配置</h3><p>配置列表显示、媒体加载、网络和主题。</p></header><div class="jhs-setting-group">
                            <div class="jhs-setting-row">
                                <span class="setting-label">每次开始鉴定数量:</span>
                                <div class="form-content">
                                    <input type="number" id="waitCheckCount" class="jhs-field" min="1" max="20">
                                </div>
                            </div>

                            <div class="jhs-setting-row">
                                <span class="setting-label">已鉴定标签展示位置:</span>
                                <div class="form-content">
                                    <select id="tagPosition" class="jhs-select-source">
                                        <option value="rightTop">右上</option>
                                        <option value="leftTop">左上</option>
                                    </select>
                                </div>
                            </div>

                            <div class="jhs-setting-row">
                                <span class="setting-label">默认显示选项卡:</span>
                                <div class="form-content">
                                    <select id="defaultQuickFilterTab" class="jhs-select-source">
                                        <option value="all">全部</option>
                                        <option value="waitCheck">待鉴定</option>
                                        <option value="favorite">收藏</option>
                                        <option value="hasDown">下载</option>
                                        <option value="hasWatch">已看</option>
                                        <option value="blockedItems">屏蔽项</option>
                                    </select>
                                </div>
                            </div>

                            <div class="jhs-setting-row">
                                <span class="setting-label jhs-setting-label-inline">鉴定后自动关闭详情页</span>
                                <div class="form-content">
                                    <input type="checkbox" id="needClosePageBasic" class="mini-switch">
                                </div>
                            </div>

                            <div class="jhs-setting-row">
                                <span class="setting-label jhs-setting-label-inline">浏览后自动移除新作品标记</span>
                                <div class="form-content">
                                    <input type="checkbox" id="autoRemoveNewVideoMarkAfterBrowse" class="mini-switch">
                                </div>
                            </div>

                            <div class="jhs-setting-row">
                                <span class="setting-label jhs-setting-label-inline">
                                    鉴定补录演员信息
                                </span>
                                <div class="form-content">
                                    <input type="checkbox" id="enableSaveActressCarInfo" class="mini-switch">
                                </div>
                            </div>



                            <div class="jhs-setting-row">
                                <span class="setting-label">
                                    功能开关
                                </span>
                            </div>
                            <div id="jhs-live-settings" class="jhs-live-settings"></div>



                            <div class="jhs-setting-row">
                                <span class="setting-label">预览视频默认画质:</span>
                                <div class="form-content">
                                    <select id="videoQuality" class="jhs-select-source">
                                        ${s}
                                    </select>
                                </div>
                            </div>

                            <div class="jhs-setting-row">
                                <span class="setting-label">评论区条数:</span>
                                <div class="form-content">
                                    <select id="reviewCount" class="jhs-select-source">
                                        <option value="10">10条</option>
                                        <option value="20">20条</option>
                                        <option value="30">30条</option>
                                        <option value="40">40条</option>
                                        <option value="50">50条</option>
                                    </select>
                                </div>
                            </div>

                            <div class="jhs-setting-row ${N?"":"do-hide"}">
                                <span class="setting-label">
                                    高亮已收藏演员
                                </span>
                                <div class="form-content">
                                    <input type="checkbox" id="enableFavoriteActresses" class="mini-switch">
                                </div>
                            </div>

                            <div class="jhs-setting-row ${N?"":"do-hide"}">
                                <span id="highlightedTagLabel" class="setting-label">
                                    分类标签|高亮演员-边框样式:
                                </span>
                                <div class="form-content">
                                    <input type="number" id="highlightedTagNumber" class="jhs-field" min="0" max="20">
                                    <input type="color" id="highlightedTagColor">
                                </div>
                            </div>



                            <div class="jhs-setting-row">
                                <span class="setting-label">请求超时时间(毫秒):</span>
                                <div class="form-content">
                                    <input type="number" id="httpTimeout" class="jhs-field" min="1000" max="10000">
                                </div>
                            </div>

                            <div class="jhs-setting-row">
                                <span class="setting-label">请求失败重试次数:</span>
                                <div class="form-content">
                                    <input type="number" id="httpRetryCount" class="jhs-field" min="0" max="10">
                                </div>
                            </div>



                            <div class="jhs-setting-row">
                                <span class="setting-label">
                                    启用控制台日志:
                                </span>
                                <div class="form-content">
                                    <select id="enableClog" class="jhs-select-source">
                                        <option value="no">禁用</option>
                                        <option value="yes">开启</option>
                                    </select>
                                </div>
                            </div>

                            <div class="jhs-setting-row">
                                <span class="setting-label">日志最大行数:</span>
                                <div class="form-content">
                                    <input type="number" id="clogMsgCount" class="jhs-field" min="100" max="3000">
                                </div>
                            </div>




                            <div class="jhs-setting-row">
                                <span class="setting-label">
                                    移动端模式
                                </span>
                                <div class="form-content">
                                    <select id="mobileMode" class="jhs-select-source">
                                        <option value="auto">自动检测</option>
                                        <option value="on">强制开启</option>
                                        <option value="off">强制关闭</option>
                                    </select>
                                </div>
                            </div>

                            <div class="jhs-setting-row">
                                <span class="setting-label">
                                    外观主题
                                </span>
                                <div class="form-content">
                                    <select id="themeMode" class="jhs-select-source">
                                        <option value="light">浅色</option>
                                        <option value="dark">深色</option>
                                        <option value="auto">跟随系统</option>
                                    </select>
                                </div>
                            </div>
                            <div class="jhs-setting-row"><span class="setting-label">页面列数:<span id="showContainerColumns"></span></span><div class="form-content"><input type="range" class="jhs-range" id="containerColumns" min="2" max="10" step="1"></div></div>
                            <div class="jhs-setting-row"><span class="setting-label">页面宽度:<span id="showContainerWidth"></span></span><div class="form-content"><input type="range" class="jhs-range" id="containerWidth" min="0" max="30" step="1"></div></div>
                        </div></section>
                        </div>

                        <div id="task-panel" class="content-panel ${o==="task-panel"?"active":""}" role="region">
                            <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>定时任务</h3><p>配置黑名单、演员同步和新作品检测。</p></header><div class="jhs-setting-group">

                            <div id="setting-task-status-list" aria-live="polite"></div>

                            <div class="jhs-setting-row">
                                <span class="setting-label">请求并发数量:</span>
                                <div class="form-content">
                                    <input type="number" id="checkConcurrencyCount" class="jhs-field" min="2" max="5">
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">请求间隔时间(毫秒):</span>
                                <div class="form-content">
                                    <input type="number" id="checkRequestSleep" class="jhs-field" min="0" max="3000">
                                </div>
                            </div>



                            <div id="setting-blacklist" class="jhs-setting-rows">
                                <h4 class="jhs-setting-subtitle">自动检测屏蔽黑名单演员</h4>
                                <div class="jhs-setting-row">
                                    <span class="setting-label">
                                        任务开关:
                                    </span>
                                    <div class="form-content">
                                        <select id="enableCheckBlacklist" class="jhs-select-source">
                                            <option value="no">禁用</option>
                                            <option value="yes">开启</option>
                                        </select>
                                    </div>
                                </div>
                                <div class="jhs-setting-row">
                                    <span class="setting-label">任务间隔时间:</span>
                                    <div class="form-content">
                                         <select id="checkBlacklist_intervalTime" class="jhs-select-source">
                                            <option value="2">每2小时</option>
                                            <option value="3">每3小时</option>
                                            <option value="6">每6小时</option>
                                            <option value="12">每12小时</option>
                                            <option value="24">每24小时</option>
                                        </select>
                                    </div>
                                </div>
                                <div class="jhs-setting-row">
                                    <span class="setting-label">检测规则:</span>
                                    <div class="form-content">
                                         <select id="checkBlacklist_ruleTime" class="jhs-select-source">
                                            <option value="0">全部检测</option>
                                            <option value="8760">不检测停更1年以上</option>
                                            <option value="17520">不检测停更2年以上</option>
                                            <option value="26280">不检测停更3年以上</option>
                                        </select>
                                    </div>
                                </div>
                            </div>

                            <div id="setting-checkFavoriteActress" class="jhs-setting-rows ${N?"":"do-hide"}">
                                <h4 class="jhs-setting-subtitle">自动同步已收藏的演员</h4>
                                <div class="jhs-setting-row">
                                    <span class="setting-label">
                                        任务开关:
                                    </span>
                                    <div class="form-content">
                                        <select id="enableCheckFavoriteActress" class="jhs-select-source">
                                            <option value="no">禁用</option>
                                            <option value="yes">开启</option>
                                        </select>
                                    </div>
                                </div>
                                <div class="jhs-setting-row">
                                    <span class="setting-label">任务间隔时间:</span>
                                    <div class="form-content">
                                         <select id="checkFavoriteActress_IntervalTime" class="jhs-select-source">
                                            <option value="12">每12小时</option>
                                            <option value="24">每24小时</option>
                                        </select>
                                    </div>
                                </div>
                            </div>

                            <div id="setting-checkNewVideo" class="jhs-setting-rows ${N?"":"do-hide"}">
                                <h4 class="jhs-setting-subtitle">自动检测已收藏演员的最新作品</h4>
                                <div class="jhs-setting-row">
                                    <span class="setting-label">
                                        任务开关:
                                    </span>
                                    <div class="form-content">
                                        <select id="enableCheckNewVideo" class="jhs-select-source">
                                            <option value="no">禁用</option>
                                            <option value="yes">开启</option>
                                        </select>
                                    </div>
                                </div>
                                <div class="jhs-setting-row">
                                    <span class="setting-label">任务间隔时间:</span>
                                    <div class="form-content">
                                         <select id="checkNewVideo_intervalTime" class="jhs-select-source">
                                            <option value="2">每2小时</option>
                                            <option value="3">每3小时</option>
                                            <option value="6">每6小时</option>
                                            <option value="12">每12小时</option>
                                            <option value="24">每24小时</option>
                                        </select>
                                    </div>
                                </div>
                                <div class="jhs-setting-row">
                                    <span class="setting-label">检测规则:</span>
                                    <div class="form-content">
                                         <select id="checkNewVideo_ruleTime" class="jhs-select-source">
                                            <option value="0">全部检测</option>
                                            <option value="8760">不检测停更1年以上</option>
                                            <option value="17520">不检测停更2年以上</option>
                                            <option value="26280">不检测停更3年以上</option>
                                        </select>
                                    </div>
                                </div>
                            </div>
                        </div></section>
                        </div>

                        <div id="domain-panel" class="content-panel ${o==="domain-panel"?"active":""}" role="region">
                            <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>外部网站</h3><p>配置外部资源来源、域名与网络。</p></header><div class="jhs-setting-group">
                            <div class="jhs-setting-row">
                                <span class="setting-label">域名 - MissAv:</span>
                                <div class="form-content">
                                    <input type="url" id="missAvUrl" class="jhs-field">
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">域名 - Jable:</span>
                                <div class="form-content">
                                    <input type="url" id="jableUrl" class="jhs-field">
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">域名 - Avgle:</span>
                                <div class="form-content">
                                    <input type="url" id="avgleUrl" class="jhs-field">
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">域名 - JavTrailer:</span>
                                <div class="form-content">
                                    <input type="url" id="javTrailersUrl" class="jhs-field">
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">域名 - 123Av:</span>
                                <div class="form-content">
                                    <input type="url" id="av123Url" class="jhs-field">
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">域名 - JavDb:</span>
                                <div class="form-content">
                                    <input type="url" id="javDbUrl" class="jhs-field">
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">域名 - JavBus:</span>
                                <div class="form-content">
                                    <input type="url" id="javBusUrl" class="jhs-field">
                                </div>
                            </div>
                            <div class="jhs-setting-row">
                                <span class="setting-label">域名 - SupJav:</span>
                                <div class="form-content">
                                    <input type="url" id="supJavUrl" class="jhs-field">
                                </div>
                            </div>
                        </div></section>
                        </div>


                        <div id="filter-panel" class="content-panel ${o==="filter-panel"?"active":""}" role="region">
                            <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>屏蔽配置</h3><p>配置文本、演员和类别筛选规则。</p></header><div class="jhs-setting-group">
                            <div class="jhs-setting-row">
                                <span class="setting-label">
                                     启用划词屏蔽
                                </span>
                                <div class="jhs-inline-fields">
                                    <input type="checkbox" id="enableTitleSelectFilter" class="mini-switch">
                                </div>
                            </div>



                            <div id="reviewKeywordContainer">
                                <div class="jhs-setting-row">
                                    <span class="setting-label">评论区屏蔽词:</span>
                                    <div class="jhs-inline-fields">
                                        <input type="text" class="keyword-input jhs-field" placeholder="添加屏蔽词">
                                        <button class="jhs-btn add-tag-btn">添加</button>
                                    </div>
                                </div>
                                <div class="tag-box"> </div>
                            </div>



                            <div id="filterKeywordContainer">
                                <div class="jhs-setting-row">
                                    <span class="setting-label">视频标题屏蔽词:</span>
                                    <div class="jhs-inline-fields">
                                        <input type="text" class="keyword-input jhs-field" placeholder="添加屏蔽词">
                                        <button class="jhs-btn add-tag-btn">添加</button>
                                    </div>
                                </div>
                                <div class="tag-box"> </div>
                            </div>
                        </div></section>
                        </div>
                        <div id="cache-panel" class="content-panel ${o==="cache-panel"?"active":""}" role="region">
                            <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>缓存管理</h3><p>查看并清理非核心缓存数据。</p></header><div class="jhs-setting-group">
                            <h2 class="jhs-section__heading">以下操作不会影响核心数据</h2>
                            <br/>
                            <div class="jhs-cache-grid">
                                ${t}
                            </div>
                            <div id="cache-data-display" class="jhs-is-hidden">
                                <pre class="jhs-cache-preview"></pre>
                            </div>
                    </div></section>
                        </div>
                        </div>

                    <div class="jhs-setting-footer">
                        <span id="settings-hydration-status" class="jhs-caption" aria-live="polite"></span>
                        <button type="button" id="saveBtn" class="jhs-btn jhs-btn--primary">保存设置</button>
                        <button id="clean-all" class="jhs-btn jhs-btn--danger jhs-is-hidden">清理全部缓存</button>
                    </div>
                </div>
            </div>
        `}d(Ql,"buildSettingDialogHtml");function Yl(){let o=$(".side-menu-item").parent();o.length&&!o.find('[data-panel="health-panel"]').length&&o.append('<button type="button" class="jhs-btn side-menu-item" data-panel="health-panel" aria-controls="health-panel">数据体检</button>');let e=$(".content-panel").parent();e.length&&!$("#health-panel").length&&e.append(`
            <div id="health-panel" class="content-panel">
                <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>数据体检</h3><p>检查本地数据并在备份后修复异常。</p></header>
                <div class="jhs-toolbar jhs-health-actions">
                    <button type="button" id="runHealthCheckBtn" class="jhs-btn jhs-btn--primary"><span>重新体检</span></button>
                    <button type="button" id="repairHealthBtn" class="jhs-btn jhs-btn--secondary"><span>备份并修复</span></button>
                </div>
                <div id="health-data-display" class="jhs-setting-output">点击重新体检查看结果</div>
                </section>
            </div>
        `)}d(Yl,"injectHealthPanel");function Zl(){let o=$(".side-menu-item").parent();o.length&&!o.find('[data-panel="plugin-mgmt-panel"]').length&&o.append('<button type="button" class="jhs-btn side-menu-item" data-panel="plugin-mgmt-panel" aria-controls="plugin-mgmt-panel">插件管理</button>');let e=$(".content-panel").parent();if(!e.length||$("#plugin-mgmt-panel").length)return;e.append(`<div id="plugin-mgmt-panel" class="content-panel">
        <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>插件管理</h3><p>按功能查看插件状态、耗时和错误记录。</p></header>
        <div class="jhs-setting-metrics">
            <div class="jhs-setting-metric"><strong id="pm-total">0</strong><span>总插件数</span></div>
            <div class="jhs-setting-metric"><strong id="pm-enabled">0</strong><span>已启用</span></div>
            <div class="jhs-setting-metric"><strong id="pm-disabled">0</strong><span>已禁用</span></div>
        </div>
        <p class="jhs-setting-help">禁用插件后需刷新页面生效。核心插件不可禁用。</p>
        <div id="plugin-mgmt-list"></div>
        <details class="jhs-diagnostics"><summary>诊断信息</summary><div class="jhs-diagnostics__content">
        <h3 class="jhs-setting-subheading">插件执行耗时</h3><p class="jhs-setting-help">页面加载时各插件 handle() 的执行时间。</p><div id="plugin-timing-table"></div>
        <h3 class="jhs-setting-subheading">错误日志</h3><div class="jhs-toolbar"><button type="button" id="pm-clear-log" class="jhs-btn jhs-btn--danger"><span>清空日志</span></button></div><div id="plugin-error-log" class="jhs-setting-output jhs-setting-output--compact">无错误记录</div>
        <h3 class="jhs-setting-subheading">缓存命中率</h3><div id="cache-hit-stats" class="jhs-setting-output"></div>
        </div></details></section>
    </div>`)}d(Zl,"injectPluginMgmtPanel");function Xl(){let o=$(".side-menu-item").parent();o.length&&!o.find('[data-panel="snapshot-panel"]').length&&o.append('<button type="button" class="jhs-btn side-menu-item" data-panel="snapshot-panel" aria-controls="snapshot-panel">恢复点</button>');let e=$(".content-panel").parent();if(!e.length||$("#snapshot-panel").length)return;e.append('<div id="snapshot-panel" class="content-panel"><section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>恢复点</h3><p>创建、下载或恢复本地数据快照。</p></header><div class="jhs-toolbar"><button type="button" id="createSnapshotBtn" class="jhs-btn jhs-btn--primary"><span>创建快照</span></button></div><p class="jhs-setting-help">快照保存当前全部数据状态,可用于恢复。最多保留 10 个,超出自动清理最旧的。</p><div id="snapshot-list"></div></section></div>')}d(Xl,"injectSnapshotPanel");function ec(){let o=$(".side-menu-item").parent();o.length&&!o.find('[data-panel="network-panel"]').length&&o.append('<button type="button" class="jhs-btn side-menu-item" data-panel="network-panel" aria-controls="network-panel">外部请求</button>');let e=$(".content-panel").parent();if(!e.length||$("#network-panel").length)return;e.append(`<div id="network-panel" class="content-panel">
        <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>外部请求</h3><p>配置熔断规则并查看站点健康状态。</p></header>
        <h3 class="jhs-setting-subheading">熔断器配置</h3><p class="jhs-setting-help">连续请求失败达到阈值后,自动停止对该站点的请求,避免拖慢整体体验。</p>
        <div class="jhs-setting-row"><span class="setting-label">熔断阈值(次):</span><div class="form-content"><input type="number" id="circuitBreakerThreshold" class="jhs-field" min="2" max="10"></div></div>
        <div class="jhs-setting-row"><span class="setting-label">冷却时间(秒):</span><div class="form-content"><input type="number" id="circuitBreakerCooldownSec" class="jhs-field" min="10" max="300"></div></div>
        <div class="jhs-toolbar"><button type="button" id="resetAllBreakersBtn" class="jhs-btn jhs-btn--danger"><span>重置全部熔断</span></button></div>
        <h3 class="jhs-setting-subheading">站点健康状态</h3><p class="jhs-setting-help">各外部站点的熔断状态和请求统计。</p><div id="site-health-table"></div>
        <h3 class="jhs-setting-subheading">域名使用统计</h3><p class="jhs-setting-help">脚本实际请求过的域名及次数。</p><div class="jhs-toolbar"><button type="button" id="clearDomainStatsBtn" class="jhs-btn jhs-btn--danger"><span>清空统计</span></button></div><div id="domain-stats-table"></div></section>
    </div>`)}d(ec,"injectNetworkPanel");function tc(){if($("#resource-sources-panel").length)return;$(".content-panel").last().after(`<div id="resource-sources-panel" class="content-panel">
      <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>磁力来源</h3><p>聚合多个来源搜索磁力结果,优先级数字越小越靠前。</p></header><div id="builtin-magnet-source-list" class="jhs-resource-card-list"></div><div class="jhs-toolbar"><h4>自定义来源</h4><button type="button" id="add-custom-magnet-source" class="jhs-btn jhs-btn--primary">+ 添加来源</button></div><div id="custom-magnet-source-list" class="jhs-resource-card-list"></div></section>
      <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>磁力规则</h3><p>使用可视化规则为结果添加标签或过滤低质量内容。</p></header><div class="jhs-toolbar"><h4>标签规则</h4><button type="button" id="add-magnet-tag-rule" class="jhs-btn">+ 新建</button></div><div id="magnet-tag-rule-list" class="jhs-resource-card-list"></div><div class="jhs-toolbar"><h4>过滤规则</h4><button type="button" id="add-magnet-filter-rule" class="jhs-btn">+ 新建</button></div><div id="magnet-filter-rule-list" class="jhs-resource-card-list"></div></section>
      <section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>截图来源</h3><p>自动选择会按优先级依次尝试可用来源。</p></header><div class="jhs-setting-group"><label class="jhs-setting-row"><span>自动选择</span><input type="radio" name="screenshotMode" value="auto"></label><label class="jhs-setting-row"><span>手动选择</span><input type="radio" name="screenshotMode" value="manual"></label></div><div id="screenshot-source-list" class="jhs-resource-card-list"></div></section>
      <details class="jhs-setting-section jhs-resource-advanced"><summary>高级 · 导入 / 导出配置</summary><p class="jhs-setting-help">高级功能:错误修改可能导致自定义来源不可用,保存前会校验配置。</p><div class="jhs-toolbar"><button type="button" id="export-resource-config" class="jhs-btn">导出资源配置</button><button type="button" id="edit-resource-config" class="jhs-btn">编辑原始 JSON</button><button type="button" id="import-resource-config" class="jhs-btn jhs-btn--primary">校验并导入</button></div><textarea id="advanced-resource-json" class="jhs-textarea" rows="10" aria-label="高级资源配置 JSON"></textarea></details>
    </div>
    <div id="cloud-services-panel" class="content-panel"><section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>统一离线服务</h3><p>115 状态:<span id="one-one-five-state" class="jhs-badge">未知</span> <button type="button" id="check-one-one-five-login" class="jhs-btn jhs-btn--ghost">检测登录状态</button></p><small>服务不可用时会在提交前显示原因。</small></header><div id="cloud-settings-catalog" class="jhs-setting-group" aria-label="云盘服务设置"></div></section></div>
    <div id="data-tools-panel" class="content-panel"><section class="jhs-setting-section"><header class="jhs-setting-section__header"><h3>番号列表导入</h3><p>支持换行、空格、逗号分隔番号。必须先解析预览,再确认导入。</p></header><label class="jhs-setting-group"><span>番号</span><textarea id="car-number-import" class="jhs-textarea" rows="8" placeholder="ABC-001&#10;ABC-002&#10;FC2-1234567"></textarea></label><label class="jhs-setting-row"><span>导入为</span><select id="car-number-import-status" class="jhs-select-source"><option value="">请选择</option><option value="favorite">收藏</option><option value="hasDown">已下载</option><option value="hasWatch">已观看</option><option value="filter">屏蔽</option></select></label><div class="jhs-toolbar"><button type="button" id="preview-car-number-import" class="jhs-btn">解析预览</button><button type="button" id="confirm-car-number-import" class="jhs-btn jhs-btn--primary" disabled>确认导入</button></div><div id="car-number-import-preview" class="jhs-card" aria-live="polite"></div></section></div>`),$(".jhs-mobile-sidebar,.setting-sidebar").first().append('<button type="button" class="jhs-btn side-menu-item" data-panel="resource-sources-panel" aria-controls="resource-sources-panel">资源来源</button><button type="button" class="jhs-btn side-menu-item" data-panel="cloud-services-panel" aria-controls="cloud-services-panel">云盘服务</button><button type="button" class="jhs-btn side-menu-item" data-panel="data-tools-panel" aria-controls="data-tools-panel">数据工具</button>')}d(tc,"injectResourceSourcesPanel");function Os(o=void 0,e={}){let t=o?Hl(o,e):null;return`
        <div class="simple-setting__panel jhs-ui">
            <div class="simple-setting__scroll jhs-scrollbar">
                ${t?t.prop("outerHTML"):'<div class="simple-setting__list"></div>'}
            </div>
            <footer class="simple-setting__footer">
                <button type="button" id="moreBtn" class="jhs-btn jhs-btn--ghost">完整设置 <span aria-hidden="true">›</span></button>
            </footer>
        </div>`}d(Os,"buildQuickSettingHtml");async function Rt(o){let e=o.getNetworkDiagnostics(),t=e.circuitBreakers,s=e.domainStats,a=await storageManager.getSetting("circuitBreakerThreshold",3),i=await storageManager.getSetting("circuitBreakerCooldown",6e4);$("#circuitBreakerThreshold").each(((l,c)=>{c.dataset.jhsHydrated||(c.value=String(a),c.dataset.jhsHydrated="1")})),$("#circuitBreakerCooldownSec").each(((l,c)=>{c.dataset.jhsHydrated||(c.value=String(Math.round(i/1e3)),c.dataset.jhsHydrated="1")}));let r=Object.entries(t);if(r.length){let l='<table class="jhs-data-table"><tr><th>域名</th><th class="is-center">状态</th><th class="is-center">失败次数</th><th class="is-center">操作</th></tr>';for(let[c,h]of r){let u=h.state==="open"?"熔断":h.state==="half-open"?"半开":"正常",p=h.state==="open"?`剩余${Math.ceil((Number(h.cooldownMs)-(Date.now()-Number(h.openTime)))/1e3)}秒`:"";l+=`<tr><td>${C(c)}</td><td class="is-center">${u} ${p}</td><td class="is-center">${Number(h.failCount)||0}</td><td class="is-center"><button type="button" class="jhs-btn jhs-btn--danger reset-breaker" data-domain="${C(c)}">重置</button></td></tr>`}l+="</table>",$("#site-health-table").html(l)}else $("#site-health-table").html('<p class="jhs-empty-note">暂无熔断记录</p>');let n=Object.entries(s).sort(((l,c)=>c[1].count-l[1].count));if(n.length){let l='<table class="jhs-data-table"><tr><th>域名</th><th class="is-right">请求数</th><th class="is-right">错误数</th><th class="is-center">最后使用</th></tr>';for(let[c,h]of n){let u=h.lastUsed?new Date(h.lastUsed).toLocaleTimeString():"-";l+=`<tr><td>${C(c)}</td><td class="is-right">${h.count}</td><td class="is-right ${h.errors>0?"is-danger":""}">${h.errors}</td><td class="is-center">${u}</td></tr>`}l+="</table>",l+=`<p class="jhs-caption">共 ${n.length} 个域名</p>`,$("#domain-stats-table").html(l)}else $("#domain-stats-table").html('<p class="jhs-empty-note">暂无统计数据</p>');$(".reset-breaker").off("click").on("click",(l=>{let c=$(l.target).data("domain");o.resetCircuitBreaker(c),show.ok(`已重置 ${c} 的熔断状态`),Rt(o)})),$("#resetAllBreakersBtn").off("click").on("click",(()=>{o.resetAllCircuitBreakers(),show.ok("已重置全部熔断状态"),Rt(o)})),$("#clearDomainStatsBtn").off("click").on("click",(()=>{o.clearDomainStats(),show.ok("已清空域名统计"),Rt(o)}))}d(Rt,"renderNetworkPanel");async function ss(){let o=await storageManager.getSnapshotList(),e={manual:"手动创建","auto-import":"导入前自动","auto-repair":"修复前自动","auto-restore":"恢复前自动"};if(o.length===0)return void $("#snapshot-list").html('<div class="jhs-empty-note">暂无快照,点击上方按钮创建</div>');$("#snapshot-list").find(".tabulator").length&&$("#snapshot-list").empty();let t=ze(globalThis.Tabulator,"#snapshot-list",{pagination:!1,layout:"fitColumns",placeholder:"暂无数据",data:o,columnDefaults:{headerHozAlign:"center",hozAlign:"center"},columns:[{title:"名称",field:"name",width:200,headerSort:!1},{title:"来源",field:"source",width:100,headerSort:!1,formatter:d(s=>e[s.getValue()]||s.getValue(),"formatter")},{title:"时间",field:"time",width:170,headerSort:!1},{title:"数据量",field:"itemCount",width:80,headerSort:!1},{title:"操作",minWidth:220,headerSort:!1,formatter:d((s,a,i)=>{let r=s.getData();return i((()=>{let n=s.getElement().querySelector(".snap-restore"),l=s.getElement().querySelector(".snap-download"),c=s.getElement().querySelector(".snap-delete");n&&n.addEventListener("click",(async h=>{utils.q(h,`恢复到快照「${C(r.name)}」? 当前数据会自动备份。`,(async()=>{let u=loading();try{await storageManager.restoreSnapshot(r.id),show.ok("恢复成功, 页面将刷新"),setTimeout(()=>location.reload(),1e3)}catch(p){clog.error(p),show.error("恢复失败: "+(p instanceof Error?p.message:String(p)))}finally{u.close()}}))})),l&&l.addEventListener("click",(async h=>{let u=loading();try{let p=await storageManager.getSnapshot(r.id);if(!p)throw new Error("快照不存在");utils.download(JSON.stringify(p.data),`snapshot_${String(r.name||"snapshot").replace(/[\\/:*?"<>|]/g,"_")}.json`),show.ok("下载成功")}catch(p){show.error("下载失败: "+(p instanceof Error?p.message:String(p)))}finally{u.close()}})),c&&c.addEventListener("click",(async h=>{utils.q(h,`删除快照「${C(r.name)}」?`,(async()=>{try{await storageManager.deleteSnapshot(r.id),show.ok("已删除"),ss()}catch(u){clog.error(u),show.error("删除失败: "+(u instanceof Error?u.message:String(u)))}}))}))})),'<button type="button" class="jhs-btn jhs-btn--primary snap-restore">恢复</button> <button type="button" class="jhs-btn jhs-btn--secondary snap-download">下载</button> <button type="button" class="jhs-btn jhs-btn--danger snap-delete">删除</button>'},"formatter")}]})}d(ss,"renderSnapshotPanel");function sc(o,e,t=null,s){let a=o.summary,i=[];for(let[c,h]of Object.entries(o.stores)){if(h.status==="unchanged")continue;let u={store:c,status:h.status,oldCount:h.oldCount,newCount:h.newCount,added:h.added.length,removed:h.removed.length,modified:h.modified.length};i.push(u)}let r='<div class="jhs-dialog-content">';if(r+='<div class="jhs-summary-grid">',r+=`<div class="jhs-summary-card jhs-summary-card--success"><strong>${a.added}</strong><span>新增数据源</span></div>`,r+=`<div class="jhs-summary-card jhs-summary-card--danger"><strong>${a.removed}</strong><span>缺失数据源</span></div>`,r+=`<div class="jhs-summary-card jhs-summary-card--warning"><strong>${a.modified}</strong><span>有变更</span></div>`,r+=`<div class="jhs-summary-card"><strong>${a.unchanged}</strong><span>无变化</span></div>`,r+="</div>",i.length>0){r+='<div class="jhs-scroll-frame"><table class="jhs-data-table"><thead><tr><th>数据源</th><th>状态</th><th class="is-center">当前</th><th class="is-center">导入</th><th class="is-center">新增</th><th class="is-center">删除</th><th class="is-center">修改</th></tr></thead><tbody>';let c={added:"新增",removed:"缺失",modified:"变更",unchanged:"无变化"};for(let h of i)r+=`<tr><td>${C(h.store)}</td><td>${c[h.status]||h.status}</td><td class="is-center">${h.oldCount}</td><td class="is-center">${h.newCount}</td><td class="is-center is-success">${h.added||"-"}</td><td class="is-center is-danger">${h.removed||"-"}</td><td class="is-center is-warning">${h.modified||"-"}</td></tr>`;r+="</tbody></table></div>"}else r+='<div class="jhs-empty-note">数据完全一致,无需导入</div>';r+='<div class="jhs-warning-note">导入将覆盖当前数据,建议先创建快照备份</div>',r+="</div>";let n=i.length>0,l=s.open({type:1,title:"数据差异预览",content:r,area:utils.getResponsiveArea(["700px","auto"]),btn:n?["确认导入","取消"]:["知道了","取消"],anim:-1,yes:d(async c=>{if(!n)return void s.close(c);let h=loading();try{await storageManager.createSnapshot("导入前自动备份","auto-import"),t?(await storageManager.importData(t),show.ok("导入成功!"),setTimeout(()=>location.reload(),1e3)):e&&(await storageManager.importData(e),show.ok("导入成功!"),setTimeout(()=>location.reload(),1e3))}catch(u){clog.error(u),show.error("导入失败: "+(u instanceof Error?u.message:String(u)))}finally{h.close()}},"yes")})}d(sc,"showDiffPreview");async function xr(o,e=null){let t=o.exportSnapshot(),s=Ge(await storageManager.getSetting("disabledPlugins","[]")),a=t.legacyPlugins,i=d(S=>{let j=new Set(S);return a.filter((k=>j.has(k)||j.has($t(k))))},"effectiveDisabledNames"),{categories:r,pluginMeta:n}=Gl(),l=new Map((t.legacyPluginDescriptors||[]).map(S=>[S.name,S])),c=new Set(a),h="";for(let[S,j]of Object.entries(r)){let k=j.plugins.filter(x=>c.has(x));if(k.length){h+='<section class="jhs-plugin-group">',h+=`<h4 class="jhs-plugin-group__title">${C(j.label)}</h4>`;for(let x of k){let _=l.get(x)?.disableable===!1,E=s.includes($t(x)),L=n[x]?.[0]||x;h+='<div class="jhs-plugin-row">',h+=`<span class="jhs-plugin-copy" title="内部插件名:${C(x)}"><strong>${C(L)}</strong></span>`,_?h+='<span class="jhs-badge jhs-badge--neutral">核心</span>':h+=`<input type="checkbox" class="mini-switch pm-toggle" data-plugin="${C(x)}" ${E?"":"checked"}>`,h+="</div>"}h+="</section>"}}$("#plugin-mgmt-list").html(h);let u=i(s),p=a.length-u.length;$("#pm-total").text(a.length),$("#pm-enabled").text(p),$("#pm-disabled").text(u.length),$(".pm-toggle").off("change").on("change",async S=>{let j=$(S.target),k=j.data("plugin"),x=j.is(":checked"),_=!x,E=Ge(await storageManager.getSetting("disabledPlugins","[]")),L=$t(k);if(x?E=E.filter(P=>P!==k&&P!==L):E.includes(L)||E.push(L),!e)throw new Error("SettingsService is unavailable");let M=d(P=>{let z=t.legacyPlugins,O=i(P);$("#pm-total").text(z.length),$("#pm-enabled").text(z.length-O.length),$("#pm-disabled").text(O.length)},"renderState");M(E);try{await e.set("disabledPlugins",JSON.stringify(E)),show.ok(`插件 "${k}" 已${x?"启用":"禁用"},刷新后生效`)}catch(P){j.prop("checked",_);let z=Ge(await storageManager.getSetting("disabledPlugins","[]"));M(z),clog.error("插件状态保存失败,已恢复",P),show.error(`插件 "${k}" 状态保存失败,已恢复`)}});let g=t.legacyStartup,m=t.legacyTimings,f=d(S=>Number.isFinite(S)?S.toFixed(1):"0.0","formatMs"),v=g?`<div class="jhs-inline-metrics"><span>就绪: <strong>${f(g.readyMs)} ms</strong></span><span>注册: ${f(g.registrationMs)} ms</span><span>样式: ${f(g.cssMs)} ms</span><span>即时插件: ${f(g.immediateMs)} ms</span><span>空闲任务: ${g.idleCompleted}/${g.idleCompleted+g.idlePending}</span></div><p class="jhs-caption">就绪耗时不包含 @require 下载及浏览器脚本解析时间。</p>`:"";if(m.length){let S=[...m].sort(((k,x)=>x.elapsed-k.elapsed)),j='<table class="jhs-data-table"><tr><th>插件</th><th class="is-center">阶段</th><th class="is-right">耗时(ms)</th><th class="is-center">状态</th></tr>';for(let k of S){let x=k.status==="disabled"?"is-muted":k.elapsed>500?"is-slow":k.elapsed>200?"is-warning":"",_=k.status==="disabled"?"已禁用":k.status==="error"?"错误":k.status==="pending-idle"?"等待空闲":k.status==="skipped-mobile"?"移动端跳过":"正常";j+=`<tr><td class="${x}">${C(k.name)}</td><td class="is-center">${k.startupMode==="idle"?"空闲":"即时"}</td><td class="is-right ${x}">${k.elapsed.toFixed(1)}</td><td class="is-center">${_}</td></tr>`}j+="</table>",$("#plugin-timing-table").html(v+j)}else $("#plugin-timing-table").html(v+'<p class="jhs-empty-note">暂无数据,刷新页面后自动采集。</p>');let b=t.errors.filter(S=>S.source==="legacy-plugin");if(b.length){let S='<table class="jhs-data-table"><tr><th>时间</th><th>插件</th><th>阶段</th><th>错误信息</th></tr>';for(let j of[...b].reverse())S+=`<tr><td class="is-muted">${C(String(j.timestamp||"").substring(11,19))}</td><td>${C(j.plugin)}</td><td>${C(j.phase)}</td><td class="is-danger">${C(j.message)}</td></tr>`;S+="</table>",$("#plugin-error-log").html(S)}else $("#plugin-error-log").text("无错误记录");let w=storageManager.getCacheHitStats();$("#cache-hit-stats").html(`<div class="jhs-inline-metrics"><span>命中: <strong>${w.hits}</strong></span><span>未命中: <strong>${w.misses}</strong></span><span>总计: <strong>${w.total}</strong></span><span>命中率: <strong>${w.rate}</strong></span></div>`)}d(xr,"renderPluginMgmtPanel");async function as(){let o=$("#health-data-display");if(o.length){o.text("体检中...");try{let e=await storageManager.inspectDataHealth(),t=e.fixable.reduce(((i,r)=>i+r.count),0),s=e.readonly.reduce(((i,r)=>i+r.count),0),a=d(i=>i.length?i.map((r=>`<li><strong>${C(r.message)}</strong>:${r.count}</li>`)).join(""):"<li>无</li>","i");o.html(`
                <div class="jhs-summary-grid">
                    <div>番号记录:<strong>${e.totals.carList}</strong></div>
                    <div>收藏演员:<strong>${e.totals.favoriteActresses}</strong></div>
                    <div>黑名单演员:<strong>${e.totals.blacklist}</strong></div>
                    <div>黑名单作品:<strong>${e.totals.blacklistCarList}</strong></div>
                </div>
                <div class="jhs-health-summary">体检时间:${C(e.checkedAt)};可修复问题 <strong>${t}</strong> 项,只读问题 <strong>${s}</strong> 项。</div>
                <div class="jhs-health-columns">
                    <div><h4>可安全修复</h4><ul>${a(e.fixable)}</ul></div>
                    <div><h4>仅报告</h4><ul>${a(e.readonly)}</ul></div>
                </div>
            `)}catch(e){clog.error(e),o.text("体检失败: "+e)}}}d(as,"renderDataHealthPanel");async function ac(){let o=JSON.stringify(await storageManager.exportData()),e=`health-backup-${utils.getNowStr("_","_")}.json`;utils.download(o,e);let t=await storageManager.repairDataHealth();show.ok(`已修复 ${t.fixedGroups} 组数据问题,修复前备份已下载`),await as()}d(ac,"repairDataHealthWithBackup");var kr=class kr extends I{constructor(){super(...arguments),A(this,"folderName","JHS-数据备份"),A(this,"resourceSettings",new rt),A(this,"pendingCarImport",null),A(this,"taskStatusUnsubscribe",null),A(this,"_desktopSettingNavMounted",!1),A(this,"_settingScope",null),A(this,"_settingNavResizeCleanup",null),A(this,"_desktopNavGeneration",0),A(this,"_settingsDialogGeneration",0),A(this,"_fullSettingBinding",null),A(this,"_cloudSettingBinding",null),A(this,"cacheItems",[{key:"jhs_dmm_video",text:"预览视频缓存",title:"预览视频缓存"},{key:"jhs_other_site",text:"第三方站点缓存",title:"第三方站点资源检测结果, 如missav,123Av等"},{key:"jhs_screenShot",text:"缩略图缓存",title:"缩略图缓存"},{key:"jhs_translate",text:"标题翻译",title:"标题翻译"},{key:"jhs_actress_info",text:"演员信息",title:"演员的年龄三围等数据信息"},{key:"jhs_score_info",text:"Top250|热播 评分数据",title:"Top250及热播的评分数据"},{key:"third_party_ttl_cache",text:"第三方TTL缓存",title:"评论、相关清单、磁力搜索、缩略图等请求缓存"},{key:"_circuitBreaker",text:"熔断状态",title:"各站点的熔断计数和状态"},{key:"_domainStats",text:"域名请求统计",title:"各域名的请求次数和错误统计"}])}getName(){return"SettingPlugin"}getFormDependencies(){return Object.freeze({otherSite:this.getOptionalDependency("OtherSitePlugin"),listPage:this.getOptionalDependency("ListPagePlugin"),translate:this.getOptionalDependency("TranslatePlugin"),actressInfo:this.getOptionalDependency("ActressInfoPlugin"),screenshot:this.getOptionalDependency("ScreenShotPlugin"),newVideo:this.getOptionalDependency("NewVideoPlugin"),blacklist:this.getOptionalDependency("BlacklistPlugin"),busImg:this.getOptionalDependency("BusImgPlugin"),host:this.getRuntimeService("host"),movie:this.getRuntimeService("movie"),settings:this.getRuntimeService("settings"),settingsRegistry:this.getRuntimeService("settingsRegistry"),webdav:this.getRuntimeService("webdav")})}async initCss(){let e=this.getRuntimeService("settings").snapshot(),t=e?.containerWidth??"100";utils.isMobileMode()&&(t="100");let s=utils.isMobileMode()?1:e?.containerColumns??5;return pr(e,{busImgPlugin:this.getOptionalDependency("BusImgPlugin"),hostAdapter:this.getRuntimeService("host")}).catch((a=>clog.error("[JHS] applyLayoutFromSettings failed:",a))),Ul(t,s,B,N)}async handle(){let e=this.getRuntimeService("settings");this.resourceSettings=new rt({getSetting:d(async(r=null,n)=>r===null?e.snapshot():Object.prototype.hasOwnProperty.call(e.snapshot(),r)?e.snapshot()[r]:n,"getSetting"),saveSettingItem:d((r,n)=>e.set(r,n),"saveSettingItem"),updateSetting:d(r=>e.update(r),"updateSetting"),patch:d(r=>e.patch(r),"patch")}),await storageManager.getSetting("enableClog",R)===R&&clog.show();let t=await this.getRuntimeService("scope")();this._settingScope=t;let s=this.getRuntimeService("settings"),a=d(r=>{let n=r.detail?.names||[];n.length&&(n.includes("themeMode")&&Vt(s.snapshot().themeMode),n.includes("enableClog")&&(s.snapshot().enableClog==="yes"?clog.show():clog.hide()),n.some(l=>["mobileMode","enableVerticalModel","containerColumns","containerWidth"].includes(l))&&pr(s.snapshot(),{busImgPlugin:this.getOptionalDependency("BusImgPlugin"),hostAdapter:this.getRuntimeService("host")}).catch(l=>clog.error("布局设置应用失败",l)))},"onSettingsChanged");s.addEventListener("settings.changed",a),t.addCleanup((()=>s.removeEventListener("settings.changed",a)));let i=d(async(r="backup-panel")=>{try{return await this.openSettingDialog(r)}catch(n){throw clog.error("设置中心打开失败",n),show.error("设置中心打开失败"),n}},"openSettings");t.addCleanup(ml(i)),t.listen(document,"click",(r=>{r.target instanceof Element&&r.target.closest("#setting-btn, #mini-setting-btn")&&(r.preventDefault(),$(".simple-setting, .mini-simple-setting").each((l,c)=>Xe(c)),clog.lowZIndex(),i().catch((()=>{})))})),t.addCleanup((()=>this.unmountDesktopSettingNav())),this.syncDesktopSettingNav(this.getRuntimeService("profile").current()==="compact")}syncDesktopSettingNav(e){e?this.unmountDesktopSettingNav():this.mountDesktopSettingNav()}mountDesktopSettingNav(){if(this._desktopSettingNavMounted)return;let e=this._settingScope;if(!e)return;this._desktopSettingNavMounted=!0;let t=this._desktopNavGeneration;if(N){let s=d(function(){$(".navbar-search").is(":hidden")?($(".mini-setting-box").hide(),$(".setting-box").show()):($(".mini-setting-box").show(),$(".setting-box").hide())},"e");$("#navbar-menu-user .navbar-end").prepend(`<div class="navbar-item has-dropdown is-hoverable setting-box jhs-setting-nav-item">
                    <button type="button" id="setting-btn" class="jhs-btn navbar-link nav-btn jhs-nav-btn jhs-nav-button">
                        设置
                    </button>
                    <div class="simple-setting"></div>
                </div>`),utils.loopDetector((()=>$("#miniHistoryBtn").length>0),(()=>{t!==this._desktopNavGeneration||!this._desktopSettingNavMounted||($(".miniHistoryBtnBox").before(`
                    <div class="navbar-item mini-setting-box jhs-mini-setting-box">
                        <button type="button" id="mini-setting-btn" class="jhs-btn navbar-link nav-btn jhs-nav-btn jhs-mini-setting-trigger">
                            设置
                        </button>
                        <div class="mini-simple-setting"></div>
                    </div>
                `),s())}),20,1e4,!0,e),this._settingNavResizeCleanup?.(),this._settingNavResizeCleanup=e.listen(window,"resize",s)}B&&(isDetailPage?$("h3").before(`
                    <div class="container-fluid jhs-setting-detail-anchor">
                        <div id="top-right-box" class="jhs-setting-anchor">
                            <div class="setting-box">
                                <button type="button" id="setting-btn" class="jhs-btn jhs-btn--dark">
                                    <span>设置</span>
                                </button>
                                <div class="simple-setting"></div>
                            </div>
                        </div>
                    </div>
               `):window.isListPage&&utils.loopDetector((()=>$("#waitCheckBtn").length),(()=>{t!==this._desktopNavGeneration||!this._desktopSettingNavMounted||$("#waitCheckBtn").parent().append(`
                    <div id="top-right-box" class="jhs-setting-anchor">
                        <div class="setting-box">
                            <button type="button" id="setting-btn" class="jhs-btn jhs-btn--dark">
                                <span>设置</span>
                            </button>
                            <div class="simple-setting"></div>
                        </div>
                    </div>
               `)}),1,1e4,!1,e)),$(".main-nav, .container-fluid").off("mouseenter.jhsSettingQuick mouseleave.jhsSettingQuick").on("mouseenter.jhsSettingQuick",".setting-box",(async s=>{let a=$(s.currentTarget).find(".simple-setting");Xe(a),a.html(Os(this.getRuntimeService("settingsRegistry"))).show();try{await Ms(this.getFormDependencies(),this.getSelector.bind(this),this.openSettingDialog.bind(this),a)}catch(i){clog.warn("桌面快捷设置初始化失败",i)}clog.lowZIndex()})).on("mouseleave.jhsSettingQuick",".setting-box",(s=>{Xe($(s.currentTarget).find(".simple-setting"))})).on("mouseenter.jhsSettingQuick",".mini-setting-box",(async s=>{let a=$(s.currentTarget).find(".mini-simple-setting");Xe(a),a.html(Os(this.getRuntimeService("settingsRegistry"))).show();try{await Ms(this.getFormDependencies(),this.getSelector.bind(this),this.openSettingDialog.bind(this),a)}catch(i){clog.warn("迷你快捷设置初始化失败",i)}clog.lowZIndex()})).on("mouseleave.jhsSettingQuick",".mini-setting-box",(s=>{Xe($(s.currentTarget).find(".mini-simple-setting"))}))}unmountDesktopSettingNav(){this._desktopNavGeneration++,this._desktopSettingNavMounted=!1,this._settingNavResizeCleanup?.(),this._settingNavResizeCleanup=null,$(".simple-setting, .mini-simple-setting").each((e,t)=>Xe(t)),$(".jhs-setting-nav-item, .jhs-mini-setting-box, .jhs-setting-anchor, .jhs-setting-detail-anchor").remove(),$(".main-nav, .container-fluid").off("mouseenter.jhsSettingQuick mouseleave.jhsSettingQuick")}async openQuickSetting(){$("#jhs-quick-setting-backdrop, #jhs-quick-setting-sheet").remove();let e=document.activeElement;await this.getRuntimeService("settings").waitForIdle();let t=!1,s=d((n=!0)=>{if(t)return;t=!0,$(document).off("keydown.jhsQuickSetting");let l=$("#jhs-quick-setting-sheet .jhs-quick-setting");Xe(l),$("#jhs-quick-setting-backdrop, #jhs-quick-setting-sheet").remove(),n&&e?.isConnected&&typeof e.focus=="function"&&e.focus()},"closeQuickSetting"),a=$('<div id="jhs-quick-setting-backdrop" class="jhs-quick-setting-backdrop"></div>'),i=$(`<section id="jhs-quick-setting-sheet" class="jhs-quick-setting-sheet jhs-ui" role="dialog" aria-modal="true" aria-labelledby="jhs-quick-setting-title">
            <header class="jhs-quick-setting__header"><h2 id="jhs-quick-setting-title">快捷设置</h2><button type="button" class="jhs-btn jhs-btn--ghost jhs-quick-setting__close" aria-label="关闭快捷设置">×</button></header>
            <div class="jhs-quick-setting"></div>
        </section>`),r=i.find(".jhs-quick-setting");r.html(Os(this.getRuntimeService("settingsRegistry"))),$("body").append(a,i),clog.lowZIndex(),a.on("click.jhsQuickSetting",(()=>s())),i.on("click.jhsQuickSetting",".jhs-quick-setting__close",(()=>s())),$(document).off("keydown.jhsQuickSetting").on("keydown.jhsQuickSetting",(n=>{if(n.key==="Escape")return n.preventDefault(),s();if(n.key!=="Tab")return;let l=i.find('a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])').filter(((u,p)=>!p.hidden&&p.getAttribute("aria-hidden")!=="true"));if(!l.length)return void n.preventDefault();let c=l[0],h=l[l.length-1];n.shiftKey&&document.activeElement===c?(n.preventDefault(),h.focus()):!n.shiftKey&&document.activeElement===h&&(n.preventDefault(),c.focus())}));try{await Ms(this.getFormDependencies(),this.getSelector.bind(this),(n=>{s(!1),this.openSettingDialog(n).catch((l=>clog.error("完整设置打开失败",l)))}),r),i.find(".jhs-quick-setting__close").trigger("focus")}catch(n){s(),clog.error("快捷设置初始化失败",n),show.error("快捷设置加载失败")}}async openSettingDialog(e="backup-panel",t){await this.getRuntimeService("settings").waitForIdle();let s=Ql(e,this.cacheItems);this.getRuntimeService("dialog").open({type:1,title:"设置",content:s,ui:{size:"lg",body:"scroll"},area:utils.getDialogArea("lg"),scrollbar:!1,success:d(async(a,i)=>{let r=++this._settingsDialogGeneration,n=$(a);this._settingsFocusCleanup?.(),this._settingsFocusCleanup=utils.trapFocus(n[0]),n.data("jhsSettingsGeneration",r),n.find(".layui-layer-content").css("position","relative"),this.renderTaskStatuses(n),Yl(),Zl(),Xl(),ec(),tc();let l=this.hydrateLiveSettings(n);this._fullSettingBinding=l,this.bindClick(n),n.find(".side-menu-item.active").attr("aria-current","page"),utils.setupEscClose(i),t&&t(),this.renderTaskStatuses(n),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=F.on("task-status-changed",(()=>this.renderTaskStatuses(n))),utils.isMobileMode()&&this.collapseAdvancedTabs(n);let c=await Promise.allSettled([this.hydrateSettingForm(a,r),this.loadResourceSettings(a,r)]),h=c[1];K.refreshAll(a),h.status==="rejected"&&(clog.error("resource-settings 加载失败",h.reason),this.getRuntimeService("diagnostics").recordError({source:"resource-settings",message:h.reason?.message||String(h.reason)}),show.error("资源设置加载失败,基本设置仍可保存"))},"success"),end:d(()=>{this._settingsDialogGeneration++,this._fullSettingBinding?.dispose?.(),this._fullSettingBinding=null,this._cloudSettingBinding?.dispose?.(),this._cloudSettingBinding=null,this._settingsFocusCleanup?.(),this._settingsFocusCleanup=null,this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=null,this.getOptionalDependency("CoverButtonPlugin")?.enableSvgBtn?.()},"end")})}hydrateLiveSettings(e){let t=$(e),s=t.find("#jhs-live-settings"),a=this.getRuntimeService("settingsRegistry"),i=this.getRuntimeService("settings"),r=this.getRuntimeService("host"),n=new Set(["needClosePage","themeMode","mobileMode","enableClog","containerColumns","containerWidth"]),l=a.list({surfaces:["full"]}).filter(p=>(p.effect||"live")==="live"&&p.section!=="cloud"&&!n.has(p.key));s.length&&l.forEach(p=>{let{row:g}=Bs(p,{value:i.snapshot()[p.key]??p.defaultValue});s.append(g)});let c=s.length?es(s,l,{settings:i}):null,h=[],u=d(p=>{let g=Fl({settings:i,root:t,...p});g&&h.push(g)},"registerStatic");return u({selector:"#needClosePageBasic",key:"needClosePage",getValue:d(()=>t.find("#needClosePageBasic").is(":checked")?"yes":"no","getValue"),setValue:d(p=>t.find("#needClosePageBasic").prop("checked",p==="yes"||p===!0),"setValue"),fallback:"yes",label:"鉴定后立即关闭"}),u({selector:"#themeMode",key:"themeMode",getValue:d(()=>t.find("#themeMode").val(),"getValue"),setValue:d(p=>t.find("#themeMode").val(String(p??"")),"setValue"),fallback:"light",label:"主题"}),u({selector:"#mobileMode",key:"mobileMode",getValue:d(()=>t.find("#mobileMode").val(),"getValue"),setValue:d(p=>t.find("#mobileMode").val(String(p??"")),"setValue"),fallback:"auto",label:"移动模式"}),u({selector:"#enableClog",key:"enableClog",getValue:d(()=>t.find("#enableClog").val(),"getValue"),setValue:d(p=>t.find("#enableClog").val(String(p??"")),"setValue"),fallback:"yes",label:"日志"}),u({selector:"#containerColumns",key:"containerColumns",getValue:d(()=>Number(t.find("#containerColumns").val())||5,"getValue"),setValue:d(p=>ts(t,r,"containerColumns",p),"setValue"),fallback:5,label:"列表列数"}),u({selector:"#containerWidth",key:"containerWidth",getValue:d(()=>Number(t.find("#containerWidth").val())+70,"getValue"),setValue:d(p=>ts(t,r,"containerWidth",p),"setValue"),fallback:100,label:"列表宽度"}),u({selector:"#defaultQuickFilterTab",key:"defaultQuickFilterTab",getValue:d(()=>Te(t.find("#defaultQuickFilterTab").val()),"getValue"),setValue:d(p=>t.find("#defaultQuickFilterTab").val(String(p??"")),"setValue"),fallback:"waitCheck",label:"列表默认筛选"}),!c&&!h.length?null:{sync:d(p=>{c?.sync?.(p);for(let g of h)g.sync?.(p)},"sync"),flush:d(async p=>{await c?.flush?.(p),await Promise.all(h.map(g=>g.flush?.(p)))},"flush"),dispose:d(()=>{c?.dispose?.();for(let p of h)p.dispose()},"dispose"),setters:c?.setters??{}}}async hydrateSettingForm(e,t){let s=$(e).find("#saveBtn"),a=$(e).find("#settings-hydration-status");s.attr("data-jhs-settings-ready","false").prop("disabled",!0).attr("title","正在加载设置…"),a.empty().text("正在加载设置…");let i=$(e);try{return await Jl(this.getFormDependencies(),i),!s[0]?.isConnected||t!==this._settingsDialogGeneration||i.data("jhsSettingsGeneration")!==t?!1:(K.refreshAll(e),s.attr("data-jhs-settings-ready","true").prop("disabled",!1).removeAttr("title"),a.empty().text("设置已加载"),!0)}catch(r){if(!s[0]?.isConnected||t!==this._settingsDialogGeneration||i.data("jhsSettingsGeneration")!==t)return!1;clog.error("settings-form 加载失败",r),this.getRuntimeService("diagnostics").recordError({source:"settings-form",message:r?.message||String(r)});let n=$('<button type="button" class="jhs-btn jhs-btn--secondary">重试加载</button>').on("click",(()=>{this.hydrateSettingForm(e,t)}));return a.empty().append(document.createTextNode("表单加载失败,已禁止保存。"),n),show.error("设置表单加载失败,保存已禁用"),!1}}renderTaskStatuses(e=null){let t=e?$(e).find("#setting-task-status-list"):$("#setting-task-status-list");if(!t.length)return;let s=this.getOptionalDependency("TaskPlugin");if(!s?.getTaskStatusSnapshot)return void t.empty();let a={blacklist:"黑名单",favoriteActress:"演员同步",newVideo:"新作品"},i={idle:"正常",running:"运行中",pending:"等待下一次任务检查",due:"待运行"},r=d(n=>n?new Date(n).toLocaleString():"无","format");t.empty(),["blacklist","favoriteActress","newVideo"].forEach((n=>{let l=s.getTaskStatusSnapshot(n),c=$('<div class="jhs-setting-row jhs-task-setting-status"></div>');c.append($('<span class="setting-label"></span>').text(`${a[n]}:${i[l.state]}`)),c.append($('<span class="form-content jhs-helper-text"></span>').text(`上次完成 ${r(l.completedAt)};下次检查 ${l.nextAt?r(l.nextAt):"立即"}`)),t.append(c)}))}collapseAdvancedTabs(e=null){let t=[{id:"health-panel",label:"数据体检",render:d(()=>as(this.getRuntimeService("diagnostics")),"render")},{id:"plugin-mgmt-panel",label:"插件管理",render:d(()=>xr(this.getRuntimeService("diagnostics"),this.getRuntimeService("settings")),"render")},{id:"snapshot-panel",label:"恢复点",render:ss},{id:"network-panel",label:"外部请求",render:d(()=>Rt(this.getRuntimeService("diagnostics")),"render")}],s=$(".jhs-mobile-sidebar"),a=$(".content-panel").parent();if(!s.length||!a.length||(t.forEach(l=>{s.find(`[data-panel="${l.id}"]`).remove()}),s.find('[data-panel="more-tools-panel"]').length||s.append('<button type="button" class="jhs-btn side-menu-item" data-panel="more-tools-panel" aria-controls="more-tools-panel">更多工具</button>'),$("#more-tools-panel").length))return;let i=t.map((l,c)=>`<button type="button" role="tab" aria-selected="${c===0}" tabindex="${c===0?"0":"-1"}" class="jhs-btn jhs-sub-tab${c===0?" active":""}" data-sub-panel="${l.id}">${l.label}</button>`).join(""),r=t.map((l,c)=>`<div id="sub-${l.id}" class="jhs-sub-panel${c===0?" active":""}" data-rendered="false"></div>`).join(""),n=`
            <div id="more-tools-panel" class="content-panel jhs-more-tools-panel">
                <div class="jhs-sub-tabs" role="tablist" aria-label="更多工具">${i}</div>
                <div class="jhs-sub-panels">${r}</div>
            </div>
        `;a.append(n),t.forEach(l=>{let c=$(`#${l.id}`);c.length&&(c.children().appendTo(`#sub-${l.id}`),c.remove(),$(`#sub-${l.id}`).attr("data-rendered","true"))}),s.on("click",'[data-panel="more-tools-panel"]',function(){$(".side-menu-item").removeClass("active").attr("aria-current","false"),$(this).addClass("active").attr("aria-current","page"),$(".content-panel").hide(),$("#more-tools-panel").show(),$("#saveBtn").show(),$("#clean-all").addClass("jhs-is-hidden")}),$("#more-tools-panel").on("click",".jhs-sub-tab",function(){let l=$(this).data("sub-panel");$("#more-tools-panel .jhs-sub-tab").removeClass("active").attr({"aria-selected":"false",tabindex:"-1"}),$(this).addClass("active").attr({"aria-selected":"true",tabindex:"0"}),$("#more-tools-panel .jhs-sub-panel").removeClass("active"),$(`#sub-${l}`).addClass("active"),$(`#sub-${l}`).attr("data-rendered")!=="true"&&$(`#sub-${l}`).attr("data-rendered","true");let c=t.find(h=>h.id===l);c&&c.render&&c.render()}).on("keydown",".jhs-sub-tab",function(l){if(!["ArrowLeft","ArrowRight","Home","End"].includes(l.key))return;l.preventDefault();let c=$("#more-tools-panel .jhs-sub-tab"),h=c.index(this),u=l.key==="Home"?0:l.key==="End"?c.length-1:l.key==="ArrowRight"?(h+1)%c.length:(h-1+c.length)%c.length;c.eq(u).trigger("click").trigger("focus")})}bindClick(e=null){let t=this,s=this.getRuntimeService("webdav"),a=this.getRuntimeService("dialog"),i=this.getRuntimeService("diagnostics"),r=this.getRuntimeService("storage"),n=this.getRuntimeService("translation"),l=d((m,f,v=null)=>sc(m,f,v,a),"previewDiff"),c=e?$(e):$(document);c.find("#saveBtn").attr("data-jhs-settings-ready","false").prop("disabled",!0).attr("title","正在加载设置…"),c.find(".side-menu-item").on("click",(function(){c.find(".side-menu-item").removeClass("active").attr("aria-current","false"),$(this).addClass("active").attr("aria-current","page"),c.find(".content-panel").hide();let m=$(this).data("panel");c.find("#"+m).show(),m==="cache-panel"?(c.find("#saveBtn").hide(),c.find("#clean-all").removeClass("jhs-is-hidden")):(c.find("#saveBtn").show(),c.find("#clean-all").addClass("jhs-is-hidden")),m==="health-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),as()),m==="plugin-mgmt-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),xr(t.getRuntimeService("diagnostics"),t.getRuntimeService("settings"))),m==="snapshot-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),ss()),m==="network-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),Rt(i))})),c.find("#importBtn").on("click",(m=>Ll(l))),c.find("#exportBtn").on("click",(m=>zl())),c.find("#preview-car-number-import").on("click",(()=>this.previewCarNumbers(c))),c.find("#confirm-car-number-import").on("click",(async m=>this.confirmCarNumbers(m,c))),c.find("#webdavBackupBtn").on("click",(m=>Bl(this.folderName,s))),c.find("#webdavBackupListBtn").on("click",(m=>Ml(this.folderName,(f,v,b)=>Ol(f,v,b,this.folderName,l,a),s))),c.find("#saveBtn").on("click",(async m=>{let f=$(m.currentTarget);if(!(f.data("jhsBusy")||f.attr("data-jhs-settings-ready")!=="true")){f.data("jhsBusy",!0).prop("disabled",!0).attr("aria-busy","true");try{if(await this._fullSettingBinding?.flush?.({throwOnFailure:!0}),(await Kl(this.getFormDependencies(),c))?.canceled)return;show.ok("保存成功")}catch(v){v?.partialFailure?show.error("部分设置保存失败,请重试"):show.error("设置保存失败"),clog.error("设置保存失败",v)}finally{f.removeData("jhsBusy").prop("disabled",f.attr("data-jhs-settings-ready")!=="true").removeAttr("aria-busy")}}})),c.find("#runHealthCheckBtn").on("click",(()=>as())),c.find("#repairHealthBtn").on("click",(m=>{utils.q(m,"修复前会自动下载备份,是否继续?",(()=>ac()))})),c.find("#pm-clear-log").on("click",(()=>{this.getRuntimeService("diagnostics").clearErrors(),c.find("#plugin-error-log").text("无错误记录"),show.ok("错误日志已清空")})),c.find("#createSnapshotBtn").on("click",(async()=>{let m=loading();try{await storageManager.createSnapshot("手动快照","manual"),show.ok("快照创建成功"),ss()}catch(f){clog.error(f),show.error("创建快照失败: "+f.message)}finally{m.close()}})),c.find(".clean-btn").on("click",(async m=>{let f=$(m.currentTarget).data("key"),v=this.cacheItems.find((b=>b.key===f));f===storageManager.third_party_cache_key?(await storageManager.clearThirdPartyCache(),await this.getRuntimeService("cache").clearNamespace("external-detail-v1")):f==="_circuitBreaker"?i.resetAllCircuitBreakers():f==="_domainStats"?i.clearDomainStats():f==="jhs_translate"?await n.clearCache():f==="jhs_actress_info"?(await this.getRuntimeService("cache").clearNamespace("actress-info"),await r.removeLocal(f)):f==="jhs_screenShot"?(await this.getRuntimeService("cache").clearNamespace("screenshot"),await r.removeLocal(f)):r.removeLocal(f),show.ok(`${v.text} 清理成功`),c.find("#cache-data-display").addClass("jhs-is-hidden"),f==="jhs_dmm_video"&&r.removeLocal("jhs_other_site_dmm")})),c.find("#clean-all").on("click",(async()=>{this.cacheItems.forEach((m=>m.key!=="jhs_translate"&&r.removeLocal(m.key))),await n.clearCache(),await this.getRuntimeService("cache").clearAll(),show.ok("全部缓存已清理"),c.find("#cache-data-display").addClass("jhs-is-hidden"),r.removeLocal("jhs_other_site_dmm"),await storageManager.clearThirdPartyCache()})),c.find(".view-btn").on("click",(async m=>{let f=$(m.currentTarget).data("key"),v;f===storageManager.third_party_cache_key?v=JSON.stringify(await storageManager.getThirdPartyCache()):f==="_circuitBreaker"?v=JSON.stringify(i.getNetworkDiagnostics().circuitBreakers):f==="_domainStats"?v=JSON.stringify(i.getNetworkDiagnostics().domainStats):f==="jhs_translate"?v=JSON.stringify(await n.inspectCache()):v=r.getLocal(f);let b=c.find("#cache-data-display"),w=b.find("pre");if(b.removeClass("jhs-is-hidden"),v)try{let S=JSON.parse(v);w.text(JSON.stringify(S,null,2))}catch{w.text(v)}else w.text("无数据")}));let h=c.find("#highlightedTagNumber"),u=c.find("#highlightedTagColor"),p=c.find("#highlightedTagLabel");function g(){let m=h.val(),f=u.val();p.css("border",`${m}px solid ${f}`)}d(g,"updatePreview"),h.on("input",g),u.on("input",g)}async loadResourceSettings(e=null,t=this._settingsDialogGeneration){let s=e?$(e):$(document),[a,i,r,n,l,c]=await Promise.all([this.resourceSettings.getMagnetSources(),this.resourceSettings.getMagnetTagRules(),this.resourceSettings.getMagnetFilterRules(),this.resourceSettings.getBuiltInSources(),this.resourceSettings.getScreenshotSettings(),this.resourceSettings.getCloudSettings()]);if(e&&(!s[0]?.isConnected||t!==this._settingsDialogGeneration))return;let h=[...Ns,...this.getRuntimeService("magnet").getBuiltInSources()];this.resourceState={custom:a,tags:i,filters:r,builtIn:h.map((u=>({...u,...n.find((p=>p.id===u.id))||{}}))),screenshot:{mode:l.mode,providers:Ls.map((u=>{let p={...u,...l.providers.find((g=>g.id===u.id))||{}};return u.implemented===!1?{...p,enabled:!1}:p}))}},this.renderResourceSettings(s),this.renderCloudSettings(s,c),s.find("#resource-sources-panel").off("change.jhsResource",'input[name="screenshotMode"]').on("change.jhsResource",'input[name="screenshotMode"]',(u=>{let p=this.resourceState.screenshot.mode;this.resourceState.screenshot.mode=u.currentTarget.value,this.resourceSettings.saveScreenshotMode(this.resourceState.screenshot.mode).catch(g=>{this.resourceState.screenshot.mode=p,s.find(`input[name="screenshotMode"][value="${p}"]`).prop("checked",!0),clog.error("截图模式保存失败",g),show.error("截图模式保存失败,已恢复原设置")})})),s.find("#add-custom-magnet-source").off("click.jhsResource").on("click.jhsResource",(()=>this.openSourceDialog(null,s))),s.find("#add-magnet-tag-rule").off("click.jhsResource").on("click.jhsResource",(()=>this.openRuleDialog("tag",null,s))),s.find("#add-magnet-filter-rule").off("click.jhsResource").on("click.jhsResource",(()=>this.openRuleDialog("filter",null,s))),s.find("#export-resource-config").off("click.jhsResource").on("click.jhsResource",(async()=>{let u=JSON.stringify(await this.resourceSettings.exportConfig(),null,2);s.find("#advanced-resource-json").val(u).prop("readonly",!0)})),s.find("#edit-resource-config").off("click.jhsResource").on("click.jhsResource",(()=>s.find("#advanced-resource-json").prop("readonly",!1).trigger("focus"))),s.find("#import-resource-config").off("click.jhsResource").on("click.jhsResource",(async()=>{try{await this.resourceSettings.importConfig(s.find("#advanced-resource-json").val()),show.ok("资源配置导入成功"),await this.loadResourceSettings(s,t),K.refreshAll()}catch(u){show.error(u.message)}})),s.find("#car-number-import,#car-number-import-status").off("input.jhsResource change.jhsResource").on("input.jhsResource change.jhsResource",(()=>{this.pendingCarImport=null,s.find("#confirm-car-number-import").prop("disabled",!0).text("确认导入")})),s.find("#check-one-one-five-login").off("click.jhsResource").on("click.jhsResource",(()=>this.checkOneOneFiveLogin(s)))}renderCloudSettings(e,t){let s=e.find("#cloud-settings-catalog");if(!s.length)return;this._cloudSettingBinding?.dispose?.();let a=this.getRuntimeService("settingsRegistry"),i=this.getRuntimeService("settings"),r=a.list({surfaces:["full"]}).filter(l=>l.section==="cloud");s.empty();let n=d(l=>l==="offlineProviderMode"?t.providerMode:l==="oneOneFiveConcurrency"?t.concurrency:l==="oneOneFiveCacheMinutes"?t.cacheMinutes:t[l],"valueFor");r.forEach(l=>{let c=Bs(l,{value:n(l.key)});c.root.attr("id",l.key),s.append(c.row)}),this._cloudSettingBinding=es(s,r,{settings:i})}renderResourceSettings(e=$(document)){let t=d((s,a,i)=>{let r=$('<article class="jhs-card jhs-resource-card"></article>');r.append($('<div class="jhs-setting-row"></div>').append($("<div></div>").append($("<strong></strong>").text(s.name),s.experimental?'<span class="jhs-badge">实验性</span>':"",$("<small></small>").text(`${s.type||"截图来源"} · ${s.domain||(()=>{try{return new URL(s.searchUrlTemplate).hostname}catch{return"未配置域名"}})()} · 优先级 ${s.priority}`)),$('<input type="checkbox" class="mini-switch jhs-source-toggle">').prop("checked",s.enabled)));let n=$('<div class="jhs-toolbar"></div>').append('<button type="button" class="jhs-btn jhs-source-test">测试</button>');return a&&n.append('<button type="button" class="jhs-btn jhs-source-edit">编辑</button><button type="button" class="jhs-btn jhs-btn--danger jhs-source-delete">删除</button>'),r.append(n),r.on("change",".jhs-source-toggle",async l=>{let c=!l.currentTarget.checked;s.enabled=l.currentTarget.checked;try{i==="screenshot"?await this.resourceSettings.updateArray("screenshotProviders",h=>{let u=h.find((p=>p.id===s.id));return u?u.enabled=s.enabled:h.push({id:s.id,enabled:s.enabled}),h}):a?await this.resourceSettings.updateArray("customMagnetSources",h=>{let u=h.find((p=>p.id===s.id));return u&&(u.enabled=s.enabled),h}):await this.resourceSettings.updateArray("magnetBuiltInSources",h=>{let u=h.find((p=>p.id===s.id));return u?u.enabled=s.enabled:h.push({id:s.id,enabled:s.enabled}),h}),this.renderResourceSettings(e)}catch{s.enabled=c,$(l.currentTarget).prop("checked",c),show.error("来源设置保存失败,已恢复原设置")}}),r.on("click",".jhs-source-test",l=>this.testSource(l.currentTarget,s.baseUrl||s.searchUrlTemplate?.replace("{keyword}","test"),{custom:a,source:s})),a&&r.on("click",".jhs-source-edit",(()=>this.openSourceDialog(s,e))).on("click",".jhs-source-delete",(l=>utils.q(l,`确认删除来源「${C(s.name)}」?`,(async()=>{try{await this.resourceSettings.updateArray("customMagnetSources",c=>c.filter((h=>h.id!==s.id))),this.resourceState.custom=await this.resourceSettings.getMagnetSources(),this.renderResourceSettings(e)}catch(c){show.error(c.message)}})))),r},"card");e.find("#builtin-magnet-source-list").empty().append(this.resourceState.builtIn.map((s=>t(s,!1,"magnet")))),e.find("#custom-magnet-source-list").empty().append(this.resourceState.custom.length?this.resourceState.custom.map((s=>t(s,!0,"magnet"))):'<p class="jhs-setting-help">暂无自定义来源</p>'),e.find("#screenshot-source-list").empty().append(this.resourceState.screenshot.providers.map((s=>t(s,!1,"screenshot")))),this.resourceState.screenshot.providers.forEach(((s,a)=>{s.implemented===!1&&e.find("#screenshot-source-list .jhs-resource-card").eq(a).find(".jhs-source-toggle").prop("disabled",!0).end().find("strong").after('<span class="jhs-badge">未实现</span>').end().find(".jhs-source-test").remove()})),e.find(`input[name="screenshotMode"][value="${this.resourceState.screenshot.mode}"]`).prop("checked",!0),this.renderRules("tag",e),this.renderRules("filter",e)}renderRules(e,t=$(document)){let s=e==="tag"?this.resourceState.tags:this.resourceState.filters,a=t.find("#magnet-"+e+"-rule-list").empty();s.length||a.append('<p class="jhs-setting-help">暂无规则</p>'),s.forEach((i=>{let r=$('<article class="jhs-card"></article>').append($("<strong></strong>").text(i.name),$("<p></p>").text(`${i.type==="regex"?"正则":"包含"}:${i.pattern}${e==="tag"?` · 权重 ${Number(i.weight)>=0?"+":""}${i.weight||0}`:` · ${i.action==="hide"?"隐藏":`降权 ${i.penalty||-20}`}`}`),'<div class="jhs-toolbar"><button class="jhs-btn jhs-rule-edit">编辑</button><button class="jhs-btn jhs-btn--danger jhs-rule-delete">删除</button></div>');r.on("click",".jhs-rule-edit",(()=>this.openRuleDialog(e,i,t))).on("click",".jhs-rule-delete",(n=>utils.q(n,`确认删除规则「${C(i.name)}」?`,(async()=>{try{await this.resourceSettings.updateArray(e==="tag"?"magnetTagRules":"magnetFilterRules",l=>l.filter((c=>c.id!==i.id))),this.resourceState[e==="tag"?"tags":"filters"]=await this.resourceSettings.getArray(e==="tag"?"magnetTagRules":"magnetFilterRules"),this.renderRules(e,t)}catch(l){show.error(l.message)}})))),a.append(r)}))}openSourceDialog(e=null,t=null){let s=this.getRuntimeService("dialog"),a=["rowSelector","titleSelector","magnetSelector","sizeSelector","dateSelector","seedersSelector","leechersSelector","resultsPath","titlePath","magnetPath","hashPath","sizePath","datePath","seedersPath"],i=$('<div class="jhs-setting-section jhs-resource-form"><label>名称<input name="name" class="jhs-field"></label><label>启用<input name="enabled" type="checkbox" class="mini-switch"></label><label>优先级<input name="priority" type="number" class="jhs-field" min="1"></label><label>搜索地址模板<input name="searchUrlTemplate" class="jhs-field"></label><label>原网页地址模板<input name="targetUrlTemplate" class="jhs-field"></label><label>解析类型<select name="parserType" class="jhs-select-source"><option value="magnet-links">自动寻找磁力链接</option><option value="torrent-table">表格/列表页面</option><option value="json">JSON API</option></select></label><div class="jhs-parser-fields"></div></div>'),r=d(()=>{let n=i.find('[name="parserType"]').val(),l=n==="torrent-table"?a.slice(0,7):n==="json"?a.slice(7):[];i.find(".jhs-parser-fields").html(l.map((c=>`<label>${c}<input name="${c}" class="jhs-field"></label>`)).join("")),l.forEach((c=>i.find(`[name="${c}"]`).val(e?.[c]||"")))},"renderFields");Object.entries(e||{enabled:!0,priority:100,parserType:"magnet-links"}).forEach(([n,l])=>{let c=i.find(`[name="${n}"]`);c.attr("type")==="checkbox"?c.prop("checked",l):c.val(l)}),i.on("change",'[name="parserType"]',r),r(),i.appendTo("body").hide(),s.open({type:1,title:e?"编辑自定义磁力源":"添加自定义磁力源",content:i,ui:{size:"md",body:"scroll"},area:utils.getDialogArea("md"),btn:["保存","取消"],success:d(()=>i.show(),"success"),end:d(()=>i.remove(),"end"),yes:d(async n=>{let l=Object.fromEntries(i.find("input,select").map(((c,h)=>[h.name,h.type==="checkbox"?h.checked:h.value])).get());try{let c=$l(l,e);await this.resourceSettings.updateArray("customMagnetSources",h=>{let u=e?h.findIndex((p=>p.id===e.id)):-1;return u>=0?h.splice(u,1,c):h.push(c),h}),this.resourceState.custom=await this.resourceSettings.getMagnetSources(),s.close(n),t&&this.renderResourceSettings(t)}catch(c){show.error(c.message)}},"yes")})}openRuleDialog(e,t=null,s=null){let a=this.getRuntimeService("dialog"),i=e==="tag",r=$(`<div class="jhs-setting-section"><label>名称<input name="name" class="jhs-field"></label>${i?"":'<label>匹配范围<select name="target" class="jhs-select-source"><option value="title">标题</option><option value="file">文件名</option></select></label>'}<label>匹配方式<select name="type" class="jhs-select-source"><option value="contains">包含</option><option value="regex">正则</option></select></label><label>匹配内容<input name="pattern" class="jhs-field"></label>${i?'<label>权重<input name="weight" type="number" class="jhs-field"></label>':'<label>动作<select name="action" class="jhs-select-source"><option value="hide">隐藏</option><option value="penalty">降权</option></select></label><label>降权分数<input name="penalty" type="number" class="jhs-field"></label>'}<label>启用<input name="enabled" type="checkbox" class="mini-switch"></label></div>`);Object.entries(t||{enabled:!0,type:"contains",weight:0,action:"hide",penalty:-20}).forEach(([n,l])=>{let c=r.find(`[name="${n}"]`);c.attr("type")==="checkbox"?c.prop("checked",l):c.val(l)}),r.appendTo("body").hide(),a.open({type:1,title:`${t?"编辑":"新建"}${i?"标签":"过滤"}规则`,content:r,ui:{size:"sm",body:"scroll"},area:utils.getDialogArea("sm"),btn:["保存","取消"],success:d(()=>r.show(),"success"),end:d(()=>r.remove(),"end"),yes:d(async n=>{let l=Object.fromEntries(r.find("input,select").map(((c,h)=>[h.name,h.type==="checkbox"?h.checked:h.value])).get());l.id=t?.id||`rule-${Date.now()}`,l.weight=Number(l.weight),l.penalty=Number(l.penalty);try{It(l),await this.resourceSettings.updateArray(i?"magnetTagRules":"magnetFilterRules",c=>{let h=t?c.findIndex((u=>u.id===t.id)):-1;return h>=0?c.splice(h,1,l):c.push(l),c}),this.resourceState[i?"tags":"filters"]=await this.resourceSettings.getArray(i?"magnetTagRules":"magnetFilterRules"),a.close(n),s&&this.renderRules(e,s)}catch(c){show.error(c.message)}},"yes")})}async saveCloudSettings(e=$(document)){await this.resourceSettings.saveCloudSettings({enable123Offline:e.find("#enable123Offline").is(":checked"),enable115Offline:e.find("#enable115Offline").is(":checked"),providerMode:e.find("#offlineProviderMode").val(),enable115Match:e.find("#enable115Match").is(":checked"),enable115LoginRedirect:e.find("#enable115LoginRedirect").is(":checked"),concurrency:Number(e.find("#oneOneFiveConcurrency").val()),cacheMinutes:Number(e.find("#oneOneFiveCacheMinutes").val())})}async checkOneOneFiveLogin(e=$(document)){let t=e.find("#one-one-five-state").text("检测中");try{let s=await this.getRuntimeService("scope")(),a=await this.getRuntimeService("offline").checkAccount("one115",{scope:s});t.text(a.authenticated?"已登录":"未登录")}catch{t.text("检测失败")}}async testSource(e,t,s={}){if(!t)return show.info("本站来源无需跨站测试");let a=$(e).prop("disabled",!0),i=a.siblings(".jhs-source-test-state").length?a.siblings(".jhs-source-test-state"):$('<span class="jhs-badge jhs-source-test-state"></span>').insertAfter(a);i.text("检测中");try{let r=new URL(t),n=await this.getRuntimeService("scope")(),l=await this.getRuntimeService("http").request({providerId:`settings-source-${s.source?.id||"unknown"}`,method:"GET",url:r.href,responseType:"text",cacheScope:"none",urlPolicy:s.custom?{trustClass:"custom-public"}:{trustClass:"builtin-public",hosts:[s.source?.domain||r.hostname]}},n);i.text(l.data?"200 · 可解析":"空响应")}catch(r){i.text(r?.code==="NOT_FOUND"?"404":r?.code==="RATE_LIMITED"?"限流":r?.code==="AUTH_REQUIRED"?"需要授权":"请求失败")}finally{a.prop("disabled",!1).text("测试")}}previewCarNumbers(e=$(document)){let t=jl(e.find("#car-number-import").val()),s=e.find("#car-number-import-status").val();this.pendingCarImport=s&&t.values.length?{...t,actionType:s}:null,e.find("#car-number-import-preview").text(`识别 ${t.recognized} 条 · 有效 ${t.values.length} · 重复 ${Math.max(0,t.recognized-t.values.length-t.invalid.length)} · 无效 ${t.invalid.length}${t.invalid.length?` · 异常示例:${t.invalid.slice(0,5).join("、")}`:""}`),e.find("#confirm-car-number-import").prop("disabled",!this.pendingCarImport).text(this.pendingCarImport?`确认导入 ${t.values.length} 条`:"确认导入"),s||show.info("请选择导入状态")}async confirmCarNumbers(e,t=$(document)){if(!this.pendingCarImport)return show.info("请先解析预览");let s=this.pendingCarImport;utils.q(e,`确认导入 ${s.values.length} 条记录?`,(async()=>{let a=new Map((await storageManager.getCarList()).map((h=>[T(h.carNum),h]))),i={added:0,updated:0,failed:0},r=ke(s.actionType),n=this.getRuntimeService("state"),l=s.values.map(h=>{let u=T(h),p=a.get(u);return u?{carNum:u,url:p?.url||Sl(u),names:p?.names||"",publishTime:p?.publishTime||""}:null}).filter(Boolean),c=75;for(let h=0;h<l.length;h+=c){let u=l.slice(h,h+c);try{await n.patch(u.map(p=>p.carNum),{[r]:!0},{type:"manual-car-number-import",records:u}),u.forEach(p=>a.has(p.carNum)?i.updated++:i.added++)}catch(p){i.failed+=u.length,clog.warn("番号批量导入块失败",p)}}this.pendingCarImport=null,t.find("#confirm-car-number-import").prop("disabled",!0),show.ok(`导入完成:新增 ${i.added},更新 ${i.updated},失败 ${i.failed}`)}))}};d(kr,"SettingPlugin");var zs=kr;async function Ve(o,e,t){let s=new URL(e,window.location.href),a=await o.request({providerId:"host-page",method:"GET",url:s.href,responseType:"text",cacheScope:"none",urlPolicy:{trustClass:"builtin-public",hosts:[window.location.hostname],expectedOrigin:window.location.origin}},t);return String(a.data??a.responseText??"")}d(Ve,"requestHostPage");function ic(o){let e=globalThis.$,t=o?.jquery?o:e(o),s=[];return t.find('.tags a[href^="/actors/"]').each((a,i)=>{let r=e(i).text().trim();r&&s.push(r)}),t.find('span[onmouseover*="star_"] a').each((a,i)=>{let r=e(i).text().trim();r&&s.push(r)}),[...new Set(s)].join(" ")}d(ic,"readCardNames");function Ce(o){let e=globalThis.$,t=o?.jquery?o:e(o),s=t.find("a"),a=t.attr("data-jhs-original-url")||s.attr("href"),i=t.find(".video-title"),r,n,l;if(i.length){let h=i.find("strong");h.length&&(r=h.text().trim()),n=s.attr("title")?s.attr("title").trim():r?i.text().replace(r,"").trim():i.text().trim(),l=t.find(".meta").text().trim()}if(!r){let h=t.find("img");h.length&&(n=h.attr("title")?.trim()||h.attr("data-title")?.trim()||n);let u=t.find("date").map((p,g)=>e(g).text().trim()).get();l=u.find(p=>/^\d{4}-\d{1,2}-\d{1,2}$/.test(p)),r=u.find(p=>!/^\d{4}-\d{1,2}-\d{1,2}$/.test(p))}let c=ee(r);if(!c)throw new TypeError("提取番号信息失败");return Object.freeze({carNum:c,aHref:a,url:a,title:n,publishTime:l,fc2Source:["fc2","123av"].includes(t.attr("data-jhs-fc2-source"))?t.attr("data-jhs-fc2-source"):"fc2"})}d(Ce,"readListItem");function Cr(o,e,t){for(let s of o)if(e.includes(s)||t.startsWith(s))return s;return null}d(Cr,"findMatchedTitleKeyword");function is(o={}){return{titleKeywords:Array.isArray(o.titleKeywords)?o.titleKeywords:[],carMap:o.carMap instanceof Map?o.carMap:new Map,actorCarNumToNameMap:o.actorCarNumToNameMap instanceof Map?o.actorCarNumToNameMap:new Map,actressCarNumToNameMap:o.actressCarNumToNameMap instanceof Map?o.actressCarNumToNameMap:new Map,recentCarNums:o.recentCarNums instanceof Set?o.recentCarNums:new Set,settings:o.settings??{}}}d(is,"createListEvaluationContext");function rs(o,e,{filter:t="waitCheck"}={}){let s=o?.carNum,a=s?e.carMap.get(s):null,i=q(a?.stateFlags),n={keyword:!!(e.titleKeywords.length&&s?Cr(e.titleKeywords,o.title||"",s):null),actorBlacklist:s?e.actorCarNumToNameMap.has(s):!1,actressBlacklist:s?e.actressCarNumToNameMap.has(s):!1},l=s?e.recentCarNums.has(s):!1,c=ft(i,n);return{flags:i,visibilityReasons:n,recent:l,hardHidden:c,matchesCurrentFilter:rr(t,i,{visibilityReasons:n,recent:l})}}d(rs,"evaluateListItem");function rc(o){return o.replace(/\/+$/,"")}d(rc,"stripTrailingSlashes");function nc(o,e){try{let t=new URL(o),s=new URL(e);return t.origin===s.origin&&rc(t.pathname)===rc(s.pathname)&&t.search===s.search}catch{return o===e}}d(nc,"isSamePageUrl");async function Us({startDom:o,itemSelector:e,nextPageSelector:t,fetchHtml:s,parseItem:a,evaluate:i,isCancelled:r=d(()=>!1,"isCancelled"),onProgress:n=d(()=>{},"onProgress"),pageDelayMs:l=500,maxPages:c=200,currentUrl:h=null,firstPageUrl:u=null}){let p=[],g=new Set,m=o,f=1,v=0;if(u&&h&&!nc(u,h)){if(r())return p;let b=await s(u);if(r())return p;let w=new DOMParser().parseFromString(b,"text/html");m=$(w)}for(;m&&m.length&&!r();){n({page:f,scanned:v,matched:p.length});let b=m.find(e).toArray();for(let k of b){if(r())break;let x=null;try{x=a($(k))}catch{continue}if(!x?.carNum)continue;v++;let _=i(x);_?.matchesCurrentFilter&&!g.has(x.carNum)&&(g.add(x.carNum),p.push({...x,flags:_.flags,visibilityReasons:_.visibilityReasons,hardHidden:_.hardHidden}))}let w=m.find(t).attr("href");if(!w||r()||f>=c||(l&&await new Promise(k=>setTimeout(k,l)),r()))break;let S=await s(w),j=new DOMParser().parseFromString(S,"text/html");m=$(j),f++}return p}d(Us,"scanAllPages");var Et=null;function Fs(){if(Et)return null;let o={id:Symbol("batch-run"),cancelRequested:!1};return Et=o,o}d(Fs,"tryBeginBatchRun");function Dt(o){return Et===o}d(Dt,"isActiveBatchRun");function oc(o){return!!o?.cancelRequested||!Dt(o)}d(oc,"isBatchRunCancelled");function lc(o){Et===o&&o&&(o.cancelRequested=!0)}d(lc,"requestCancelBatchRun");function Vs(o){Et===o&&(Et=null)}d(Vs,"endBatchRun");function Hs(o,e){let t=o.find("title, body").text(),s=/Just a moment|cf-chl-|Cloudflare/i.test(t),a=o.find(e.boxSelector).length>0;return{state:s?"challenge":a?"valid":"invalid",items:a?o.find(e.requestDomItemSelector):null,isEmpty:a&&o.find(e.requestDomItemSelector).length===0}}d(Hs,"parseDetailPage");function cc(){if(!F)throw new Error("Blacklist EventBus 未初始化");return F}d(cc,"getBlacklistEventBus");var _r=class _r extends I{constructor(){super(...arguments),this.blacklistSearchDebounced=null,this.taskStatusUnsubscribe=null}getName(){return"BlacklistPlugin"}async initCss(){return`<style>
            .jhs-blacklist-layout { display:flex; flex-direction:column; height:100%; min-height:0; padding:var(--jhs-space-3) var(--jhs-space-4); overflow:hidden; }
            .jhs-blacklist-toolbar { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:var(--jhs-space-2); margin-bottom:var(--jhs-space-2); }
            .jhs-blacklist-toolbar__group { display:flex; align-items:center; flex-wrap:wrap; gap:var(--jhs-space-2); }
            .jhs-blacklist-layout #table-container { flex:1; min-height:0; }
            .jhs-table-counter-note { margin-left:var(--jhs-space-2); }
            .jhs-blacklist-task-status { margin-bottom:var(--jhs-space-2); padding:var(--jhs-space-2) var(--jhs-space-3); border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-sm); background:var(--jhs-surface-2); }
            .jhs-blacklist-task-status .jhs-task-status__name { color:var(--jhs-text); font-weight:700; }
            .jhs-blacklist-task-status .jhs-task-status__meta { display:block; margin-top:var(--jhs-space-1); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-xs); }
        </style>`}async addBlacklist(e){let t={clientX:e.clientX,clientY:e.clientY+80},s=$("#addBlacklistBtn span").text().includes("已加入"),a,i;if(Y.includes("/tags")){let p=new URL(Y);p.searchParams.delete("page");let g=$("#jhs-check-tag").text().trim();a={starId:"no-"+g,name:"虚拟演员-"+g,allName:["虚拟演员"],role:"虚拟演员",movieType:g,blacklistUrl:p.toString()},i=`是否将分类 <span class="jhs-task-emphasis">${C(g)}</span> 加入到黑名单中?`,s&&(i=`分类 <span class="jhs-task-emphasis">${C(g)}</span> 已在黑名单中, 是否从当前页开始追加屏蔽?`)}else a=this.getActressPageInfo(),i=`是否将该演员 <span class="jhs-task-emphasis">${C(a.name)}</span> 加入到黑名单中?`,s&&(i=`演员 <span class="jhs-task-emphasis">${C(a.name)}</span> 已在黑名单中, 是否从当前页开始追加屏蔽?`);let{starId:r,name:n,allName:l,role:c,movieType:h,blacklistUrl:u}=a;if(Y.includes("page")&&!Y.includes("page=1")&&(i+="<br/> 注意: 当前页面非第一页, 屏蔽数据将从此页面开始"),B){let p=Y.split("/star/")[1].split("/");p.length>1&&parseInt(p[1])>1&&(i+="<br/> 注意: 当前页面非第一页, 屏蔽数据将从此页面开始")}utils.q(t,i,(async()=>{let p=this.getOptionalDependency("TaskPlugin");if(!p)return void show.error("后台任务功能已禁用,无法执行黑名单抓取");navigator.locks.request(p.singleTaskKey,{ifAvailable:!0},(async g=>{if(clog.debug("获取锁",g),g){this.loadObj=loading();try{await storageManager.addBlacklistItem({starId:r,name:n,allName:l,role:c,movieType:h,url:u}),await this.filterActorVideo(n,r,null,B?je:Be);let m=show.ok(`屏蔽结束,是否跳转到最后一页: ${this.lastPageLink}`,{duration:-1,close:!0,onClick:d(()=>{m.closeShow(),window.location.href=this.lastPageLink},"onClick")})}catch(m){clog.error(m);let f=show.error("发生错误, 是否填转到解析失败的那一页? (点击并跳转)",{duration:-1,close:!0,onClick:d(()=>{f.closeShow(),window.location.href=this.nextPageLink},"onClick")})}finally{this.loadObj.close()}}else show.error("当前有定时任务在后台执行中, 无法发起此操作")})).catch((g=>{clog.error("锁任务出现错误:",g)}))}))}async resetBtnTip(){let e=this.getOptionalDependency("TaskPlugin"),t=e?this.getRuntimeService("storage").getLocal(e.lastCheckBlacklistTimeKey)||"无":"任务已禁用",s=await storageManager.getSetting("checkBlacklist_intervalTime",12);this.checkBlacklist_ruleTime=await storageManager.getSetting("checkBlacklist_ruleTime",8760),(this.blacklistRoot||$()).find("#checkBlacklistBtn").attr("data-tip",`上次整批检测: ${t}; 检测间隔时间: ${s}小时`)}async openBlacklistDialog(){let e=this.getOptionalDependency("TaskPlugin"),t=await storageManager.getSetting(),a=`
            <div class="jhs-layout-7cb3f981">
                 <div class="jhs-layout-da5a4919">
                    <div class="jhs-layout-31a824a2">
                        <button type="button" id="checkBlacklistBtn" class="jhs-btn jhs-btn--secondary" data-tip="上次整批检测: ${e?this.getRuntimeService("storage").getLocal(e.lastCheckBlacklistTimeKey)||"无":"任务已禁用"}; 检测间隔时间: ${t.checkBlacklist_intervalTime}小时">${this.blacklistSvg}<span>手动检测黑名单</span></button>
                        <button type="button" class="jhs-btn jhs-btn--ghost" id="toSetting">${this.settingSvg}<span>配置</span></button>
                    </div>
                    <div class="jhs-layout-31a824a2">
                        <select id="dataType" class="jhs-select-source">
                            <option value="" selected>所有</option>
                            <option value="actor">男演员</option>
                            <option value="actress">女演员</option>
                        </select>
                        <select id="statusType" class="jhs-select-source">
                            <option value="" selected>全部状态</option>
                            <option value="normal">继续检测</option>
                            <option value="stop">停更跳过</option>
                        </select>
                        <select id="urlType" data-tip="在演员页屏蔽时,是否选择了分类" class="jhs-select-source${N?"":" jhs-is-hidden"}">
                            <option value="" selected>--屏蔽类型--</option>
                            <option value="hasT">按所选分类屏蔽</option>
                            <option value="noT">未筛选分类</option>
                        </select>
                        <input id="searchValue" type="search" placeholder="搜索名称、别名或 ID" class="jhs-field">
                        <button type="button" id="cleanQueryBtn" class="jhs-btn jhs-btn--secondary jhs-layout-21a4fe43">重置</button>
                    </div>

                </div>
                <div id="table-container" class="jhs-layout-d44e70c7"></div>
            </div>
        `;this.getRuntimeService("dialog").open({type:1,title:"演员黑名单",ui:{body:"table"},content:a,scrollbar:!1,area:utils.getDialogArea("xl"),anim:-1,success:d(async i=>{let r=$(i).find(".layui-layer-content > div").first().addClass("jhs-blacklist-layout").removeAttr("style");this.blacklistRoot=r;let n=r.children("div").first().addClass("jhs-blacklist-toolbar").removeAttr("style");n.children("div").addClass("jhs-blacklist-toolbar__group").removeAttr("style"),n.find("select,input,a").removeAttr("style"),r.find("#table-container").removeAttr("style"),r.find("#table-container").before('<div id="blacklist-task-status" class="jhs-task-status jhs-blacklist-task-status" aria-live="polite"></div>'),K.enhance(i),e||r.find("#checkBlacklistBtn").prop("disabled",!0).attr("title","后台任务功能已禁用"),this.renderTaskStatus(),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=cc().on("task-status-changed",(()=>this.renderTaskStatus())),await this.loadTableData();let l=$(i).find(".layui-layer-content"),c=l.find("#searchValue");this.blacklistSearchDebounced=utils.debounce((()=>{this.reloadTable()}),200),l.on("click","#cleanQueryBtn",(async()=>{c.val(""),K.setValue(this.blacklistRoot.find("#dataType"),"",!1),K.setValue(this.blacklistRoot.find("#statusType"),"",!1),K.setValue(this.blacklistRoot.find("#urlType"),"",!1),await this.reloadTable()})).on("input","#searchValue",this.blacklistSearchDebounced).on("change","#dataType,#statusType,#urlType",(async()=>{await this.reloadTable()})).on("click","#toSetting",(()=>{this.getOptionalDependency("SettingPlugin")?.openSettingDialog?.("task-panel",(()=>{$("#setting-blacklist").css({border:"1px solid var(--jhs-status-filter)"})}))})).on("click",".open-url",(h=>{h.preventDefault();let u=$(h.currentTarget),p=u.attr("data-url"),g=u.attr("data-name");utils.openPage(p,g,!0,h)})).on("click","#checkBlacklistBtn",(h=>{let u=$(h.currentTarget),p=u.find("span").last(),g=p.text();!e||u.attr("aria-busy")==="true"||(u.attr("aria-busy","true").prop("disabled",!0),p.text("检测中…"),navigator.locks.request(e.singleTaskKey,{ifAvailable:!0},(async m=>{m?await e.checkBlacklist(!0):show.error("后台任务正在运行,请稍后再试")})).catch((m=>{clog.error("锁任务出现错误:",m),e.isNetworkBlocked(m)&&show.error(m.message||"任务执行失败")})).finally((()=>{u.removeAttr("aria-busy").prop("disabled",!1),p.text(g)})))}))},"success"),end:d(async()=>{this.blacklistRoot=null,this.blacklistSearchDebounced?.cancel?.(),this.blacklistSearchDebounced=null,this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=null,this.tableObj&&(this.tableObj.destroy(),this.tableObj=null),await cc().emit("blacklist-rules-changed")},"end")})}renderTaskStatus(){let e=(this.blacklistRoot||$()).find("#blacklist-task-status");if(!e.length)return;let t=this.getOptionalDependency("TaskPlugin");if(!t)return void e.empty().text("后台任务功能已禁用");let s=t.getTaskStatusSnapshot("blacklist"),a={idle:"正常",running:"运行中",pending:"等待下一次任务检查",due:"待运行"},i=d(n=>n?new Date(n).toLocaleString():"无","format"),r=s.state;e.empty().append($('<span class="jhs-task-status__name"></span>').text(`黑名单:${a[r]||a.idle}`),$('<span class="jhs-task-status__meta"></span>').text(`上次完成 ${i(s.completedAt)};下次检查 ${s.nextAt?i(s.nextAt):"立即"}`))}async reloadTable(){if(!this.tableObj)return;let e=await this.getTableData();this.tableObj.setData(e)}async getTableData(){let e=this.blacklistRoot||$(),t=await storageManager.getBlacklist(),s=await storageManager.getBlacklistCarList(),a=String(e.find("#searchValue").val()||"").trim().toLocaleLowerCase(),i=e.find("#statusType").val(),r=e.find("#dataType"),n=r.val(),l=e.find("#urlType").val(),c=t.length,h=0,u=0,p=t.map(f=>{f.role===Me?h++:f.role===st&&u++;let v=!1;return v=pt(f.lastPublishTime,this.checkBlacklist_ruleTime),{...f,isUnCheck:v}}).filter(f=>{let v=Array.isArray(f.allName)?f.allName.join(" "):f.allName||"",b=`${f.name||""} ${v} ${f.starId||""}`.toLocaleLowerCase(),w=!a||b.includes(a),S=!i||i==="normal"&&!f.isUnCheck||i==="stop"&&f.isUnCheck,j=!n||f.role===n,k=f.url.includes("t=");return w&&S&&j&&(!l||l==="hasT"&&k||l==="noT"&&!k)});r.html(`
            <option value="">所有 (${c})</option>
            <option value="actor">男演员 (${h})</option>
            <option value="actress">女演员 (${u})</option>
        `),K.setValue(r,n,!1);let g=new Map;for(let f of s){let v=f.starId;g.has(v)||g.set(v,[]),g.get(v).push(f)}let m=p.map(f=>{let v=f.starId,b=g.get(v)||[];return{...f,carList:b,count:b.length}});return this.currentCarCount=m.reduce(((f,v)=>f+(v.count||0)),0),m}async loadTableData(){this.checkBlacklist_ruleTime=ae(await storageManager.getSetting("checkBlacklist_ruleTime"),8760,{min:0});let e=await this.getTableData(),t=document.createElement("div");Oe(t,{type:"empty",title:"没有符合当前筛选条件的黑名单记录"});let s=(this.blacklistRoot||$()).find("#table-container").get(0);this.tableObj=ze(globalThis.Tabulator,s,{layout:"fitColumns",placeholder:t,virtualDom:!0,data:e,pagination:!0,paginationMode:"local",paginationSize:20,paginationSizeSelector:[20,50,100,1e3],paginationCounter:d((a,i,r,n,l)=>`演员: ${n} &nbsp;&nbsp;&nbsp;番号总数: ${this.currentCarCount}  <span id="checkBlacklistMsg" class="jhs-table-counter-note"></span>`,"paginationCounter"),responsiveLayout:"collapse",responsiveLayoutCollapse:!0,columnDefaults:{headerHozAlign:"center",hozAlign:"center"},index:"starId",columns:[{title:"演员",field:"name",sorter:"string",minWidth:100,responsive:0,headerSort:!1,formatter:d((a,i,r)=>{let n=a.getData(),l=gt(n.url),c=document.createElement("a");return c.className="open-url",c.textContent=String(n.name||""),c.dataset.name=String(n.name||""),l?(c.href=l,c.dataset.url=l,c.target="_blank",c.rel="noopener noreferrer"):(c.href="#",c.setAttribute("aria-disabled","true")),c},"formatter")},{title:"性别角色",field:"role",sorter:"string",width:120,responsive:5,formatter:d((a,i,r)=>{let n=a.getData().role,l=n;return n===Me?l="男演员":n===st&&(l="女演员"),l},"formatter")},{title:"影视类别",field:"movieType",sorter:"string",width:120,responsive:5,formatter:d((a,i,r)=>{let n=a.getData().movieType,l=n;return n===Je?l="有码":n===Ke&&(l="无码"),l},"formatter")},{title:"屏蔽类型",field:"url",sorter:"string",minWidth:120,responsive:4,visible:N,formatter:d((a,i,r)=>{let n=a.getData().url.includes("t=");return`<span class="jhs-badge ${n?"jhs-badge--filter":"jhs-badge--neutral"}">${n?"按所选分类屏蔽":"未筛选分类"}</span>`},"formatter")},{title:"番号数量",field:"count",sorter:"number",width:170,responsive:1},{title:"创建时间",field:"createTime",sorter:"string",width:170,responsive:5},{title:"最后发行时间",field:"lastPublishTime",sorter:"string",width:170,responsive:1},{title:"状态",field:"isUnCheck",sorter:"string",width:120,responsive:1,formatter:d((a,i,r)=>{let n="",l="继续检测";return a.getData().isUnCheck&&(n=`停更${this.checkBlacklist_ruleTime/24/365}年以上, 下轮任务不再进行检测`,l="停更跳过"),`<span class="jhs-badge ${n?"jhs-badge--filter":"jhs-badge--neutral"}" data-tip="${n}">${l}</span>`},"formatter")},{title:"操作",sorter:"string",cssClass:"action-cell-dropdown",minWidth:150,responsive:0,headerSort:!1,formatter:d((a,i,r)=>{let n=a.getData();return r((()=>{var l,c;(l=a.getElement().querySelector(".delete-btn"))==null||l.addEventListener("click",(h=>{let u=n.name,p=n.starId;u?p?utils.q(h,`是否移除对 ${C(u)} 的屏蔽?`,(async()=>{await storageManager.removeBlacklistCarList(p),await storageManager.deleteBlacklistItem(p),show.info("操作成功"),await this.reloadTable()})):show.error("获取starId失败"):show.error("获取名称失败")})),(c=a.getElement().querySelector(".keyword-btn"))==null||c.addEventListener("click",(h=>{let u=n.carList.reduce(((g,m)=>{let f=m.carNum.split("-")[0]+"-";return g[f]=(g[f]||0)+1,g}),{}),p=Object.entries(u).map((([g,m])=>({prefix:g,count:m}))).sort(((g,m)=>m.count-g.count));clog.debug(p)}))})),'<button type="button" class="jhs-btn jhs-btn--danger delete-btn"><span>删除</span></button>'},"formatter")}],initialSort:[{column:"createTime",dir:"desc"}]})}async filterAllVideo(e,{filter:t=this.getOptionalDependency("ListPagePlugin")?.activeQuickFilter||"waitCheck",confirm:s=!0,root:a=null}={}){let i=Te(t),r=Re[i],n=i==="all"?"将处理当前搜索全部分页的所有作品(包括屏蔽项)并加入黑名单。":`将处理当前搜索全部分页中符合「${r}」筛选的作品并加入黑名单。`;if(s&&!await new Promise(u=>utils.q(null,n,()=>u(!0),()=>u(!1))))return{cancelled:!0};let l=Fs();if(!l)return show.error("已有批量任务正在执行"),{cancelled:!0,busy:!0};let c=d(()=>(this.blacklistRoot||$()).find("#checkBlacklistMsg"),"statusHost");try{$("#favoriteAllVideo, #hasDownAllVideo, #filterAllVideo").attr("aria-disabled","true").addClass("jhs-batch-busy");let h=await this.getRuntimeService("scope")(),u=this.getOptionalDependency("ListPagePlugin"),p=typeof u?.createEvaluationContext=="function"?await u.createEvaluationContext():is({}),g=d(()=>!Dt(l)||!!h?.disposed,"isCancelled"),m=await Us({startDom:a?$(a):$(document),currentUrl:a?null:window.location.href,firstPageUrl:a?null:this.getRuntimeService("host")?.resolveFirstPageUrl?.(window.location.href)??window.location.href,itemSelector:this.getSelector().requestDomItemSelector,nextPageSelector:this.getSelector().nextPageSelector,fetchHtml:d(async b=>Ve(this.getRuntimeService("http"),b,h),"fetchHtml"),parseItem:d(b=>Ce(b),"parseItem"),evaluate:d(b=>rs({carNum:b.carNum,title:b.title||""},p,{filter:i}),"evaluate"),isCancelled:g,onProgress:d(({page:b,scanned:w,matched:S})=>{let j=c();j.length&&j.text(`正在扫描第 ${b} 页 · 已扫描 ${w} · 匹配 ${S} 个番号`)},"onProgress")});if(g())return{cancelled:!0};let f=0;for(let b=0;b<m.length;b+=75){let w=m.slice(b,b+75);await this.getRuntimeService("state").patch(w.map(S=>S.carNum),{blocked:!0},{type:"actor-page-block",records:w.map(S=>({carNum:S.carNum,url:S.url||"",names:e,publishTime:S.publishTime||"",fc2Source:S.fc2Source}))}),f+=w.length,clog.log("一键屏蔽进度",`已屏蔽 ${f}/${m.length} 个番号`)}let v=c();return v.length&&v.text(`处理完成 · 共屏蔽 ${f} 个番号`),{matched:m.length,updated:f}}finally{Dt(l)&&Vs(l),$("#favoriteAllVideo, #hasDownAllVideo, #filterAllVideo").removeAttr("aria-disabled").removeClass("jhs-batch-busy")}}async filterActorVideo(e,t,s,a=B?je:Be,i=1,r=0,n=new Set){let{nextPageLink:l,recordCount:c}=await this.parseAndSaveFilterInfo(s,e,t,a);if(r+=c,(this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`正在处理第 ${i} 页 · 已屏蔽 ${r} 个番号`),this.nextPageLink=l,l&&i<200&&!n.has(l)){n.add(l);let h;this.lastPageLink=l,clog.log("正在请求下一页内容:",l);let u=await this.getRuntimeService("scope")(),p=await Ve(this.getRuntimeService("http"),l,u);h=utils.htmlTo$dom(p),await this.filterActorVideo(e,t,h,a,i+1,r,n)}else i>=200?((this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`已达到页数上限(200 页),已停止 · 已屏蔽 ${r} 个番号`),clog.warn("演员视频分页扫描已达上限,已停止")):(this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`处理完成 · ${i} 页 · 新增 ${r} 个番号`)}async parseAndSaveFilterInfo(e,t,s,a){if(![Be,je].includes(a))throw new Error(`未知黑名单来源站点: ${a}`);let i=e||$(document),r=this.getSelector(a);a===je&&i.find(".avatar-box").length>0&&i.find(".avatar-box").parent().remove();let n=Hs(i,{boxSelector:a===je?`${r.boxSelector}, #waterfall`:r.boxSelector,requestDomItemSelector:e?r.requestDomItemSelector:r.itemSelector}),l=i.find(r.nextPageSelector).attr("href");if(n.state!=="valid")throw new Error(`黑名单作品页面无效: ${n.state}`);if(n.isEmpty&&l)throw new Error("黑名单作品空页面包含下一页");let c=[],h=[];for(let u of n.items){let p=$(u),{carNum:g,url:m,publishTime:f}=Ce(p);f&&h.push(f),m&&g&&c.push({carNum:g,url:m,names:t,actionType:ce,starId:s,publishTime:f})}return await storageManager.batchSaveBlacklistCarList(c),{nextPageLink:l,lastPublishTime:Kt(h),recordCount:c.length}}};d(_r,"BlacklistPlugin");var qs=_r;var $r=class $r extends I{getName(){return"FilterTitleKeywordPlugin"}async handle(){isDetailPage&&await this.bindDetailRoot(document)}async bindDetailRoot(e,{layerIndex:t=null}={}){if(await storageManager.getSetting("enableTitleSelectFilter",R)!==R)return;let s=$(e),a=N?".title strong, .current-title":B?"h3":".current-title, .origin-title, .jhs-detail-title";s.off("contextmenu.jhsTitleFilter",a).on("contextmenu.jhsTitleFilter",a,(i=>{let r=window.getSelection()?.toString()||"";if(r){i.preventDefault();let n={clientX:i.clientX,clientY:i.clientY+80};utils.q(n,`是否屏蔽标题关键词 ${C(r)}?`,(async()=>{let l=r.replace(/\r?\n+/g," ").replace(/\s{2,}/g," ").trim().slice(0,120);l&&await storageManager.saveTitleFilterKeyword(l),await F?.emit("filter-rules-changed",{scope:"title-keyword"}),utils.closePage({root:s,layerIndex:t})}))}}))}};d($r,"FilterTitleKeywordPlugin");var Ws=$r;function Js(o,{retry:e=null,tone:t="neutral",extraClass:s=""}={}){let a=globalThis.$,i=a('<div class="jhs-panel-state"></div>').text(o);return s&&i.addClass(s),t==="error"&&i.addClass("is-error"),e&&i.append(" ",a('<button type="button" class="jhs-btn jhs-btn--secondary jhs-btn--sm">重试</button>').on("click",e)),i}d(Js,"createPanelState");function dc(o="正在加载…"){return Js(o)}d(dc,"createPanelLoading");function hc(o,e=null){return Js(o,{retry:e,tone:"error"})}d(hc,"createPanelError");function Tr(o){try{let e=new URL(String(o||""));return["http:","https:"].includes(e.protocol)?e.href:null}catch{return null}}d(Tr,"normalizeUrl");function he(o,e,t=null){let s=globalThis.$,a=s(o).empty(),i=Js(e,{retry:t,tone:t?"error":"neutral",extraClass:"jhs-fc2-state"});a.append(i)}d(he,"renderFc2State");function ns(o,e,t=null){let s=globalThis.$,a=[...new Set((e||[]).map(Tr).filter(Boolean))],i=o.root.find('[data-jhs-role="gallery-grid"]').empty(),r=o.root.find('[data-jhs-role="main-preview"]').empty();o.galleryUrls=new Set(a);let n=Tr(t);if(n&&r.append(s("<img>").attr({src:n,alt:`${o.carNum} 概览`,loading:"eager"})),!a.length)return he(i,"暂无剧照");a.forEach((c,h)=>i.append(s('<button type="button" class="jhs-btn jhs-fc2-gallery-item"></button>').attr("aria-label",`查看剧照 ${h+1}`).append(s("<img>").addClass("jhs-fc2-gallery__image").attr({src:c,alt:`剧照 ${h+1}`,loading:"lazy"}))));let l=o.root.find('[data-jhs-role="screenshot"]');l.find("img").each((c,h)=>{let u=h.getAttribute("src");u&&o.galleryUrls.has(u)&&l.empty()})}d(ns,"renderFc2Gallery");function Ks(o,e){let t=globalThis.$,s=t('<div class="jhs-fc2-source-links" aria-label="影片来源"></div>'),a=e.sourceUrls({carNum:o.carNum},["fc2ppvdb","fc2content"]);return[[o.source==="123av"?"123AV 原页面":"JavDB 原页面",Tr(o.url)],...a.map(r=>[r.providerId==="fc2ppvdb"?"FC2PPVDB":"FC2 市场",r.url])].forEach(([r,n])=>n&&s.append(t("<a></a>").addClass("jhs-btn jhs-btn--ghost jhs-btn--sm").attr({href:n,target:"_blank",rel:"noopener noreferrer"}).text(r))),s}d(Ks,"createFc2SourceLinks");var Ar=class Ar extends I{constructor(){super(...arguments),this.$contentBox=null,this.$listRoot=null,this.urlParams=new URLSearchParams(window.location.search),this.currentPage=Math.max(1,parseInt(this.urlParams.get("page")||"1",10)||1),this.maxPage=null,this._queryGeneration=0,this.keyword=this.urlParams.get("keyword")||null}getName(){return"Fc2By123AvPlugin"}async resolveMovieId(e){let t=await this.getRuntimeService("scope")();return(await this.getRuntimeService("movie").resolve({carNum:e},{scope:t}))?.movieId||null}async handle(){$("#navbar-menu-hero > div > div:nth-child(1) > div > a:nth-child(4)").after('<a class="navbar-item" href="/advanced_search?type=100&released_start=2099-09">123Av-Fc2</a>'),$('.tabs li:contains("FC2")').after('<li><a href="/advanced_search?type=100&released_start=2099-09"><span>123Av-Fc2</span></a></li>'),Y.includes("/advanced_search?type=100")&&(this.hookPage(),await this.handleQuery())}hookPage(){let e=this.getRuntimeService("host"),t=e.locateListRoot?.(),s=e.getListContainer?.();if(!t||!s)throw new Error("JavDB 列表容器不可用");this.$contentBox=$(s),this.$listRoot=$(e.createOwnedListRoot(["jhs-123av-list","jhs-layout-d2c171b1"]));let a=$("h2.section-title");a.contents().first().replaceWith("123Av"),a.css("marginBottom","0"),a.append(`
            <div class="jhs-layout-f5f47b30">
                <input id="search-123av-keyword" type="text" placeholder="搜索123Av Fc2ppv内容" class="jhs-field">
                <button type="button" id="search-123av-btn" class="jhs-btn jhs-btn--primary jhs-layout-21a4fe43">搜索</button>
                <button type="button" id="clear-123av-btn" class="jhs-btn jhs-btn--secondary jhs-layout-21a4fe43">重置</button>
            </div>
        `),$("#search-123av-keyword").val(this.keyword),$("#search-123av-btn").on("click",(async()=>{let i=String($("#search-123av-keyword").val()||"").trim();i&&(this.keyword=i,utils.setHrefParam("keyword",i),this.currentPage=1,this.maxPage=null,utils.setHrefParam("page",1),await this.handleQuery())})),$("#clear-123av-btn").on("click",(async()=>{$("#search-123av-keyword").val(""),this.keyword="",utils.setHrefParam("keyword",""),this.currentPage=1,this.maxPage=null,utils.setHrefParam("page",1),$(".page-box").show(),await this.handleQuery()})),$(".empty-message").remove(),$("#foldCategoryBtn").remove(),this.$contentBox.children(".box").remove(),$("#sort-toggle-btn").remove(),this.$contentBox.append(this.$listRoot),this.$contentBox.append('<div class="page-box"></div>'),utils.setHrefParam("page",this.currentPage),$(".page-box").append(`
            <nav class="pagination">
                <button type="button" class="jhs-btn pagination-previous">上一页</button>
                <ul class="pagination-list"></ul>
                <button type="button" class="jhs-btn pagination-next">下一页</button>
            </nav>
        `),$(document).on("click",".pagination-link",(i=>{i.preventDefault(),this.currentPage=parseInt($(i.target).data("page")),utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery()})),$(".pagination-previous").on("click",(i=>{i.preventDefault(),this.currentPage>1&&(this.currentPage--,utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery())})),$(".pagination-next").on("click",(i=>{i.preventDefault(),this.currentPage<(this.maxPage??0)&&(this.currentPage++,utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery())}))}renderPagination(){let e=$(".pagination-list");e.empty();let t=this.maxPage??1,s=Math.max(1,this.currentPage-2),a=Math.min(t,this.currentPage+2);this.currentPage<=3?a=Math.min(6,t):this.currentPage>=t-2&&(s=Math.max(t-5,1)),s>1&&(e.append('<li><button type="button" class="jhs-btn pagination-link" data-page="1">1</button></li>'),s>2&&e.append('<li><span class="pagination-ellipsis">…</span></li>'));for(let i=s;i<=a;i++){let r=i===this.currentPage?" is-current":"";e.append(`<li><button type="button" class="jhs-btn pagination-link${r}" data-page="${i}">${i}</button></li>`)}a<t&&(a<t-1&&e.append('<li><span class="pagination-ellipsis">…</span></li>'),e.append(`<li><button type="button" class="jhs-btn pagination-link" data-page="${t}">${t}</button></li>`))}async handleQuery(){let e=loading(),t=++this._queryGeneration;try{$(".page-box").show();let s=await this.getRuntimeService("scope")();if(t!==this._queryGeneration)return;let a=await this.getRuntimeService("movie").catalog("av123",{page:this.currentPage,keyword:this.keyword||""},{scope:s});if(t!==this._queryGeneration)return;let i=a.items;this.maxPage=Math.max(1,Number(a.maxPage)||1),this.currentPage=Math.min(Math.max(1,this.currentPage),this.maxPage),this.renderPagination(),i.length===0&&(clog.log(i),show.error("无结果"),clog.error("123AV 获取数据失败"));let r=this.markDataListHtml(i);this.$listRoot?.html(r),await utils.smoothScrollToTop()}catch(s){clog.error(s)}finally{e.close()}}async loadDetail(e,t){let s=this.loadSummary(e,t),a=this.getImgList(e.carNum),i=this.getActressInfo(e.carNum);a.then((r=>e.isAlive()&&ns(e,r,null))).catch((r=>e.isAlive()&&he(e.root.find('[data-jhs-role="gallery-grid"]'),"剧照加载失败",(()=>{this.reloadImages(e)})))),i.then((async r=>{await s.catch((()=>null)),e.isAlive()&&this.render123AvActress(e,r)})).catch((r=>clog.error("FC2 演员信息加载失败",r))),await Promise.allSettled([s,a,i])}async loadSummary(e,t){try{let s=await this.get123AvVideoInfo(e.carNum,t);return e.isAlive()?(this.render123AvSummary(e,s),s):null}catch(s){throw e.isAlive()&&he(e.root.find('[data-jhs-role="summary-content"]'),"影片信息加载失败",(()=>{this.loadSummary(e,t)})),clog.error("123AV 详情加载失败",s),s}}render123AvSummary(e,t){let s=e.root.find('[data-jhs-role="summary-content"]').empty(),a=$('<h1 class="jhs-fc2-title"><strong class="current-title"></strong></h1>');a.find("strong").text(t.title||"无标题"),s.append(a,$('<div class="jhs-fc2-meta"></div>').append($("<span></span>").text(`番号:${e.carNum}`),$("<span></span>").text(`发行:${t.publishDate||"未知"}`)),'<div class="jhs-fc2-actors" data-jhs-role="actors"><strong>主演:</strong><span>正在加载演员…</span></div>','<div class="jhs-fc2-meta" data-jhs-role="seller"></div>',Ks(e,this.getRuntimeService("movie")),$('<span class="jhs-is-hidden" data-jhs-role="publish-time"></span>').text(t.publishDate||""))}async get123AvVideoInfo(e,t){let s=await this.getRuntimeService("scope")(),a=await this.getRuntimeService("movie").detail({carNum:e,url:t,providerId:"av123"},{scope:s});return{title:a?.title||"",publishDate:a?.releaseDate||"",moviePoster:null}}async getActressInfo(e){let t=await this.getRuntimeService("scope")();return this.getRuntimeService("movie").people("fc2ppvdb",{carNum:e},{scope:t})}async getImgList(e){let t=await this.getRuntimeService("scope")();return(await this.getRuntimeService("movie").images("fc2content",{carNum:e},{scope:t})).map((s=>s.url))}async reloadImages(e){try{let t=await this.getImgList(e.carNum);e.isAlive()&&ns(e,t,null)}catch{e.isAlive()&&he(e.root.find('[data-jhs-role="gallery-grid"]'),"剧照加载失败",(()=>{this.reloadImages(e)}))}}render123AvActress(e,t){let s=e.root.find('[data-jhs-role="actors"]').empty().append("<strong>主演:</strong>");t.actors.length?t.actors.forEach((a=>s.append($("<a></a>").addClass("jhs-fc2-actor").attr({href:a.url,target:"_blank",rel:"noopener noreferrer"}).text(a.name)))):s.append($("<span></span>").text("暂无演员信息")),e.root.find('[data-jhs-role="actress-data"]').remove(),e.root.find(".jhs-fc2-summary__body").append($('<span class="jhs-is-hidden" data-jhs-role="actress-data"></span>').text(t.actors.map((a=>a.name)).join(" "))),t.seller&&e.root.find('[data-jhs-role="seller"]').empty().append("卖家:",t.seller.url?$("<a></a>").attr({href:t.seller.url,target:"_blank",rel:"noopener noreferrer"}).text(t.seller.name):document.createTextNode(t.seller.name))}markDataListHtml(e){let t="";return e.forEach((s=>{let a=s.url,i=s.imageUrl;a&&(t+=`
                <div class="item" data-jhs-fc2-source="123av">
                    <a href="${C(a)}" class="box" title="${C(s.title)}">
                        <div class="cover ">${i?`<img loading="lazy" src="${C(i)}" alt="">`:""}</div>
                        <div class="video-title"><strong>${C(s.carNum)}</strong> ${C(s.title)}</div>
                        <div class="score"></div><div class="meta"></div><div class="jhs-toolbar"></div>
                    </a>
                </div>
            `)})),t}};d(Ar,"Fc2By123AvPlugin");var Gs=Ar;var Ph=Object.freeze({blocked:{id:"filterBtn",tone:"filter",label:Ne},favorite:{id:"favoriteBtn",tone:"fav",label:Le},downloaded:{id:"hasDownBtn",tone:"down",label:fe},watched:{id:"hasWatchBtn",tone:"watch",label:ve}});function Nt({actions:o=["blocked","favorite","downloaded","watched"],ids:e={}}={}){let t=globalThis.$,s=t('<div class="jhs-state-actions"><div class="jhs-state-actions__buttons" role="group" aria-label="影片状态"></div></div>');s.attr("data-jhs-state-count",String(o.length));for(let a of o){let i=Ph[a];if(!i)continue;let r=t('<button type="button" class="jhs-btn jhs-state-action" aria-pressed="false"><span></span></button>');r.attr("id",e[a]||i.id).addClass(`jhs-btn--${i.tone}`).find("span").text(i.label),s.children().append(r)}return s}d(Nt,"createStateActions");var pc={blocked:{selector:"#filterBtn",inactive:d(()=>Ne,"inactive"),active:d(()=>et,"active")},favorite:{selector:"#favoriteBtn",inactive:d(()=>Le,"inactive"),active:d(()=>tt,"active")},downloaded:{selector:"#hasDownBtn",inactive:d(()=>fe,"inactive"),active:d(()=>"已标记下载","active")},watched:{selector:"#hasWatchBtn",inactive:d(()=>ve,"inactive"),active:d(()=>"已标记观看","active")}};function uc(){return Object.entries(pc)}d(uc,"stateButtonEntries");var Pr=class Pr{constructor(e){this.stateService=e}bind({root:e=document,closeRoot:t=e,layerIndex:s=null,carNum:a,getRecord:i=null,activityType:r="detail-state",selectors:n={}}){let l={root:e,closeRoot:t,layerIndex:s,carNum:T(a),getRecord:i,activityType:r,selectors:n};for(let[c,h]of uc()){let u=n[c]||h.selector;$(e).find(u).off("click.jhsDetailState").on("click.jhsDetailState",(p=>{p.preventDefault(),p.stopPropagation(),this.requestToggle(l,c,p)}))}return this.render(l),l}async requestToggle(e,t,s=null){if(!e.carNum)return void show.error("番号不可用,无法更新状态");let a=await storageManager.getCar(e.carNum),i=q(a?.stateFlags);return t==="blocked"&&!i.blocked?void utils.q(s,`是否屏蔽${e.carNum}?`,(()=>this.toggle(e,t,s))):this.toggle(e,t,s)}async toggle(e,t,s=null){if(!e.carNum)return void show.error("番号不可用,无法更新状态");let a=e.selectors[t]||pc[t].selector,i=s?.currentTarget?$(s.currentTarget):$(e.root).find(a);if(!i.prop("disabled")){i.prop("disabled",!0).attr("aria-busy","true");try{let r=typeof e.getRecord=="function"?await e.getRecord():e.getRecord||{carNum:e.carNum};await this.stateService.toggle(e.carNum,t,{type:e.activityType,record:r}),await this.render(e),await utils.closePage({layerIndex:e.layerIndex,root:e.closeRoot||e.root})}catch(r){clog.error("详情状态更新失败",r),show.error("操作失败")}finally{i[0]?.isConnected&&i.prop("disabled",!1).removeAttr("aria-busy")}}}async render({root:e=document,carNum:t,selectors:s={}}){let a=await storageManager.getCar(T(t)),i=q(a?.stateFlags);for(let[r,n]of uc()){let l=$(e).find(s[r]||n.selector),c=!!i[r];l.attr("aria-pressed",String(c)).each((h,u)=>$(u).find("span").first().text(c?n.active():n.inactive()))}return i}};d(Pr,"DetailStateController");var Lt=Pr;var Ir="https://jdforrepam.com/api",gc=0,Qs="",os=new Map;async function Rr(){let o=globalThis;if(o.credentialService?.get)return o.credentialService.get("jhs_appAuthorization");let e=localStorage.getItem("jhs_appAuthorization");return e?Ze(e):""}d(Rr,"readJavDbToken");function Ih(o){return o&&typeof o=="object"?o:{}}d(Ih,"asResponseRecord");function Er(){let o=Math.floor(Date.now()/1e3);return Qs&&o-gc<=20||(gc=o,Qs=`${o}.lpw6vgqzsp.${md5(`${o}71cf27bb3c0bcdf207b64abecddc970098c7421ee7203b9cdae54478478a199e7d5a6e1a57691123c1a931c057842fb73ba3b3c83bcd69c17ccf174081e3d8aa`)}`),Qs}d(Er,"O");async function mc(o){let e=String(o||"").trim(),t=await Rr();if(!t)throw Object.assign(new Error("请先登录 JavDB 账号"),{code:"LOGIN_REQUIRED"});if(!e)throw new Error("JavDB 影片 ID 无效");let s="----jhs-javdb-want-watch",a=[["status","want_watch"],["score","0"],["content",""]].map((([i,r])=>`--${s}\r
Content-Disposition: form-data; name="${i}"\r
\r
${r}\r
`)).join("")+`--${s}--\r
`;try{let i=await gmHttp.gmRequest("POST",`${Ir}/v1/movies/${encodeURIComponent(e)}/reviews`,a,{},{"user-agent":"Dart/3.5 (dart:io)","accept-language":"zh-TW",authorization:`Bearer ${t}`,jdsignature:await Er(),"content-type":`multipart/form-data; boundary=${s}`});if(i?.success===0)throw i;return await storageManager.deleteCachedRequest(`movie-detail:${e}`),os.set(e,!0),i}catch(i){let r=Ih(i);if(r.status===401||r.action==="JWTVerificationError"||/未登录|登录|unauthorized|jwt/i.test(r.message||"")){let n=globalThis;throw n.credentialService?.remove?await n.credentialService.remove("jhs_appAuthorization"):localStorage.removeItem("jhs_appAuthorization"),Object.assign(new Error("JavDB 登录已失效,请重新登录"),{code:"LOGIN_REQUIRED"})}throw i instanceof Error?i:new Error(r.message||"加入 JavDB 想看失败")}}d(mc,"markJavDbWantWatch");async function fc(o){let e=String(o||"").trim(),t=await Rr();if(!t)return null;if(!e)throw new Error("JavDB 影片 ID 无效");if(os.has(e))return os.get(e);let s=48;for(let a=1;a<=100;a++){let i=`${Ir}/v2/users/review_movies?status=want_watch&type=0&sort_by=create&order_by=desc&page=${a}&limit=${s}`,r=await gmHttp.gmRequest("GET",i,null,{},{"user-agent":"Dart/3.5 (dart:io)","accept-language":"zh-TW",authorization:`Bearer ${t}`,jdsignature:await Er()}),n=r?.data?.movies??r?.movies;if(!Array.isArray(n))throw new Error("JavDB 想看状态响应无效");if(n.some(l=>String(l.id)===e))return os.set(e,!0),!0;if(n.length<s)return os.set(e,!1),!1}return!1}d(fc,"getJavDbWantWatchState");var vc=d(async(o="all",e="",t=1,s=40)=>{let a=`${Ir}/v1/movies/top?start_rank=1&type=${o}&type_value=${e}&ignore_watched=false&page=${t}&limit=${s}`,r={"user-agent":"Dart/3.5 (dart:io)","accept-language":"zh-TW",host:"jdforrepam.com",authorization:"Bearer "+await Rr(),jdsignature:await Er()};return await gmHttp.get(a,null,r)},"q");async function Ys(o){if(o.isActive&&o.isActive()===!1)return;let e=globalThis.$,t=o.root?e(o.root):e(document),s=t.find(".origin-title").first();if(s.length||(s=t.find(".current-title").first()),s.length||(s=t.find("h3").first()),!s.length)return;let a=s.text().trim();if(!a)throw new TypeError("获取标题失败, 无法进行翻译");let i=s.nextAll(".translated-title").first();i.length||(i=e('<div class="translated-title"></div>').insertAfter(s)),i.removeClass("is-error").text("翻译中...");try{let r=await o.translation.translate(a,{cacheAlias:o.carNum,scope:o.scope});if(o.isActive&&!o.isActive()||!s[0]?.isConnected||!i[0]?.isConnected)return;i.text(r)}catch(r){if(o.isActive&&!o.isActive()||!s[0]?.isConnected||!i[0]?.isConnected)return;let n=r instanceof Error?r.message:String(r);globalThis.clog?.error("翻译失败:",r),i.addClass("is-error").text(`翻译失败: ${n}`)}}d(Ys,"renderTranslatedTitle");function Rh(o){try{let e=new URL(String(o||""));return e.protocol==="https:"?e.href:null}catch{return null}}d(Rh,"normalizeImageUrl");function Eh(o,e,t){let s=globalThis.$,a=Rh(e);if(!a)return null;let i=s("<img>").attr({src:a,alt:t,loading:"lazy"}).addClass("jhs-fc2-gallery__image"),r=s('<button type="button" class="jhs-btn jhs-fc2-gallery-item jhs-fc2-screenshot-thumbnail"></button>').attr("aria-label",`查看${t}大图`).append(i);return o.empty().append(r).off("click.jhsScreenshot").on("click.jhsScreenshot",".jhs-fc2-screenshot-thumbnail",n=>{n.preventDefault(),n.stopPropagation(),globalThis.showImageViewer(i[0])}),a}d(Eh,"renderImage");async function Zs(o){let e=globalThis.$,t=e(o.target),s=o.isActive??(()=>!0),a=o.providerId??"javstore";if(!t.length||!o.screenshot.isEnabled(o.settings))return t.empty(),null;let{mode:i}=o.screenshot.getScreenshotSettings(o.settings),r=o.screenshot.getEnabledProviders(o.settings);if(i!=="manual"&&!r.some(u=>u.id===a))return t.empty(),null;if(!r.length)return t.empty().append(e('<div class="jhs-panel-state">没有可用截图来源</div>')),t;let n=d(async(u=t,p=a)=>{u.empty().append(dc("正在加载缩略图…"));try{let g=await o.screenshot.resolve({carNum:o.carNum},{providerId:p,scope:o.scope,settings:o.settings});if(!s())return null;let m=Array.isArray(g)?g[0]:g;return!m?.url||o.isDuplicate?.(m.url)?(u.empty(),null):Eh(u,m.url,"缩略图")}catch(g){return s()&&(u.empty().append(hc("缩略图加载失败 ",()=>{n(u,p)})),globalThis.clog?.error("缩略图加载失败",g)),null}},"load");if(i!=="manual")return n();let l=e('<div class="jhs-screenshot-providers" role="tablist" aria-label="截图来源"></div>'),c=`jhs-screenshot-result-${String(o.carNum).replace(/[^a-z0-9_-]/gi,"-")}`,h=e('<div class="jhs-screenshot-result" role="tabpanel"></div>').attr("id",c).text("请选择截图来源");return r.forEach((u,p)=>{let g=e('<button type="button" class="jhs-btn jhs-btn--secondary" role="tab" aria-selected="false"></button>').attr({"aria-controls":c,tabindex:p===0?"0":"-1"}).text(u.name);g.on("click",async()=>{l.find("[role='tab']").attr({"aria-selected":"false",tabindex:"-1"}),g.attr({"aria-selected":"true",tabindex:"0"}),await n(h,u.id)}),l.append(g)}),l.on("keydown","[role='tab']",(u=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(u.key))return;u.preventDefault();let p=l.find("[role='tab']"),g=p.index(u.currentTarget),m=u.key==="Home"?0:u.key==="End"?p.length-1:u.key==="ArrowRight"?(g+1)%p.length:(g-1+p.length)%p.length;p.eq(m).trigger("focus").trigger("click")})),t.empty().append(l,h),t}d(Zs,"renderScreenshotPanel");var Dr=class Dr{constructor(e){this.related=e.related,this.settings=e.settings,this.scope=e.scope}async show(e,t,s={}){let a=globalThis.$,i=s.isActive??(()=>!0);if(!t)throw new TypeError("未传入movieId");if(!i()||!e?.length)return a();let r=e.children('[data-jhs-panel="related"]').filter((b,w)=>a(w).attr("data-jhs-movie-id")===String(t)).first();if(r.length)return r;let n=a('<section class="jhs-related-panel" data-jhs-panel="related"></section>').attr("data-jhs-movie-id",String(t)),l=a('<header class="jhs-panel-header"><h3>相关清单</h3></header>'),c=a('<button type="button" class="jhs-btn jhs-btn--secondary jhs-panel-toggle jhs-related-toggle"><span class="toggle-text"></span><span class="toggle-icon" aria-hidden="true"></span></button>'),h=await this.scope(),u=new te(`related:${t}`);if(!i()||h?.disposed)return a();let p=h?.addCleanup?.(()=>u.dispose());s.ownCleanup?.(()=>{u.dispose(),p?.()});let g={movieId:t,panel:n,panelScope:u,floorIndex:1,loaded:!1,loading:!1,page:1,enabled:!1,generation:0,isActive:d(()=>!u.disposed&&i(),"isActive"),requestScope:null};l.append(c),s.ownedSection?s.ownedSection.find('[data-jhs-section-actions="related"]').first().append(c):n.append(l),n.append('<div class="jhs-related-list jhs-related-container"></div>','<div class="jhs-panel-footer jhs-related-footer"></div>'),e.append(n);let m=(this.settings.snapshot().enableLoadRelated??"no")==="yes",f=d(b=>{if(!g.isActive())return;let w=b==="yes";if(g.enabled!==w&&(g.enabled=w,g.generation++,w||(g.requestScope?.dispose(),g.loading=!1)),this.updateToggle(c,w),n.find(".jhs-related-container, .jhs-related-footer").toggle(w),g.loading||n.find(".jhs-related-load-more").prop("disabled",!1).text("加载更多清单"),w&&!g.loaded&&!g.loading)return this.fetch(g)},"applyExpanded");this.settings.addEventListener&&u.listen(this.settings,"settings.changed",b=>{b.detail?.names?.includes("enableLoadRelated")&&f(this.settings.snapshot().enableLoadRelated??"no")});let v=Fe({settings:this.settings,key:"enableLoadRelated",fallback:"no",apply:d(b=>{f(b)},"apply"),onError:d(b=>{globalThis.clog?.error("相关清单展开设置保存失败,已恢复",b),globalThis.show?.error?.("相关清单展开设置保存失败,已恢复原设置")},"onError")});return c.on("click",b=>{b.preventDefault(),b.stopPropagation(),v(g.enabled?"no":"yes")}),u.addCleanup(()=>{g.requestScope?.dispose(),c.off("click"),n.find("button").off("click")}),await f(m?"yes":"no"),n}updateToggle(e,t){e.attr("aria-expanded",String(t)),e.find(".toggle-text").text(t?"折叠":"展开"),e.find(".toggle-icon").text(t?"▲":"▼")}async fetch(e){if(e.loading||!e.enabled||!e.isActive())return;e.loading=!0;let t=e.panel.find(".jhs-related-container"),s=e.panel.find(".jhs-related-footer");t.empty().append(globalThis.$("<div></div>").addClass("jhs-panel-state").text("获取清单中...")),s.empty();let a=e.generation,i=new te(`related:${e.movieId}:page:1`),r=e.panelScope.addCleanup(()=>i.dispose());e.requestScope=i;try{let n=await this.related.list({movieId:e.movieId},{page:1,limit:20,scope:i});if(!e.isActive()||i.signal.aborted||a!==e.generation||!e.enabled)return;if(e.loading=!1,e.loaded=!0,t.empty(),!n.length)return void t.append(globalThis.$("<div></div>").addClass("jhs-panel-state").text("无清单"));this.display(e,n,t),n.length===20?this.bindLoadMore(e,t,s):s.append(globalThis.$("<div></div>").addClass("jhs-panel-end").text("已加载全部清单"))}catch(n){if(a===e.generation&&(e.loading=!1),!e.isActive()||i.signal.aborted||a!==e.generation||!e.enabled)return;globalThis.clog?.error("获取清单失败:",n),this.renderRetry(t,()=>{this.fetch(e)})}finally{r(),e.requestScope===i&&(e.requestScope=null)}}renderRetry(e,t){let s=globalThis.$;e.empty().append(s('<div class="jhs-panel-state"></div>').append(document.createTextNode("获取清单失败 "),s('<button type="button" class="jhs-btn jhs-btn--secondary jhs-btn--sm">重试</button>').on("click",t)))}bindLoadMore(e,t,s){let a=globalThis.$,i=a('<button type="button" class="jhs-btn jhs-btn--secondary jhs-related-load-more">加载更多清单</button>'),r=a('<div class="jhs-panel-end jhs-related-end">已加载全部清单</div>').hide();s.empty().append(i,r),i.on("click",async()=>{if(!e.enabled||!e.isActive()||e.loading)return;let n=e.page+1,l=e.generation,c=new te(`related:${e.movieId}:page:${n}`),h=e.panelScope.addCleanup(()=>c.dispose());e.loading=!0,e.requestScope=c,i.text("加载中...").prop("disabled",!0);try{let u=await this.related.list({movieId:e.movieId},{page:n,limit:20,scope:c});if(!e.isActive()||c.signal.aborted||l!==e.generation||!e.enabled)return;e.page=n,this.display(e,u,t),u.length<20?(i.remove(),r.show()):i.text("加载更多清单").prop("disabled",!1)}catch(u){if(!e.isActive()||c.signal.aborted||l!==e.generation||!e.enabled)return;globalThis.clog?.error("加载更多清单失败:",u),i.text("加载失败,请重试").prop("disabled",!1)}finally{h(),l===e.generation&&(e.loading=!1),e.requestScope===c&&(e.requestScope=null)}})}display(e,t,s){let a=globalThis.$;t.forEach(i=>{let r=a("<a></a>").addClass("jhs-related-title").attr({href:`/lists/${encodeURIComponent(i.id)}`,target:"_blank",rel:"noopener noreferrer"}).text(i.name||"未命名清单"),n=a('<div class="jhs-related-heading"></div>').append(a("<span></span>").addClass("jhs-related-index").text(`#${e.floorIndex++}`),r),l=a('<div class="jhs-related-meta"></div>'),c=i.createdAt?globalThis.utils.formatDate(i.createdAt):"未知";l.append(a("<span></span>").text(`视频:${Number(i.movieCount)||0}`),a("<span></span>").text(`收藏:${Number(i.collectionCount)||0}`),a("<span></span>").text(`查看:${Number(i.viewCount)||0}`),a('<time class="jhs-related-time"></time>').text(`创建时间:${c}`)),s.append(a('<article class="jhs-related-item"></article>').append(n,l))})}};d(Dr,"RelatedPanel");var Bt=Dr;var Nr=class Nr{constructor(e){this.review=e.review,this.settings=e.settings,this.storage=e.storage,this.scope=e.scope}async show(e,t,s={}){let a=globalThis.$,i=s.isActive??(()=>!0);if(!i()||!t?.length)return a();let r=t.children('[data-jhs-panel="reviews"]').filter((b,w)=>a(w).attr("data-jhs-movie-id")===String(e)).first();if(r.length)return r;let n=a('<section class="jhs-review-panel" data-jhs-panel="reviews"></section>').attr("data-jhs-movie-id",String(e)),l=a('<header class="jhs-panel-header"><h3>评论</h3></header>'),c=a('<button type="button" class="jhs-btn jhs-btn--secondary jhs-panel-toggle jhs-review-toggle"><span class="toggle-text"></span><span class="toggle-icon" aria-hidden="true"></span></button>'),h=await this.scope(),u=new te(`reviews:${e}`);if(!i()||h?.disposed)return a();let p=h?.addCleanup?.(()=>u.dispose());s.ownCleanup?.(()=>{u.dispose(),p?.()});let g={movieId:e,panel:n,panelScope:u,floorIndex:1,loaded:!1,loading:!1,page:1,enabled:!1,generation:0,isActive:d(()=>!u.disposed&&i(),"isActive"),requestScope:null};l.append(c),s.ownedSection?s.ownedSection.find('[data-jhs-section-actions="reviews"]').first().append(c):n.append(l),n.append('<div class="jhs-review-list jhs-review-container"></div>','<div class="jhs-panel-footer jhs-review-footer"></div>'),t.append(n),this.bindFilter(n);let m=(this.settings.snapshot().enableLoadReview??"yes")==="yes",f=d(b=>{if(!g.isActive())return;let w=b==="yes";if(g.enabled!==w&&(g.enabled=w,g.generation++,w||(g.requestScope?.dispose(),g.loading=!1)),this.updateToggle(c,w),n.find(".jhs-review-container, .jhs-review-footer").toggle(w),n.find(".jhs-review-load-more").prop("disabled",!1).text("加载更多评论"),w&&!g.loaded&&!g.loading)return this.fetch(g)},"applyExpanded");this.settings.addEventListener&&u.listen(this.settings,"settings.changed",b=>{b.detail?.names?.includes("enableLoadReview")&&f(this.settings.snapshot().enableLoadReview??"yes")});let v=Fe({settings:this.settings,key:"enableLoadReview",fallback:"yes",apply:d(b=>{f(b)},"apply"),onError:d(b=>{globalThis.clog?.error("评论面板展开设置保存失败,已恢复",b),globalThis.show?.error?.("评论面板展开设置保存失败,已恢复原设置")},"onError")});return c.on("click",b=>{b.preventDefault(),b.stopPropagation();let S=c.find(".toggle-text").text()==="展开"?"yes":"no";v(S)}),u.addCleanup(()=>{g.requestScope?.dispose(),c.off("click"),n.off("contextmenu.jhsReviewFilter")}),await f(m?"yes":"no"),n}updateToggle(e,t){e.attr("aria-expanded",String(t)),e.find(".toggle-text").text(t?"折叠":"展开"),e.find(".toggle-icon").text(t?"▲":"▼")}async fetch(e){if(e.loading||!e.enabled||!e.isActive())return;let t=globalThis.$,s=e.panel.find(".jhs-review-container"),a=e.panel.find(".jhs-review-footer");e.loading=!0,s.empty().append(t('<div class="jhs-panel-state"></div>').text("获取评论中...")),a.empty();let i=Number(this.settings.snapshot().reviewCount)||20,r=e.generation,n=new te(`reviews:${e.movieId}:page:1`),l=e.panelScope.addCleanup(()=>n.dispose());e.requestScope=n;try{let c=await this.review.list({movieId:e.movieId},{page:1,limit:i,scope:n});if(!e.isActive()||n.signal.aborted||r!==e.generation||!e.enabled)return;let h=await this.getKeywords();if(!e.isActive()||n.signal.aborted||r!==e.generation||!e.enabled)return;if(e.loading=!1,e.loaded=!0,s.empty(),!c.length)return void s.append(t('<div class="jhs-panel-state"></div>').text("无评论"));await this.display(e,c,s,h),c.length===i?this.bindLoadMore(e,i,h,s,a):a.append(t('<div class="jhs-panel-end"></div>').text("已加载全部评论"))}catch(c){if(r===e.generation&&(e.loading=!1),!e.isActive()||n?.signal?.aborted)return;globalThis.clog?.error("获取评论失败:",c),this.renderRetry(s,"获取评论失败",()=>{this.fetch(e)})}finally{l(),e.requestScope===n&&(e.requestScope=null)}}async getKeywords(){return Wt(this.storage)}async saveKeyword(e){await Wt(this.storage,e)}renderRetry(e,t,s){let a=globalThis.$;e.empty().append(a('<div class="jhs-panel-state"></div>').append(document.createTextNode(`${t} `),a('<button type="button" class="jhs-btn jhs-btn--secondary jhs-btn--sm">重试</button>').on("click",s)))}bindLoadMore(e,t,s,a,i){let r=globalThis.$,n=r('<button type="button" class="jhs-btn jhs-btn--secondary jhs-review-load-more">加载更多评论</button>'),l=r('<div class="jhs-panel-end jhs-review-end">已加载全部评论</div>').hide();i.empty().append(n,l),n.on("click",async()=>{if(!e.enabled||!e.isActive()||e.loading)return;let c=e.page+1,h=e.generation,u=new te(`reviews:${e.movieId}:page:${c}`),p=e.panelScope.addCleanup(()=>u.dispose());e.requestScope=u,e.loading=!0,n.text("加载中...").prop("disabled",!0);try{let g=await this.review.list({movieId:e.movieId},{page:c,limit:t,scope:u});if(!e.isActive()||u.signal.aborted||h!==e.generation||!e.enabled)return;e.page=c,await this.display(e,g,a,s),g.length<t?(n.remove(),l.show()):n.text("加载更多评论").prop("disabled",!1)}catch(g){if(!e.isActive()||u?.signal?.aborted)return;globalThis.clog?.error("加载更多评论失败:",g),n.text("加载失败,请重试").prop("disabled",!1)}finally{p(),h===e.generation&&(e.loading=!1),e.requestScope===u&&(e.requestScope=null)}})}async display(e,t,s,a){let i=globalThis.$,r=a.length?new RegExp(a.map(n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|")):null;for(let n of t){let l=String(n.content||"");if(r?.test(l))continue;let c=i('<article class="jhs-review-item"></article>'),h=i('<div class="jhs-review-meta"></div>'),u=i('<div class="review-content jhs-review-content"></div>');h.append(i("<span></span>").addClass("jhs-review-author").text(n.author||"匿名用户"));let p=i('<span class="score-stars" aria-label="评分"></span>'),g=Math.max(0,Math.min(5,Number(n.score)||0));for(let f=0;f<g;f++)p.append('<i class="icon-star"></i>');let m=globalThis.utils.formatDate(n.createdAt);h.append(p,i("<time></time>").text(m),i("<span></span>").text(`点赞:${Number(n.likes)||0}`),i("<span></span>").addClass("jhs-review-floor").text(`#${e.floorIndex++}楼`)),this.appendContent(u,l),c.append(h,u),s.append(c)}}appendContent(e,t){let s=/ed2k:\/\/\|file\|[^|]+\|\d+\|[a-fA-F0-9]{32}\|\/|magnet:\?[^\s"'<>`,;\u4e00-\u9fa5,。?!()【】]+|https?:\/\/[^\s"'<>`,;\u4e00-\u9fa5,。?!()【】]+/g,a=0,i;for(;i=s.exec(t);)i.index>a&&e.append(document.createTextNode(t.slice(a,i.index))),this.appendLink(e,i[0]),a=i.index+i[0].length;a<t.length&&e.append(document.createTextNode(t.slice(a)))}appendLink(e,t){let s=globalThis.$,a=t.startsWith("ed2k://"),i=t.startsWith("magnet:"),r=a?"ED2K 链接":i?"Magnet 链接":"打开链接",n=a||i,l=s(n?'<span class="jhs-review-link-wrap"></span>':'<span class="jhs-review-inline-controls"></span>'),c=s('<span class="jhs-review-link-main"></span>'),h=a?s('<button type="button" class="jhs-btn jhs-review-link"></button>').text(r).on("click",()=>globalThis.utils.copyToClipboard(r,t)):s("<a></a>").addClass("jhs-review-link").attr({href:t,target:"_blank",rel:"noopener noreferrer"}).text(r),u=s('<button type="button" class="jhs-btn jhs-review-link jhs-review-link-copy">复制</button>').on("click",()=>globalThis.utils.copyToClipboard(r,t));c.append(h,u),l.append(c),n&&l.append(s('<span class="jhs-review-link-actions"></span>').append(s('<button type="button" class="jhs-btn jhs-review-link jhs-review-offline-btn jhs-offline-btn">离线</button>').attr("data-resource",t))),e.append(l)}bindFilter(e){e.off("contextmenu.jhsReviewFilter",".review-content").on("contextmenu.jhsReviewFilter",".review-content",async t=>{if((this.settings.snapshot().enableTitleSelectFilter??"yes")!=="yes")return;let s=String(window.getSelection()?.toString()||"");s&&(t.preventDefault(),await globalThis.utils.q(t,`是否将 '${C(s)}' 加入评论区关键词?`,async()=>{await this.saveKeyword(s),globalThis.show.ok("操作成功, 刷新页面后生效")}))})}};d(Nr,"ReviewPanel");var Mt=Nr;function Dh(o,e="other"){if(!o||typeof o!="object"||Array.isArray(o))return null;let t=o,s=T(t.carNum);return s?Object.freeze({...t,carNum:s,movieId:typeof t.movieId=="string"&&t.movieId.trim()?t.movieId.trim():t.movieId??null,surface:t.surface||e}):null}d(Dh,"normalizeWorkspaceMovieContext");function bc({carNum:o="",source:e="fc2",mode:t="dialog"}={}){let s=$('<div class="jhs-fc2-workspace jhs-ui"></div>').attr({"data-jhs-fc2-source":e,"data-jhs-fc2-mode":t,"data-jhs-car-num":T(o)||""});return[["summary","影片概览"],["gallery","预览与剧照"],["resources","资源"],["reviews","评论"],["related","相关清单"]].forEach((([i,r])=>{let n=$('<section class="jhs-fc2-section"></section>').attr("data-jhs-section",i),l=$('<header class="jhs-fc2-section__header"></header>'),c=$("<h2></h2>").text(r),h=$('<div class="jhs-fc2-section__actions"></div>').attr("data-jhs-section-actions",i);n.append(l.append(c,h),$('<div class="jhs-fc2-section__content"></div>').attr("data-jhs-slot",i)),s.append(n)})),s}d(bc,"createFc2DetailShell");function wc(o,e={}){let t=$(o).is(".jhs-fc2-workspace")?$(o):$(o).find(".jhs-fc2-workspace").first(),s=!1,a=`.jhsFc2Detail${Date.now()}${Math.random().toString(36).slice(2)}`,i=new Set,r=e.mode==="dialog"?"fc2-dialog":"native-detail",n=Dh({...e,carNum:e.carNum||t.attr("data-jhs-car-num"),detailUrl:e.url,surface:r},r),l={...e,movieContext:n,root:t,workspace:t,namespace:a,observers:i,getSlot:d(c=>t.find(`[data-jhs-slot="${c}"]`).first(),"getSlot"),getSection:d(c=>t.find(`[data-jhs-section="${c}"]`).first(),"getSection"),isAlive:d(()=>!s&&t[0]?.isConnected!==!1,"isAlive"),addObserver(c){return c&&i.add(c),c},destroy(){s||(s=!0,t.off(a).find("*").off(a),i.forEach((c=>c.disconnect?.())),i.clear(),t.removeData("jhsFc2Context"))}};return t.data("jhsFc2Context",l).attr("data-jhs-surface",r),n&&t.data("jhsMovieContext",n),l}d(wc,"createFc2DetailContext");function Nh(o){return dl(o,window.location.origin)}d(Nh,"parseExplicitJavDbMovieId");var Lr=class Lr extends I{constructor(){super(...arguments),this.detailStateController=null,this.translationGeneration=0}getName(){return"Fc2Plugin"}getDetailStateController(){return this.detailStateController||(this.detailStateController=new Lt(this.getRuntimeService("state")))}async resolveMovieId(e){let t=await this.getRuntimeService("scope")();return(await this.getRuntimeService("movie").resolve({carNum:e},{scope:t}))?.movieId||null}async resolveMovieIdForRecord(e,t=""){return Nh(t)||this.resolveMovieId(e)}async initCss(){return`<style>
            .movie-detail-layer .layui-layer-content { min-height:0; overflow:hidden; background:var(--jhs-bg); }
            .movie-detail-layer .jhs-fc2-dialog-host { height:100%; min-height:0; }
            .jhs-fc2-workspace { display:grid; grid-auto-rows:max-content; align-content:start; width:min(100%,1440px); min-width:0; margin:0 auto; padding:var(--jhs-space-5); gap:var(--jhs-space-4); box-sizing:border-box; background:var(--jhs-bg); color:var(--jhs-text); }
            .jhs-fc2-workspace[data-jhs-fc2-mode="dialog"] { height:100%; min-height:0; overflow-x:hidden; overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch; }
            .jhs-fc2-section { min-width:0; overflow:hidden; border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); background:var(--jhs-surface); }
            .jhs-fc2-section__header { display:flex; min-height:var(--jhs-control-height); align-items:center; justify-content:space-between; gap:var(--jhs-space-3); padding:var(--jhs-space-3) var(--jhs-space-5); border-bottom:1px solid var(--jhs-border); background:var(--jhs-surface-2); }
            .jhs-fc2-section__header h2 { margin:0; color:var(--jhs-text); font-size:var(--jhs-font-size-lg); }
            .jhs-fc2-section__actions { display:flex; align-items:center; gap:var(--jhs-space-2); }
            .jhs-fc2-section__content { min-width:0; padding:var(--jhs-space-5); }
            .jhs-fc2-summary { display:grid; grid-template-columns:minmax(220px,34%) minmax(0,1fr); gap:var(--jhs-space-5); }
            .jhs-fc2-preview { display:grid; min-height:240px; place-items:center; overflow:hidden; border-radius:var(--jhs-radius-sm); background:var(--jhs-surface-2); }
            .jhs-fc2-preview:empty::after { color:var(--jhs-text-faint); content:"暂无预览"; }
            .jhs-fc2-preview img { display:block; width:100%; height:100%; max-height:520px; object-fit:contain; }
            .jhs-fc2-title { margin:0 0 var(--jhs-space-3); color:var(--jhs-text); font-size:clamp(20px,2.4vw,28px); line-height:1.35; }
            .jhs-fc2-meta { display:flex; flex-wrap:wrap; gap:var(--jhs-space-2) var(--jhs-space-4); margin-bottom:var(--jhs-space-3); color:var(--jhs-text-muted); }
            .jhs-fc2-actors { display:flex; flex-wrap:wrap; align-items:center; gap:var(--jhs-space-2); }
            .jhs-fc2-actor { display:inline-flex; padding:var(--jhs-space-1) var(--jhs-space-2); border-radius:var(--jhs-radius-pill); background:var(--jhs-surface-2); color:var(--jhs-text); font-size:var(--jhs-font-size-sm); }
            .jhs-fc2-toolbar { display:flex; flex-wrap:wrap; gap:var(--jhs-space-2); margin-top:var(--jhs-space-4); }
            .jhs-fc2-gallery-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(112px,144px)); justify-content:start; gap:var(--jhs-space-3); }
            .jhs-fc2-gallery-item { display:block; width:100%; min-width:0; padding:0; overflow:hidden; border:1px solid transparent; border-radius:var(--jhs-radius-sm); background:var(--jhs-surface-2); aspect-ratio:3/2; cursor:zoom-in; }
            .jhs-fc2-gallery-item:focus-visible { border-color:var(--jhs-accent); outline:2px solid var(--jhs-accent); outline-offset:2px; }
            .jhs-fc2-gallery__image { display:block; width:100%; height:100%; object-fit:cover; }
            .jhs-fc2-screenshot { margin-top:var(--jhs-space-4); overflow:hidden; border-radius:var(--jhs-radius-sm); }
            .jhs-fc2-screenshot:empty { display:none; margin:0; }
            .jhs-fc2-screenshot-thumbnail { width:112px; max-width:100%; }
            .jhs-fc2-resource-stack { display:grid; gap:var(--jhs-space-4); }
            .jhs-fc2-resource-group { min-width:0; }
            .jhs-fc2-resource-group + .jhs-fc2-resource-group { padding-top:var(--jhs-space-4); border-top:1px solid var(--jhs-border); }
            .jhs-fc2-resource-title { margin:0 0 var(--jhs-space-3); color:var(--jhs-text); font-size:var(--jhs-font-size-md); }
            .jhs-fc2-magnet-item { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:var(--jhs-space-3); padding:var(--jhs-space-3) 0; border-bottom:1px solid var(--jhs-border); }
            .jhs-fc2-magnet-item:last-child { border-bottom:0; }
            .jhs-fc2-magnet-name { min-width:0; overflow-wrap:anywhere; }
            .jhs-fc2-magnet-tags { display:flex; flex-wrap:wrap; gap:var(--jhs-space-1); margin-top:var(--jhs-space-2); }
            .jhs-fc2-source-links { display:flex; flex-wrap:wrap; gap:var(--jhs-space-2); margin-top:var(--jhs-space-3); }
            .jhs-fc2-resource-group.is-collapsed > [data-jhs-role="magnet-hub"] > [data-jhs-role="magnet-hub-content"] { display:none; }
            .jhs-fc2-state { padding:var(--jhs-space-5); color:var(--jhs-text-muted); text-align:center; }
            .jhs-fc2-state.is-error { color:var(--jhs-danger); }
            @media (max-width:767px) {
                .jhs-fc2-workspace { padding:var(--jhs-space-3); gap:var(--jhs-space-3); }
                .jhs-fc2-section__header,.jhs-fc2-section__content { padding:var(--jhs-space-3); }
                .jhs-fc2-summary { grid-template-columns:1fr; }
                .jhs-fc2-preview { min-height:200px; }
                .jhs-fc2-gallery-grid { grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--jhs-space-2); }
                .jhs-fc2-toolbar .jhs-btn,.jhs-fc2-section__actions .jhs-btn { min-height:44px; }
                .jhs-fc2-magnet-item { grid-template-columns:1fr; }
            }
            @media (max-width:420px) { .jhs-fc2-toolbar { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); } .jhs-fc2-toolbar .jhs-btn { width:100%; } }
            @media (max-width:339px) { .jhs-fc2-toolbar { grid-template-columns:1fr; } }
            @media (prefers-reduced-motion:reduce) { .jhs-fc2-workspace * { scroll-behavior:auto!important; transition-duration:0.01ms!important; } }
        </style>`}async handle(){let e="/advanced_search?type=3&score_min=0&d=1";if($('.navbar-item:contains("FC2")').attr("href",e),$('.tabs a:contains("FC2")').attr("href",e),Y.includes("advanced_search?type=3")&&($("h2.section-title").contents().first().replaceWith("Fc2PPV"),$(".section .container > .box").remove()),!Y.includes("collection_codes?movieId"))return;let t=new URLSearchParams(window.location.search),s=t.get("movieId"),a=t.get("carNum"),i=t.get("url"),r=t.get("source"),n=$("section").first().empty();if(!a||!i)return void n.append($('<div class="jhs-fc2-state is-error"></div>').text("FC2 详情参数不完整"));let l=s&&s!=="search"?s:await this.resolveMovieIdForRecord(a,i),c=["fc2","123av"].includes(r||"")?r:await this.resolveFc2Source({url:i}),h=this.mountFc2Detail(n,{movieId:l,carNum:a,url:i,source:c,mode:"page"});$(window).off("pagehide.jhsFc2Detail").one("pagehide.jhsFc2Detail",(()=>h.destroy()))}openFc2Dialog(e,t,s,{source:a=""}={}){a=["fc2","123av"].includes(a)?a:"";let i=null;return this.getRuntimeService("dialog").open({type:1,title:t,content:'<div class="jhs-fc2-dialog-host"></div>',ui:{size:"workspace",body:"scroll"},area:utils.getDialogArea("workspace"),skin:"movie-detail-layer",scrollbar:!1,shadeClose:!0,success:d((r,n)=>{i=this.mountFc2Detail($(r).find(".jhs-fc2-dialog-host"),{movieId:e,carNum:t,url:s,source:a,layerIndex:n,mode:"dialog"}),utils.setupEscClose(n)},"success"),end:d(()=>i?.destroy(),"end")})}mountFc2Detail(e,t){let s=$(e);s.data("jhsFc2Context")?.destroy?.(),s.empty();let i=bc(t).appendTo(s),r=wc(i,t);return s.data("jhsFc2Context",r),r.translationGeneration=0,r.screenshotGeneration=0,r.otherSiteGeneration=0,this.initializeWorkspace(r),this.bindFc2FeatureLifecycle(r),r}initializeWorkspace(e){let t=$('<div class="jhs-fc2-summary"><div class="jhs-fc2-preview" data-jhs-role="main-preview"></div><div class="jhs-fc2-summary__body"><div data-jhs-role="summary-content"><div class="jhs-fc2-state">正在加载影片信息…</div></div></div></div>'),s=$('<div class="jhs-fc2-toolbar" role="toolbar" aria-label="影片操作"></div>');s.append(Nt()),s.append('<button type="button" class="jhs-btn jhs-btn--secondary" data-jhs-action="javdb-want" aria-pressed="false" disabled>JavDB 想看(关联中)</button>','<button type="button" class="jhs-btn jhs-btn--secondary" data-jhs-action="subtitlecat">字幕 (SubtitleCat)</button>','<button type="button" class="jhs-btn jhs-btn--secondary" data-jhs-action="xunlei">字幕 (迅雷)</button>'),t.find(".jhs-fc2-summary__body").append(s),e.getSlot("summary").append(t);let a=$('<div class="jhs-fc2-gallery-grid" data-jhs-role="gallery-grid"></div>'),i=$('<div class="jhs-fc2-screenshot" data-jhs-role="screenshot"></div>');a.on(`click${e.namespace}`,".jhs-fc2-gallery-item",(f=>{let v=$(f.currentTarget).find("img")[0];v&&globalThis.showImageViewer(v,"",{galleryRoot:a[0]})})),e.getSlot("gallery").append(a,i);let r=$('<div class="jhs-fc2-resource-stack"></div>'),n=this.createResourceGroup("站内磁力","native-magnets"),l=this.createResourceGroup("第三方站点","other-sites"),c=this.createResourceGroup("更多磁力来源","magnet-hub"),h=$('<button type="button" class="jhs-btn jhs-btn--secondary" data-jhs-action="magnet-hub" aria-expanded="false">展开磁力搜索</button>'),u=null;c.find('[data-jhs-role="magnet-hub"]').append(h,'<div data-jhs-role="magnet-hub-content"></div>'),r.append(n,l,c),e.getSlot("resources").append(r),s.on(`click${e.namespace}`,'[data-jhs-action="subtitlecat"]',(f=>{let v=this.getRuntimeService("movie").sourceUrls({carNum:e.carNum},["subtitlecat"])[0]?.url;v&&utils.openPage(v,e.carNum,!1,f)}));let p=this.getOptionalDependency("DetailPageButtonPlugin");p?s.on(`click${e.namespace}`,'[data-jhs-action="xunlei"]',(()=>p.searchXunLeiSubtitle(e.carNum))):s.find('[data-jhs-action="xunlei"]').remove();let g=this.getOptionalDependency("MagnetHubPlugin");g||c.remove(),h.on(`click${e.namespace}`,(async()=>{if(!g||!e.isAlive())return;let f=c.find('[data-jhs-role="magnet-hub-content"]');if(h.attr("aria-expanded")==="true")return c.addClass("is-collapsed"),void h.attr("aria-expanded","false").text("展开磁力搜索");u||(u=g.createMagnetHub({movieContext:e.movieContext,root:e.root}));let b=await u;e.isAlive()&&!f.children().length&&f.append(b),e.isAlive()&&(c.removeClass("is-collapsed"),h.attr("aria-expanded","true").text("收起磁力搜索"),f[0]?.scrollIntoView?.({block:"nearest"}))})),this.getDetailStateController().bind({root:e.root,layerIndex:e.layerIndex??null,carNum:e.carNum,activityType:"fc2-state",getRecord:d(()=>({carNum:e.carNum,url:e.url,fc2Source:e.source,names:e.root.find('[data-jhs-role="actress-data"]').text(),publishTime:e.root.find('[data-jhs-role="publish-time"]').text()}),"getRecord")}),e.source==="123av"?this.load123AvDetail(e):this.loadNativeDetail(e);let m=this.getOptionalDependency("FilterTitleKeywordPlugin");m&&Promise.resolve().then((()=>m.bindDetailRoot(e.root,{layerIndex:e.layerIndex??null}))).catch((f=>clog.error("FC2 关键词过滤初始化失败",f))),this.mountFc2OtherSites(e,l,this.getOptionalDependency("OtherSitePlugin")),this.loadFc2Screenshot(e)}bindFc2FeatureLifecycle(e){let t=this.getRuntimeService("settings"),s=d(a=>{let i=a.detail?.names;if(i?.length&&(i.includes("enableLoadScreenShot")&&(t.snapshot().enableLoadScreenShot==="no"?(e.screenshotGeneration=(e.screenshotGeneration||0)+1,this.unmountFc2Screenshot(e)):this.loadFc2Screenshot(e)),i.includes("translateTitle")&&((t.snapshot().translateTitle??R)===R?this.applyFc2Translation(e):(e.translationGeneration=(e.translationGeneration||0)+1,this.revertFc2Translation(e))),i.includes("enableMagnetsFilter")&&e.magnetFilterApply?.((t.snapshot().enableMagnetsFilter??R)===R),i.includes("enableLoadOtherSite"))){let r=e.getSection("resources").find('[data-jhs-role="other-sites"]').closest(".jhs-fc2-resource-group");t.snapshot().enableLoadOtherSite==="no"?(e.otherSiteGeneration=(e.otherSiteGeneration||0)+1,this.unmountFc2OtherSites(e,r)):this.mountFc2OtherSites(e,r,this.getOptionalDependency("OtherSitePlugin"))}},"handler");t.addEventListener("settings.changed",s),e.addObserver({disconnect:d(()=>t.removeEventListener("settings.changed",s),"disconnect")})}loadFc2Screenshot(e){let t=this.getRuntimeService("screenshot"),s=this.getRuntimeService("settings"),a=e.root.find('[data-jhs-role="screenshot"]');if(!t.isEnabled(s.snapshot()))return void a.empty();let i=(e.screenshotGeneration||0)+1;e.screenshotGeneration=i,Promise.resolve().then((()=>this.getRuntimeService("scope")())).then(r=>Zs({target:a,carNum:e.carNum.replace("FC2-",""),screenshot:t,settings:s.snapshot(),scope:r,isActive:d(()=>e.isAlive()&&s.snapshot().enableLoadScreenShot!=="no"&&i===e.screenshotGeneration,"isActive"),isDuplicate:d(n=>!!e.galleryUrls?.has(n),"isDuplicate")})).then(r=>{if(!(!e.isAlive()||i!==e.screenshotGeneration)&&s.snapshot().enableLoadScreenShot==="no")return void a.empty()}).catch(r=>{!e.isAlive()||i!==e.screenshotGeneration||(a.empty(),clog.error("FC2 剧照初始化失败",r))})}unmountFc2Screenshot(e){e.screenshotGeneration=(e.screenshotGeneration||0)+1,e.root.find('[data-jhs-role="screenshot"]').empty()}applyFc2Translation(e){let t=this.getRuntimeService("settings");if(!e.isAlive()||(t.snapshot().translateTitle??R)!==R)return;let s=(e.translationGeneration||0)+1;e.translationGeneration=s,Promise.resolve().then((()=>this.getRuntimeService("scope")())).then(a=>Ys({root:e.root,carNum:e.carNum,translation:this.getRuntimeService("translation"),scope:a,isActive:d(()=>e.isAlive()&&(t.snapshot().translateTitle??R)===R&&s===e.translationGeneration,"isActive")})).catch((a=>clog.error("FC2 标题翻译失败",a)))}revertFc2Translation(e){e.root.find(".translated-title").remove()}mountFc2OtherSites(e,t,s){if(!s)return void t.remove();let a=this.getRuntimeService("settings"),i=(e.otherSiteGeneration||0)+1;e.otherSiteGeneration=i,t.length&&t.show(),Promise.resolve().then((()=>s.loadOtherSite(e.carNum.replace("FC2-",""),e.carNum,{root:e.root,target:t.find('[data-jhs-role="other-sites"]'),autoDetect:!1,isActive:d(()=>e.isAlive()&&a.snapshot().enableLoadOtherSite!=="no"&&i===e.otherSiteGeneration,"isActive")}))).then(r=>{!e.isAlive()||i!==e.otherSiteGeneration||(r?t.show():t.hide())}).catch(r=>{!e.isAlive()||i!==e.otherSiteGeneration||(t.show(),he(e.root.find('[data-jhs-role="other-sites"]'),"外部站点加载失败"),clog.error("FC2 外部站点加载失败",r))})}unmountFc2OtherSites(e,t){e.otherSiteGeneration=(e.otherSiteGeneration||0)+1,e.root.find("[data-jhs-other-site-box],[data-jhs-other-site-settings]").remove(),t.length&&t.hide()}createResourceGroup(e,t){return $('<section class="jhs-fc2-resource-group"><h3 class="jhs-fc2-resource-title"></h3><div></div></section>').find("h3").text(e).end().find("div").attr("data-jhs-role",t).end()}async loadNativeDetail(e){let t=Promise.resolve(e.movieId);this.configureJavDbWantButton(e,t),await Promise.allSettled([this.fetchAndRenderNativeDetail(e),this.fetchAndRenderNativeMagnets(e),this.mountPanels(e,t)]),e.isAlive()&&this.applyFc2Translation(e)}async load123AvDetail(e){let t=this.getOptionalDependency("Fc2By123AvPlugin");if(!t)return void he(e.getSlot("summary"),"123AV 详情功能已禁用");let s=t.resolveMovieId(e.carNum);this.configureJavDbWantButton(e,s),this.mountPanels(e,s),s.then((a=>{if(e.isAlive())return this.fetchAndRenderNativeMagnets(e,a)})).catch((a=>{e.isAlive()&&he(e.root.find('[data-jhs-role="native-magnets"]'),"站内磁力关联失败",(()=>{this.load123AvMagnets(e)})),clog.error("123AV 磁力关联失败",a)})),await t.loadDetail(e,e.url),e.isAlive()&&this.applyFc2Translation(e)}async load123AvMagnets(e){let t=this.getOptionalDependency("Fc2By123AvPlugin");if(!t)throw new Error("123AV 详情功能已禁用");let s=await t.resolveMovieId(e.carNum);return this.fetchAndRenderNativeMagnets(e,s)}async configureJavDbWantButton(e,t){let s=e.root.find('[data-jhs-action="javdb-want"]');try{let a=await t;if(!e.isAlive())return;if(!a)return void s.prop("disabled",!0).text("JavDB 暂无对应作品");try{let i=await fc(a);if(!e.isAlive())return;if(i)return void s.prop("disabled",!0).attr("aria-pressed","true").text("已在 JavDB 想看")}catch(i){clog.warn("读取 JavDB 想看状态失败,保留手动操作",i)}s.prop("disabled",!1).text("JavDB 想看").off(`click${e.namespace}`).on(`click${e.namespace}`,(()=>{this.submitJavDbWant(e,a,s)}))}catch(a){e.isAlive()&&s.prop("disabled",!1).text("JavDB 关联失败,重试").off(`click${e.namespace}`).on(`click${e.namespace}`,(()=>{this.configureJavDbWantButton(e,this.resolveMovieId(e.carNum))})),clog.error("FC2 JavDB 想看关联失败",a)}}async submitJavDbWant(e,t,s){if(!(!e.isAlive()||s.data("jhsBusy")||s.attr("aria-pressed")==="true")){s.data("jhsBusy",!0).attr({"aria-busy":"true","aria-disabled":"true"}).text("正在加入想看…");try{if(await mc(t),!e.isAlive())return;s.attr({"aria-pressed":"true","aria-disabled":"false"}).text("已加入 JavDB 想看"),show.ok("已加入 JavDB 想看")}catch(a){if(!e.isAlive())return;let i=a;if(i?.code==="LOGIN_REQUIRED")return s.attr("aria-disabled","false").text("JavDB 想看"),this.getOptionalDependency("TOP250Plugin")?.openLoginDialog({onSuccess:d(()=>this.submitJavDbWant(e,t,s),"onSuccess")});s.attr("aria-disabled","false").text("JavDB 想看"),show.error(i?.message||"加入 JavDB 想看失败"),clog.error("加入 JavDB 想看失败",a)}finally{e.isAlive()&&s.removeData("jhsBusy").removeAttr("aria-busy")}}}async fetchAndRenderNativeDetail(e){try{let t=await this.getRuntimeService("scope")(),s=await this.getRuntimeService("movie").detail({movieId:e.movieId,carNum:e.carNum,providerId:"javdb"},{scope:t});if(!s)throw new Error("JavDB 影片详情不存在");if(!e.isAlive())return;this.renderSummary(e,s),ns(e,s.imageUrls||[],s.coverUrl||null)}catch(t){e.isAlive()&&he(e.root.find('[data-jhs-role="summary-content"]'),"影片信息加载失败",(()=>{this.fetchAndRenderNativeDetail(e)})),clog.error("FC2 详情加载失败",t)}}renderSummary(e,t){let s=e.root.find('[data-jhs-role="summary-content"]').empty(),a=$('<h1 class="jhs-fc2-title"><strong class="current-title"></strong></h1>');a.find("strong").text(t.title||"无标题"),s.append(a),t.originalTitle&&t.originalTitle!==t.title&&s.append($('<div class="jhs-fc2-original-title"></div>').text(t.originalTitle));let i=$('<div class="jhs-fc2-meta"></div>');[`番号:${t.carNum||e.carNum}`,`发行:${t.releaseDate||"未知"}`,`评分:${Number.isFinite(Number(t.score))?t.score:"无"}`,`时长:${Number.isFinite(Number(t.duration))?t.duration+" 分钟":"无"}`].forEach((l=>i.append($("<span></span>").text(l)))),s.append(i);let r=[],n=$('<div class="jhs-fc2-actors"><strong>主演:</strong></div>');(t.actors||[]).forEach((l=>{n.append($("<a></a>").addClass("jhs-fc2-actor").attr({href:`/actors/${encodeURIComponent(l.id)}`,target:"_blank",rel:"noopener noreferrer"}).text(l.name||"未知演员")),l.gender===0&&r.push(l.name)})),t.actors?.length||n.append($("<span></span>").text("暂无演员信息")),s.append(n,Ks(e,this.getRuntimeService("movie")),$('<span class="jhs-is-hidden" data-jhs-role="actress-data"></span>').text(r.join(" ")),$('<span class="jhs-is-hidden" data-jhs-role="publish-time"></span>').text(t.releaseDate||""))}async fetchAndRenderNativeMagnets(e,t=e.movieId){let s=e.root.find('[data-jhs-role="native-magnets"]');he(s,"正在加载站内磁力…");try{if(!t)return he(s,"JavDB 暂无对应作品");let a=await this.getRuntimeService("scope")(),i=await this.getRuntimeService("magnet").listNative({movieId:t,providerId:"javdb"},{scope:a});if(!e.isAlive())return;if(s.empty(),!i.length)return he(s,"暂无站内磁力");let r=[],n=this.getRuntimeService("magnet");i.forEach((l=>{let c=yl(l.hash);if(!c)return;let h=`magnet:?xt=urn:btih:${c}`,u=n.assess({title:l.title,hasHdTag:l.hasHdTag,hasSubtitleTag:l.hasSubtitleTag,date:l.createdAt,seeders:l.seeders}),p=$('<div class="jhs-fc2-magnet-item"></div>').attr("data-jhs-high-quality",String(u.highQuality)),g=$('<div class="jhs-fc2-magnet-name"></div>'),m=$('<div class="jhs-toolbar"></div>'),f=$('<div class="jhs-fc2-magnet-tags"></div>');r.push(u),f.append($("<span></span>").addClass("jhs-badge").attr("title",`磁力质量评分 ${u.score.total}`).text(`${u.grade} ${u.score.total}`)),l.hasHdTag&&f.append('<span class="jhs-badge">高清</span>'),l.hasSubtitleTag&&f.append('<span class="jhs-badge">字幕</span>'),g.append($("<a></a>").attr("href",h).text(l.title||h),$("<div></div>").addClass("jhs-fc2-meta").text(`${(Number(l.sizeMb||0)/1024).toFixed(2)} GB · ${Number(l.fileCount)||0} 个文件${l.createdAt?` · ${l.createdAt}`:""}`),f),m.append($('<button type="button" class="jhs-btn jhs-btn--secondary copy-to-clipboard">复制</button>').attr("data-clipboard-text",h),$('<button type="button" class="jhs-btn jhs-btn--secondary jhs-offline-btn">离线</button>').attr({"data-resource":h,"data-jhs-offline-owner":"fc2"})),s.append(p.append(g,m))})),await this.bindNativeMagnetFilter(e,s,r.some((l=>l.highQuality)))}catch(a){e.isAlive()&&he(s,"站内磁力加载失败",(()=>{this.fetchAndRenderNativeMagnets(e,t)})),clog.error("FC2 磁力加载失败",a)}}async bindNativeMagnetFilter(e,t,s){let a=e.getSection("resources"),i=a.find(".jhs-fc2-section__actions");i.find('[data-jhs-action="filter-native-magnets"]').remove();let n=$('<button type="button" class="jhs-btn jhs-btn--ghost jhs-btn--sm" data-jhs-action="filter-native-magnets"></button>'),l=d(u=>{t.find(".jhs-fc2-magnet-item").show(),u&&s&&t.find('.jhs-fc2-magnet-item[data-jhs-high-quality="false"]').hide(),n.attr("aria-pressed",String(u&&s)).text(s?u?"显示全部磁力":"过滤低质量":"暂无可过滤项").prop("disabled",!s)},"apply"),c=this.getRuntimeService("settings"),h=Fe({settings:c,key:"enableMagnetsFilter",fallback:"no",apply:d(u=>l(u===R),"apply"),onError:d(u=>{clog.error("磁力过滤设置保存失败,已恢复",u),show.error("磁力过滤设置保存失败,已恢复原设置")},"onError")});e.magnetFilterApply=l,i.append(n),l((c.snapshot().enableMagnetsFilter??R)===R),n.on(`click${e.namespace}`,(async()=>{let u=n.attr("aria-pressed")!=="true";await h(u?R:"no")}))}async mountPanels(e,t){try{let s=await t;if(!e.isAlive())return;if(!s)return this.clearOwnedPanel(e,"reviews"),this.clearOwnedPanel(e,"related"),he(e.getSlot("reviews"),"JavDB 暂无对应作品"),he(e.getSlot("related"),"JavDB 暂无对应作品");this.clearOwnedPanel(e,"reviews"),this.clearOwnedPanel(e,"related");let a=d(()=>this.getRuntimeService("scope")(),"scope"),i=new Bt({related:this.getRuntimeService("related"),settings:this.getRuntimeService("settings"),scope:a}),r=new Mt({review:this.getRuntimeService("review"),settings:this.getRuntimeService("settings"),storage:this.getRuntimeService("storage"),scope:a});await Promise.allSettled([r.show(s,e.getSlot("reviews"),{ownedSection:e.getSection("reviews"),isActive:e.isAlive,ownCleanup:d(n=>e.addObserver({disconnect:n}),"ownCleanup")}),i.show(e.getSlot("related"),s,{ownedSection:e.getSection("related"),isActive:e.isAlive,ownCleanup:d(n=>e.addObserver({disconnect:n}),"ownCleanup")})])}catch(s){if(!e.isAlive())return;this.clearOwnedPanel(e,"reviews"),this.clearOwnedPanel(e,"related");let a=d(()=>{this.mountPanels(e,this.resolveMovieId(e.carNum))},"retry");he(e.getSlot("reviews"),"评论关联失败",a),he(e.getSlot("related"),"相关清单关联失败",a),clog.error("FC2 JavDB 关联失败",s)}}clearOwnedPanel(e,t){e.getSlot(t).empty(),e.getSection(t).find(".jhs-fc2-section__actions").empty()}async resolveFc2Source(e={}){if(e.fc2Source&&["fc2","123av"].includes(e.fc2Source))return e.fc2Source;try{let t=new URL(e.url||"",window.location.origin);return this.getRuntimeService("movie").matchesProviderUrl("av123",t.href)?"123av":t.origin===window.location.origin?"fc2":""}catch{return""}}createFc2PageUrl(e,t,s,{source:a=""}={}){if(!String(e||"").trim())throw new TypeError("FC2 owned detail requires movieId");let i=new URL("/users/collection_codes",window.location.origin);return i.searchParams.set("movieId",String(e).trim()),i.searchParams.set("carNum",t),i.searchParams.set("url",s),i.searchParams.set("source",a),i.href}async openFc2Page(e,t,s,a={newTab:!0},{source:i=""}={}){i=["fc2","123av"].includes(i)?i:"";let r=String(e||"").trim();if(!r)return void utils.openPage(s,t,!0,a);utils.openPage(this.createFc2PageUrl(r,t,s,{source:i}),t,!0,a)}};d(Lr,"Fc2Plugin");var Xs=Lr;var Br=class Br extends I{constructor(){super(),this.$contentBox=null,this.$listRoot=null,this.loadGeneration=0}getName(){return"HitShowPlugin"}async initCss(){return"<style>.jhs-hitshow-heading{display:flex;align-items:center;justify-content:space-between;gap:var(--jhs-space-3);flex-wrap:wrap}.jhs-hitshow-title{margin:0!important}.jhs-hitshow-list{margin-top:var(--jhs-space-3)}.jhs-hitshow-state{display:flex;min-height:180px;align-items:center;justify-content:center;flex-direction:column;gap:var(--jhs-space-3);color:var(--jhs-text-muted);text-align:center}</style>"}async handle(){$('a[href*="rankings/playback"]').on("click",(e=>{if(e.ctrlKey||e.metaKey||e.button===1)return void window.open("/advanced_search?handlePlayback=1&period=daily","_blank");e.preventDefault(),e.stopPropagation(),window.location.href="/advanced_search?handlePlayback=1&period=daily"})),await this.handlePlayback()}hookPage(){let e=this.getRuntimeService("host"),t=e.getListContainer?.()??e.getListLayoutContainer?.();if(!t||!e.createOwnedListRoot)throw new Error("JavDB 列表容器不可用");this.$contentBox=$(t),this.$listRoot=$(e.createOwnedListRoot(["jhs-hitshow-list"]));let s=$("h2.section-title");s.length||(s=$("<h2></h2>").addClass("section-title").prependTo(this.$contentBox)),s.contents().first().replaceWith("热播"),s.addClass("jhs-hitshow-title"),s.parent(".jhs-hitshow-heading").length||s.wrap('<header class="jhs-hitshow-heading"></header>'),$(".empty-message").remove(),this.$contentBox.children(".box").remove(),e.mountOwnedListRoot(t,this.$listRoot[0])}async handlePlayback(){if(!We())return;let e=new URLSearchParams(window.location.search).get("period"),t=++this.loadGeneration,s=loading(),a=!1;try{this.hookPage(),this.toolBar(e),await this.getOptionalDependency("ListPageButtonPlugin")?.mountOwnedRankingControls?.()?.catch?.(r=>clog.error("热播操作按钮挂载失败",r));let i=await this.fetchPlaybackWithRetry(e);if(t!==this.loadGeneration)return;if(!i.length)return void this.renderState("当前周期暂无热播数据");this.$listRoot.html(this.markDataListHtml(i)),await this.initializeRenderedList(),$("#jhs-hitshow-period").length||$(".jhs-hitshow-heading").length&&this.toolBar(e),s.close(),a=!0,this.loadScore(i,t).catch((r=>clog.error("热播评分补全失败",r)))}catch(i){clog.error("所有重试尝试均失败,无法获取数据。",i),this.$listRoot?.length?this.renderState("热播数据加载失败,请稍后重试",!0):show.error("热播页面初始化失败")}finally{a||s.close()}}renderState(e,t=!1){if(!this.$listRoot?.length)return;let s=$("<div></div>").addClass(`jhs-hitshow-state${t?" jhs-hitshow-state--error":""}`).attr("role",t?"alert":"status"),a=$("<p></p>").text(e);s.append(a),t&&s.append($('<button type="button" class="jhs-btn jhs-btn--secondary"></button>').text("重新加载").on("click",(()=>{this.handlePlayback()}))),this.$listRoot.empty().append(s)}async fetchPlaybackWithRetry(e){let t;for(let s=1;s<=3;s++)try{let a=await this.getRuntimeService("scope")();return await this.getRuntimeService("movie").rankings({period:e,scope:a})}catch(a){t=a,s<3&&(clog.error(`获取热播数据失败 (第 ${s} 次重试)`,a),await new Promise((i=>setTimeout(i,1e3))))}throw t}async initializeRenderedList(){let e=this.getOptionalDependency("ListPagePlugin");if(e){let t=e.advanceListGeneration?.()??null,s=this.getRuntimeService("settings").snapshot().hoverBigImg;e.configureHoverPreview(s==="yes"?"yes":"no"),e.replaceHdImg(),await e.doFilter(t||void 0),await e.createQuickFilter?.(),t!==null&&e.reconcileListItems?e.reconcileListItems(null,t):e.applyVisibility(),e.rebuildItemIndex?.(),e.bindMovieDetailNavigation(e.getSelector().boxSelector),await e.bindClick?.()}await this.getOptionalDependency("CoverButtonPlugin")?.addSvgBtn?.(),await F?.emit("list-items-added",{items:this.$listRoot?.find(".item").toArray()??[]},{broadcast:!1})}toolBar(e){$("#jhs-hitshow-period").remove();let t=e==="weekly"?"weekly":e==="monthly"?"monthly":"daily",s=d((l,c)=>`<a role="tab" class="jhs-segmented__item ${t===l?"active":""}" aria-selected="${t===l?"true":"false"}" tabindex="${t===l?"0":"-1"}" href="/advanced_search?handlePlayback=1&period=${l}">${c}</a>`,"tab"),a=`
            <nav id="jhs-hitshow-period" class="jhs-segmented" role="tablist" aria-label="热播周期">
                ${s("daily","日榜")}
                ${s("weekly","周榜")}
                ${s("monthly","月榜")}
            </nav>
        `,i=$(".jhs-hitshow-heading");if(!i.length)return;let r=i.children("h2.section-title");r.length?r.after(a):i.append(a);let n=$("#jhs-hitshow-period");n.off("keydown.jhsPeriod").on("keydown.jhsPeriod",(l=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(l.key))return;l.preventDefault();let c=n.find('[role="tab"]'),h=c.index(l.target),u=l.key==="Home"?0:l.key==="End"?c.length-1:l.key==="ArrowRight"?(h+1)%c.length:(h-1+c.length)%c.length;c.get(u)?.focus()}))}getStarRating(e){let t="",s=Math.floor(e);for(let a=0;a<s;a++)t+='<i class="icon-star"></i>';for(let a=0;a<5-s;a++)t+='<i class="icon-star gray"></i>';return t}async loadScore(e,t=this.loadGeneration){if(e.length===0)return;let s="jhs_hitshow_scores_v1",a=await storageManager.cachedRequest(s,6048e5,async()=>({})),i=a&&typeof a=="object"&&!Array.isArray(a)?{...a}:{},r=[...e],n=Array.from({length:Math.min(4,r.length)},(()=>this.scoreWorker(r,i,t)));if(await Promise.all(n),t===this.loadGeneration&&await storageManager.cacheSet(s,i,6048e5),t===this.loadGeneration){let l=this.getOptionalDependency("ListPageButtonPlugin");(l?.activeSortMethod?.()??"default")==="rateCount"&&await l?.sortItems?.()}}async scoreWorker(e,t,s){for(;;){let a=e.shift();if(!a)return;try{if(s!==this.loadGeneration)return;let i=a.movieId??a.id;if(!$(`#score_${i}`).length)continue;if(t[i]){let h=this.normalizeScoreData(t[i]);this.appendScore(i,h.score,h.watchedCount);continue}let r=await this.getRuntimeService("scope")(),n=await this.getRuntimeService("movie").detail({movieId:i,providerId:"javdb"},{scope:r});if(!n)throw new Error("JavDB 影片详情不存在");if(s!==this.loadGeneration)return;let l=Number(n.score),c=Number(n.watchedCount);this.appendScore(i,l,c),t[i]={score:Number.isFinite(l)?l:0,watchedCount:Number.isFinite(c)?c:0}}catch(i){let r=a.movieId??a.id,n=a.carNum??a.number,l=i instanceof Error?i:new Error(String(i));$(`#${r}`).attr("data-jhs-rate-count","0"),clog.error(`解析评分数据失败 | 编号: ${n}
`,`错误详情: ${l.message}
`,l.stack?`调用栈:
${l.stack}`:"")}}}normalizeScoreData(e){let t=e&&typeof e=="object"?e:{},s=typeof e=="string"?e:String(t.html||""),a=Number(t.score??(s.match(/([\d.]+)分/)||[0,0])[1]),i=Number(t.watchedCount??(s.match(/由(\d+)人/)||[0,0])[1]);return{score:Number.isFinite(a)?a:0,watchedCount:Number.isFinite(i)?i:0}}appendScore(e,t,s=0){let a=Math.min(5,Math.max(0,Number(t)||0)),i=Math.max(0,Number(s)||0),r=$(`#${e}`),n=$(`#score_${e}`);if(r.attr("data-jhs-rate-count",String(i)),!n.length||n.text().trim()!=="")return;let l=$('<span class="value"></span>'),c=$('<span class="score-stars"></span>').html(this.getStarRating(a));l.append(c,document.createTextNode(`  ${a}分,由${i}人评价`)),n.hide().empty().append(l).slideDown(500)}markDataListHtml(e,{thumbnailFirst:t=!0}={}){let s="";return e.forEach(((a,i)=>{let r=a.movieId??a.id,n=a.carNum??a.number,l=a.title??a.origin_title,c=a.releaseDate??a.release_date,h=ir(a.coverUrl??a.cover_url),u=ir(a.thumbUrl??a.thumb_url),p=u??(h?h.replace("/covers/","/thumbs/"):null),g=t?p??h:h??p,m=h??p??"",f=a.hasSubtitle??a.has_cnsub,v=Number(a.magnetCount??a.magnets_count),b=a.newMagnets??a.new_magnets;s+=`
                <div class="item" id="${C(r)}" data-jhs-publish-time="${C(c)}" data-jhs-rate-count="0" data-original-index="${i}">
                    <a href="/v/${C(r)}" class="box" title="${C(l)}">
                        <div class="cover ">${g?`<img loading="lazy" decoding="async" src="${C(g)}" data-full="${C(m)}" alt="">`:""}</div>
                        <div class="video-title"><strong>${C(n)}</strong> ${C(l)}</div>
                        <div class="score" id="score_${C(r)}"></div>
                        <div class="meta">${C(c)}</div>
                        <div class="tags"></div>
                        <div class="jhs-toolbar">
                           ${f?'<span class="jhs-badge jhs-badge--watch">含中字磁力</span>':v>0?'<span class="jhs-badge jhs-badge--success">含磁力</span>':'<span class="jhs-badge jhs-badge--neutral">无磁力</span>'}
                           ${b?'<span class="jhs-badge jhs-badge--accent">今日新增</span>':""}
                        </div>
                    </a>
                </div>
            `})),s}};d(Br,"HitShowPlugin");var ea=Br;var Mr=class Mr extends I{getName(){return"JavTrailersPlugin"}constructor(){super(),this.hasBand=!1}async handle(){let e=window.location.href;if(!e.includes("handle=1"))return;if($("h1:contains('Page not found')").length){clog.log("番号无法匹配, 跳搜索");let a=e.split("?")[0].split("video/")[1].toLowerCase().replace("00","-");return void(window.location.href="/search/"+encodeURIComponent(a)+window.location.search)}let t=$(".videos-list .video-link").toArray();if(t.length){let a=e.split("?")[0].split("search/")[1].toLowerCase(),i=t.find((r=>$(r).find(".vid-title").text().toLowerCase().includes(a)));if(i)return void(window.location.href=$(i).attr("href")+window.location.search)}let s=await this.getRuntimeService("scope")();this.handlePlayJavTrailers(s),this.bindPlaybackControls(s)}bindPlaybackControls(e){let t=$("#videoPlayerContainer"),s=d(()=>this.handlePlayJavTrailers(e),"replay");t.off("click.jhsJavTrailers").on("click.jhsJavTrailers",s),e.addCleanup((()=>t.off("click.jhsJavTrailers",s))),e.listen(window,"message",(()=>{let a=document.getElementById("vjs_video_3_html5_api");a&&(a.currentTime+=5)}))}handlePlayJavTrailers(e){if(this.hasBand||e.signal.aborted)return;let t=utils.loopDetector((()=>$("#vjs_video_3_html5_api").length!==0),(()=>{e.signal.aborted||e.ownTimeout(setTimeout((()=>{if(e.signal.aborted)return;this.hasBand=!0;let a=document.getElementById("vjs_video_3_html5_api");a&&(clog.debug(a),de(a,{context:"JavTrailers 预览"}),a.currentTime=5,e.listen(a,"timeupdate",(function(){a.currentTime>=14&&a.currentTime<16&&(a.currentTime+=2)})),$("#vjs_video_3_html5_api").css({position:"fixed",width:"100vw",height:"100vh",objectFit:"cover",zIndex:String(J.debug)}),$(".vjs-control-bar").css({position:"fixed",bottom:"20px",zIndex:String(J.debug)}))}),100))}),20,1e4,!0,e),s=utils.loopDetector((()=>$("#vjs_video_3 canvas").length>0),(()=>{e.signal.aborted||$("#vjs_video_3 canvas").length!==0&&$("#vjs_video_3 canvas").css({position:"fixed",width:"100vw",height:"100vh",objectFit:"cover",top:"0",right:"0",zIndex:String(J.debug-1)})}),20,1e4,!0,e);e.addCleanup(t),e.addCleanup(s)}};d(Mr,"JavTrailersPlugin");var ta=Mr;var sa=Object.freeze({magnet:216e5,screenshot:6048e5,screenshotNegative:432e5,match115:36e5,externalDetail:864e5}),Or=class Or extends Error{constructor(e,t,s,a={}){super(s,{cause:a.cause}),this.name="ProviderError",this.provider=e,this.code=t,this.status=a.status||0,this.url=a.url||"",this.retryable=!!a.retryable}};d(Or,"ProviderError");var we=Or;function ls(o){let e=0,t=Number(o.seeders)||0,s=t>=50?35:t>=10?25:t>=1?15:3;e+=s;let a=String(o.title||"").toLowerCase(),i=String(o.resolution||"").toLowerCase(),r=/4k|2160p/.test(i)||/4k|2160p/.test(a)?25:/1080p/.test(i)||/1080p/.test(a)?20:/720p/.test(i)||/720p/.test(a)?15:5;e+=r;let n=o.hasSubtitle||/-c\b|-uc\b|chinese|中字|字幕/.test(a)?20:0;e+=n;let l=Lh(o.date),c=l<=7?15:l<=30?12:l<=90?8:3;e+=c;let h=/sample|预告|trailer/.test(a)?-15:0;return e+=h,{total:Math.max(0,Math.min(100,e)),seeders:s,resolution:r,subtitle:n,freshness:c,completeness:h}}d(ls,"calcMagnetScore");function Lh(o){try{let e=new Date(String(o||""));return Number.isNaN(e.getTime())?999:Math.max(0,Math.floor((Date.now()-e.getTime())/864e5))}catch{return 999}}d(Lh,"daysSince");function zr(o,e=!1){let t=String(o||"").toLowerCase(),s=/(?:4k|2160p|1080p|720p)/.exec(t)?.[0]||"",a=e||/(?:-c\b|-u(?:c)?\b|chinese|中字|字幕)/.test(t);return{resolution:s,subtitle:a,recognized:!!s||a,highQuality:s==="4k"||s==="2160p"||a}}d(zr,"getMagnetQualitySignals");function yc({title:o="",hasHdTag:e=!1,hasSubtitleTag:t=!1,date:s=null,seeders:a=0}={}){let i=zr(o,t),r=e||i.highQuality,n=ls({title:o,date:s,seeders:a,resolution:e&&!i.resolution?"1080p":i.resolution,hasSubtitle:i.subtitle});return{...i,highQuality:r,score:n,grade:n.total>=70?"高":n.total>=40?"中":"低"}}d(yc,"assessMagnetQuality");function wt(o,e="other"){if(!o||typeof o!="object"||Array.isArray(o))return null;let t=o,s=T(t.carNum);return s?Object.freeze({...t,carNum:s,movieId:typeof t.movieId=="string"&&t.movieId.trim()?t.movieId.trim():null,surface:t.surface||e}):null}d(wt,"normalizeMovieContext");function jc(o,e="other"){let t=wt(o,e);if(!t)throw new TypeError("Movie context requires a valid carNum");return t}d(jc,"createMovieContext");function aa(o){let e=o?.nodeType?o:o?.[0]||null;for(;e;){let s=(typeof globalThis.$=="function"?globalThis.$(e):null)?.data?.("jhsMovieContext")||e.__jhsMovieContext,a=wt(s);if(a)return a;e=e.parentElement||null}return null}d(aa,"readOwnedMovieContext");function Ur(o={}){let e=wt(o.explicitContext);if(e)return{context:e,source:"explicit"};let t=wt(o.ownedResolver?.()??aa(o.trigger),"other");if(t)return{context:t,source:t.surface==="fc2-dialog"?"fc2-workspace":"owned-surface"};let s=wt(o.listResolver?.(),"list-item");if(s)return{context:s,source:"list-item"};let a=wt(o.nativeResolver?.(),"native-detail");if(a)return{context:a,source:"native-detail"};let i=wt(o.legacyResolver?.(),"other");return i?(o.logger?.("movie-context source=legacy-fallback",i),{context:i,source:"legacy-fallback"}):{context:null,source:"missing"}}d(Ur,"resolveMovieContext");var Fr=class Fr extends I{constructor(){super(...arguments),this.sourceRegistry=new Qt,this.searchEngines=[]}async initializeSources(){let e=new rt,t=this.getRuntimeService("magnet"),s=await e.getBuiltInSources(),a=await e.getMagnetSources(),i=t.getBuiltInSources(),r=[...Ns,...i],n=d(h=>({...r.find(u=>u.id===h)||{},...s.find(u=>u.id===h)||{}}),"configured"),l=i.map((h=>{let u=n(h.id),p=String(u.baseUrl||h.baseUrl).replace(/\/$/,"");return{...h,...u,search:d(async g=>t.searchSource(h.id,g,{baseUrl:p,scope:await this.getRuntimeService("scope")()}),"search"),targetUrl:d(g=>t.getSourceTargetUrl(h.id,g,{baseUrl:p}),"targetUrl")}}));this.sourceRegistry=new Qt([{name:"JavDB 本站",id:"native-javdb",applicable:N,enabled:N,priority:1,search:d(async(h,u=document)=>or(u?.jquery?u[0]:u,"javdb"),"search"),targetUrl:d(()=>window.location.href,"targetUrl")},{name:"JavBus 本站",id:"native-javbus",applicable:B,enabled:B,priority:2,search:d(async(h,u=document)=>or(u?.jquery?u[0]:u,"javbus"),"search"),targetUrl:d(()=>window.location.href,"targetUrl")},...l].map((h=>{let u=n(h.id),p=h.applicable??!0;return{...h,...u,enabled:p&&(u.enabled??h.enabled??!0),search:h.search,targetUrl:h.targetUrl}}))),a.filter(h=>h.enabled).forEach(h=>this.sourceRegistry.register({...h,id:`custom:${h.id}`,search:d(u=>this.searchCustomSource(h,u),"search"),targetUrl:d(u=>h.targetUrlTemplate.replaceAll("{keyword}",encodeURIComponent(u)),"targetUrl")}));let c=this.sourceRegistry.getEnabledSources().map((h=>({...h,targetPage:h.targetUrl("{keyword}").replace("%7Bkeyword%7D","{keyword}")})));this.searchEngines=c.length?[{id:"all",name:"全部",priority:0,targetPage:"#",targetUrl:d(()=>"#","targetUrl"),search:d(h=>this.searchAllSources(c,h),"search")},...c]:[]}getName(){return"MagnetHubPlugin"}async initCss(){return`<style>
            .magnet-container { width:100%; margin:var(--jhs-space-4) auto; }
            .magnet-tabs { display:flex; justify-content:space-between; margin-bottom:var(--jhs-space-3); border-bottom:1px solid var(--jhs-border); }
            .magnet-results { min-height:200px; }
            .magnet-result { position:relative; padding:var(--jhs-space-3); border-bottom:1px solid var(--jhs-border); }
            .magnet-result:hover { background:var(--jhs-surface-hover); }
            .magnet-title { overflow:hidden; margin-bottom:var(--jhs-space-1); padding-right:80px; font-weight:700; text-overflow:ellipsis; white-space:nowrap; }
            .magnet-info { display:flex; justify-content:space-between; margin-bottom:var(--jhs-space-1); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-xs); }
            .magnet-loading { padding:var(--jhs-space-4); text-align:center; }
            .magnet-error { padding:var(--jhs-space-2); color:var(--jhs-danger); }
            .magnet-copy { position:absolute; top:var(--jhs-space-2); right:var(--jhs-space-3); }
        </style>`}async createMagnetHub(e,t={}){await this.initializeSources();let s=typeof e=="string"?null:e,a=typeof e=="string"?jc({carNum:e}):s?.movieContext;if(!a?.carNum)return $('<div class="magnet-container jhs-ui"></div>').append($('<div class="magnet-error"></div>').text("无法确定影片身份,未加载磁力"));let i=a.carNum.replace("FC2-",""),r=t.root??s?.root?$(t.root??s?.root):$(document),n=[...this.searchEngines],l=this.getRuntimeService("storage"),c=$('<div class="magnet-container jhs-ui"></div>'),h=$('<div class="magnet-tabs"></div>'),u="jhs_magnetHub_selectedEngine",p=l.getLocal(u);c.data("jhsMovieContext",a);let g=$('<div class="magnet-tabs__options" role="tablist" aria-label="磁力来源"></div>'),m=n.find((w=>w.id===p))||n[0];if(!m)return c.append($('<div class="magnet-error"></div>').text("暂无可用磁力来源,请前往设置启用来源"));let f=m;n.forEach((w=>g.append($('<button type="button" class="jhs-btn magnet-tab" role="tab" aria-selected="false" tabindex="-1"></button>').attr("data-engine",w.id).text(w.name).toggleClass("active",w.id===f.id))));let v=$('<a class="jhs-btn jhs-btn--ghost" data-jhs-role="magnet-target" target="_blank" rel="noopener noreferrer">原网页</a>').attr("href",(f.targetPage||"#").replace("{keyword}",encodeURIComponent(i))).toggle(f.id!=="all");h.append(g),h.append(v),g.find(".magnet-tab.active").attr({"aria-selected":"true",tabindex:"0"}),c.append(h);let b=$('<div class="magnet-results"></div>');return c.append(b),c.on("click",".magnet-tab",(w=>{let S=$(w.target).data("engine");f=n.find((j=>j.id===S))||f,f&&(c.find('[data-jhs-role="magnet-target"]').attr("href",(f.targetPage||"#").replace("{keyword}",encodeURIComponent(i))).toggle(f.id!=="all"),l.setLocal(u,S),c.find(".magnet-tab").removeClass("active").attr({"aria-selected":"false",tabindex:"-1"}),$(w.target).addClass("active").attr({"aria-selected":"true",tabindex:"0"}),this.searchEngine(b,f,i,r))})),c.on("keydown",".magnet-tab",(w=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(w.key))return;w.preventDefault();let S=c.find(".magnet-tab"),j=S.index(w.currentTarget),k=w.key==="Home"?0:w.key==="End"?S.length-1:w.key==="ArrowRight"?(j+1)%S.length:(j-1+S.length)%S.length;S.eq(k).trigger("click").trigger("focus")})),this.searchEngine(b,f,i,r),c}async searchEngine(e,t,s,a=$(document)){e.html(`<div class="magnet-loading">正在从 ${C(t.name)} 搜索 "${C(s)}"...</div>`);let i=`${t.name}_${s}`;if(t.search)try{return void this.displayResults(e,await this.applyRuntimeRules(Es(await t.search(s,a))),t.name)}catch(r){return clog.error(`磁力源 ${t.name} 请求失败`,r),void e.html(`<div class="magnet-error">${C(t.name)} 请求失败</div>`)}if(t.parseHtml)try{let r=t.url.replace("{keyword}",encodeURIComponent(s)),n=await this.requestSource(t.id,r,{ttlMs:216e5}),l=t.parseHtml.call(this,n,s);return void this.displayResults(e,l,t.name)}catch(r){return void e.html(`<div class="magnet-error">解析 ${C(t.name)} 结果失败: ${C(r instanceof Error?r.message:String(r))}</div>`)}t.parseJson&&await t.parseJson.call(this,e,t,s,i)}async searchCustomSources(e){let s=JSON.parse(await storageManager.getSetting("customMagnetSources","[]")).filter(i=>i.enabled).map(bt),a=await $e(s,4,(async i=>{let r=i.searchUrlTemplate.replaceAll("{keyword}",encodeURIComponent(e));try{let n=await this.requestSource(i.id,r,{ttlMs:sa.magnet,custom:!0,responseType:i.parserType==="json"?"json":"text"}),l=i.parserType==="json"&&typeof n=="string"?JSON.parse(n):n;return lr(i,l,i.id)}catch(n){let l=n;return clog.error(`自定义磁力源 ${i.name} 失败`,new we(i.id,l.code||"HTTP_ERROR",l.message||String(n),{cause:n,url:r,status:l.status,retryable:l.retryable})),[]}}));return Es(a.flat())}async searchCustomSource(e,t){let s=e.searchUrlTemplate.replaceAll("{keyword}",encodeURIComponent(t)),a=await this.requestSource(e.id,s,{ttlMs:sa.magnet,custom:!0,responseType:e.parserType==="json"?"json":"text"});return lr(e,e.parserType==="json"&&typeof a=="string"?JSON.parse(a):a,e.id)}async searchAllSources(e,t){let s=await $e(e,3,(async a=>{try{return await a.search(t)}catch(i){return clog.warn(`磁力源 ${a.name} 聚合失败`,i),[]}}));return Es(s.flat())}async requestSource(e,t,s={}){let a=await this.getRuntimeService("scope")();return(await this.getRuntimeService("http").request({providerId:`magnet:${e}`,method:s.method||"GET",url:t,body:s.body,headers:s.headers,responseType:s.responseType||"text",cacheScope:s.method&&s.method!=="GET"?"none":"public",ttlMs:s.ttlMs??sa.magnet,urlPolicy:s.custom?{trustClass:"custom-public"}:{trustClass:"builtin-public",hosts:s.hosts||[new URL(t).hostname]}},a)).data}async applyRuntimeRules(e){let t=new rt,[s,a]=await Promise.all([t.getMagnetTagRules(),t.getMagnetFilterRules()]);return e.map((i=>_l(i,s,a.filter((r=>(r.target||"title")==="title")),a.filter((r=>r.target==="file"))))).filter((i=>!i.hidden))}async displayResults(e,t,s){function a(i){let r=i.text();i.addClass("copied").text("已复制"),setTimeout((()=>{i.removeClass("copied").text(r)}),2e3)}d(a,"a"),e.empty(),t.length!==0?(t.forEach((i=>{let r=this.calcMagnetScore(i);i._score={...r,total:Math.max(0,Math.min(100,r.total+(i.customTagWeight||0)+(i.filterPenalty||0)))}})),t.sort(((i,r)=>r._score.total-i._score.total)),t.forEach((i=>{let r=i._score?i._score.total:0,n=r>=80?"高":r>=60?"中":"低",l=i._score?`做种:${i._score.seeders}/35 分辨率:${i._score.resolution}/25 字幕:${i._score.subtitle}/20 新鲜度:${i._score.freshness}/15 完整性:${i._score.completeness}/5`:"",c=C(i.title),h=C(i.magnet),u=C(String(i.size||"未知")),p=C(String(i.date||"未知")),g=$(`
                <div class="magnet-result">
                    <div class="magnet-title">
                        <span class="magnet-score" title="${l}">${n} ${r}</span>
                        <a href="${h}">${c}</a>
                    </div>
                    <div class="magnet-info">
                        <span>大小: ${u}</span>
                        <span>做种: ${i.seeders||"—"}</span>
                        <span>日期: ${p}</span>
                    </div>
                    <div class="magnet-copy">
                        <button type="button" class="jhs-btn magnet-hub-btn copy-btn" data-magnet="${h}">复制链接</button>
                    </div>
                </div>
            `);i.tags?.length&&g.find(".magnet-info").after($("<div></div>").addClass("magnet-tags").append(i.tags.map((f=>$("<span></span>").addClass("jhs-badge").text(f)))));let m=g.find(".magnet-copy");g.find(".copy-btn").removeClass("magnet-hub-btn").addClass("jhs-btn--secondary"),m.append(`<button type="button" class="jhs-btn jhs-btn--secondary jhs-offline-btn" data-resource="${h}">离线</button>`),g.appendTo(e)})),e.on("click",".copy-btn",(async i=>{let r=$(i.currentTarget),n=r.data("magnet");await utils.copyToClipboard("磁力链接",n)&&a(r)}))):e.append('<div class="magnet-error">没有找到相关结果</div>')}calcMagnetScore(e){return ls(e)}};d(Fr,"MagnetHubPlugin");var ia=Fr;var Vr=class Vr extends I{constructor(){super(...arguments),this.mountGeneration=0,this._mountGenerations=new WeakMap,this.siteConfigs=[{id:"javTrailersBtn"},{id:"123AvBtn",providerId:"av123"},{id:"jableBtn"},{id:"avgleBtn"},{id:"missAvBtn"},{id:"supJavBtn"},{id:"javDbBtn",condition:d(()=>B,"condition")},{id:"javBusBtn",condition:d(e=>!!(N&&e&&!e.includes("FC2")),"condition")},{id:"fanzaBtn",providerId:"dmm",noHandle:!0,condition:d(e=>!!(e&&!e.includes("FC2")),"condition")}]}getName(){return"OtherSitePlugin"}async getSiteConfigs(){let e=await this.getSettingCache(),t=this.getRuntimeService("movie").externalSites(e);return this.siteConfigs.map(s=>({...t.find((a=>a.id===s.id))||{},...s}))}async initCss(){return`
            <style>
                [data-jhs-other-site-box], [data-jhs-other-site-settings], #otherSiteBox, #settingsArea { margin-top:var(--jhs-space-2); user-select:none; }
                .jhs-site-list, [data-jhs-role="site-checkboxes"], #siteCheckboxes { display:flex; flex-wrap:wrap; gap:var(--jhs-space-2); }
                .site-btn { position:relative; }
                .site-btn::before { width:7px; height:7px; border-radius:50%; background:var(--jhs-brand-color,var(--jhs-text-faint)); content:""; }
                [data-jhs-site-id="javTrailersBtn"],#javTrailersBtn { --jhs-brand-color:#d4a72c; } [data-jhs-site-id="123AvBtn"],#123AvBtn { --jhs-brand-color:#e05d44; }
                [data-jhs-site-id="jableBtn"],#jableBtn { --jhs-brand-color:#c94556; } [data-jhs-site-id="avgleBtn"],#avgleBtn { --jhs-brand-color:#4677c8; }
                [data-jhs-site-id="missAvBtn"],#missAvBtn { --jhs-brand-color:#8b5cf6; } [data-jhs-site-id="supJavBtn"],#supJavBtn { --jhs-brand-color:#ef6c35; }
                [data-jhs-site-id="javDbBtn"],#javDbBtn { --jhs-brand-color:#2684ff; } [data-jhs-site-id="javBusBtn"],#javBusBtn { --jhs-brand-color:#cc3d3d; } [data-jhs-site-id="fanzaBtn"],#fanzaBtn { --jhs-brand-color:#ea4c89; }
                .site-btn.is-checking { opacity:.65; pointer-events:none; }
                .site-btn.is-available { border-color:var(--jhs-status-down-text); background:var(--jhs-status-down-tint); }
                .site-btn.is-unavailable { border-color:var(--jhs-status-filter-text); background:var(--jhs-status-filter-tint); }
                .site-btn.is-domain-error { border-color:var(--jhs-status-watch-text); background:var(--jhs-status-watch-tint); }
                .site-tag { margin-left:var(--jhs-space-1); padding:1px var(--jhs-space-1); border-radius:var(--jhs-radius-pill); background:var(--jhs-surface-2); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-xs); }
                .jhs-site-option { display:flex; align-items:center; gap:var(--jhs-space-2); }
            </style>`}async handle(){let e=this.getRuntimeService("settings"),t=await this.getRuntimeService("scope")(),s=d(a=>{a.detail?.names?.includes("enableLoadOtherSite")&&(e.snapshot().enableLoadOtherSite==="no"?this.unmount():this.mount().catch((r=>clog.error("外部站点重新挂载失败",r))))},"onSettingsChanged");e.addEventListener("settings.changed",s),t.addCleanup((()=>e.removeEventListener("settings.changed",s))),await this.mount()}async mount(){isDetailPage&&this.getRuntimeService("settings").snapshot().enableLoadOtherSite!=="no"&&await this.loadOtherSite(null,null,{autoDetect:!1})}unmount(){this.mountGeneration++,this._mountGenerations.set(document,(this._mountGenerations.get(document)||0)+1),$("[data-jhs-other-site-box],[data-jhs-other-site-settings]").remove()}async loadOtherSite(e,t,s={}){let a=this.getRuntimeService("settings");if(a.snapshot().enableLoadOtherSite==="no")return;let i=s.root?.[0]||null,r=i?(this._mountGenerations.get(i)||0)+1:++this.mountGeneration;i&&this._mountGenerations.set(i,r);let n=d(()=>(i?r===this._mountGenerations.get(i):r===this.mountGeneration)&&(typeof s.isActive=="function"?s.isActive():!0)&&a.snapshot().enableLoadOtherSite!=="no","isActive"),l=s.root?$(s.root):$(document),c=s.target?$(s.target):$(this.getRuntimeService("host").locateDetailSlots().summary);if(!c.length||!n())return;l.find("#otherSiteBox,#settingsArea,[data-jhs-other-site-box],[data-jhs-other-site-settings]").remove(),e=T(e)||this.getPageInfo().carNum;let h=this.getEnabledSites(),u=(await this.getSiteConfigs()).map((v=>({...v,sourceCarNum:t})));if(!n())return;let p={root:l,target:c,configs:u,carNum:e,isActive:n},g=$('<div class="panel-block" data-jhs-other-site-box><div class="jhs-site-list"></div></div>'),m=g.find(".jhs-site-list"),f=$('<div class="panel-block jhs-is-hidden" data-jhs-other-site-settings><div data-jhs-role="site-checkboxes"></div></div>');if(u.forEach((v=>{if(v.condition&&v.condition(v.sourceCarNum)===!1)return;let b=$('<a target="_blank" class="site-btn jhs-btn jhs-btn--secondary"><span></span></a>').attr("data-jhs-site-id",v.id).toggleClass("jhs-is-hidden",!h.includes(v.id));b.find("span").text(v.id.replace("Btn","")),m.append(b)})),m.append('<button type="button" class="site-btn jhs-btn jhs-btn--primary" data-jhs-role="detect-sites"><span>检测外部站点</span></button>','<button type="button" class="site-btn jhs-btn jhs-btn--secondary" data-jhs-role="site-settings"><span>设置</span></button>'),c.append(g,f),p.box=g,p.settings=f,!e)return g.find(".site-btn").removeAttr("href").attr({"aria-disabled":"true",title:"番号不可用"}),g.find('[data-jhs-role="detect-sites"]').prop("disabled",!0),this.renderSettingsArea(p),this.setupEventListeners(p),void clog.warn("跳过第三方站点解析:番号不可用");if(g.find('[data-jhs-site-id="javTrailersBtn"]').on("click",(v=>{v.preventDefault();let b=$(v.currentTarget).attr("href"),w=v.ctrlKey||v.metaKey?b:b+"?handle=1";utils.openPage(w,e,!1,v)})),await $e(u,4,(async v=>{v.condition&&v.condition(v.sourceCarNum)===!1||await this.prepareSiteLink(e,v,p)})),!!n())return this.renderSettingsArea(p),this.setupEventListeners(p),g.find('[data-jhs-role="detect-sites"]').off("click").on("click",(v=>{v.preventDefault(),this.detectOtherSites(e,p)})),s.autoDetect&&await this.detectOtherSites(e,p),g}async prepareSiteLink(e,t,s={root:$(document),configs:[],isActive:d(()=>!0,"isActive")}){let a=s.root.find(`[data-jhs-site-id="${t.id}"],#${t.id}`).first();if(!(e=T(e)))return a.removeAttr("href").attr({"aria-disabled":"true",title:"番号不可用"}),void this.setSiteState(a,"idle");if(t.providerId){let i=this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e});return void(i?(a.attr("href",i),a.attr("title","点击前往外部搜索页"),this.setSiteState(a,"idle")):(a.attr("title","外部站点地址不可用"),this.setSiteState(a,"domain-error")))}try{s.isActive?.()!==!1&&t.searchUrl&&(a.attr("href",t.searchUrl(e)),a.attr("title","点击前往外部搜索页;点击检测按钮后才自动检测"),this.setSiteState(a,"idle"))}catch{s.isActive?.()!==!1&&(a.attr("title","外部站点地址未配置或不可用"),this.setSiteState(a,"domain-error"))}}async detectOtherSites(e,t={root:$(document),configs:this.siteConfigs,isActive:d(()=>!0,"isActive")}){let s=t.root.find('[data-jhs-role="detect-sites"],#detectOtherSiteBtn').first(),a=s.text();return(e=T(e))?(s.text("检测中").prop("disabled",!0).addClass("is-checking"),await $e(t.configs,4,(async i=>{i.condition&&i.condition(i.sourceCarNum)===!1||await this.handleSite(e,i,t)})),t.isActive?.()!==!1&&s.text(a).prop("disabled",!1).removeClass("is-checking")):(s.prop("disabled",!0),void clog.warn("跳过第三方站点检测:番号不可用"))}setSiteState(e,t){e.removeClass("is-checking is-available is-unavailable is-domain-error"),t!=="idle"&&e.addClass(`is-${t}`)}async handleSite(e,t,s={root:$(document),configs:[],isActive:d(()=>!0,"isActive")}){let a=s.root.find(`[data-jhs-site-id="${t.id}"],#${t.id}`).first();if(a.removeAttr("href").find(".site-tag").remove(),this.setSiteState(a,"checking"),t.noHandle&&t.noHandle===!0){a.attr("href",this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e})||"");let i="jhs_other_site_dmm",r=this.getRuntimeService("storage").getLocal(i),n=null;try{let l=r?JSON.parse(r):{};n=l&&typeof l=="object"?l[e]:null}catch{n=null}n?(a.attr("href",n.url),n.type==="multiple"&&a.append('<span class="site-tag">多结果</span>'),this.setSiteState(a,"available")):this.setSiteState(a,"idle")}else if(t.providerId)try{let i=await this.getRuntimeService("scope")(),r=await this.getRuntimeService("movie").resolve({carNum:e,providerId:t.providerId},{scope:i});if(s.isActive?.()===!1)return;let n=this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e});a.attr("href",r?.url||n||""),this.setSiteState(a,r?.url?"available":"unavailable"),r?.url||a.attr("title","未查询到, 点击前往搜索页")}catch{s.isActive?.()!==!1&&(a.attr("title","请求失败。"),this.setSiteState(a,"unavailable"),clog.warn(`检测第三方资源失败, ${t.id.replace("Btn","")}`))}else try{if(a.attr("href"))return void this.setSiteState(a,"idle");if(utils.isHidden(a))return;let i="jhs_other_site",r=this.getRuntimeService("storage"),n=r.getLocal(i),l=n?JSON.parse(n):{},c=e+"_"+t.id.replace("Btn",""),h=l[c],u=Date.now();if(h&&h.time&&u-h.time<864e5)return a.attr("href",h.url),h.type==="multiple"&&a.append('<span class="site-tag">多结果</span>'),void this.setSiteState(a,"available");let p=await this.getRuntimeService("scope")(),g=await this.getRuntimeService("movie").searchExternalSite(t.id,e,{settings:await this.getSettingCache(),scope:p}),m=g.searchUrl;if(a.attr("href",m),s.isActive?.()===!1)return;let f=g.matches,v="",b=null;if(f.length===1){let w=f[0];a.attr("href",w),this.setSiteState(a,"available"),b={type:"single",url:w,time:u}}else f.length>1?(a.attr("href",m),v+='<span class="site-tag">多结果</span>',this.setSiteState(a,"available"),b={type:"multiple",url:m,time:u}):(a.attr("href",m),a.attr("title","未查询到, 点击前往搜索页"),this.setSiteState(a,"unavailable"));if(b){let w=r.getLocal(i),S=w?JSON.parse(w):{};S[c]=b,r.setLocal(i,JSON.stringify(S))}v&&a.append(v)}catch(i){let r=String(i),n=t.id.replace("Btn",""),l=i?.code;l==="CIRCUIT_OPEN"?(a.attr("title",r),this.setSiteState(a,"domain-error"),clog.warn(`检测第三方资源跳过, ${n} 已熔断`)):l==="CF_BLOCKED"?(a.attr("title","请求失败:Cloudflare 安全检查。"),this.setSiteState(a,"domain-error"),clog.warn(`检测第三方资源失败, ${n} 需Cloudflare安全检查`)):l==="INVALID_URL"?(a.attr("title","域名失效"),this.setSiteState(a,"domain-error"),clog.warn(`检测第三方资源失败, ${n} 域名或重定向无效`)):l==="NOT_FOUND"?(a.attr("title","未查询到, 点击前往搜索页"),this.setSiteState(a,"unavailable")):(clog.error(i),a.attr("title","请求失败。"),this.setSiteState(a,"unavailable"),clog.warn(`检测第三方资源失败, ${n}`))}}async getSettingCache(){return this.getRuntimeService("settings").snapshot()}async getMissAvUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="missAvBtn")?.baseUrl||""}async getjableUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="jableBtn")?.baseUrl||""}async getAvgleUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="avgleBtn")?.baseUrl||""}async getJavTrailersUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="javTrailersBtn")?.baseUrl||""}async getAv123Url(){return this.getRuntimeService("movie").providerOrigin("av123")||""}async getJavDbUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="javDbBtn")?.baseUrl||""}async getJavBusUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="javBusBtn")?.baseUrl||""}async getSupJavUrl(){return(await this.getSiteConfigs()).find(e=>e.id==="supJavBtn")?.baseUrl||""}getEnabledSites(){let e=this.siteConfigs.map((t=>t.id));try{let t=this.getRuntimeService("storage").getLocal("jhs_enabled_sites");if(!t)return e;let s=JSON.parse(t);return Array.isArray(s)?s.filter((a=>e.includes(a))):e}catch(t){return clog.warn("外部站点配置损坏,已回退默认值",t),e}}saveEnabledSites(e){this.getRuntimeService("storage").setLocal("jhs_enabled_sites",JSON.stringify(e))}renderSettingsArea(e={root:$(document),configs:this.siteConfigs}){let t=this.getEnabledSites(),s=e.root.find('[data-jhs-role="site-checkboxes"],#siteCheckboxes').first().empty();e.configs.forEach((a=>{let i=$('<input type="checkbox">').attr("data-site-id",a.id).prop("checked",t.includes(a.id));s.append($('<label class="jhs-site-option"></label>').append(i,$("<span></span>").text(a.id.replace("Btn",""))))}))}setupEventListeners(e={root:$(document),configs:this.siteConfigs,carNum:null}){let t=e.root.find("[data-jhs-other-site-settings],#settingsArea").first();e.root.find('[data-jhs-role="site-settings"],#settingSiteBtn').off("click.jhsOtherSite").on("click.jhsOtherSite",(()=>{t.toggleClass("jhs-is-hidden")})),t.off("change.jhsOtherSite").on("change.jhsOtherSite",'input[type="checkbox"]',(async s=>{let a=$(s.currentTarget).attr("data-site-id");try{if(s.currentTarget.checked){e.root.find(`[data-jhs-site-id="${a}"],#${a}`).removeClass("jhs-is-hidden");let i=e.carNum||this.getPageInfo().carNum,r=e.configs.find((n=>n.id===a));r&&await this.prepareSiteLink(i,r,e)}else e.root.find(`[data-jhs-site-id="${a}"],#${a}`).addClass("jhs-is-hidden");this.saveEnabledSites(t.find('input[type="checkbox"]:checked').map(((i,r)=>$(r).attr("data-site-id"))).get())}catch(i){clog.warn(`外部站点 ${a||"unknown"} 状态更新失败`,i)}}))}};d(Vr,"OtherSitePlugin");var ra=Vr;var Hr=class Hr extends I{getName(){return"RelatedPlugin"}async handle(){if(!window.isDetailPage||!N)return;let e=new URL(window.location.href).pathname.split("/").filter(Boolean).pop();e&&await this.showRelated(this.getHostedSlot("related"),e)}getHostedSlot(e){let t=this.getRuntimeService("host").locateDetailSlots()[e];return t?$(t):$()}async showRelated(e,t,s={}){return new Bt({related:this.getRuntimeService("related"),settings:this.getRuntimeService("settings"),scope:d(()=>this.getRuntimeService("scope")(),"scope")}).show(e?.length?e:this.getHostedSlot("related"),t,s)}};d(Hr,"RelatedPlugin");var na=Hr;var qr=class qr extends I{getName(){return"ReviewPlugin"}async handle(){if(window.isDetailPage){if(N){let e=this.parseMovieId(window.location.href);await this.showReview(e,this.getHostedSlot("reviews"))}if(B){let e=this.getPageInfo().carNum;if(!e)return void clog.warn("跳过 JavBus 评论解析:番号不可用");let t=await this.getRuntimeService("scope")(),s=this.getRuntimeService("settings"),a=!1,i=d(async()=>{if(!(a||t?.disposed||s.snapshot().enableLoadReview==="no")){a=!0;try{let r=await this.getRuntimeService("movie").resolve({carNum:e},{scope:t});r?.movieId&&!t?.disposed&&s.snapshot().enableLoadReview!=="no"&&await this.showReview(r.movieId,this.getHostedSlot("reviews"))}finally{a=!1}}},"mount");t?.listen?.(s,"settings.changed",r=>{r.detail?.names?.includes("enableLoadReview")&&i().catch(n=>clog.error("加载评论失败",n))}),await i()}}}getHostedSlot(e){let t=this.getRuntimeService("host").locateDetailSlots()[e];return t?$(t):$()}async showReview(e,t,s={}){return new Mt({review:this.getRuntimeService("review"),settings:this.getRuntimeService("settings"),storage:this.getRuntimeService("storage"),scope:d(()=>this.getRuntimeService("scope")(),"scope")}).show(e,t?.length?t:this.getHostedSlot("reviews"),s)}};d(qr,"ReviewPlugin");var oa=qr;var Wr="jhs_appAuthorization",ca=class ca extends I{constructor(){super(),A(this,"has_cnsub",""),A(this,"$contentBox",null),A(this,"$listRoot",null),A(this,"movies",[]),A(this,"loginDialogOpen",!1)}getName(){return"TOP250Plugin"}async initCss(){return"<style>.jhs-top250-filters>.jhs-segmented{box-sizing:border-box;max-width:100%;overflow-x:auto}.jhs-top250-filters>.jhs-segmented>.jhs-segmented__item{flex-shrink:0;white-space:nowrap}</style>"}async handle(){let e=$('.main-tabs ul li:contains("猜你喜歡")').length?$('.main-tabs ul li:contains("猜你喜歡")'):$('.main-tabs ul li:contains("猜你喜欢")');e.length&&e.html('<a href="/rankings/top"><span>Top250</span></a>'),$('a[href*="rankings/top"]').off("click.jhsTop250").on("click.jhsTop250",(t=>{t.preventDefault(),t.stopPropagation();let s=$(t.target),a=(s.is("a")?s:s.closest("a")).attr("href");if(!a)return;let i=a.includes("?")?a.split("?")[1]:a,r=new URLSearchParams(i);this.checkLogin(t,r)})),await this.handleTop()}hookPage(){let e=this.getRuntimeService("host"),t=e.getListContainer?.()??e.getListLayoutContainer?.();if(!t||!e.createOwnedListRoot)throw new Error("JavDB 列表容器不可用");this.$contentBox=$(t),this.$listRoot=$(e.createOwnedListRoot(["jhs-top250-list","jhs-layout-d2c171b1"]));let s=$("h2.section-title");s.length||(s=$("<h2></h2>").addClass("section-title").prependTo(this.$contentBox)),s.contents().first().replaceWith("Top250"),$(".empty-message").remove(),this.$contentBox.children(".box").remove(),$("#sort-toggle-btn").remove(),this.$contentBox.children(".jhs-top250-filters").remove(),this.$contentBox.children(".tool-box.jhs-layout-d2c171b1").remove(),this.$contentBox.children("nav.pagination").remove(),this.$contentBox.append('<div class="tool-box jhs-layout-d2c171b1"></div>'),e.mountOwnedListRoot(t,this.$listRoot[0])}renderPagination(){let e=new URLSearchParams(window.location.search),t=parseInt(e.get("page")||"",10)||1;this.$contentBox.append((s=>{let a=s>=5,i="";for(let r=1;r<=5;r++)i+=`<li><button type="button" class="jhs-btn pagination-link ${s===r?"is-current":""}" data-page="${r}">${r}</button></li>`;return`
                <nav class="pagination">
                    <button type="button" class="jhs-btn pagination-previous ${s<=1?"do-hide":""}" data-page="${s-1}">上一页</button>
                    <button type="button" class="jhs-btn pagination-next ${a?"do-hide":""}" data-page="${s+1}">下一页</button>

                    <ul class="pagination-list">
                        ${i}
                    </ul>
                </nav>
            `})(t)),this.$contentBox.on("click",".pagination-link, .pagination-previous, .pagination-next",(s=>{s.preventDefault();let a=parseInt(String($(s.currentTarget).data("page")),10);!isNaN(a)&&a>0&&(i=>{e.set("page",String(i)),window.history.pushState({},"","?"+e.toString()),window.location.reload()})(a)}))}async handleTop(){if(!window.location.href.includes("handleTop=1"))return;let e=this.getOptionalDependency("HitShowPlugin");if(!e)return void show.info("热播列表功能已禁用");let t=new URLSearchParams(window.location.search),s=t.get("handleType")||"all",a=t.get("type_value")||"";this.has_cnsub=t.get("has_cnsub")||"";let i=Number(t.get("page"))||1;this.hookPage(),this.toolBar(s,a),this.renderPagination(),await this.getOptionalDependency("ListPageButtonPlugin")?.mountOwnedRankingControls?.($(".jhs-top250-filters"))?.catch?.(c=>clog.error("Top250 操作按钮挂载失败",c));let r=this.$listRoot;r.html("");let n=loading(),l=!1;for(let c=1;c<=3&&!l;c++)try{let h=await vc(s,a,i,50),u=h.success,p=h.action;if(u===1){let g=h.data.movies;if(g.length===0)return show.error("无数据"),void n.close();this.movies=g;let m=g.filter((v=>this.has_cnsub==="1"?v.has_cnsub:this.has_cnsub!=="0"||!v.has_cnsub)),f=e.markDataListHtml(m,{thumbnailFirst:!0});r.html(f),await e.initializeRenderedList(),await e.loadScore(m),l=!0}else{if(clog.error(h),r.html(`<h3>${C(h.message)}</h3>`),show.error(h.message),p==="JWTVerificationError"){let g=this.getRuntimeService("credential");try{g?.remove&&await g.remove(Wr)}catch(m){clog.warn("删除失效 JavDB Token 失败,仍继续打开登录框",m)}this.openLoginDialog({onSuccess:d(()=>this.handleTop(),"onSuccess")})}l=!0}}catch(h){c<3?(clog.error(`获取Top数据失败 (第 ${c} 次重试):`,h),await new Promise((u=>setTimeout(u,1e3)))):(clog.error("所有重试尝试均失败,无法获取Top数据。",h),r.html("<h3>无法加载数据,请稍后再试。</h3>"))}finally{(l||c===3)&&n.close()}}toolBar(e,t){let s="";for(let n=new Date().getFullYear();n>=2008;n--)s+=`<a class="jhs-segmented__item jhs-layout-186f17ef ${t===String(n)?"active":""}" aria-current="${t===String(n)?"page":"false"}" href="/advanced_search?handleTop=1&handleType=year&type_value=${n}&has_cnsub=${this.has_cnsub}">${n}</a>`;let a=d((n,l,c="video_type")=>`<a class="jhs-segmented__item jhs-layout-186f17ef ${n===(n==="all"?e:t)?"active":""}" aria-current="${n===(n==="all"?e:t)?"page":"false"}" href="/advanced_search?handleTop=1&handleType=${c}&type_value=${n==="all"?"":n}&has_cnsub=${this.has_cnsub}">${l}</a>`,"typeLink"),i=`<div class="jhs-top250-filters"><nav class="jhs-segmented jhs-layout-701bf0f9" aria-label="类型条件">${a("all","全部","all")}${a("0","有码")}${a("1","无码")}${a("2","欧美")}${a("3","Fc2")}<button type="button" class="jhs-btn jhs-btn--secondary jhs-btn--sm jhs-layout-2335597e ${this.has_cnsub==="1"?"active":""}" aria-pressed="${this.has_cnsub==="1"}" data-cnsub-value="1">含中字磁力</button><button type="button" class="jhs-btn jhs-btn--secondary jhs-btn--sm jhs-layout-186f17ef ${this.has_cnsub==="0"?"active":""}" aria-pressed="${this.has_cnsub==="0"}" data-cnsub-value="0">无字幕</button><button type="button" class="jhs-btn jhs-btn--secondary jhs-btn--sm jhs-layout-186f17ef" aria-pressed="false" data-cnsub-value="">重置</button></nav><nav class="jhs-segmented" aria-label="年份条件">${s}</nav></div>`,r=this.$contentBox.children("h2.section-title").first();r.length?r.after(i):this.$contentBox.prepend(i),$("button[data-cnsub-value]").on("click",(n=>{let l=String($(n.currentTarget).data("cnsub-value")),c=new URLSearchParams(window.location.search);c.set("handleTop","1"),c.set("handleType",e),c.set("type_value",t),c.set("has_cnsub",l),c.delete("page"),window.location.href=`/advanced_search?${c.toString()}`}))}async checkLogin(e,t){let s=this.getRuntimeService("credential");if(!s?.get||!await s.get(Wr))return show.error("该类别依赖移动端接口,请先完成登录"),void this.openLoginDialog();let a="all",i="",r=t.get("t")||"";/^y\d+$/.test(r)?(a="year",i=r.substring(1)):r!==""&&(a="video_type",i=r);let n=`/advanced_search?handleTop=1&handleType=${a}&type_value=${i}`;e&&(e.ctrlKey||e.metaKey)?GM_openInTab(window.location.origin+n,{insert:0}):window.location.href=n}openLoginDialog({onSuccess:e=null}={}){if(this.loginDialogOpen)return null;this.loginDialogOpen=!0;let t=this.getRuntimeService("dialog"),s=this.getRuntimeService("account"),a=this.getRuntimeService("scope");try{return t.open({type:1,title:"JavDB",closeBtn:1,area:utils.getResponsiveArea(["360px","auto"]),shadeClose:!1,content:`
                <style>#loginBtn:hover{background:var(--jhs-accent-hover)}</style>
                <div class="jhs-layout-e32cff7f">
                    <div class="jhs-layout-598afa5a">
                        <input type="text" id="username" name="username"

                            placeholder="用户名 | 邮箱"
                            onfocus="this.style.borderColor='var(--jhs-accent)'; this.style.background='var(--jhs-surface)'"
                            onblur="this.style.borderColor='var(--jhs-border-strong)'; this.style.background='var(--jhs-surface-2)'" class="jhs-field">
                    </div>

                    <div class="jhs-layout-da303dcf">
                        <input type="password" id="password" name="password"

                            placeholder="密码"
                            onfocus="this.style.borderColor='var(--jhs-accent)'; this.style.background='var(--jhs-surface)'"
                            onblur="this.style.borderColor='var(--jhs-border-strong)'; this.style.background='var(--jhs-surface-2)'" class="jhs-field">
                    </div>

                    <button id="loginBtn"

                             class="jhs-btn jhs-layout-c4eb15bf">
                        登录
                    </button>
                </div>
            `,success:d((i,r)=>{$("#loginBtn").click((async()=>{let n=$("#username").val(),l=$("#password").val();if(!n||!l)return void show.error("请输入用户名和密码");let c=loading();s.login("javdb",{username:n,password:l},{scope:await a()}).then((async h=>{if(!h.success)show.error(h.message);else{let u=this.getRuntimeService("credential");if(!u?.set)throw new Error("凭证服务不可用");await u.set(Wr,h.token),show.ok("登录成功"),t.close(r),typeof e=="function"?await e():window.location.href="/advanced_search?handleTop=1&period=daily"}})).catch((h=>{clog.error("登录异常:",h),show.error(h instanceof Error?h.message:String(h))})).finally((()=>{c.close()}))}))},"success"),end:d(()=>{this.loginDialogOpen=!1},"end")})}catch(i){throw this.loginDialogOpen=!1,i}}};d(ca,"Top250Plugin"),lt(ca,"legacyPluginId","TOP250Plugin");var la=ca;var Jr=class Jr extends I{getName(){return"FavoriteActressesPlugin"}getStartupMode(){return"idle"}bindImmediateEvents(){this.bindEvent()}async handle(){await this.highlightActress(),this.replaceActressAvatar()}async highlightActress(){if(!isDetailPage||await storageManager.getSetting("enableFavoriteActresses",R)!==R)return;let e=await storageManager.getFavoriteActressList();if(!e||e.length===0)return;let t=new Set;e.forEach((s=>{s.starId&&t.add(String(s.starId).trim())})),t.size!==0&&$(".female").prev().each(((s,a)=>{let i=$(a),r=i.attr("href"),n=null;if(r){let c=(r.endsWith("/")?r.slice(0,-1):r).split("/"),h=c[c.length-1];h&&(n=h.trim())}let l=!1;n&&(l=t.has(n)),l&&(i.addClass("highlighted"),i.attr("title","高亮已收藏演员, 可在设置-基础配置中关闭"))}))}async removeActorFromStorage(e){await storageManager.removeFavoriteActress(e)&&(clog.log("移除演员成功"),document.dispatchEvent(new CustomEvent("actress-state-changed",{detail:{starId:String(e)}})))}bindEvent(){let e=/\/actors\/(\w+)\/(collect|uncollect)/;$(document).on("confirm:complete",'a[href*="/actors/"][href*="/uncollect"]',(async t=>{let[s]=t.detail;if(!s)return;let a=$(t.currentTarget).attr("href").match(e),i=a?a[1]:null;i&&await this.removeActorFromStorage(i)})),$("#button-collect-actor").click((async t=>{let s=$("#button-collect-actor").attr("href").match(e),a=s?s[1]:null,i=[],r=$(".actor-section-name");r.length&&r.text().trim().split(",").forEach((u=>{i.push(u.trim())}));let n=$(".section-meta:not(:contains('影片'))");if(n.length&&n.text().trim().split(",").forEach((u=>{i.push(u.trim())})),!i.length)return void clog.error("获取演员名称失败");let l=i[0];if(!a)return void clog.error("无法获取演员ID进行收藏操作。");let c=($(".avatar").first().css("background-image")||"").replace(/^url\(["']?|["']?\)$/g,""),h={starId:a,name:l,allName:i,avatar:c};await storageManager.addFavoriteActressList([h])===1?(clog.log(`收藏演员成功: ${l} (ID: ${a})`),document.dispatchEvent(new CustomEvent("actress-state-changed",{detail:{starId:String(a)}}))):clog.log(`收藏演员失败: ${l} (ID: ${a})`)})),$("#button-uncollect-actor").click((async t=>{let s=$("#button-uncollect-actor").attr("href").match(e),a=s?s[1]:null;a?await this.removeActorFromStorage(a):clog.error("无法获取演员ID进行取消收藏操作。")}))}async replaceActressAvatar(){let e=this.getActressId();if(!e)return;let t=(await storageManager.getFavoriteActressList()).find((s=>s.starId===e));if(t&&t.avatar){let s=`url('${t.avatar}')`,a=$(".avatar").first();if(a.length===0&&($(".section-columns").prepend('<div class="column actor-avatar"> <div class="image"> <span class="avatar"></span> </div> </div>'),a=$(".avatar").first()),a.length===0)return;a.css("background-image").trim().toLowerCase()!==s.trim().toLowerCase()&&(a.css("background-image",s),a.css("background-size","cover"),a.css("background-position","top center"),a.css("background-repeat","no-repeat"))}}};d(Jr,"FavoriteActressesPlugin");var da=Jr;var Kr=class Kr extends I{getName(){return"BusImgPlugin"}handle(){}async getVisibleImageItems(e,t){let s=[],a=document.querySelectorAll(e);for(let i of a)if(!utils.isHidden(i)){let r=i.querySelector(t);if(!(r instanceof HTMLImageElement))continue;r.style.removeProperty("height");let n=r.offsetHeight;n>0&&s.push({element:i,imgElement:r,height:n})}return s}async logImageHeightsByRow(e={}){let t=e.vertical??e.enableVerticalModel??await storageManager.getSetting("enableVerticalModel",ne),s=e.columns??e.containerColumns??await storageManager.getSetting("containerColumns",5);if(t===R)return;let a=this.getSelector().itemSelector,i=Number(s)||5,r=await this.getVisibleImageItems(a,"img");if(r.length===0)return;let n=[];for(let l=0;l<r.length;l++){let c=Math.floor(l/i);n[c]||(n[c]=[]),n[c].push(r[l])}n.forEach(((l,c)=>{let h=l.map((m=>m.height));if(h.length<2)return;let u=Math.min(...h),p=Math.max(...h),g=0;p-u>50&&(g=u,l.forEach((m=>{if(m.height!==g){let f=`${g}px`;m.imgElement.style.setProperty("height",f,"important")}})))}))}};d(Kr,"BusImgPlugin");var ha=Kr;var Ot=d((o,e)=>{if(!o||o.length===0)return null;let t=new Set(o);if(e&&t.has(e))return e;let s=at.map((a=>a.quality)).reverse();for(let a of s)if(t.has(a))return a;return o[0]||null},"Z"),Gr="jhs_dmm_video",Bh=30*864e5,Sc=500;function Qr(o){if(!o)return{};try{let e=JSON.parse(o);return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}d(Qr,"parseJsonMap");function Yr(o){let e=Date.now();for(let s of Object.keys(o)){let a=o[s];(!a||a.time&&e-a.time>Bh)&&delete o[s]}let t=Object.keys(o);if(t.length>Sc){t.sort(((s,a)=>(o[s].time||0)-(o[a].time||0)));for(let s of t.slice(0,t.length-Sc))delete o[s]}return o}d(Yr,"pruneDmmCache");function Ae(o){return o?.enablePreviewVideo!=="no"}d(Ae,"isPreviewEnabled");function cs(o){return o?.enableLoadPreviewVideo!=="no"}d(cs,"isDmmEnabled");function xc(o){return Ae(o)}d(xc,"canUsePreview");function zt(o){return Ae(o)&&cs(o)}d(zt,"canUseDmmPreview");function ua(o){return zt(o)}d(ua,"canUseCardPreview");var en=class en{constructor(e,t,s,a){this.carNum=e||"",this.storage=t,this.movie=s,this.scope=a,this.lastError=null}_checkCache(){let e=Yr(Qr(this.storage.getLocal(Gr)));return e[this.carNum]?(clog.debug("缓存中存在预览视频信息",e[this.carNum]),e[this.carNum]):null}_updateCache(e){let t=Yr(Qr(this.storage.getLocal(Gr)));t[this.carNum]={...e,time:Date.now()},clog.debug("成功解析出预览视频并已缓存:",e),this.storage.setLocal(Gr,JSON.stringify(t))}async _fetchRemote(){let e=await this.movie.preview("dmm",{carNum:this.carNum},{scope:this.scope}),t=$("#fanzaBtn");if(!e.sources)return clog.warn("所有关键词尝试均未找到匹配的Content ID, 解析Dmm视频失败"),t.attr("href",e.searchUrl).attr("title","未查询到, 点击前往搜索页").css("backgroundColor","var(--jhs-status-filter)"),null;t.attr("href",e.pageUrl).css("backgroundColor","var(--jhs-status-down)"),e.matchType==="multiple"&&t.append('<span class="site-tag jhs-layout-294497f1">多结果</span>');let s="jhs_other_site_dmm",a=Yr(Qr(this.storage.getLocal(s)));return a[this.carNum]={type:e.matchType,url:e.pageUrl,time:Date.now()},this.storage.setLocal(s,JSON.stringify(a)),e.sources}async fetchVideo(){let e=T(this.carNum);if(!e)return clog.warn("跳过 DMM 解析:番号不可用"),null;this.carNum=e;let t=this._checkCache();if(t)return t;try{let s=this.carNum.toLowerCase();if(s.startsWith("heyzo")||/^(n\d+|\d+(-\d+)*)$/.test(s)||/^n\d+$/.test(s))return clog.debug("无码番号类型,取消 DMM 解析"),null;if(this.carNum.includes("VR-"))return clog.debug("VR 类型,取消 DMM 解析"),null;let a=await this._fetchRemote();return a?(this._updateCache(a),a):null}catch(s){let a=s;this.lastError=s instanceof we?s:new we("dmm",a?.code||"PARSE_ERROR",a?.message||String(s),{cause:s,retryable:a?.retryable===!0}),clog.error("DMM API 搜索失败:",this.lastError);let i=$("#fanzaBtn");return i.attr("href",this.movie.searchUrl("dmm",{carNum:this.carNum})),i.attr("title","未查询到, 点击前往搜索页"),i.css("backgroundColor","var(--jhs-status-filter)"),null}}};d(en,"DmmPreviewParser");var Zr=en;async function Xr(o,e,t,s){let a=new Zr(o,e,t,s);return{sources:await a.fetchVideo(),error:a.lastError}}d(Xr,"fetchDmmPreview");async function pa(o,e,t,s,a){return cs(a)?Xr(o,e,t,s):{sources:null,error:null}}d(pa,"fetchDmmPreviewIfEnabled");var tn=class tn extends I{constructor(){super(...arguments),this._busPreviewGeneration=0}getName(){return"BusPreviewVideoPlugin"}async initCss(){return`
            .bus-preview-modal { position:fixed; inset:0; z-index:var(--jhs-z-modal); display:flex; align-items:center; justify-content:center; visibility:hidden; opacity:0; background:rgba(0,0,0,.95); transition:opacity var(--jhs-motion-base) var(--jhs-ease); }
            .bus-preview-modal.is-open { visibility:visible; opacity:1; }
            .bus-preview-modal-content { position:relative; display:flex; max-width:95%; max-height:95%; flex-direction:column; align-items:center; gap:var(--jhs-space-3); }
            .video-player-wrapper { position:relative; width:80vw; max-width:100%; max-height:85vh; aspect-ratio:16/9; background:#000; }
            .video-player-wrapper #preview-video { position:absolute; inset:0; }
        `}initModal(e){if($("#bus-preview-modal").length===0){$("body").append(`
                <div id="bus-preview-modal" class="bus-preview-modal">
                    <div class="bus-preview-modal-content">
                        </div>
                </div>
            `);let t=$("#bus-preview-modal");t.on("click",(s=>{s.target instanceof Element&&s.target.id==="bus-preview-modal"&&this.closeVideoModal()})),e.listen(document,"keydown",(s=>{s instanceof KeyboardEvent&&s.key==="Escape"&&t.hasClass("is-open")&&this.closeVideoModal()})),e.addCleanup((()=>{t.off(),t.remove()}))}}closeVideoModal(){let e=$("#preview-video");e.length>0&&e[0].pause(),$("#bus-preview-modal").removeClass("is-open")}unmountPreview(){this._busPreviewMounted=!1,this.closeVideoModal(),$("#bus-preview-modal").remove(),$(".preview-video-container").off("click.jhsBusPreview").remove()}async handle(){if(!isDetailPage)return;let e=this.getRuntimeService("settings");if(this._busScope||(this._busScope=await this.getRuntimeService("scope")()),!this._settingsListenerBound){this._settingsListenerBound=!0;let t=d(s=>{s.detail?.names?.some(i=>i==="enablePreviewVideo"||i==="enableLoadPreviewVideo")&&this.reconfigure()},"onSettingsChanged");e.addEventListener("settings.changed",t),this._busScope.addCleanup((()=>{e.removeEventListener("settings.changed",t),this._settingsListenerBound=!1}))}this.reconfigure()}reconfigure(){this._busPreviewGeneration++;let e=this.getRuntimeService("settings").snapshot();if(!zt(e))return void this.unmountPreview();this.mountPreview()}mountPreview(){if(this._busPreviewMounted)return;this._busPreviewMounted=!0;let e=this._busScope;this.initModal(e);let t=$("#sample-waterfall .sample-box .photo-frame img:first").attr("src"),s=$(`
            <button type="button" class="jhs-btn preview-video-container sample-box jhs-layout-3b6a3a65">
                <div class="photo-frame jhs-layout-87db2275">
                    <img src="${t}" class="video-cover" alt="">
                    <div class="play-icon jhs-play-overlay">
                        ▶
                    </div>
                </div>
            </button>`);$("#sample-waterfall").prepend(s);let a=!1,i=$(".preview-video-container");i.on("click",(async r=>{if(r.preventDefault(),r.stopPropagation(),a)show.info("正在加载中, 勿重复点击");else{a=!0;try{await this.handleVideo()}finally{a=!1}}})),window.location.href.includes("autoPlay=1")&&i.trigger("click")}async handleVideo(){let e=this._busPreviewGeneration,t=$("#bus-preview-modal"),s=t.find(".bus-preview-modal-content"),a=$("#preview-video");if(e!==this._busPreviewGeneration||!Ae(this.getRuntimeService("settings").snapshot()))return;if(a.length>0)return t.addClass("is-open"),void await de(a[0],{context:"JavBus 预览视频",notify:!0});let i=this.getPageInfo().carNum,r=await this.getRuntimeService("scope")(),{sources:n,error:l}=await pa(i,this.getRuntimeService("storage"),this.getRuntimeService("movie"),r,this.getRuntimeService("settings").snapshot());e!==this._busPreviewGeneration||!Ae(this.getRuntimeService("settings").snapshot())||(n&&Object.keys(n).length!==0?(await this.createVideoPlayerAndControls(n,s),a=$("#preview-video"),a.length>0?(t.addClass("is-open"),await de(a[0],{context:"JavBus 预览视频",notify:!0,message:l?.code==="REGION_BLOCKED"?l.message:"当前视频源无法播放"})):show.error("视频播放器创建失败。")):show.error(l?.code==="REGION_BLOCKED"?l.message:"未找到可用的视频源。"))}async createVideoPlayerAndControls(e,t){let s=this.getRuntimeService("settings").snapshot().videoQuality;s=Ot(Object.keys(e),s);let a=e[s],i=$('<div class="video-player-wrapper"></div>'),r=$('<video id="preview-video" class="jhs-video-player" controls playsinline></video>'),n=$(document.createElement("source")).attr("src",a),l=$('<div class="jhs-video-toolbar jhs-video-quality-list" role="group" aria-label="视频画质"></div>');r.append(n),i.append(r),t.empty().append(i,l);let c=$("#preview-video"),h=c.find("source"),u=t.find(".jhs-video-quality-list");if(!c.length||!h.length)return;let p=this.getRuntimeService("settings"),g=c[0],m=p.snapshot().videoMuted;g.muted=m==null||m===!0,c.off("volumechange.jhsVideo").on("volumechange.jhsVideo",(()=>{p.set("videoMuted",g.muted).catch((v=>clog.error("保存视频静音设置失败",v)))})),at.forEach((v=>{let b=e[v.quality];if(b){let w=s===v.quality,S=$('<button type="button" class="jhs-btn jhs-video-quality-btn"></button>');w&&S.addClass("active"),S.attr({"data-quality":v.quality,"data-video-src":b,"aria-pressed":w?"true":"false"}).text(v.text),u.append(S)}}));let f=u.find(".jhs-video-quality-btn");u.off("click.jhsVideo").on("click.jhsVideo",".jhs-video-quality-btn",(async v=>{try{let b=$(v.currentTarget);if(b.hasClass("active"))return;let w=b.attr("data-video-src");h.attr("src",w);let S=g.currentTime;g.load(),g.currentTime=S,await de(g,{context:"JavBus 画质切换",notify:!0})&&(f.removeClass("active").attr("aria-pressed","false"),b.addClass("active").attr("aria-pressed","true"))}catch(b){clog.error("切换画质失败:",b)}}))}};d(tn,"BusPreviewVideoPlugin");var ga=tn;var sn=class sn extends I{constructor(){super(...arguments),this.previewGeneration=0}getName(){return"CoverButtonPlugin"}async initCss(){return`
            <style>
                .box .tags { justify-content:space-between; }
                .jhs-cover-tools { display:flex; align-items:center; justify-content:flex-end; gap:var(--jhs-space-2); margin-left:auto; }
                .jhs-cover-tools svg path { fill:var(--jhs-icon-color); }
                .jhs-cover-tools .screenSvg, .jhs-cover-tools .videoSvg { opacity:.65; }
                .jhs-cover-tools .screenSvg:hover, .jhs-cover-tools .videoSvg:hover { opacity:1; }
                ${B?".jhs-cover-tools .icon, .setting-label .icon{height:24px;width:24px}":""}
                .more-tools-container { position:relative; }
                .jhs-card-menu { top:auto; right:0; bottom:calc(100% + var(--jhs-space-2)); width:152px; }
                .jhs-card-menu .jhs-btn, .jhs-card-menu .site-btn { width:100%; min-height:var(--jhs-control-height); justify-content:flex-start; margin:0; }
                .jhs-card-menu__dot { width:8px; height:8px; flex:none; border-radius:50%; background:var(--jhs-border-strong); }
                .jhs-card-menu__dot--watch { background:var(--jhs-status-watch); }
                .jhs-card-menu__dot--down { background:var(--jhs-status-down); }
                .jhs-card-menu__dot--fav { background:var(--jhs-status-fav); }
                .jhs-card-menu__dot--filter { background:var(--jhs-status-filter); }
                .loading { opacity:.7; filter:blur(1px); }
                .loading-spinner { position:absolute; top:50%; left:50%; width:40px; height:40px; border:3px solid rgba(255,255,255,.3); border-top-color:#fff; border-radius:50%; transform:translate(-50%,-50%); animation:spin 1s ease-in-out infinite; z-index:var(--jhs-z-elevated); }
                @keyframes spin { to { transform:translate(-50%,-50%) rotate(360deg); } }
            </style>`}async handle(){if(!window.isListPage)return;let e=await this.getRuntimeService("scope")(),t=this.getRuntimeService("settings"),s=d(a=>{let i=a.detail?.names||[];i.some(r=>r==="enablePreviewVideo"||r==="enableLoadPreviewVideo")&&(this.previewGeneration++,ua(t.snapshot())?this.addSvgBtn().catch((r=>clog.error("卡片预览重新挂载失败",r))):($('[id$="_preview_video"]').each((r,n)=>{n.pause?.(),$(n).parent().remove()}),this.enableSvgBtn())),i.some(r=>["enableScreenSvg","enableVideoSvg","enableHandleSvg","enableSiteSvg","enableCopySvg"].includes(r))&&this.enableSvgBtn()},"onSettingsChanged");this._settingsListenerBound||(this._settingsListenerBound=!0,t.addEventListener("settings.changed",s),e.addCleanup((()=>{t.removeEventListener("settings.changed",s),this._settingsListenerBound=!1}))),this.addSvgBtn(),await this.bindClick(e)}buildToolBox(){return`
            <div class="tool-box jhs-cover-tools">
                <button type="button" class="jhs-btn jhs-icon-btn screenSvg" title="长缩略图" aria-label="长缩略图">${this.screenSvg}</button>
                <button type="button" class="jhs-btn jhs-icon-btn videoSvg" title="播放视频" aria-label="播放视频">${this.videoSvg}</button>
                <div class="more-tools-container handleSvg">
                    <button type="button" title="鉴定处理" aria-label="鉴定处理" aria-haspopup="menu" aria-expanded="false" class="jhs-btn jhs-icon-btn jhs-card-menu-trigger">${this.handleSvg}</button>
                    <div class="jhs-popover jhs-card-menu" role="menu">
                        <button type="button" role="menuitem" class="jhs-btn jhs-btn--ghost jhs-card-status-item hasWatchBtn"><span class="jhs-card-menu__dot jhs-card-menu__dot--watch"></span><span>${ve}</span></button>
                        <button type="button" role="menuitem" class="jhs-btn jhs-btn--ghost jhs-card-status-item hasDownBtn"><span class="jhs-card-menu__dot jhs-card-menu__dot--down"></span><span>${fe}</span></button>
                        <button type="button" role="menuitem" class="jhs-btn jhs-btn--ghost jhs-card-status-item favoriteBtn"><span class="jhs-card-menu__dot jhs-card-menu__dot--fav"></span><span>${Le}</span></button>
                        <button type="button" role="menuitem" class="jhs-btn jhs-btn--ghost jhs-card-status-item filterBtn"><span class="jhs-card-menu__dot jhs-card-menu__dot--filter"></span><span>${Ne}</span></button>
                    </div>
                </div>
                <div class="more-tools-container siteSvg">
                    <button type="button" title="第三方网站" aria-label="第三方网站" aria-haspopup="menu" aria-expanded="false" class="jhs-btn jhs-icon-btn jhs-card-menu-trigger">${this.siteSvg}</button>
                    <div class="jhs-popover jhs-card-menu" role="menu">
                        <a role="menuitem" class="site-btn site-jable"><span>Jable</span></a>
                        <a role="menuitem" class="site-btn site-avgle"><span>Avgle</span></a>
                        <a role="menuitem" class="site-btn site-miss-av"><span>MissAv</span></a>
                        <a role="menuitem" class="site-btn site-123-av"><span>123Av</span></a>
                    </div>
                </div>
                <div class="more-tools-container copySvg">
                    <button type="button" title="复制" aria-label="复制" aria-haspopup="menu" aria-expanded="false" class="jhs-btn jhs-icon-btn jhs-card-menu-trigger">${this.copySvg}</button>
                    <div class="jhs-popover jhs-card-menu" role="menu">
                        <button type="button" role="menuitem" class="jhs-btn jhs-btn--ghost carNumSvg">${this.carNumSvg}<span>复制番号</span></button>
                        <button type="button" role="menuitem" class="jhs-btn jhs-btn--ghost titleSvg">${this.titleSvg}<span>复制标题</span></button>
                        <button type="button" role="menuitem" class="jhs-btn jhs-btn--ghost downSvg">${this.downSvg}<span>下载封面</span></button>
                    </div>
                </div>
            </div>`}async addSvgBtn(e=null){this.getOptionalDependency("ListPagePlugin")&&((e?$(e).toArray():$(this.getSelector().itemSelector).toArray()).forEach((t=>{let s=$(t);if(s.find(".tool-box").length||B&&s.find(".avatar-box").length)return;let a=N?s.find(".tags").first():s.find(".photo-info").first();a.length&&a.append(this.buildToolBox())})),this.enableSvgBtn(e))}async enableSvgBtn(e=null){let t=this.getRuntimeService("settings").snapshot(),{enableScreenSvg:s=R,enableVideoSvg:a=R,enablePreviewVideo:i=R,enableHandleSvg:r=R,enableSiteSvg:n=R,enableCopySvg:l=R}=t,c=e?$(e):$(document);[{selector:".screenSvg",enabled:s===R&&this.getOptionalDependency("ScreenShotPlugin")?R:"no"},{selector:".videoSvg",enabled:a===R&&ua(t)?R:"no"},{selector:".handleSvg",enabled:r},{selector:".siteSvg",enabled:n},{selector:".copySvg",enabled:l}].forEach((({selector:h,enabled:u})=>{c.find(h).toggle(u===R)}))}closeCardMenus(e=!1){let t=$(".jhs-card-menu.is-open"),s=t.siblings(".jhs-card-menu-trigger");t.removeClass("is-open"),s.attr("aria-expanded","false"),e&&s.first().trigger("focus")}async bindClick(e){this.getSelector();let t=this.getOptionalDependency("ListPagePlugin");if(!t)return;let s=$(document);s.off(".jhsCoverButton"),e.addCleanup((()=>s.off(".jhsCoverButton"))),s.on("click.jhsCoverButton",".jhs-card-menu-trigger",(h=>{h.preventDefault(),h.stopPropagation();let u=$(h.currentTarget),p=u.siblings(".jhs-card-menu"),g=!p.hasClass("is-open");this.closeCardMenus(),p.toggleClass("is-open",g),u.attr("aria-expanded",String(g)),g&&p.children().first().trigger("focus")})).on("keydown.jhsCoverButton",".jhs-card-menu [role='menuitem']",(h=>{let u=$(h.currentTarget).closest(".jhs-card-menu"),p=u.find("[role='menuitem']"),g=p.index(h.currentTarget);if(h.key==="Escape")return h.preventDefault(),this.closeCardMenus(!0);if(!["ArrowDown","ArrowUp","Home","End"].includes(h.key))return;h.preventDefault();let m=h.key==="Home"?0:h.key==="End"?p.length-1:h.key==="ArrowDown"?(g+1)%p.length:(g-1+p.length)%p.length;p.eq(m).trigger("focus")})).on("click.jhsCoverButton",(h=>{$(h.target).closest(".more-tools-container").length||this.closeCardMenus()})),s.on("click.jhsCoverButton",".videoSvg",(h=>{h.preventDefault(),$('.videoSvg[title!="播放视频"]').each(((g,m)=>{let f=$(m),v=f.closest(".item"),b=v.find("img"),{carNum:w}=t.findCarNumAndHref(v);this.showImg(f,b,w),f.html(this.videoSvg).attr({title:"播放视频","aria-label":"播放视频"})}));let u=$(h.target).closest(".item"),p=u.find(".videoSvg");if(p.attr("title")==="播放视频"){p.html(this.recoveryVideoSvg).attr({title:"切回封面","aria-label":"切回封面"});let{carNum:g}=t.findCarNumAndHref(u),m=u.find("img");if(!m.length)return void show.error("没有找到图片");this.showVideo(p,m,g).catch((f=>clog.error("卡片预览视频打开失败",f)))}})),s.on("click.jhsCoverButton",".screenSvg",(async h=>{h.preventDefault();let u=loading();try{let p=$(h.currentTarget).closest(".item"),{carNum:g}=t.findCarNumAndHref(p);g=g.replace("FC2-","");let m=this.getOptionalDependency("ScreenShotPlugin");if(!m)throw new Error("剧照功能已禁用");let f=await m.getScreenshot(g,{allowWhenDisabled:!0});u.close(),globalThis.showImageViewer(f)}catch(p){clog.error("图片预览出错:",p),show.error("图片预览出错:"+p)}finally{u.close()}})),s.on("click.jhsCoverButton",".filterBtn, .favoriteBtn, .hasDownBtn, .hasWatchBtn",(h=>{h.preventDefault(),h.stopPropagation();try{let u=$(h.currentTarget),p=u.closest(".item"),{carNum:g,url:m,publishTime:f,fc2Source:v}=t.findCarNumAndHref(p),b=d(async w=>{try{let S=await t.parseActressName(m),j=ke(w);if(!j)throw new Error("不支持的状态操作");await this.getRuntimeService("state").patch(g,{[j]:!0},{type:"list-card-state",record:{carNum:g,url:m,names:S,publishTime:f,fc2Source:v}}),show.ok("操作成功")}catch(S){clog.error("保存操作失败:",S),show.error("操作失败")}},"r");u.hasClass("filterBtn")?utils.q(h,`是否屏蔽${C(g)}?`,(()=>b(ce))):u.hasClass("favoriteBtn")?b(ue):u.hasClass("hasDownBtn")?b(pe):u.hasClass("hasWatchBtn")&&b(me),this.closeCardMenus()}catch(u){clog.error("按钮点击处理失败:",u)}}));let a=this.getRuntimeService("settings").snapshot(),i=this.getRuntimeService("movie"),r=i.externalSiteOrigin("missAvBtn",a),n=i.externalSiteOrigin("jableBtn",a),l=i.externalSiteOrigin("avgleBtn",a),c=i.providerOrigin("av123")||"";$(this.getSelector().itemSelector).each(((h,u)=>{let p=$(u),{carNum:g}=t.findCarNumAndHref(p);p.find(".site-jable").attr({href:`${n}/search/${g}/`,target:"_blank",rel:"noopener noreferrer"}),p.find(".site-avgle").attr({href:`${l}/vod/search.html?wd=${g}`,target:"_blank",rel:"noopener noreferrer"}),p.find(".site-miss-av").attr({href:`${r}/search/${g}`,target:"_blank",rel:"noopener noreferrer"}),p.find(".site-123-av").attr({href:`${c}/cn/search?keyword=${encodeURIComponent(g)}`,target:"_blank",rel:"noopener noreferrer"})})),s.on("click.jhsCoverButton",".site-jable, .site-avgle, .site-miss-av, .site-123-av",(h=>{try{h.preventDefault(),h.stopPropagation();let u=$(h.currentTarget),p=u.closest(".item"),{carNum:g}=t.findCarNumAndHref(p),m=null;if(u.hasClass("site-jable")?m=`${n}/search/${g}/`:u.hasClass("site-avgle")?m=`${l}/vod/search.html?wd=${g}`:u.hasClass("site-miss-av")?m=`${r}/search/${g}`:u.hasClass("site-123-av")&&(m=`${c}/cn/search?keyword=${encodeURIComponent(g)}`),!m)return;h.ctrlKey||h.metaKey?GM_openInTab(m,{insert:0}):window.open(m),this.closeCardMenus()}catch(u){clog.error("站点按钮处理失败:",u)}})),s.on("click.jhsCoverButton",".titleSvg, .carNumSvg, .downSvg",(h=>{h.preventDefault(),h.stopPropagation();let u=$(h.currentTarget).closest(".item"),{carNum:p,title:g}=t.findCarNumAndHref(u),m=u.find(B?".photo-frame img":".cover img");$(h.currentTarget).hasClass("titleSvg")?utils.copyToClipboard("标题",g):$(h.currentTarget).hasClass("carNumSvg")?utils.copyToClipboard("番号",p):$(h.currentTarget).hasClass("downSvg")&&fetch(m.attr("src")).then((f=>f.blob())).then((f=>utils.download(f,p+" "+g+".jpg"))),this.closeCardMenus()}))}showImg(e,t,s){e.html(this.videoSvg).attr({title:"播放视频","aria-label":"播放视频"});let a=$(`#${`${s}_preview_video`}`);a.length>0&&(a[0].pause(),a.parent().hide()),t.show(),t.removeClass("loading"),t.next(".loading-spinner").remove()}async showVideo(e,t,s){let a=this.getRuntimeService("settings").snapshot();if(!ua(a))return show.error("预览视频已关闭");let i=this.previewGeneration,r=`${s}_preview_video`,n=$(`#${r}`);if(n.length>0)return n.parent().show(),await de(n[0],{context:"列表卡片预览",notify:!0}),void t.hide();t.addClass("loading"),t.after('<div class="loading-spinner"></div>');let l=t.attr("data-full")||t.attr("src"),c=await this.getRuntimeService("scope")(),{sources:h,error:u}=await pa(s,this.getRuntimeService("storage"),this.getRuntimeService("movie"),c,a);if(i!==this.previewGeneration||!Ae(this.getRuntimeService("settings").snapshot()))return void this.showImg(e,t,s);if(!h)return show.error(u?.code==="REGION_BLOCKED"?u.message:"未解析到视频"),void this.showImg(e,t,s);let p=this.getRuntimeService("settings").snapshot().videoQuality;p=Ot(Object.keys(h),p);let g=h[p],m=document.createElement("div"),f=document.createElement("video");B||(m.className="jhs-layout-d543acf8"),f.src=g,f.poster=l||"",f.id=r,f.controls=!0,f.loop=!0,f.muted=!0,f.playsInline=!0,f.className="jhs-layout-a38a0e50",m.appendChild(f),t.parent().append(m),t.hide(),t.removeClass("loading"),t.next(".loading-spinner").remove(),n=$(f);let v=n[0];v.load(),v.muted=!1,await de(v,{context:"列表卡片预览",notify:!0,message:u?.code==="REGION_BLOCKED"?u.message:"当前视频源无法播放"}),n.trigger("focus")}};d(sn,"CoverButtonPlugin");var ma=sn;var an=class an extends I{constructor(){super(...arguments),this.previewGeneration=0,this.previewSession=null}getName(){return"PreviewVideoPlugin"}async initCss(){return".jhs-dmm-preview-player{display:none;width:100%;height:auto}.jhs-dmm-preview-player.is-active{display:block}.jhs-native-preview-hidden{display:none!important}"}async handle(){if(!isDetailPage)return;let e=this.getRuntimeService("settings");if(this.lifecycleScope||(this.lifecycleScope=await this.getRuntimeService("scope")()),!this._settingsListenerBound){this._settingsListenerBound=!0;let t=d(s=>{s.detail?.names?.some(i=>i==="enablePreviewVideo"||i==="enableLoadPreviewVideo")&&this.reconfigure()},"onSettingsChanged");e.addEventListener("settings.changed",t),this.lifecycleScope.addCleanup((()=>{e.removeEventListener("settings.changed",t),this._settingsListenerBound=!1,this.unmountPreview()}))}this.reconfigure()}reconfigure(){this.previewGeneration++;let e=this.getRuntimeService("settings").snapshot();if(!xc(e))return void this.unmountPreview();this.mountPreview(),zt(e)?this.initDmm(this.lifecycleScope).catch((t=>clog.error("预加载 DMM 失败",t))):(this.unmountDmmPlayer(),$(".fancybox-content #preview-video").length&&!$("#video-bottom-toolbar").length&&this.handleVideo().catch(t=>clog.error("恢复原生预览操作失败",t)))}mountPreview(){if(this._previewMounted)return;this._previewMounted=!0,$(".preview-video-container").removeClass("jhs-native-preview-hidden");let e=$(".preview-video-container"),t=d(()=>{this.cancelOpenWait?.(),this.cancelOpenWait=utils.loopDetector((()=>$(".fancybox-content #preview-video").length>0),(()=>{this.handleVideo().catch((a=>clog.error("预览视频处理失败",a)))}),20,1e4,!0,this.lifecycleScope)},"openVideo");e.off("click.jhsVideo").on("click.jhsVideo",t),this.lifecycleScope.addCleanup((()=>e.off("click.jhsVideo",t)));let s=window.location.href;(s.includes("gallery-1")||s.includes("gallery-2"))&&t(),s.includes("autoPlay=1")&&e.length>0&&e[0].click()}unmountDmmPlayer(){this.dmmRequestScope?.dispose(),$("[data-jhs-dmm-trigger]").remove();let e=$("#jhs-preview-video"),t=e[0],s=this.previewSession?.native;s&&t&&this.isSessionOpen(this.previewSession)&&(this.seekVideo(s,t.currentTime),!t.paused&&Ae(this.getRuntimeService("settings").snapshot())?de(s,{context:"恢复原生预览",notify:!1}).then(()=>{this.previewSession?.native!==s&&s.pause()}):s.pause()),t&&(t.pause(),e.removeAttr("src"),t.load(),e.remove()),$("#video-bottom-toolbar .jhs-video-quality-list").empty(),$("#preview-video").removeClass("jhs-native-preview-hidden"),this.dmmPreviewPromise=null,this.previewSession&&!s&&this.disposePreviewSession()}unmountPreview(){this._previewMounted=!1,this.cancelOpenWait?.(),this.disposePreviewSession(),this.unmountDmmPlayer(),$("#video-bottom-toolbar").remove(),$(".preview-video-container").addClass("jhs-native-preview-hidden")}unmountJhsPreview(){this.disposePreviewSession(),$("[data-jhs-dmm-trigger]").remove();let e=$("#jhs-preview-video"),t=e[0];t&&(t.pause(),e.removeAttr("src"),t.load(),e.remove()),$("#video-bottom-toolbar").remove(),$("#preview-video").removeClass("jhs-native-preview-hidden"),$(".preview-video-container").addClass("jhs-native-preview-hidden")}async initDmm(e){let t=this.previewGeneration,s=this.getRuntimeService("settings");try{let{sources:a}=await this.getDmmPreview(e);if(t!==this.previewGeneration||e?.disposed||!Ae(s.snapshot())||!cs(s.snapshot())||!a)return;if($(".fancybox-content #preview-video").length){await this.handleVideo();return}if($("#preview-video")[0])return;clog.debug("JavDB没有视频播放元素, 开始创建...");let n=$(".column-video-cover img").attr("src");if($("[data-jhs-dmm-trigger]").length)return;let l=$('<button type="button" class="jhs-btn preview-video-container" data-jhs-dmm-trigger="true"><span>预告片</span></button>');l.append($('<img class="video-cover jhs-layout-8cf76fd7" alt="">').attr("src",n||"")),$(".preview-images").first().prepend(l),l.on("click.jhsVideo",()=>this.openDmmDialog())}catch(a){clog.error("预加载 DMM 失败:",a)}}getDmmPreview(e=this.lifecycleScope){if(this.dmmPreviewPromise)return this.dmmPreviewPromise;let t=new te("javdb-dmm-request");this.dmmRequestScope=t;let s,a=Promise.resolve(e||this.getRuntimeService("scope")()).then(i=>{if(i?.disposed||t.disposed)throw new Error("预览请求已取消");return s=i?.addCleanup?.(()=>t.dispose()),Xr(this.getPageInfo().carNum,this.getRuntimeService("storage"),this.getRuntimeService("movie"),t)}).then((i=>(this.dmmPreviewPromise===a&&(i.error?.retryable||i.error?.code==="HTTP_ERROR")&&(this.dmmPreviewPromise=null),i)),(i=>{throw this.dmmPreviewPromise===a&&(this.dmmPreviewPromise=null),i})).finally(()=>{t.dispose(),typeof s=="function"&&s()});return this.dmmPreviewPromise=a,a}createDmmPlayer(e){let t=e.length?e.parent():$(this.previewSession?.host),s=t.find("#jhs-preview-video");if(s.length)return s;let a=$('<video id="jhs-preview-video" class="jhs-video-player jhs-dmm-preview-player" controls playsinline></video>');return t.append(a),a}isSessionOpen(e){if(!e||e.scope.disposed||!e.host.isConnected||e.native&&!e.host.contains(e.native))return!1;for(let t=e.host;t;t=t.parentElement)if(t.getAttribute("aria-hidden")==="true"||getComputedStyle(t).display==="none")return!1;return!0}seekVideo(e,t){let s=d(()=>{try{e.currentTime=Math.max(0,Math.min(t||0,Number.isFinite(e.duration)?e.duration:1/0))}catch{}},"seek");s();let a=this.previewSession;if(a?.seekCleanups?.get(e)?.(),!e.readyState&&a){a.seekCleanups||(a.seekCleanups=new Map);let i=d(()=>{l(),this.isSessionOpen(a)&&s()},"loaded"),r=d(()=>l(),"failed"),n=setTimeout(r,5e3),l=a.scope.addCleanup(()=>{clearTimeout(n),e.removeEventListener("loadedmetadata",i),e.removeEventListener("error",r),a.seekCleanups.delete(e)});e.addEventListener("loadedmetadata",i,{once:!0}),e.addEventListener("error",r,{once:!0}),a.seekCleanups.set(e,l)}}disposePreviewSession(){let e=this.previewSession;if(this.previewSession=null,!e)return;this.dmmRequestScope?.dispose(),this.dmmPreviewPromise=null,e.scope.dispose(),$(e.host).find("#video-bottom-toolbar").remove();let t=e.host.querySelector("#jhs-preview-video");t&&(t.pause(),t.removeAttribute("src"),t.load(),t.remove()),e.native?.classList.remove("jhs-native-preview-hidden"),e.native?.pause(),e.dialogId!=null&&this.getRuntimeService("dialog").close(e.dialogId)}openDmmDialog(){if(!zt(this.getRuntimeService("settings").snapshot())||this.previewSession)return;let e=$('<div data-jhs-preview-host="true"></div>');this.getRuntimeService("dialog").open({type:1,title:"预告片",ui:{body:"media"},content:e,area:utils.getDialogArea("lg"),success:d((t,s)=>{this.handleVideo(e[0],s).catch(a=>clog.error("预览失败",a))},"success"),end:d(()=>{this.previewSession?.host===e[0]&&this.disposePreviewSession()},"end")})}waitForDmmReady(e){let t=this.previewSession?.scope.signal;return t?.aborted||e.error?Promise.resolve(!1):e.readyState>=3?Promise.resolve(!0):new Promise(s=>{let a=d(l=>{clearTimeout(n),e.removeEventListener("canplay",i),e.removeEventListener("error",r),t?.removeEventListener("abort",r),s(l)},"finish"),i=d(()=>a(!0),"loaded"),r=d(()=>a(!1),"failed"),n=setTimeout(r,1e4);e.addEventListener("canplay",i,{once:!0}),e.addEventListener("error",r,{once:!0}),t?.addEventListener("abort",r,{once:!0})})}async restoreNativePlayer(e,t,s=!1,a=!0){if(!t||!this.isSessionOpen(this.previewSession))return!1;let i=e.parent().find("#jhs-preview-video"),r=i[0];return r&&(r.pause(),i.removeAttr("src"),r.load(),i.remove()),e.removeClass("jhs-native-preview-hidden"),a?de(t,{context:"JavDB 原生预览回退",notify:s}):(t.pause(),!0)}async handleVideo(e=null,t=null){let s=$(".fancybox-content #preview-video"),a=e||s[0]?.closest(".fancybox-content");if(!a||!Ae(this.getRuntimeService("settings").snapshot())||getComputedStyle(a).display==="none")return;if(this.previewSession?.host!==a){this.disposePreviewSession();let L=new te("javdb-preview");this.previewSession={host:a,native:s[0]||null,scope:L,dialogId:t},L.observe(document.body,()=>{this.previewSession?.host===a&&!this.isSessionOpen(this.previewSession)&&this.disposePreviewSession()},{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","aria-hidden"]})}let i=this.previewSession;if(i.generation===this.previewGeneration)return;i.generation=this.previewGeneration;let r=d(()=>this.previewSession===i&&this.isSessionOpen(i)&&u===this.previewGeneration&&Ae(this.getRuntimeService("settings").snapshot()),"alive"),n=this.getRuntimeService("settings"),l=$(a),c=s[0],h=n.snapshot().videoMuted,u=this.previewGeneration,p=cs(this.getRuntimeService("settings").snapshot()),g=p?await this.getDmmPreview():{sources:null,error:null};if(!r())return;let{sources:m,error:f}=g,v=$("<div></div>").attr("id","video-bottom-toolbar").addClass("jhs-video-toolbar"),b=$("<div></div>").addClass("jhs-video-quality-list").attr({role:"group","aria-label":"视频画质"});l.find("#video-bottom-toolbar").remove();let w=!1,S=null,j=null;if(m){let L=this.getRuntimeService("settings").snapshot().videoQuality,M=Ot(Object.keys(m),L),P=m[M],z=c?.currentTime||0,O=!c||!c.paused;S=this.createDmmPlayer(s),j=S[0],j.muted=h==null||h===!0,S.off("volumechange.jhsVideo").on("volumechange.jhsVideo",(()=>{n.set("videoMuted",j.muted).catch(Q=>clog.error("保存视频静音设置失败",Q))})),S.attr("src",P),j.load(),this.seekVideo(j,z),S.addClass("is-active");let H=await this.waitForDmmReady(j);if(!r()){j.pause();return}if(w=H&&(!O||await de(j,{context:"JavDB 高画质预览",notify:!1})),!r()){j.pause();return}if(H&&!w&&!j.muted&&(j.muted=!0,w=await de(j,{context:"JavDB 高画质预览静音重试",notify:!1})),!r()){j.pause();return}if(w?(c?.pause(),s.addClass("jhs-native-preview-hidden")):(S.removeClass("is-active"),await this.restoreNativePlayer(s,c,!0,O)),!r())return;if(!w&&!c){show.error("当前视频源无法播放"),this.disposePreviewSession();return}w&&at.forEach((Q=>{let se=m[Q.quality];if(!se)return;let ge=w&&M===Q.quality;b.append($('<button type="button" class="jhs-btn jhs-video-quality-btn"></button>').toggleClass("active",ge).attr({"data-quality":Q.quality,"data-video-src":se,"aria-pressed":String(ge)}).text(Q.text))}))}v.append(b);let k=$("<div></div>").addClass("jhs-toolbar");if(this.getOptionalDependency("DetailPageButtonPlugin")&&k.append(Nt({actions:["blocked","favorite"],ids:{blocked:"video-filterBtn",favorite:"video-favoriteBtn"}})),k.append('<button type="button" class="jhs-btn jhs-btn--secondary" id="speed-btn">快进</button>'),!r())return;v.append(k),l.append(v),v.off("click.jhsVideo").on("click.jhsVideo",".jhs-video-quality-btn",(async L=>{let M=$(L.currentTarget);if(!M.hasClass("active"))try{if(!j?.isConnected||!r())return;let P=j.currentTime,z=S.attr("src"),O=!j.paused;S.attr("src",M.data("video-src")),j.load(),this.seekVideo(j,P);let H=await this.waitForDmmReady(j);if(!r())return;let Q=H&&(!O||await de(j,{context:"JavDB 画质切换",notify:!1}));if(!r())return;if(Q)v.find(".jhs-video-quality-btn").removeClass("active").attr("aria-pressed","false"),M.addClass("active").attr("aria-pressed","true");else{z&&(S.attr("src",z),j.load(),j.currentTime=P);let se=z&&await this.waitForDmmReady(j)&&(!O||await de(j,{context:"JavDB 画质切换回退",notify:!1}));if(!r())return;se||await this.restoreNativePlayer(s,c,!0,O)}}catch(P){clog.error("切换画质失败:",P)}})),$("#speed-btn").off("click.jhsVideo").on("click.jhsVideo",(()=>{let L=l.find("#jhs-preview-video.is-active")[0]||c;L?.isConnected&&this.isSessionOpen(i)&&this.seekVideo(L,L.currentTime+10)})),v.off("contextmenu.jhsVideo").on("contextmenu.jhsVideo","#speed-btn",(L=>(L.preventDefault(),this.getOptionalDependency("DetailPageButtonPlugin")?.filterOne?.(L)))),$("#video-filterBtn").off("click.jhsVideo").on("click.jhsVideo",(L=>this.getOptionalDependency("DetailPageButtonPlugin")?.filterOne?.(L))),$("#video-favoriteBtn").off("click.jhsVideo").on("click.jhsVideo",(L=>this.getOptionalDependency("DetailPageButtonPlugin")?.favoriteOne?.(L)));let _=this.getOptionalDependency("DetailPageButtonPlugin"),E=_?.getDetailStateController?.();if(E){v.find("#video-filterBtn,#video-favoriteBtn").off("click.jhsVideo");let L=E.bind({root:v[0],closeRoot:document.documentElement,carNum:this.getPageInfo().carNum,layerIndex:utils.getOwningLayerIndex({root:document.documentElement}),getRecord:d(()=>_.getStateRecord(),"getRecord"),selectors:{blocked:"#video-filterBtn",favorite:"#video-favoriteBtn"}});i.stateCleanup?.(),i.stateCleanup=F?.on("car-state-changed",M=>{if(M.carNums?.includes(L.carNum)&&this.isSessionOpen(i))return E.render(L)}),i.stateCleanup&&i.scope.addCleanup(i.stateCleanup)}}};d(an,"PreviewVideoPlugin");var fa=an;function kc(o){if(typeof o=="string")return new DOMParser().parseFromString(o,"text/html");if(typeof o?.querySelectorAll=="function")return o;let e=o?.[0]??o?.get?.(0);if(typeof e?.querySelectorAll=="function")return e;throw new TypeError("JavStore document is invalid")}d(kc,"resolveDocument");function ds(o,e="https://javstore.net"){if(!o)return null;try{let t=new URL(String(o),e),s=t.hostname.toLowerCase();return["http:","https:"].includes(t.protocol)?(t.protocol==="http:"&&(s==="javstore.net"||s.endsWith(".javstore.net"))&&(t.protocol="https:"),t.href):null}catch{return null}}d(ds,"normalizeJavStoreAssetUrl");function Cc(o,e,t="https://javstore.net"){let s=ee(e);if(!s)return[];if(typeof o?.find=="function"){let a=globalThis.jQuery??globalThis.$??o.constructor;return o.find('a[href$="-pn.html"]').filter(((i,r)=>a(r).text().trim().toUpperCase().includes(s.toUpperCase()))).map(((i,r)=>new URL(a(r).attr("href"),t).href)).get()}return[...kc(o).querySelectorAll('a[href$="-pn.html"]')].filter(a=>a.textContent?.trim().toUpperCase().includes(s.toUpperCase())).map(a=>new URL(a.getAttribute("href")||"",t).href)}d(Cc,"parseJavStoreSearch");function _c(o,e){if(typeof o?.find=="function"){let a=globalThis.jQuery??globalThis.$??o.constructor,r=o.find("a").filter(((l,c)=>a(c).text().trim()==="CLICK HERE!")).first().attr("href");if(!r)return null;let n=ds(r,e);return n?n.replace(".th",""):null}let t=[...kc(o).querySelectorAll("a")].find(a=>a.textContent?.trim()==="CLICK HERE!")?.getAttribute("href");if(!t)return null;let s=ds(t,e);return s?s.replace(".th",""):null}d(_c,"parseJavStorePreview");var rn=class rn extends I{getName(){return"ScreenShotPlugin"}getScreenshotService(){return this.getRuntimeService("screenshot")}getSettingsSnapshot(){return this.getRuntimeService("settings")?.snapshot?.()??{}}async initCss(){return"<style>.jhs-screenshot-message{margin-top:50px;color:var(--jhs-text-muted);cursor:auto}.jhs-screenshot-message--bus{margin-top:30px}</style>"}async handle(){if(!isDetailPage)return;let e=this.getRuntimeService("settings"),t=await this.getRuntimeService("scope")(),s=d(a=>{a.detail?.names?.includes("enableLoadScreenShot")&&(e.snapshot().enableLoadScreenShot==="no"?this.unmountHosted():this.loadScreenShot().catch(r=>clog.error("长缩略图重新加载失败",r)))},"onSettingsChanged");e.addEventListener("settings.changed",s),t.addCleanup((()=>e.removeEventListener("settings.changed",s))),this.loadScreenShot().catch(a=>clog.error("长缩略图加载失败",a))}unmountHosted(){$(".screen-container, .jhs-screenshot-providers").remove()}async loadScreenShot(){if(!isDetailPage||!this.getScreenshotService().isEnabled(this.getSettingsSnapshot()))return;let t=this.getPageInfo().carNum;N&&$(".preview-images .tile-item").first().before(' <a class="tile-item screen-container jhs-layout-cd9d5db1"><div class="jhs-layout-9db87399">正在加载缩略图</div></a> '),B&&$("#sample-waterfall .sample-box:first").after(' <a class="sample-box screen-container jhs-layout-b5c4e4f7"><div class="jhs-layout-3536a853">正在加载缩略图</div></a> ');try{let s=await this.getScreenshot(t);s?(this.addImg("缩略图",s),clog.log("加载缩略图:",s)):this.showErrorFallback(t,null)}catch(s){this.showErrorFallback(t,s)}}async getScreenshot(e){if(e=T(e),!e)throw clog.warn("跳过缩略图解析:番号不可用"),new Error("缩略图番号不可用");let t=arguments[1]||{},s=this.getScreenshotService(),a=this.getSettingsSnapshot();if(!t.allowWhenDisabled&&!s.isEnabled(a))return clog.warn("长缩略图功能已关闭,跳过请求"),null;let i=await this.getRuntimeService("scope")(),r=await s.resolve({carNum:e},{scope:i,settings:a,allowWhenDisabled:t.allowWhenDisabled===!0});return(Array.isArray(r)?r[0]:r)?.url||null}addImg(e,t){let s=ds(t);if(!s)return;let a=$(".screen-container").empty(),i=$("<img>").attr({src:s,alt:e,loading:"lazy"});N&&a.append(i.addClass("jhs-layout-cad980f4")),B&&a.append($('<div class="photo-frame"></div>').append(i.attr("title",e).addClass("jhs-layout-d4a575e8"))),a.on("click",(r=>{r.stopPropagation(),r.preventDefault(),globalThis.showImageViewer(r.currentTarget)}))}showErrorFallback(e,t){let s=t instanceof Error?t.message:"";t&&clog.error("获取缩略图失败:",s.substring(0,100));let a=`jhs-screenshot-message${B?" jhs-screenshot-message--bus":""}`,i=T(e);if(!i)return void $(".screen-container").empty().append($("<div></div>").addClass(a).text("无法获取番号,缩略图未加载"));let r=this.getScreenshotService().getSearchUrl({carNum:i}),n=$(".screen-container").empty(),l=$("<div></div>").addClass(a).text(t instanceof Error?"获取缩略图失败":"暂无缩略图结果"),c=$('<a href="#" class="retry-link">点击重试</a>');n.append(l,$("<br>"),c),r&&n.append(document.createTextNode(" 或 "),$('<a class="check-link" target="_blank" rel="noopener noreferrer">前往确认</a>').attr("href",r)),n.off("click",".retry-link").off("click",".check-link").on("click",".retry-link",(async h=>{h.stopPropagation(),h.preventDefault(),n.empty().append($("<div></div>").addClass(a).text("正在重新加载..."));try{let u=await this.getScreenshot(i);u?this.addImg("缩略图",u):this.showErrorFallback(i,null)}catch(u){this.showErrorFallback(i,u)}})).on("click",".check-link",(h=>{h.stopPropagation(),h.preventDefault(),window.open(r,"_blank")}))}async loadInto(e,t,{isActive:s=d(()=>!0,"isActive")}={}){let a=$(e);if(!a.length||!this.getScreenshotService().isEnabled(this.getSettingsSnapshot()))return a.empty(),null;let i=await this.getRuntimeService("scope")();return Zs({target:a,carNum:t,screenshot:this.getScreenshotService(),settings:this.getSettingsSnapshot(),scope:i,isActive:s})}renderInto(e,t,s){let a=$(e),i=$("<img>").attr({src:ds(t),alt:s,loading:"lazy"}).addClass("jhs-fc2-gallery__image"),r=$('<button type="button" class="jhs-btn jhs-fc2-gallery-item jhs-fc2-screenshot-thumbnail"></button>').attr("aria-label",`查看${s}大图`).append(i);a.empty().append(r).off("click.jhsScreenshot").on("click.jhsScreenshot",".jhs-fc2-screenshot-thumbnail",(n=>{n.preventDefault(),n.stopPropagation(),globalThis.showImageViewer(i[0])}))}};d(rn,"ScreenShotPlugin");var va=rn;var $c="jhs_img_cdn_index";function Mh(o,e,t,s=Date.now()){let a=new Map;for(let i of o)if(Array.isArray(i.newVideoList))for(let r of i.newVideoList){let n=typeof r=="object"?r:{},l=T(typeof r=="string"?r:r.carNum);if(!l)continue;let c=a.get(l)||{carNum:l,coverUrl:"",title:"",publishTime:"",actresses:[],starIds:[],categories:new Set,score:0,voteCount:0,url:"",isVr:!1};c.coverUrl||(c.coverUrl=n.coverUrl||""),c.title||(c.title=n.title||""),c.publishTime=[c.publishTime,n.publishTime||""].sort().at(-1),c.score=Math.max(c.score,Number(n.score)||0),c.voteCount=Math.max(c.voteCount,Number(n.voteCount)||0),c.url||(c.url=n.url||""),c.isVr||(c.isVr=n.isVr===!0||/(^|[^A-Z])VR([^A-Z]|$)/i.test(`${n.title||""} ${(n.tags||[]).join?.(" ")||""} ${(n.categories||[]).join?.(" ")||""}`)),i.name&&!c.actresses.includes(i.name)&&c.actresses.push(i.name),i.starId&&!c.starIds.includes(i.starId)&&c.starIds.push(i.starId),i.actressType&&c.categories.add(i.actressType),a.set(l,c)}return[...a.values()].map((i=>{let r=e.get(i.carNum),n=q(r?.stateFlags),l=t[i.carNum]||null,c=l?l.action==="snoozed"&&l.until&&Date.parse(l.until)<=s?"pending":l.action:"pending";return{...i,actressName:i.actresses.join("、"),starId:i.starIds[0]||"",categories:[...i.categories],flags:n,decision:l,decisionState:c}}))}d(Mh,"aggregateNewVideoRecords");var nn=class nn extends I{constructor(){super(...arguments),A(this,"currentPage",1),A(this,"pageSize",30),A(this,"nvCurrentPage",1),A(this,"nvPageSize",60),A(this,"nvFlatListCache",[]),A(this,"nvAllItemsMap",new Map),A(this,"nvActressesCache",[]),A(this,"nvCarMapCache",new Map),A(this,"nvSortBy","publishTime_desc"),A(this,"nvSelected",new Set),A(this,"nvDecisionsCache",{}),A(this,"nvCoverCache",new Map),A(this,"nvActorCoverRequests",new Map),A(this,"nvRenderGeneration",0),A(this,"nvSearchDebounced",null),A(this,"nvInvalidationTimer",null),A(this,"nvWorkspaceReloadPromise",null),A(this,"nvWorkspaceReloadDirty",!1),A(this,"nvWorkspaceMounted",!1),A(this,"nvEventUnsubscribe",null),A(this,"taskStatusUnsubscribe",null),A(this,"nvCoverPreview",null),A(this,"nvWorkspaceRoot",null),A(this,"nvJavDbUrl",""),A(this,"nvRuleTime",8760),A(this,"avatarSources",[]),A(this,"avatarSourceIndex",0)}getName(){return"NewVideoPlugin"}getStartupMode(){return"idle"}async initCss(){return`
            <style>
                .newVideoToolBox { display:flex; flex-direction:column; width:100%; height:100%; min-width:0; min-height:0; box-sizing:border-box; overflow:hidden; padding:var(--jhs-space-3); }
                .jhs-new-video-toolbar { display:flex; align-items:center; justify-content:space-between; gap:var(--jhs-space-3); margin-bottom:var(--jhs-space-3); }
                .jhs-new-video-toolbar__actions, .jhs-new-video-toolbar__filters { display:flex; align-items:center; flex-wrap:wrap; gap:var(--jhs-space-2); }
                .jhs-new-video-toolbar select { min-width:150px; }
                #actress-card-container { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr)); gap:var(--jhs-space-3); width:100%; min-width:0; max-width:1680px; box-sizing:border-box; margin:0 auto; padding:var(--jhs-space-1); overflow-x:hidden; overflow-y:auto; }
                .actress-card { position:relative; display:flex; flex-direction:column; min-width:0; padding:var(--jhs-space-4); border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); background:var(--jhs-surface); }
                .actress-card.is-paused { background:var(--jhs-surface-2); }
                .actress-card__badges { display:flex; align-items:center; gap:var(--jhs-space-1); margin-bottom:var(--jhs-space-3); }
                .actress-card__profile { display:grid; grid-template-columns:64px minmax(0,1fr); align-items:center; gap:var(--jhs-space-3); color:inherit; text-decoration:none; }
                .actress-card-avatar { width:64px; height:64px; border-radius:50%; object-fit:cover; background:var(--jhs-surface-2); }
                .actress-card-name { overflow:hidden; color:var(--jhs-text); font-size:var(--jhs-font-size-lg); font-weight:700; text-overflow:ellipsis; white-space:nowrap; }
                .actress-card-allname { overflow:hidden; margin-top:var(--jhs-space-1); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-sm); text-overflow:ellipsis; white-space:nowrap; }
                .actress-card__meta { display:grid; gap:var(--jhs-space-2); margin:var(--jhs-space-3) 0; }
                .actress-card__meta-row { display:grid; grid-template-columns:76px minmax(0,1fr); gap:var(--jhs-space-2); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-sm); }
                .actress-card__meta-row dt { color:var(--jhs-text-faint); }
                .actress-card__meta-row dd { overflow:hidden; margin:0; color:var(--jhs-text); text-overflow:ellipsis; white-space:nowrap; }
                .actress-card__note { min-height:20px; margin-bottom:var(--jhs-space-3); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-sm); }
                .actress-card__actions { display:flex; align-items:center; gap:var(--jhs-space-2); margin-top:auto; }
                .actress-card__actions .btn-check-actress { flex:1; }
                .actress-card__menu { position:relative; }
                .actress-card__menu summary { list-style:none; }
                .actress-card__menu summary::-webkit-details-marker { display:none; }
                .actress-card__menu-popover { position:static; min-width:128px; margin-top:var(--jhs-space-1); padding:var(--jhs-space-1); border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); background:var(--jhs-surface); box-shadow:var(--jhs-shadow-md); }
                .actress-card__menu-popover button { width:100%; justify-content:flex-start; }
                .card-tag.is-uncensored { color:var(--jhs-status-down); background:var(--jhs-status-down-tint); }
                .card-tag.is-censored { color:var(--jhs-status-watch); background:var(--jhs-status-watch-tint); }
                .card-tag.is-unknown { color:var(--jhs-text-muted); background:var(--jhs-surface-2); }
                #new-video-list-container { display:none; flex:1; min-width:0; min-height:0; overflow-x:hidden; overflow-y:auto; }
                #new-video-list-footer { display:none; padding:var(--jhs-space-2) 0; border-top:1px solid var(--jhs-border); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-sm); }
                .jhs-new-video-view { flex:0 0 auto; }
                .jhs-new-video-batch { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:var(--jhs-space-2); width:100%; }
                .jhs-new-video-batch__actions { display:flex; align-items:center; flex-wrap:wrap; gap:var(--jhs-space-2); }
                .jhs-new-video-batch__more { position:relative; }
                .jhs-new-video-batch__more summary { list-style:none; }
                .jhs-new-video-batch__more summary::-webkit-details-marker { display:none; }
                .jhs-new-video-batch__menu { top:auto; bottom:calc(100% + var(--jhs-space-1)); }
                .jhs-task-status-list { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--jhs-space-2); margin-bottom:var(--jhs-space-3); }
                .jhs-task-status { padding:var(--jhs-space-2) var(--jhs-space-3); border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-sm); background:var(--jhs-surface-2); }
                .jhs-task-status__name { color:var(--jhs-text); font-weight:700; }
                .jhs-task-status__meta { display:block; margin-top:var(--jhs-space-1); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-xs); }
                .jhs-new-video-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(min(100%,260px),1fr)); gap:var(--jhs-space-3); width:100%; min-width:0; box-sizing:border-box; padding:var(--jhs-space-1); }
                .nv-card__link { display:block; color:inherit; text-decoration:none; }
                .nv-card__cover { position:relative; width:100%; overflow:hidden; aspect-ratio:3/2; border-radius:var(--jhs-radius-sm); background:var(--jhs-surface-2); }
                .nv-cover-img { width:100%; height:100%; object-fit:cover; cursor:zoom-in; }
                .nv-card__empty { display:flex; align-items:center; justify-content:center; height:100%; color:var(--jhs-text-faint); font-size:var(--jhs-font-size-xs); }
                .nv-card__rating { position:absolute; top:var(--jhs-space-1); right:var(--jhs-space-1); }
                .nv-card__body { padding:var(--jhs-space-2) var(--jhs-space-1); }
                .nv-card__title, .nv-card__actress { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
                .nv-card__title { color:var(--jhs-text); font-size:var(--jhs-font-size-sm); font-weight:700; }
                .nv-card__actress, .nv-card__date { color:var(--jhs-text-muted); font-size:var(--jhs-font-size-xs); }
                .jhs-new-video-pagination { flex:0 0 auto; padding:var(--jhs-space-2) 0; border-top:1px solid var(--jhs-border); text-align:center; }
                .jhs-form-dialog { display:grid; gap:var(--jhs-space-3); padding:var(--jhs-space-4); }
                .jhs-avatar-editor { display:grid; grid-template-columns:100px minmax(0,1fr); gap:var(--jhs-space-3); align-items:start; }
                .jhs-avatar-editor__preview { width:100px; height:100px; border:2px solid var(--jhs-border); border-radius:50%; object-fit:cover; }
                .jhs-avatar-editor__actions { margin-top:var(--jhs-space-2); }
                #gfriends-image-list-container { height:100%; box-sizing:border-box; padding:var(--jhs-space-4); background:var(--jhs-surface-2); }
                #gfriends-prompt { margin:0 0 var(--jhs-space-3); padding-bottom:var(--jhs-space-2); border-bottom:1px solid var(--jhs-border); color:var(--jhs-text-muted); font-weight:600; }
                #gfriends-image-list { display:grid; grid-template-columns:repeat(auto-fill,minmax(144px,1fr)); gap:var(--jhs-space-3); }
                .gfriends-image-item-wrapper { display:grid; grid-template-rows:200px auto; min-height:44px; overflow:hidden; padding:0; border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); background:var(--jhs-surface); color:var(--jhs-text); cursor:pointer; }
                .gfriends-image-item-wrapper:hover { border-color:var(--jhs-border-strong); background:var(--jhs-surface-hover); }
                .gfriends-image-item-wrapper:focus-visible { outline:2px solid var(--jhs-focus); outline-offset:2px; }
                .gfriends-image-item-wrapper[aria-pressed="true"] { border-color:var(--jhs-accent); box-shadow:0 0 0 2px var(--jhs-accent-tint); }
                .gfriends-selectable-img { width:100%; height:200px; object-fit:cover; }
                .gfriends-size-tag { min-height:28px; padding:var(--jhs-space-1) var(--jhs-space-2); border-top:1px solid var(--jhs-border); color:var(--jhs-text-muted); font-size:var(--jhs-font-size-xs); line-height:20px; text-align:center; }
                .jhs-form-dialog__body, .jhs-form-field { display:grid; gap:var(--jhs-space-1); }
                .jhs-form-label, .jhs-form-dialog__title { color:var(--jhs-text); font-size:var(--jhs-font-size-sm); font-weight:600; }
                .jhs-form-dialog :where(.jhs-field,.jhs-select,.jhs-textarea) { width:100%; }
                .jhs-form-dialog .jhs-textarea { min-height:60px; overflow-y:hidden; }
                .jhs-option-row { display:flex; align-items:center; gap:var(--jhs-space-2); min-height:36px; }
                #actress-pagination { display:flex; align-items:center; justify-content:center; flex-wrap:wrap; gap:var(--jhs-space-1); }
                @media (max-width:767px) { .jhs-new-video-toolbar { align-items:stretch; flex-direction:column; } .jhs-new-video-toolbar select, .jhs-new-video-toolbar .jhs-btn { min-height:44px; } .newVideoToolBox .jhs-task-status-list { display:flex; flex-shrink:0; overflow-x:auto; } .newVideoToolBox .jhs-task-status { flex:0 0 180px; } .page-number-btn { display:none !important; } }
                @media (prefers-reduced-motion:reduce) { .gfriends-image-item-wrapper { transition:none; } }
                @media (max-width:767px) { .newVideoToolBox { overflow-y:auto; } .newVideoToolBox #new-video-list-container { min-height:160px; } }
            </style>
        `}async handle(){this.initializeLocalState(),this.nvEventUnsubscribe||(this.nvEventUnsubscribe=F.on("new-video-changed",(()=>this.scheduleWorkspaceReload()))),this.taskStatusUnsubscribe||(this.taskStatusUnsubscribe=F.on("task-status-changed",(()=>this.isWorkspaceMounted()&&this.renderTaskStatuses()))),await this.showNewVideoCount()}initializeLocalState(){this.avatarSources=this.getRuntimeService("actressInfo").getAvatarSources();let e=parseInt(this.getRuntimeService("storage").getLocal($c)||"0",10);this.avatarSourceIndex=Number.isInteger(e)&&e>=0&&e<this.avatarSources.length?e:0}isWorkspaceMounted(){return this.nvWorkspaceMounted&&$(".newVideoToolBox").length>0}scheduleWorkspaceReload(){this.nvWorkspaceReloadDirty=!0,this.nvInvalidationTimer||(this.nvInvalidationTimer=setTimeout((()=>{this.nvInvalidationTimer=null,this.flushWorkspaceReload()}),0))}async flushWorkspaceReload(){return this.nvWorkspaceReloadPromise?this.nvWorkspaceReloadPromise:(this.nvWorkspaceReloadPromise=(async()=>{do this.nvWorkspaceReloadDirty=!1,await this.showNewVideoCount(),this.isWorkspaceMounted()&&await this.reloadNewVideoWorkspaceData({preservePage:!0});while(this.nvWorkspaceReloadDirty)})().catch((e=>clog.error("新作品数据刷新失败",e))).finally((()=>{this.nvWorkspaceReloadPromise=null})),this.nvWorkspaceReloadPromise)}getPendingNewVideoCount(e,t){return Array.isArray(e?.newVideoList)?new Set(e.newVideoList.map((s=>T(typeof s=="string"?s:s.carNum))).filter((s=>s&&!t.has(s)&&!this.isDecisionHidden(s)))).size:0}isDecisionHidden(e){let t=this.nvDecisionsCache[T(e)];return t?["ignored","dismissed"].includes(t.action)||t.action==="snoozed"&&(!t.until||Date.parse(t.until)>Date.now()):!1}async getPendingNewVideoTotal(){let e=await storageManager.getCarMap(),t=new Set;return this.nvDecisionsCache=await this.getRuntimeService("state").getNewVideoDecisions(),(await storageManager.getFavoriteActressList()).forEach((s=>Array.isArray(s.newVideoList)&&s.newVideoList.forEach((a=>{let i=T(typeof a=="string"?a:a.carNum);i&&!oe(q(e.get(i)?.stateFlags))&&!this.isDecisionHidden(i)&&t.add(i)})))),t.size}async showNewVideoCount(){let e=await this.getPendingNewVideoTotal();$("#newVideoCount").text(`${e}`)}async resetBtnTip(){let e=this.getRuntimeService("storage"),t=this.getOptionalDependency("TaskPlugin"),s=await storageManager.getSetting(),a=t?e.getLocal(t.lastCheckFavoriteActressTimeKey)||"无":"任务已禁用",i=s.checkFavoriteActress_IntervalTime,r=t?e.getLocal(t.lastCheckNewVideoTimeKey)||"无":"任务已禁用",n=s.checkNewVideo_intervalTime;$("#checkFavoriteActress").attr("data-tip",`上次完整同步: ${a}; 检测间隔时间: ${i}小时`),$("#checkNewVideo").attr("data-tip",`上次整批检测: ${r}; 检测间隔时间: ${n}小时`)}async openDialog(){let e=this.getRuntimeService("storage");this.cleanupNewVideoWorkspace(),this._viewMode=e.getLocal("jhs_newVideoViewMode")==="list"?"list":"actress",this.currentPage=1,this.nvCurrentPage=1,this.nvSelected=new Set,this.nvCoverCache=new Map,this.nvActorCoverRequests=new Map,this.nvRenderGeneration++;let t=this.getOptionalDependency("TaskPlugin"),s=await storageManager.getSetting(),a=t?e.getLocal(t.lastCheckFavoriteActressTimeKey)||"无":"任务已禁用",i=s.checkFavoriteActress_IntervalTime,r=t?e.getLocal(t.lastCheckNewVideoTimeKey)||"无":"任务已禁用",n=s.checkNewVideo_intervalTime,l=`
            <div class="newVideoToolBox jhs-ui">
                <div class="jhs-new-video-toolbar" role="toolbar" aria-label="新作品工作区工具">
                    <div class="jhs-new-video-toolbar__actions">
                        <button type="button" class="jhs-btn jhs-btn--secondary" id="checkFavoriteActress" data-tip="上次完整同步: ${a}; 检测间隔时间: ${i}小时">${this.actressSvg}<span>手动同步演员</span></button>
                        <button type="button" class="jhs-btn jhs-btn--secondary" id="checkNewVideo" data-tip="上次整批检测: ${r}; 检测间隔时间: ${n}小时">${this.newSvg}<span>手动检测最新作品</span></button>
                        <button type="button" class="jhs-btn jhs-btn--ghost" id="toSetting">${this.settingSvg}<span>配置</span></button>
                        <span id="checkNewVideoMsg" role="status" aria-live="polite"></span>
                    </div>
                    <div class="jhs-new-video-toolbar__filters">
                        <select id="paramActressType" class="jhs-select-source" aria-label="演员类型"><option value="all" selected>所有</option><option value="uncensored">无码</option><option value="censored">有码</option><option value="">未知</option></select>
                        <input id="nvSearch" class="jhs-field jhs-is-hidden" type="search" placeholder="搜索番号、标题或演员" aria-label="搜索新作品">
                        <select id="nvCategoryFilter" class="jhs-select-source jhs-is-hidden" aria-label="新作品类别"><option value="all" selected>所有类别</option><option value="uncensored">无码</option><option value="censored">有码</option><option value="unknown">未知</option><option value="vr">VR</option></select>
                        <select id="nvStateFilter" class="jhs-select-source jhs-is-hidden" aria-label="作品状态"><option value="all">所有状态</option><option value="pending" selected>待处理</option><option value="favorite">已收藏</option><option value="downloaded">已下载</option><option value="watched">已观看</option><option value="blocked">已屏蔽</option></select>
                         <select id="nvDecisionFilter" class="jhs-select-source jhs-is-hidden" aria-label="新作决策"><option value="pending" selected>待处理</option><option value="ignored">已忽略</option><option value="snoozed">已暂缓</option><option value="dismissed">已移除</option><option value="all">所有决策</option></select>
                        <select id="paramSortBy" class="jhs-select-source" aria-label="演员排序">
                            <option value="default" selected>默认排序</option><optgroup label="发行时间"><option value="lastPublishTime_desc">发行时间 新→旧</option><option value="lastPublishTime_asc">发行时间 旧→新</option></optgroup><optgroup label="检测时间"><option value="lastCheckTime_desc">检测时间 新→旧</option><option value="lastCheckTime_asc">检测时间 旧→新</option></optgroup><optgroup label="新作品数"><option value="newVideoCount_desc">新作品数 多→少</option><option value="newVideoCount_asc">新作品数 少→多</option></optgroup>
                        </select>
                        <select id="nvSortBy" class="jhs-select-source jhs-is-hidden" aria-label="新作品排序"><option value="publishTime_desc" selected>发行时间 新→旧</option><option value="publishTime_asc">发行时间 旧→新</option><option value="voteCount_desc">评价人数 多→少</option><option value="voteCount_asc">评价人数 少→多</option><option value="actress_asc">演员名 A→Z</option><option value="actress_desc">演员名 Z→A</option><option value="carNum_asc">番号 A→Z</option><option value="carNum_desc">番号 Z→A</option></select>
                        <div class="jhs-segmented jhs-new-video-view" role="tablist" aria-label="新作品视图">
                            <button type="button" class="jhs-btn jhs-segmented__item" id="nvViewActress" role="tab" aria-controls="actress-card-container" data-view="actress">演员视图</button>
                            <button type="button" class="jhs-btn jhs-segmented__item" id="nvViewList" role="tab" aria-controls="new-video-list-container" data-view="list">新作品</button>
                        </div>
                        <button type="button" class="jhs-btn jhs-btn--ghost" id="reLoad">${this.refreshSvg}<span>刷新</span></button>
                    </div>
                </div>
                <div id="jhs-task-status-list" class="jhs-task-status-list" aria-live="polite"></div>
                <div id="actress-card-container" class="jhs-scrollbar"></div>
                <div id="new-video-list-container"></div>
                <div id="new-video-list-footer"></div>
                <div id="actress-pagination"></div>
            </div>`;this.getRuntimeService("dialog").open({type:1,title:'<span class="jhs-dialog-title" data-tip="数据来源: 女优页面首页,含磁链分类">新作品检测</span>',content:l,scrollbar:!1,ui:{size:"workspace",body:"scroll"},area:utils.getDialogArea("workspace"),anim:-1,success:d(async(c,h)=>{this.nvWorkspaceMounted=!0,this.nvWorkspaceRoot=c,K.enhance(c),this.bindClick(),this.applyViewMode(),this.renderTaskStatuses(),await this.reloadNewVideoWorkspaceData(),utils.setupEscClose(h)},"success"),end:d(()=>this.cleanupNewVideoWorkspace(),"end")})}cleanupNewVideoWorkspace(){this.nvSearchDebounced?.cancel?.(),this.nvSearchDebounced=null,this.nvWorkspaceMounted=!1,this.nvWorkspaceRoot=null,this.nvRenderGeneration++,this.nvSelected.clear(),this.nvCoverCache=new Map,this.nvActorCoverRequests=new Map,this.nvCoverPreview?.destroy?.(),this.nvCoverPreview=null,this.nvAllItemsMap.clear(),this.nvFlatListCache=[],this.nvActressesCache=[],this.nvCarMapCache=new Map,this.nvDecisionsCache={},this.nvCurrentPageItems=[]}bindClick(){let e=this.getOptionalDependency("TaskPlugin");e||$("#checkFavoriteActress,#checkNewVideo").prop("disabled",!0).attr("title","后台任务功能已禁用"),$("#reLoad").on("click",(()=>{this.reloadNewVideoWorkspaceData(),$("#checkNewVideoMsg").text("")})),$("#new-video-list-container").on("click",".nv-card__link",(async t=>{let s=$(t.currentTarget).closest(".nv-card").attr("data-car");if(s)try{if(await storageManager.getSetting("autoRemoveNewVideoMarkAfterBrowse",ne)!==R)return;await this.getRuntimeService("state").removeFromNewVideoList([s],"browse")}catch(a){clog.error("移除新作品标记失败:",a)}})),$("#toSetting").on("click",(t=>{this.getOptionalDependency("SettingPlugin")?.openSettingDialog?.("task-panel",(()=>{$("#setting-checkFavoriteActress").css({border:"1px solid var(--jhs-status-filter)"}),$("#setting-checkNewVideo").css({border:"1px solid var(--jhs-status-filter)"})}))})),$("#checkFavoriteActress").on("click",(t=>{this.runManualTask($(t.currentTarget),"同步中…",(async()=>{if(!$('a[href*="/users/profile"]').length)return void show.error("未登录 JavDB,同步失败");await e?.checkFavoriteActress?.(!0)}))})),$("#checkNewVideo").on("click",(t=>{this.runManualTask($(t.currentTarget),"检测中…",(()=>e?.checkNewVideo?.(!0)))})),$("#paramActressType").on("change",(t=>{this.currentPage=1,this.nvRenderGeneration++,this._viewMode==="actress"&&this.renderActressCards()})),$("#paramSortBy").on("change",(t=>{this.currentPage=1,this.nvRenderGeneration++,this._viewMode==="actress"&&this.renderActressCards()})),$("#nvSortBy").on("change",(t=>{this.nvSortBy=$("#nvSortBy").val(),this.nvCurrentPage=1,this.nvRenderGeneration++,this.renderNewVideoList()})),$("#nvCategoryFilter,#nvStateFilter,#nvDecisionFilter").on("change",(t=>{this.nvCurrentPage=1,this.nvRenderGeneration++,this._viewMode==="list"&&this.renderNewVideoList()})),this.nvSearchDebounced=utils.debounce((()=>{this.nvCurrentPage=1,this.nvRenderGeneration++,this._viewMode==="list"&&this.renderNewVideoList()}),200),$("#nvSearch").on("input",this.nvSearchDebounced),$(".jhs-new-video-view").on("click",'[role="tab"]',(t=>{this.setViewMode($(t.currentTarget).data("view"))})).on("keydown",'[role="tab"]',(t=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;t.preventDefault();let s=$(t.delegateTarget).find('[role="tab"]'),a=s.index(t.currentTarget),i=t.key==="Home"?0:t.key==="End"?s.length-1:t.key==="ArrowRight"?(a+1)%s.length:(a-1+s.length)%s.length;s.eq(i).trigger("click").trigger("focus")})),this.bindBatchActions()}async runManualTask(e,t,s){if(e.attr("aria-busy")==="true")return;let a=this.getOptionalDependency("TaskPlugin");if(!a)return void show.info("后台任务功能已禁用");let i=e.find("span").last(),r=i.text();e.attr("aria-busy","true").prop("disabled",!0),i.text(t);try{await navigator.locks.request(a.singleTaskKey,{ifAvailable:!0},(async n=>{if(!n)return void show.error("后台任务正在运行,请稍后再试");await s()}))}catch(n){clog.error("手动任务执行失败",n),a.isNetworkBlocked(n)&&show.error(n.message||"任务执行失败")}finally{e.removeAttr("aria-busy").prop("disabled",!1),i.text(r),this.renderTaskStatuses()}}setViewMode(e){!["actress","list"].includes(e)||e===this._viewMode||(this._viewMode=e,this.getRuntimeService("storage").setLocal("jhs_newVideoViewMode",e),e==="list"?this.nvCurrentPage=1:this.currentPage=1,this.nvRenderGeneration++,this.applyViewMode(),this.renderCurrentView())}applyViewMode(){let e=this._viewMode==="list";$("#nv-pagination-bar").toggle(e),$("#actress-card-container").toggle(!e),$("#actress-pagination").toggle(!e),$("#new-video-list-container").toggle(e),$("#new-video-list-footer").toggle(e),K.setVisible("#paramSortBy",!e),K.setVisible("#nvSortBy",e),K.setVisible("#paramActressType",!e),K.setVisible("#nvCategoryFilter",e),K.setVisible("#nvStateFilter",e),K.setVisible("#nvDecisionFilter",e),$("#nvSearch").toggleClass("jhs-is-hidden",!e),$(".jhs-new-video-view [role='tab']").each(((t,s)=>{let a=$(s).data("view")===this._viewMode;$(s).attr({"aria-selected":String(a),tabindex:a?"0":"-1"}).toggleClass("active",a)}))}renderCurrentView(){return this._viewMode==="list"?this.renderNewVideoList():this.renderActressCards()}loadData(){return this.currentPage=1,this.reloadNewVideoWorkspaceData()}async reloadNewVideoWorkspaceData({preservePage:e=!1}={}){if(!this.isWorkspaceMounted())return;let t=++this.nvRenderGeneration,s=this._viewMode==="list"?$("#new-video-list-container"):$("#actress-card-container");$("#nv-pagination-bar").remove(),Oe(s,{type:"loading",title:"加载中"});try{let a=await storageManager.getSetting(),[i,r,n,l]=await Promise.all([storageManager.getFavoriteActressList(),storageManager.getCarMap(),this.getRuntimeService("state").getNewVideoDecisions(),storageManager.getSetting("checkNewVideo_ruleTime",8760)]),c=this.getRuntimeService("movie").externalSiteOrigin("javDbBtn",a);if(!this.isWorkspaceMounted()||t!==this.nvRenderGeneration)return;this.nvActressesCache=i,this.nvCarMapCache=r,this.nvDecisionsCache=n,this.nvJavDbUrl=c,this.nvRuleTime=ae(l,8760,{min:0});let h=Mh(i,r,n),u=new Map;h.forEach((p=>u.set(T(p.carNum),{...p,carNum:T(p.carNum)}))),this.nvAllItemsMap=u;for(let p of[...this.nvSelected])u.has(p)||this.nvSelected.delete(p);e||(this.currentPage=1,this.nvCurrentPage=1),await this.renderCurrentView(),this.renderTaskStatuses()}catch(a){if(t!==this.nvRenderGeneration||!this.isWorkspaceMounted())return;clog.error("加载新作品工作区失败",a),Oe(s,{type:"error",title:"加载失败",description:a.message||String(a),actionLabel:"重试",onAction:d(()=>this.reloadNewVideoWorkspaceData({preservePage:!0}),"onAction")})}}renderTaskStatuses(){let e=$("#jhs-task-status-list");if(!e.length)return;let t=this.getOptionalDependency("TaskPlugin"),s={favoriteActress:"演员同步",newVideo:"新作品",blacklist:"黑名单"},a={idle:"正常",running:"运行中",pending:"等待下一次任务检查",due:"待运行"},i=d(r=>r?new Date(r).toLocaleString():"无","format");if(!t)return void e.empty().text("后台任务功能已禁用");e.empty(),["favoriteActress","newVideo","blacklist"].forEach((r=>{let n=t.getTaskStatusSnapshot(r),l=$('<div class="jhs-task-status"></div>');l.append($('<span class="jhs-task-status__name"></span>').text(`${s[r]}:${a[n.state]}`)),l.append($('<span class="jhs-task-status__meta"></span>').text(`上次完成 ${i(n.completedAt)};下次检查 ${n.nextAt?i(n.nextAt):"立即"}`)),e.append(l)}))}async renderActressCards(){let e=$("#actress-card-container");if(!e.length)return;let t=[...this.nvActressesCache],s=$("#paramActressType").val();s!=="all"&&(t=t.filter((j=>j.actressType===s)));let a=this.nvCarMapCache,i=d(j=>this.getPendingNewVideoCount(j,a),"_newVideoCount"),r=$("#paramSortBy").val(),n={lastPublishTime_desc:[{key:"lastPublishTime",order:"desc"}],lastPublishTime_asc:[{key:"lastPublishTime",order:"asc"}],lastCheckTime_desc:[{key:"lastCheckTime",order:"desc"}],lastCheckTime_asc:[{key:"lastCheckTime",order:"asc"}],newVideoCount_desc:[{key:i,order:"desc"}],newVideoCount_asc:[{key:i,order:"asc"}]},l=[{key:i,order:"desc"},{key:"lastPublishTime",order:"desc"}],c=utils.genericSort(t,n[r]||l),h=c.length,u=Math.ceil(h/this.pageSize),p=(this.currentPage-1)*this.pageSize,g=p+this.pageSize;u>0&&this.currentPage>u&&(this.currentPage=u);let m=(this.currentPage-1)*this.pageSize,f=c.slice(m,m+this.pageSize),v=this.nvJavDbUrl,b=this.getOptionalDependency("TaskPlugin"),w=this.nvRuleTime;if(f.length===0)return Oe(e,{type:"empty",title:this.nvActressesCache.length?"没有符合当前筛选条件的演员":"暂无收藏演员"}),void this.renderPagination(h,u);let S=f.map((j=>{let k=Array.isArray(j.allName)?j.allName.join(","):"",x=String(j.name||""),_=String(j.remark||""),E=String(j.starId||""),L=this.getPendingNewVideoCount(j,a),M=j.lastPublishTime||"",P=gt(`/actors/${encodeURIComponent(E)}?t=d`,v),z=gt(j.avatar,v)||this.getRuntimeService("actressInfo").placeholderUrl("javdb"),O=pt(M,w),H="未知",Q="is-unknown";j.actressType===Ke?(H="无码",Q="is-uncensored"):j.actressType===Je&&(H="有码",Q="is-censored");let se=String(M||"暂无记录"),ge=O?`停更 ${w/24/365} 年以上,下轮任务不再检测`:_||"暂无备注",Ee=$('<article class="actress-card"></article>').toggleClass("is-paused",O).attr("data-starId",E),nt=$('<div class="actress-card__badges"></div>');nt.append($('<span class="jhs-badge jhs-badge--soft card-new-count-tag"></span>').attr("data-tip",`最新作品数量: ${L}`).text(`${L} 新`),$('<span class="jhs-badge card-tag"></span>').addClass(Q).text(H)),O&&nt.append('<span class="jhs-badge jhs-badge--neutral">停更</span>');let De=$('<a class="actress-card__profile" target="_blank" rel="noopener noreferrer"></a>').attr("href",P||"#"),U=$("<span></span>").append($('<span class="actress-card-name"></span>').text(x),$('<span class="actress-card-allname"></span>').attr("title",k).text(k||"暂无别名"));De.append($('<img class="actress-card-avatar" loading="lazy">').attr({src:z,alt:k}),U);let X=$('<dl class="actress-card__meta"></dl>').append($('<div class="actress-card__meta-row"><dt>最近作品</dt></div>').append($("<dd></dd>").attr("title",se).text(se)),$('<div class="actress-card__meta-row"><dt>上次检测</dt></div>').append($("<dd></dd>").text(String(j.lastCheckTime||"暂无记录")))),ie=$('<div class="actress-card__actions"></div>'),xt=$('<button type="button" class="jhs-btn jhs-btn--secondary btn-check-actress"><span>重新检测</span></button>').attr("data-starId",E).prepend(this.checkSvg),us=$('<button type="button" class="jhs-btn jhs-btn--icon jhs-btn--ghost btn-delete-actress" title="取消收藏"></button>').attr({"aria-label":`取消收藏 ${x}`,"data-starId":E}).append(this.deleteSvg),ye=$('<button type="button" class="jhs-btn jhs-btn--ghost btn-edit-actress" role="menuitem"><span>编辑资料</span></button>').attr("data-starId",E).prepend(this.editSvg);return ie.append(xt,us,$('<details class="actress-card__menu"><summary class="jhs-btn jhs-btn--icon jhs-btn--ghost" aria-label="更多操作" title="更多操作">•••</summary><div class="actress-card__menu-popover" role="menu"></div></details>').find(".actress-card__menu-popover").append(ye).end()),Ee.append(nt,De,X,$('<p class="actress-card__note"></p>').attr("title",ge).text(ge),ie)[0]}));e.empty().append(S),$(".btn-delete-actress").off("click").on("click",(j=>{j.preventDefault();let k=$(j.currentTarget).attr("data-starId"),x=c.find((_=>_.starId===k));utils.q(j,`是否取消收藏 ${C(x.name)}?`,(async()=>{let _=this.getRuntimeService("movie").externalSiteOrigin("javDbBtn",await storageManager.getSetting()),E=document.querySelector("meta[name=csrf-token]").content,L=await this.getRuntimeService("actressInfo").uncollect("javdb",{actorId:k,baseUrl:_,csrfToken:E},{scope:await this.getRuntimeService("scope")()});L.success?(await storageManager.removeFavoriteActress(k),await F.emit("new-video-changed",{reason:"favorite-actress-removed"})):(show.error("移除失败"),clog.error("移除失败,返回值:",L))}))})),$(".btn-edit-actress").off("click").on("click",(j=>{j.preventDefault();let k=$(j.currentTarget).attr("data-starId"),x=c.find((_=>_.starId===k));x?this.editActress(x):show.error(`未找到 starId 为 ${k} 的女优记录。`)})),$(".btn-check-actress").off("click").on("click",(j=>{j.preventDefault();let k=$(j.currentTarget),x=k.attr("data-starId"),_=c.find((E=>E.starId===x));this.runManualTask(k,"检测中…",(()=>b?.checkOneNewVideo?.(_)))})),$(".actress-card__menu").on("keydown",(j=>{if(j.key!=="Escape")return;j.preventDefault(),$(j.currentTarget).prop("open",!1).find("summary").trigger("focus")})).on("click","[role='menuitem']",(j=>{$(j.currentTarget).closest("details").prop("open",!1)})),this.renderPagination(h,u)}async getNewVideoFlatList(){let e=$("#nvCategoryFilter").val()||"all",t=$("#nvStateFilter").val()||"pending",s=$("#nvDecisionFilter").val()||"pending",a=String($("#nvSearch").val()||"").trim().toUpperCase();return[...this.nvAllItemsMap.values()].filter((i=>{let r=e==="all"||e==="vr"?e==="all"||i.isVr:e==="unknown"?i.categories.length===0:i.categories.includes(e),n=t==="all"||t==="pending"?t==="all"||!oe(i.flags):!!i.flags[t],l=s==="all"||i.decisionState===s,c=!a||`${i.carNum} ${i.title} ${i.actressName}`.toUpperCase().includes(a);return r&&n&&l&&c})).sort(((i,r)=>(r.publishTime||"").localeCompare(i.publishTime||"")))}getActorCoverRequest(e,t){let s=t.get(e);if(s)return s;let a=this.getRuntimeService("scope")().then((i=>this.getRuntimeService("actressInfo").movies("javdb",{actorId:e,baseUrl:this.nvJavDbUrl},{scope:i}))).then((i=>{let r=new Map;return i.forEach((n=>n.carNum&&n.coverUrl&&r.set(T(n.carNum),{coverUrl:n.coverUrl,title:n.title}))),r})).finally((()=>{t.get(e)===a&&t.delete(e)}));return t.set(e,a),a}async loadCoverForItems(e,t=this.nvRenderGeneration){return this.hydrateVisibleCovers(e,t)}async hydrateVisibleCovers(e,t){let s=this.nvCoverCache,a=this.nvActorCoverRequests,i=[...new Set(e.filter((r=>!r.coverUrl&&!s.has(T(r.carNum))&&r.starId)).map((r=>r.starId)))];await $e(i,3,(async r=>{try{let n=await this.getActorCoverRequest(r,a);if(t!==this.nvRenderGeneration||s!==this.nvCoverCache||!this.isWorkspaceMounted())return;n.forEach(((l,c)=>{s.set(T(c),l.coverUrl);let h=$(".nv-card").filter(((p,g)=>T($(g).attr("data-car"))===T(c)));if(!h.length)return;let u=$('<img class="nv-cover-img" loading="lazy">').attr({src:l.coverUrl,"data-full":l.coverUrl}).on("error",(function(){$(this).addClass("jhs-is-hidden").siblings(".nv-card__empty").removeClass("jhs-is-hidden")}));h.find(".nv-placeholder").replaceWith(u),h.find(".nv-card__empty").addClass("jhs-is-hidden"),l.title&&h.attr("title",l.title)}))}catch(n){clog.warn(`获取演员封面失败: ${r}`,n)}}))}async renderNewVideoList(){let e=$("#new-video-list-container"),t=this.nvRenderGeneration;if(!e.length)return;let s=await this.getNewVideoFlatList();if(t!==this.nvRenderGeneration||!this.isWorkspaceMounted())return;$("#nv-pagination-bar").remove(),this.nvFlatListCache=s,this.nvSortBy=$("#nvSortBy").val()||this.nvSortBy;let a=Math.ceil(s.length/this.nvPageSize);if(this.nvCurrentPage=a?Math.min(this.nvCurrentPage,a):1,!s.length){let i=String($("#nvSearch").val()||"").trim(),r=["nvCategoryFilter","nvStateFilter","nvDecisionFilter"].some((n=>$("#"+n).val()!==(n==="nvCategoryFilter"?"all":"pending")));return this.nvAllItemsMap.size?i?Oe(e,{type:"empty",title:`没有找到“${i}”的作品`,actionLabel:"清除搜索",onAction:d(()=>{$("#nvSearch").val(""),this.nvCurrentPage=1,this.nvRenderGeneration++,this.renderNewVideoList()},"onAction")}):r?Oe(e,{type:"empty",title:"没有符合当前筛选条件的作品",actionLabel:"清除筛选",onAction:d(()=>{K.setValue("#nvCategoryFilter","all",!1),K.setValue("#nvStateFilter","pending",!1),K.setValue("#nvDecisionFilter","pending",!1),this.nvCurrentPage=1,this.nvRenderGeneration++,this.renderNewVideoList()},"onAction")}):Oe(e,{type:"empty",title:"暂无待处理的新作品"}):Oe(e,{type:"empty",title:"暂无新作品记录"}),void this.renderBatchBar()}this.nvRenderPage(t),this.renderBatchBar()}selectedItems(){return[...this.nvSelected].map((e=>this.nvAllItemsMap.get(T(e)))).filter(Boolean)}applyProcessedSelection(e){(e?.changed||[]).map(T).filter(Boolean).forEach((t=>this.nvSelected.delete(t))),this.renderBatchBar()}async runBatchMutation(e,t){let s=this.selectedItems();if(!s.length)return void show.info("请先选择作品");try{let a=await e(s);this.applyProcessedSelection(a),a?.changed?.length?show.ok(`${t} ${a.changed.length} 个番号`):show.info("没有需要更新的项目")}catch(a){clog.error("批量操作失败",a),show.error(`批量操作失败: ${a.message||a}`)}}bindBatchActions(){$("#new-video-list-footer").off(".jhsNvBatch").on("click.jhsNvBatch","#nvSelectPage",(()=>{(this.nvCurrentPageItems||[]).forEach((t=>this.nvSelected.add(T(t.carNum)))),$("#new-video-list-container .nv-select").prop("checked",!0),this.renderBatchBar()})).on("click.jhsNvBatch","#nvClearSelection",(()=>{this.nvSelected.clear(),$("#new-video-list-container .nv-select").prop("checked",!1),this.renderBatchBar()})).on("click.jhsNvBatch","#batchMarkFavorite,#batchMarkWatched,#batchMarkDownloaded",(t=>{let s={batchMarkFavorite:"favorite",batchMarkWatched:"watched",batchMarkDownloaded:"downloaded"}[t.currentTarget.id];this.runBatchMutation((a=>this.getRuntimeService("state").patch(a.map((i=>i.carNum)),{[s]:!0},{type:"new-video-batch-state",records:a.map((i=>({carNum:i.carNum,url:i.url||`/search?q=${encodeURIComponent(i.carNum)}`,names:i.actressName,publishTime:i.publishTime})))})),"已处理")})).on("click.jhsNvBatch","#batchIgnore",(()=>{this.runBatchMutation((t=>this.getRuntimeService("state").setNewVideoDecision(t.map((s=>s.carNum)),"ignored")),"已忽略")})).on("click.jhsNvBatch","#batchSnooze",(()=>{this.runBatchMutation((t=>this.getRuntimeService("state").setNewVideoDecision(t.map((s=>s.carNum)),"snoozed",new Date(Date.now()+7*864e5).toISOString())),"已暂缓")})).on("click.jhsNvBatch","#batchRestore",(()=>{this.runBatchMutation((t=>this.getRuntimeService("state").setNewVideoDecision(t.map((s=>s.carNum)),null)),"已恢复")})).on("click.jhsNvBatch","#batchRemoveFromNewVideo",(t=>{let s=this.selectedItems();s.length&&utils.q(t,`确认将 ${s.length} 个作品从新作列表移除?<br>不会删除作品状态记录。`,(()=>{this.runBatchMutation((a=>this.getRuntimeService("state").removeFromNewVideoList(a.map((i=>i.carNum)),"manual")),"已移除")}))}))}renderBatchBar(){let e=$("#new-video-list-footer");if(!e.length)return;let t=new Set(this.nvFlatListCache.flatMap((i=>i.actresses||[i.actressName])).filter(Boolean)),s=this.nvSelected.size,a=this.nvFlatListCache.filter((i=>this.nvSelected.has(T(i.carNum)))).length;if(!s)return void e.html(`<div class="jhs-new-video-batch"><span>共 <b>${this.nvFlatListCache.length}</b> 个番号,涉及 <b>${t.size}</b> 位演员</span><button type="button" class="jhs-btn jhs-btn--secondary" id="nvSelectPage">全选当前页</button></div>`);e.html(`<div class="jhs-new-video-batch"><span>已选择 <b>${s}</b> 项${a!==s?`,当前结果中 ${a} 项`:""}</span><div class="jhs-new-video-batch__actions"><button type="button" class="jhs-btn jhs-btn--secondary" id="batchMarkFavorite">收藏</button><button type="button" class="jhs-btn jhs-btn--secondary" id="batchMarkWatched">已看</button><button type="button" class="jhs-btn jhs-btn--secondary" id="batchMarkDownloaded">已下载</button><details class="jhs-new-video-batch__more"><summary class="jhs-btn jhs-btn--ghost">更多 ▾</summary><div class="jhs-popover jhs-new-video-batch__menu is-open" role="menu"><button type="button" class="jhs-btn jhs-btn--ghost" role="menuitem" id="batchIgnore">忽略</button><button type="button" class="jhs-btn jhs-btn--ghost" role="menuitem" id="batchSnooze">暂缓 7 天</button><button type="button" class="jhs-btn jhs-btn--ghost" role="menuitem" id="batchRestore">恢复</button><button type="button" class="jhs-btn jhs-btn--danger" role="menuitem" id="batchRemoveFromNewVideo">从新作列表移除</button></div></details><button type="button" class="jhs-btn jhs-btn--ghost" id="nvClearSelection">取消选择</button></div></div>`)}nvSortList(e){let t=this.nvSortBy||"publishTime_desc",[s,a]=t.split("_");return e.slice().sort(((i,r)=>{let n=0;switch(s){case"publishTime":n=(i.publishTime||"").localeCompare(r.publishTime||"");break;case"actress":n=(i.actressName||"").localeCompare(r.actressName||"");break;case"carNum":n=(i.carNum||"").localeCompare(r.carNum||"");break;case"voteCount":n=(i.voteCount||0)-(r.voteCount||0);break}return a==="desc"?-n:n}))}nvRenderPage(e=this.nvRenderGeneration){let t=this.nvFlatListCache;if(!t||t.length===0)return;let s=this.nvSortList(t),a=this.nvPageSize,i=(this.nvCurrentPage-1)*a,r=i+a,n=s.slice(i,r),l=Math.ceil(s.length/a),c=this.nvJavDbUrl;if(this.nvCurrentPageItems=n,e!==this.nvRenderGeneration)return;$("#nv-pagination-bar").remove();let h=$("#new-video-list-container"),u="";u+='<div id="nv-grid" class="jhs-new-video-grid">';for(let p of n){let g=T(p.carNum),m=C(g),f=C(p.title||g),v=this.nvCoverCache.get(g),b=C((v||p.coverUrl||"").replace("thumbs","covers")),w=C(p.url||`${c}/search?q=${encodeURIComponent(g)}`),S=`番号: ${m}\\n演员: ${C(p.actressName)}\\n发行: ${C(String(p.publishTime||"未知"))}`;p.voteCount&&(S+=`\\n评价人数: ${p.voteCount}`);let j=p.voteCount?`<span class="jhs-badge jhs-badge--neutral nv-card__rating">${p.voteCount}人评价</span>`:"";u+=`<div class="nv-card" data-car="${m}" title="${S}"><label class="jhs-option-row"><input type="checkbox" class="nv-select" value="${m}" ${this.nvSelected.has(g)?"checked":""}><span>选择</span></label>`,u+=`<a class="nv-card__link" href="${w}" target="_blank" rel="noopener noreferrer">`,u+='<div class="nv-card__cover">',b?u+=`<img class="nv-cover-img" src="${b}" data-full="${b}" loading="lazy" onerror="this.classList.add('jhs-is-hidden');this.nextElementSibling.classList.remove('jhs-is-hidden');">${j}<div class="nv-card__empty jhs-is-hidden">无封面</div>`:u+='<div class="nv-placeholder nv-card__empty">加载中...</div>',u+="</div>",u+='<div class="nv-card__body">',u+=`<div class="nv-card__title" title="${m}">${m}</div>`,u+=`<div class="nv-card__actress" title="${C(p.actressName)}">${C(p.actressName)}</div>`,p.publishTime&&(u+=`<div class="nv-card__date">${C(String(p.publishTime))}</div>`),p.decisionState&&p.decisionState!=="pending"&&(u+=`<span class="jhs-badge jhs-badge--neutral">${p.decisionState==="ignored"?"已忽略":p.decisionState==="dismissed"?"已移除":"已暂缓"}</span>`),u+="</div></a></div>"}if(u+="</div>",l>1){u+='<div id="nv-pagination-bar" class="jhs-new-video-pagination">',this.nvCurrentPage>1&&(u+=`<button type="button" class="jhs-btn jhs-btn--secondary pagination-btn" data-nvpage="${this.nvCurrentPage-1}">上一页</button>`);let p=Math.max(1,this.nvCurrentPage-2),g=Math.min(l,p+4);g-p<4&&(p=Math.max(1,g-4));for(let m=p;m<=g;m++)u+=`<button type="button" class="jhs-btn jhs-btn--secondary ${m===this.nvCurrentPage?"is-current":""} pagination-btn" data-nvpage="${m}" ${m===this.nvCurrentPage?'aria-current="page"':""}>${m}</button>`;this.nvCurrentPage<l&&(u+=`<button type="button" class="jhs-btn jhs-btn--secondary pagination-btn" data-nvpage="${this.nvCurrentPage+1}">下一页</button>`),u+=`<span class="jhs-pagination__summary">第 ${this.nvCurrentPage}/${l} 页,共 ${s.length} 条</span>`,u+="</div>"}h.html(u),h.find(".nv-cover-img").on("error",(function(){$(this).addClass("jhs-is-hidden").siblings(".nv-card__empty").removeClass("jhs-is-hidden")})),h.find(".nv-select").on("change",(p=>{let g=T(p.currentTarget.value);p.currentTarget.checked?this.nvSelected.add(g):this.nvSelected.delete(g),this.renderBatchBar()})),h.find(".pagination-btn").off("click").on("click",(p=>{let g=parseInt($(p.currentTarget).data("nvpage"));g>=1&&g<=l&&g!==this.nvCurrentPage&&(this.nvCurrentPage=g,this.nvRenderGeneration++,this.nvRenderPage(this.nvRenderGeneration),this.renderBatchBar(),h.scrollTop(0))})),h.find("#nv-pagination-bar").insertAfter(h),this.nvCoverPreview??(this.nvCoverPreview=new window.ImageHoverPreview({selector:".nv-cover-img",dataAttribute:"data-full",owner:this.nvWorkspaceRoot,resolveOwner:d(()=>this.nvWorkspaceRoot,"resolveOwner"),zIndexStrategy:"owner"})),this.hydrateVisibleCovers(n,e)}async editActress(e){let t=this.getRuntimeService("dialog"),s=null,a=String(e.name||""),i=gt(e.avatar,this.nvJavDbUrl)||"",r=String(e.remark||""),n=Array.isArray(e.allName)?e.allName.join(","):"",l=Array.isArray(e.newVideoList)?e.newVideoList.map((g=>typeof g=="string"?g:g.carNum)).join(","):"",c=String(e.starId||""),h=e.actressType||"",u=d(g=>C(String(g||"")),"safe"),p=`
            <div class="jhs-form-dialog">
                <div class="jhs-avatar-editor">
                    <img id="edit-avatar-preview" src="${u(i)}" alt="Avatar Preview"
                         class="jhs-avatar-editor__preview">
                    <div class="jhs-form-dialog__body">
                        <label class="jhs-form-label">头像链接:</label>
                        <input type="text" id="edit-actress-avatar" value="${u(i)}"
                               class="jhs-field">
                       <div class="jhs-toolbar jhs-avatar-editor__actions">
                            <button type="button" id="search-avatar-btn"
                                class="jhs-btn jhs-btn--secondary">
                                搜索头像
                            </button>
                            <button type="button" id="select-cdn-btn"
                                class="jhs-btn jhs-btn--secondary">
                                选择 CDN 源
                            </button>
                        </div>
                    </div>
                </div>
                <div class="jhs-form-field">
                    <label class="jhs-form-label">主名称:</label>
                    <input type="text" id="edit-actress-name" value="${u(a)}"
                           class="jhs-field">
                </div>
                <div class="jhs-form-field">
                    <label class="jhs-form-label">所有别名(用逗号隔开):</label>
                    <textarea id="edit-actress-allname" class="jhs-textarea">${u(n)}</textarea>
                </div>
                <div class="jhs-form-field">
                    <label class="jhs-form-label">演员类别:</label>
                    <select id="actressType" class="jhs-select-source">
                        <option value="" ${h===""?"selected":""}>未知</option>
                        <option value="censored" ${h==="censored"?"selected":""}>有码</option>
                        <option value="uncensored" ${h==="uncensored"?"selected":""}>无码</option>
                    </select>
                </div>
                <div class="jhs-form-field">
                    <label class="jhs-form-label">最新作品(用逗号隔开):</label>
                    <textarea id="edit-actress-newvideolist" class="jhs-textarea">${u(l)}</textarea>
                </div>
                <div class="jhs-form-field">
                    <label class="jhs-form-label">备注:</label>
                   <textarea id="edit-remark" class="jhs-textarea">${u(r)}</textarea>
                </div>
            </div>
        `;t.open({type:1,title:`编辑女优: ${u(a)} (${u(c)})`,ui:{size:"sm",body:"scroll"},area:utils.getDialogArea("sm"),content:p,btn:["保存","取消"],success:d((g,m)=>{s=$(g),this._editActressRoot=s,K.enhance(g);let f=d(w=>{w.css("height","auto"),w.css("height",w[0].scrollHeight+15+"px")},"n");s.find("#edit-actress-avatar").on("input",(function(){let w=$(this).val();s.find("#edit-avatar-preview").attr("src",w)}));let v=s.find("#edit-actress-allname");v.on("input",(function(){f($(this))})),f(v);let b=s.find("#edit-actress-newvideolist");b.on("input",(function(){f($(this))})),f(b),s.find("#search-avatar-btn").on("click",(async()=>{await this.searchAvatar()})),s.find("#select-cdn-btn").on("click",(async()=>{await(async()=>{let w=this.avatarSourceIndex,S=this.avatarSources.map(((k,x)=>`
        <label class="jhs-option-row" for="cdn-${x}">
            <input type="radio" id="cdn-${x}" name="cdn-source" value="${x}" ${x===w?"checked":""}>
            <span>${k.name} ${k.recommended?"(推荐)":""}</span>
        </label>
    `)).join(""),j=`
        <div class="jhs-form-dialog">
            <p class="jhs-form-dialog__title">请选择头像数据源 (当前: ${this.avatarSources[w]?.name||"无可用来源"}):</p>
            ${S}
            <p class="jhs-helper-text">切换后将在下次搜索时使用所选来源。</p>
        </div>
    `;t.open({type:1,title:"选择 CDN 源",area:utils.getResponsiveArea(["400px","auto"]),content:j,btn:["确定","取消"],success:d((k,x)=>{utils.setupEscClose(x)},"success"),yes:d(async k=>{let x=$('input[name="cdn-source"]:checked').val(),_=parseInt(x,10);_!==this.avatarSourceIndex&&this.avatarSources[_]&&(this.avatarSourceIndex=_,this.getRuntimeService("storage").setLocal($c,_.toString()),show.ok(`CDN 源已切换为: ${this.avatarSources[_].name}`)),t.close(k)},"yes")})})()})),utils.setupEscClose(m)},"success"),yes:d(async g=>{let m=s||$(document),f=m.find("#edit-actress-avatar").val().trim(),v=m.find("#edit-actress-name").val().trim(),b=m.find("#edit-actress-allname").val().trim(),w=m.find("#edit-actress-newvideolist").val().trim(),S=m.find("#edit-remark").val().trim(),j=m.find("#actressType").val();if(!v)return show.error("主名称不能为空"),!1;let k=b.split(/[\uff0c,]/).map((_=>_.trim())).filter((_=>_.length>0)),x=w.split(/[\uff0c,]/).map((_=>_.trim())).filter((_=>_.length>0));e.avatar=f,e.name=v,e.allName=k,e.newVideoList=x,e.actressType=j,e.remark=S;try{await storageManager.updateFavoriteActress(e),await F.emit("new-video-changed",{reason:"favorite-actress-edited"}),show.ok(`女优 ${v} 信息已更新`),t.close(g)}catch(_){show.error("修改失败: "+(_.message||_))}},"yes")})}renderPagination(e,t){let s=this.currentPage,a="",i=$("#actress-pagination");if(t===0)return a='<span class="jhs-pagination__summary">共 0 条记录</span>',void i.html(a);s>1&&t>5&&(a+='<button type="button" class="jhs-btn pagination-btn" data-page="1">首页</button>'),s>1&&(a+=`<button type="button" class="jhs-btn pagination-btn" data-page="${s-1}">上一页</button>`);let r=Math.max(1,s-Math.floor(2.5)),n=Math.min(t,r+5-1);n-r<4&&(r=Math.max(1,n-5+1));for(let l=r;l<=n;l++)a+=`<button type="button" class="jhs-btn pagination-btn page-number-btn ${l===s?"active":""}" data-page="${l}" ${l===s?'aria-current="page"':""}>${l}</button>`;s<t&&(a+=`<button type="button" class="jhs-btn pagination-btn" data-page="${s+1}">下一页</button>`),s<t&&t>5&&(a+=`<button type="button" class="jhs-btn pagination-btn" data-page="${t}">尾页</button>`),a+=`<span class="jhs-pagination__summary">共 ${e} 条记录 (第 ${s}/${t} 页)</span>`,i.html(a),i.find(".pagination-btn").off("click").on("click",(l=>{if($(l.currentTarget).is("[disabled]"))return;let c=parseInt($(l.currentTarget).data("page"));c>=1&&c<=t&&c!==this.currentPage&&(this.currentPage=c,this.renderActressCards())}))}async searchAvatar(){let e=this.getRuntimeService("dialog"),t=this._editActressRoot||$(document),s=t.find("#edit-actress-name"),a=t.find("#edit-actress-allname"),i=s.val().trim(),r=a.val().trim().split(/[\uff0c,]/).map((p=>p.trim())).filter((p=>p.length>0));if(i&&r.unshift(i),r.length===0)return void show.error("请先填写女优主名称或别名进行搜索。");let n=loading("正在搜索头像..."),l=[];try{let p=this.avatarSources[this.avatarSourceIndex],g=await this.getRuntimeService("scope")();l=p?await this.getRuntimeService("actressInfo").searchAvatars(r,p.id,{scope:g}):[]}catch(p){return void show.error(`头像数据加载或搜索失败: ${p.message||p}`)}finally{n.close()}if(l.length===0)return void show.error(`未找到与 '${r.join("、")}' 相关的头像。请检查名称。`);let c=$('<div id="gfriends-image-list-container"><p id="gfriends-prompt"></p><div id="gfriends-image-list" role="group" aria-label="头像候选"></div></div>');c.find("#gfriends-prompt").text(`点击图片即可选择(初始共 ${l.length} 张)`);let h=c.find("#gfriends-image-list");l.forEach(((p,g)=>{let m=$('<button type="button" class="jhs-btn gfriends-image-item-wrapper" aria-pressed="false"></button>').attr({"data-url":p,"aria-label":`选择第 ${g+1} 张头像`});m.append($('<img class="gfriends-selectable-img" alt="">').attr("src",p)),m.append($('<span class="gfriends-size-tag">载入中</span>')),h.append(m)}));let u=0;e.open({type:1,title:`选择女优头像 (${l.length} 张)`,area:utils.getResponsiveArea(["900px","85%"]),content:c[0],btn:["关闭"],success:d((p,g)=>{let m=$(p),f=m.find(".gfriends-selectable-img"),v=m.find("#gfriends-prompt"),b=m.find(".gfriends-image-item-wrapper");f.each((function(){let w=$(this),S=w.closest(".gfriends-image-item-wrapper"),j=S.find(".gfriends-size-tag");w.on("load",(function(){j.text(`${this.naturalWidth} x ${this.naturalHeight}`)})),w.on("error",(function(){S.remove(),u++;let k=l.length-u;v.text(`点击图片即可选择(已移除 ${u} 张错误图片,剩余 ${k} 张)`),k===0&&(show.error("所有搜索到的头像链接均已失效,无法选择。"),e.close(g))})),this.complete&&(this.naturalWidth>0?w.trigger("load"):w.trigger("error"))})),b.on("click",(function(){let w=$(this),S=w.attr("data-url");t.find("#edit-actress-avatar").val(S),t.find("#edit-avatar-preview").attr("src",S),b.attr("aria-pressed","false"),w.attr("aria-pressed","true"),setTimeout((()=>{e.close(g)}),150)})),utils.setupEscClose(g)},"success")})}};d(nn,"NewVideoPlugin");var ba=nn;var on=class on{constructor(){this.queue=Promise.resolve()}addTask(e){let t=this.queue.then((()=>e()));return this.queue=t.catch((s=>{clog.error("执行异步队列任务失败:",s)})),t}async waitAllFinished(){return this.queue}};d(on,"StorageQueue");var wa=on;var ln=class ln extends I{constructor(){super(...arguments),this.singleTaskKey="checkNewActressActorFilterCar",this.taskConfig=null,this.storageQueue=new wa,this.lastCheckFavoriteActressTimeKey="jhs_time_checkFavoriteActress",this.lastCheckBlacklistTimeKey="jhs_time_checkBlacklist",this.lastCheckNewVideoTimeKey="jhs_time_checkNewVideo",this.lastCheckFavoriteActressAttemptKey="jhs_time_checkFavoriteActress_attempt",this.lastCheckFavoriteActressNextKey="jhs_time_checkFavoriteActress_next",this.lastCheckBlacklistAttemptKey="jhs_time_checkBlacklist_attempt",this.lastCheckBlacklistNextKey="jhs_time_checkBlacklist_next",this.lastCheckNewVideoAttemptKey="jhs_time_checkNewVideo_attempt",this.lastCheckNewVideoNextKey="jhs_time_checkNewVideo_next",this.taskTimer=null,this.taskRunning=!1,this.visibilityHandler=null,this.pageHideHandler=null,this.lifecycleScope=null,this.settingsHandler=null,this.taskConfigDirty=!1,this.configLoadPromise=null,this.configLoadQueued=!1,this.configRefreshPromise=null,this.configRefreshQueued=!1,this.activeTasks=new Set}getName(){return"TaskPlugin"}getStartupMode(){return"idle"}async limitConcurrency(e,t,s,a){let i=0,r=!1,n=Math.max(1,Math.min(t,e.length)),l=Array.from({length:n},(async()=>{for(;!r;){let u=i++;if(u>=e.length)return;try{await a(e[u])}catch(g){throw this.isNetworkBlocked(g)&&(r=!0),g}let p=e.length-i;p>0&&(clog.htmlDebug(`剩余任务数: <span class="jhs-task-emphasis">${p}</span>`),await utils.sleep(s))}})),c=await Promise.allSettled(l),h=c.find(u=>u.status==="rejected");if(h)throw h.reason}isNetworkBlocked(e){return["CF_BLOCKED","CIRCUIT_OPEN","ABORTED"].includes(e?.code)||e?._cfBlocked===!0||e?._circuitBroken===!0}async requestHostPage(e,t){let s=new URL(e),a=t===Be?"javdb.com":t===je?"javbus.com":null,r=a&&(s.hostname===a||s.hostname.endsWith(`.${a}`))?{trustClass:"builtin-public",hosts:[a],expectedOrigin:s.origin}:{trustClass:"custom-public",expectedOrigin:s.origin};try{let n=await this.getRuntimeService("http").request({providerId:`host-task:${t}`,method:"GET",url:s.href,responseType:"text",cacheScope:"none",timeout:this.taskConfig?.httpTimeout,retryCount:Math.max(0,(this.taskConfig?.httpRetryCount??1)-1),circuitThreshold:this.taskConfig?.circuitBreakerThreshold,circuitCooldownMs:this.taskConfig?.circuitBreakerCooldown,urlPolicy:r},await this.getRuntimeService("scope")());if(typeof n.data!="string")throw new TypeError("宿主页面响应不是 HTML 文本");return n.data}catch(n){let l=n;throw l._taskNetwork=!0,l}}createTaskResult(e={}){return{attempted:!1,completed:!1,fatal:!1,success:0,networkFailed:0,parseFailed:0,aborted:0,skippedInterval:0,skippedStopped:0,...e}}async runBackgroundTask(e,t){try{return await t()}catch(s){if(this.isNetworkBlocked(s))throw s;return clog.error(`${e}执行失败,继续后续后台任务`,s),this.createTaskResult({attempted:!0,error:s})}}isUnnecessaryCheck(e,t){if(!t)throw new Error("未传入checkIntervalTime");return t=parseInt(String(t)),utils.getHourDifference(new Date(e),new Date)<t}getTaskSchedule(e){let t={blacklist:{completedKey:this.lastCheckBlacklistTimeKey,attemptKey:this.lastCheckBlacklistAttemptKey,nextKey:this.lastCheckBlacklistNextKey,intervalSetting:"checkBlacklist_intervalTime",defaultInterval:12},favoriteActress:{completedKey:this.lastCheckFavoriteActressTimeKey,attemptKey:this.lastCheckFavoriteActressAttemptKey,nextKey:this.lastCheckFavoriteActressNextKey,intervalSetting:"checkFavoriteActress_IntervalTime",defaultInterval:24},newVideo:{completedKey:this.lastCheckNewVideoTimeKey,attemptKey:this.lastCheckNewVideoAttemptKey,nextKey:this.lastCheckNewVideoNextKey,intervalSetting:"checkNewVideo_intervalTime",defaultInterval:12}};if(!t[e])throw new Error(`未知任务调度: ${e}`);return t[e]}getTaskScheduleState(e){let t=this.getRuntimeService("storage"),s=this.getTaskSchedule(e),a=_e(t.getLocal(s.completedKey)),i=_e(t.getLocal(s.attemptKey));return{...s,completed:a,attempt:i,pending:i!=null&&(a==null||i>a)}}getTaskStatusSnapshot(e){let t=this.getTaskScheduleState(e),s=_e(this.getRuntimeService("storage").getLocal(t.nextKey)),a=s??(t.pending&&t.attempt!=null?t.attempt+3e5:0),i=Date.now(),r="idle";return this.activeTasks.has(e)?r="running":t.pending&&i<a?r="pending":(s==null||i>=a)&&(r="due"),{name:e,state:r,completedAt:t.completed,attemptAt:t.attempt,nextAt:a,isPending:t.pending,pendingUntil:t.pending?a:null}}async emitTaskStatus(e,t){try{await globalThis.jhsEventBus?.emit?.("task-status-changed",{taskName:e,phase:t},{broadcast:!1})}catch(s){clog.error(`任务状态通知失败: ${e}/${t}`,s)}}async emitNewVideoChanged(e,t=[]){try{await globalThis.jhsEventBus?.emit?.("new-video-changed",{reason:e,carNums:t.map(T).filter(Boolean)})}catch(s){clog.error("新作品状态通知失败",s)}}async withActiveTask(e,t){this.activeTasks.add(e);try{return await this.emitTaskStatus(e,"started"),await t()}finally{this.activeTasks.delete(e),await this.emitTaskStatus(e,"finished")}}async getLatestTaskInterval(e){let t=this.getTaskSchedule(e);return storageManager._invalidateCache?.(storageManager.setting_key),ae(await storageManager.getSetting(t.intervalSetting,t.defaultInterval),t.defaultInterval,{min:Number.EPSILON})}async shouldStartTask(e,t=!1){if(t)return!0;let s=this.getRuntimeService("storage"),a=this.getTaskSchedule(e),i=await this.getLatestTaskInterval(e),r=_e(s.getLocal(a.completedKey)),n=_e(s.getLocal(a.attemptKey)),l=_e(s.getLocal(a.nextKey));return l==null&&(l=n!=null&&(r==null||n>r)?n+3e5:r==null?0:r+36e5*i,s.setLocal(a.nextKey,String(l))),Date.now()>=l}beginTaskAttempt(e){let t=this.getRuntimeService("storage"),s=this.getTaskSchedule(e),a=_e(t.getLocal(s.completedKey)),i=Math.floor(Date.now()/1e3)*1e3,r=a==null?i:Math.max(i,a+1e3);return t.setLocal(s.attemptKey,String(r)),t.setLocal(s.nextKey,String(r+3e5)),r}async finalizeTask(e,t){let s=this.getRuntimeService("storage"),a=this.getTaskSchedule(e);if(!t)return s.setLocal(a.nextKey,String(Date.now()+3e5));let i=_e(s.getLocal(a.attemptKey))||0,r=Math.max(Math.floor(Date.now()/1e3)*1e3,i),n=await this.getLatestTaskInterval(e);s.setLocal(a.completedKey,utils.getNowStr("-",":",r)),s.setLocal(a.nextKey,String(r+36e5*n))}async recalculateSchedules(){await this.loadConfig();for(let[e,t]of[["blacklist",this.taskConfig.checkBlacklist_intervalTime],["favoriteActress",this.taskConfig.checkFavoriteActress_IntervalTime],["newVideo",this.taskConfig.checkNewVideo_intervalTime]]){let s=this.getTaskScheduleState(e);s.pending||this.getRuntimeService("storage").setLocal(s.nextKey,String(s.completed==null?Date.now():s.completed+36e5*t))}}async invalidateConfig(e=!1){if(this.taskConfigDirty=!0,!!e)return this.configRefreshPromise?(this.configRefreshQueued=!0,this.configRefreshPromise):(this.configRefreshPromise=(async()=>{do this.configRefreshQueued=!1,await this.recalculateSchedules();while(this.configRefreshQueued)})().finally((()=>{this.configRefreshPromise=null})),this.configRefreshPromise)}async handle(){if(window.isListPage)return this.lifecycleScope||(this.lifecycleScope=await this.getRuntimeService("scope")()),this.visibilityHandler||(this.visibilityHandler=()=>{document.hidden?this.clearSchedule():this.scheduleTask(0)},this.pageHideHandler=()=>this.clearSchedule(),this.lifecycleScope.listen(document,"visibilitychange",this.visibilityHandler),this.lifecycleScope.listen(window,"pagehide",this.pageHideHandler),this.lifecycleScope.addCleanup((()=>this.clearSchedule()))),this.settingsHandler||(this.settingsHandler=async()=>{try{storageManager._invalidateCache?.(storageManager.setting_key),await this.invalidateConfig(!0),this.scheduleTask(0)}catch(e){clog.error("任务设置刷新失败",e)}},this.lifecycleScope.addCleanup(globalThis.jhsEventBus?.on?.("settings-changed",this.settingsHandler)||(()=>{}))),document.hidden?void 0:this.runAndSchedule()}clearSchedule(){this.taskTimer&&(clearTimeout(this.taskTimer),this.taskTimer=null)}scheduleTask(e=3e5){if(!window.isListPage||document.hidden)return void this.clearSchedule();this.clearSchedule(),this.taskTimer=setTimeout((()=>{this.taskTimer=null,this.runAndSchedule()}),e)}async runAndSchedule(){if(!(this.taskRunning||!window.isListPage||document.hidden)){this.taskRunning=!0;try{await this.doTask()}finally{this.taskRunning=!1,this.scheduleTask()}}}async doTask(){if(window.isListPage)return await this.loadConfig(),this.javDbUrl=await this.getConfiguredSiteOrigin("javDbBtn"),navigator.locks.request(this.singleTaskKey,{ifAvailable:!0},(async e=>{e?window.isListPage&&(this.taskConfig.enableCheckBlacklist===R?await this.runBackgroundTask("黑名单整批检测",(()=>this.checkBlacklist())):clog.warn("自动检测屏蔽黑名单-禁用"),!B)&&(this.taskConfig.enableCheckFavoriteActress===R?$('a[href*="/users/profile"]').length>0?await this.runBackgroundTask("演员收藏同步",(()=>this.checkFavoriteActress())):clog.debug("未登录 JavDB,跳过自动同步演员"):clog.warn("自动同步已收藏的演员-禁用"),this.taskConfig.enableCheckNewVideo===R?await this.runBackgroundTask("新作品整批检测",(()=>this.checkNewVideo())):clog.warn("自动检测已收藏演员的最新作品-禁用")):clog.debug("争夺任务锁失败, 跳过执行")})).catch((e=>{this.isNetworkBlocked(e)?clog.warn(`后台检测已停止: ${e.message}`):clog.error("锁任务出现错误:",e)}))}async loadConfig(){return this.configLoadPromise?(this.configLoadQueued=!0,this.configLoadPromise):(this.configLoadPromise=(async()=>{do{this.configLoadQueued=!1;let e=await storageManager.getSetting(),t={checkConcurrencyCount:ae(e.checkConcurrencyCount,2,{min:2,max:5}),checkRequestSleep:ae(e.checkRequestSleep,100,{min:0,max:3e3}),enableCheckBlacklist:e.enableCheckBlacklist||R,checkBlacklist_intervalTime:ae(e.checkBlacklist_intervalTime,12,{min:Number.EPSILON}),checkBlacklist_ruleTime:ae(e.checkBlacklist_ruleTime,8760,{min:0}),enableCheckFavoriteActress:e.enableCheckFavoriteActress||R,checkFavoriteActress_IntervalTime:ae(e.checkFavoriteActress_IntervalTime,24,{min:Number.EPSILON}),enableCheckNewVideo:e.enableCheckNewVideo||R,checkNewVideo_intervalTime:ae(e.checkNewVideo_intervalTime,12,{min:Number.EPSILON}),checkNewVideo_ruleTime:ae(e.checkNewVideo_ruleTime,8760,{min:0}),httpTimeout:ae(e.httpTimeout,5e3,{min:1e3,max:12e4}),httpRetryCount:ae(e.httpRetryCount,3,{min:0,max:5}),circuitBreakerThreshold:ae(e.circuitBreakerThreshold,3,{min:1,max:20}),circuitBreakerCooldown:ae(e.circuitBreakerCooldown,6e4,{min:1e3,max:36e5})};this.taskConfig=t,this.taskConfigDirty=!1}while(this.configLoadQueued||this.taskConfigDirty);return this.taskConfig})().finally((()=>{this.configLoadPromise=null})),this.configLoadPromise)}async ensureReady(){if((!this.taskConfig||this.taskConfigDirty)&&await this.loadConfig(),this.javDbUrl||(this.javDbUrl=await this.getConfiguredSiteOrigin("javDbBtn")),!this.javDbUrl)throw new Error("JavDB 地址未配置")}async getConfiguredSiteOrigin(e){return this.getRuntimeService("movie").externalSiteOrigin(e,await storageManager.getSetting())}async resolveBlacklistSite(e){try{let t=new URL(e),[s,a]=await Promise.all([this.getConfiguredSiteOrigin("javDbBtn"),this.getConfiguredSiteOrigin("javBusBtn")]);for(let[r,n]of[[s,Be],[a,je]])try{if(r&&t.hostname===new URL(r).hostname)return n}catch(l){clog.warn(`忽略无效的站点配置: ${r}`,l)}let{site:i}=gs(e);return[Be,je].includes(i)?i:null}catch{return null}}async checkBlacklist(e=!1){let t=this.createTaskResult({skippedHost:0}),s=this.getOptionalDependency("BlacklistPlugin");return s?(await this.ensureReady(),await this.shouldStartTask("blacklist",e)?(this.beginTaskAttempt("blacklist"),t.attempted=!0,this.withActiveTask("blacklist",async()=>{let a=null,i=!1;try{let r=await storageManager.getBlacklist();r=r.sort(((m,f)=>m.createTime<f.createTime?1:m.createTime>f.createTime?-1:0));let n=this.taskConfig.checkConcurrencyCount,l=this.taskConfig.checkRequestSleep,c=this.taskConfig.checkBlacklist_intervalTime,h=this.taskConfig.checkBlacklist_ruleTime,u=[],p=new URL(window.location.href).hostname;for(let m of r){let f;try{f=new URL(m.url)}catch(v){t.parseFailed++,clog.error("黑名单地址无效:",m.url,v);continue}if(p!==f.hostname){t.skippedHost++;continue}if(!e&&m.checkTime&&this.isUnnecessaryCheck(m.checkTime,c))t.skippedInterval++;else if(pt(m.lastPublishTime,h))t.skippedStopped++;else{let v=await this.resolveBlacklistSite(f.href);v?u.push({item:m,site:v}):(t.parseFailed++,clog.error(`不支持的黑名单来源站点: ${f.hostname}`))}}clog.html(`<span class="jhs-task-emphasis">检测屏蔽黑名单, 总任务数: ${u.length}, 并发限制:${n}, 请求间隔时间:${l}ms</span>`);try{await this.limitConcurrency(u,n,l,(async m=>{let{item:f,site:v}=m,{starId:b,name:w,url:S}=f,j;try{clog.log("正在检屏黑名单演员:",w,S),$("#checkBlacklistMsg").text(`正在检屏黑名单演员: ${w} ${S}`),j=await this.requestHostPage(S,v)}catch(k){if(t.networkFailed++,this.isNetworkBlocked(k))throw k;return void clog.error("检测屏蔽演员网络错误:",S,k)}try{let k=utils.htmlTo$dom(j);await this.storageQueue.addTask((async()=>{let x=await s.parseAndSaveFilterInfo(k,w,b,v);await storageManager.updateBlacklistItem({starId:b,name:w,checkTime:utils.getNowStr(),lastPublishTime:x.lastPublishTime})})),t.success++}catch(k){t.parseFailed++,clog.error("解析或保存黑名单演员失败:",S,k)}})),await this.storageQueue.waitAllFinished()}catch(m){if(!this.isNetworkBlocked(m))throw m;a=m,t.aborted=Math.max(0,u.length-t.success-t.parseFailed-t.networkFailed)}let g=t.parseFailed+t.networkFailed+t.aborted===0;t.completed=g,t.fatal=!!a,await this.finalizeTask("blacklist",g),i=!0,this.renderBlacklistResult(t,g);try{await s.resetBtnTip()}catch(m){clog.error("刷新黑名单检测提示失败",m)}if(a)throw a;return t}catch(r){if(i||await this.finalizeTask("blacklist",!1),t.completed=!1,t.fatal=this.isNetworkBlocked(r),t.fatal)throw r;return t.parseFailed++,clog.error("黑名单整批检测失败",r),t}})):(clog.debug("检测黑名单未到整批执行时间"),t)):(clog.warn("黑名单功能已禁用,跳过自动检测"),t)}renderBlacklistResult(e,t){let s=t?"":",5 分钟后补偿未完成项",a=`黑名单整批检测:成功 ${e.success},解析/存储失败 ${e.parseFailed},网络失败 ${e.networkFailed},停更跳过 ${e.skippedStopped},间隔跳过 ${e.skippedInterval},异站跳过 ${e.skippedHost}${e.aborted?`,未执行 ${e.aborted}`:""}${s}`;$("#checkBlacklistMsg").text(a),clog.log(a)}async checkFavoriteActress(e=!1){await this.ensureReady();let t=this.createTaskResult({pages:0,actorCount:0});return await this.shouldStartTask("favoriteActress",e)?(this.beginTaskAttempt("favoriteActress"),t.attempted=!0,this.withActiveTask("favoriteActress",async()=>{try{let s=[],a=await this.scrapeActorInfo(`${this.javDbUrl}/users/collection_actors`,s);return s.length>0&&await storageManager.addFavoriteActressList(s),t.success=s.length,t.actorCount=s.length,t.pages=a.pages,await this.finalizeTask("favoriteActress",!0),t.completed=!0,clog.log("所有演员信息已收集, 总计数量:",s.length),$("#checkNewVideoMsg").text(`完整同步完成:演员 ${s.length},页面 ${a.pages}`),s.length>0&&await this.emitNewVideoChanged("favorite-actress-sync"),t}catch(s){let a=s;if(t.completed=!1,a?._taskNetwork?t.networkFailed++:t.parseFailed++,t.fatal=this.isNetworkBlocked(a),await this.finalizeTask("favoriteActress",!1),$("#checkNewVideoMsg").text("演员同步失败,5 分钟后重试整轮"),clog.error("同步收藏演员失败",a),t.fatal)throw s;return t}})):(clog.debug("同步收藏演员未到整批执行时间"),t)}async scrapeActorInfo(e,t=[]){let s=new URL("/users/collection_actors",this.javDbUrl),a=new Set,i=new URL(e,this.javDbUrl),r=0;for(;i;)try{if(i.origin!==s.origin||i.pathname!==s.pathname)throw new Error(`收藏演员分页地址越界: ${i.href}`);if(a.has(i.href))throw new Error(`收藏演员分页循环: ${i.href}`);if(r>=200)throw new Error("收藏演员分页超过 200 页");a.add(i.href),r++,clog.log(`正在抓取页面: ${i.href}`),$("#checkNewVideoMsg").text(`正在解析已收藏的演员: ${i.href}`);let n=await this.getRuntimeService("actressInfo").collection("javdb",{baseUrl:this.javDbUrl,pageUrl:i.href},{scope:await this.getRuntimeService("scope")()});if(n.state!=="valid")throw Object.assign(new Error(`收藏演员页面无效: ${n.state}`),{_taskParse:!0});if(n.isEmpty&&n.nextUrl)throw Object.assign(new Error("收藏演员空页面包含下一页"),{_taskParse:!0});t.push(...n.actors),i=n.nextUrl?new URL(n.nextUrl,i.href):null}catch(n){let l=["NETWORK_ERROR","TIMEOUT","AUTH_REQUIRED","RATE_LIMITED","CF_BLOCKED","CIRCUIT_OPEN","ABORTED"],c=n;throw l.includes(c?.code)&&(c._taskNetwork=!0),c._taskNetwork||Object.prototype.hasOwnProperty.call(c,"_taskParse")||(c._taskParse=!0),clog.error(`抓取 ${i?.href||e} 时发生错误,停止本轮同步:`,c),c}return{actors:t,pages:r}}async checkNewVideo(e=!1){await this.ensureReady();let t=this.createTaskResult();return await this.shouldStartTask("newVideo",e)?(this.beginTaskAttempt("newVideo"),t.attempted=!0,this.withActiveTask("newVideo",async()=>{let s=null,a=!1;try{let i=await storageManager.getFavoriteActressList(),r=utils.genericSort(i,[{key:d(g=>g.newVideoList?.length??0,"key"),order:"desc"},{key:"lastPublishTime",order:"desc"}]),n=this.taskConfig.checkConcurrencyCount,l=this.taskConfig.checkRequestSleep,c=this.taskConfig.checkNewVideo_intervalTime,h=this.taskConfig.checkNewVideo_ruleTime,u=[];for(let g of r)!e&&g.lastCheckTime&&this.isUnnecessaryCheck(g.lastCheckTime,c)?t.skippedInterval++:pt(g.lastPublishTime,h)?t.skippedStopped++:u.push(g);if(clog.html(`<span class="jhs-task-emphasis">检测最新作品, 总任务数: ${u.length}, 并发限制:${n}, 请求间隔时间:${l}ms</span>`),u.length>0){let g=await storageManager.getTitleFilterKeyword(),m=await storageManager.getBlacklistCarList(),f=new Set(m.map(v=>v.carNum));try{await this.limitConcurrency(u,n,l,(async v=>{let{name:b,starId:w}=v,S=`${this.javDbUrl}/actors/${w}?t=d`;try{clog.log("正在检测最新作品, 演员:",b,S),$("#checkNewVideoMsg").text(`正在检测最新作品, 演员: ${b}`);let j=await this.getRuntimeService("actressInfo").movies("javdb",{actorId:w,baseUrl:this.javDbUrl},{scope:await this.getRuntimeService("scope")(),ttlMs:0});try{await this.storageQueue.addTask((async()=>this.parseActorMovies(j,w,b,g,f))),t.success++}catch(k){t.parseFailed++,clog.error("解析或保存演员作品失败:",S,k)}}catch(j){if(this.isNetworkBlocked(j))throw t.networkFailed++,j;t.networkFailed++,clog.error("检测演员信息发生网络错误:",S,j)}})),await this.storageQueue.waitAllFinished()}catch(v){if(!this.isNetworkBlocked(v))throw v;s=v,t.fatal=!0,t.aborted=Math.max(0,u.length-t.success-t.parseFailed-t.networkFailed),clog.warn(`网络阻断,本轮停止,未执行 ${t.aborted}`)}}let p=t.parseFailed+t.networkFailed+t.aborted===0;if(t.completed=p,await this.finalizeTask("newVideo",p),a=!0,clog.html('<span class="jhs-task-emphasis">检测最新作品---结束</span>'),this.renderCheckResult(t,p?i.length?"整批检测结束":"收藏为空,整批检测完成":"整批检测未完成,5 分钟后补偿未完成项"),t.success>0&&await this.emitNewVideoChanged("task-completed"),s)throw s;return t}catch(i){if(a||await this.finalizeTask("newVideo",!1),t.completed=!1,t.fatal=this.isNetworkBlocked(i),t.fatal)throw i;return t.parseFailed++,this.renderCheckResult(t,"整批检测失败,5 分钟后补偿"),clog.error("新作品整批检测失败",i),t}})):(clog.debug("检测新作品未到整批执行时间"),t)}renderCheckResult(e,t="检测结束"){let s=`${t}:成功 ${e.success},解析/存储失败 ${e.parseFailed},网络失败 ${e.networkFailed},停更跳过 ${e.skippedStopped},间隔跳过 ${e.skippedInterval}${e.aborted?`,未执行 ${e.aborted}`:""}`;$("#checkNewVideoMsg").text(s),clog.log(s)}async parsePage(e,t,s,a,i,r){let n=this.getSelector(t);t===je&&e.find(".avatar-box").length>0&&e.find(".avatar-box").parent().remove();let l=Hs(e,{boxSelector:t===je?`${n.boxSelector}, #waterfall`:n.boxSelector,requestDomItemSelector:n.requestDomItemSelector});if(l.state!=="valid")throw clog.error("新作品检测-解析列表失败"),new Error("新作品检测-解析列表失败");let c=l.items,h=e.find(n.nextPageSelector).attr("href");if(c.length===0&&h)throw new Error("新作品检测-空列表包含下一页");if(c.length===0)return await storageManager.updateFavoriteActress({starId:s,lastCheckTime:utils.getNowStr(),newVideoList:[]}),0;let u=[],p=[];for(let w of c){let S=$(w),{carNum:j,url:k,title:x,publishTime:_}=Ce(S);_&&p.push(_),j&&(i.find(E=>x.includes(E)||j.includes(E))||r.has(j)||(()=>{let E=S.find("img").attr("src")||"";E&&!E.startsWith("http")&&(E=E.startsWith("/")?this.javDbUrl+E:this.javDbUrl+"/"+E);let L=k||"";L&&!L.startsWith("http")&&(L=L.startsWith("/")?this.javDbUrl+L:this.javDbUrl+"/"+L);let M=S.find(".score .value, .score").text().trim(),P=parseFloat(M)||0,z=M.match(/由(\d+)人/),O=0;if(z)O=parseInt(z[1]);else{let H=S.find(".score .count, .meta .count").text().trim();O=parseInt(H.replace(/[^\d]/g,""))||0}u.push({carNum:j,coverUrl:E,title:x||"",publishTime:_||"",score:P,voteCount:O,url:L})})())}let g=Kt(p),m=await storageManager.getCarMap(),f=await this.getRuntimeService("state")?.getNewVideoDecisions?.()||{},v=u.filter(w=>!m.has(w.carNum)),b=v.filter(w=>f[w.carNum]?.action!=="dismissed");return b.length>0&&clog.html(`<span class="jhs-task-emphasis">检测出新作品, ${C(a)}, 共${b.length}部</span>`),await storageManager.updateFavoriteActress({starId:s,lastCheckTime:utils.getNowStr(),newVideoList:v,lastPublishTime:g}),b.length}async parseActorMovies(e,t,s,a,i){if(!e.length)return await storageManager.updateFavoriteActress({starId:t,lastCheckTime:utils.getNowStr(),newVideoList:[]}),0;let r=e.map(g=>g.publishTime).filter(Boolean),n=e.filter(g=>!g.carNum||i.has(g.carNum)?!1:!a.some(m=>g.title?.includes(m)||g.carNum.includes(m))).map(g=>({carNum:g.carNum,coverUrl:g.coverUrl||"",title:g.title||"",publishTime:g.publishTime||"",score:Number(g.score)||0,voteCount:Number(g.voteCount)||0,url:g.url||""})),l=Kt(r),c=await storageManager.getCarMap(),h=await this.getRuntimeService("state")?.getNewVideoDecisions?.()||{},u=n.filter(g=>!c.has(g.carNum)),p=u.filter(g=>h[g.carNum]?.action!=="dismissed");return p.length>0&&clog.html(`<span class="jhs-task-emphasis">检测出新作品, ${C(s)}, 共${p.length}部</span>`),await storageManager.updateFavoriteActress({starId:t,lastCheckTime:utils.getNowStr(),newVideoList:u,lastPublishTime:l}),p.length}async checkOneNewVideo(e){await this.ensureReady();let t=await storageManager.getTitleFilterKeyword(),s=await storageManager.getBlacklistCarList(),a=new Set(s.map(h=>h.carNum)),{lastCheckTime:i,name:r,starId:n}=e,l=`${this.javDbUrl}/actors/${n}?t=d`,c=$("#checkNewVideoMsg");try{clog.log("正在检测最新作品, 演员:",r,l),c.text(`正在检测最新作品, 演员: ${r}`);let h=await this.getRuntimeService("actressInfo").movies("javdb",{actorId:n,baseUrl:this.javDbUrl},{scope:await this.getRuntimeService("scope")(),ttlMs:0});await this.parseActorMovies(h,n,r,t,a),clog.html('<span class="jhs-task-emphasis">检测最新作品---结束</span>'),c.text("检测完毕"),await this.emitNewVideoChanged("single-actress-check")}catch(h){clog.error("检测屏蔽演员信息, 发生错误:",l,h),show.error("检测屏蔽演员信息, 发生错误:"+h,"bottom","right"),c.text(`检测屏蔽演员信息, 发生错误: ${l}`)}}};d(ln,"TaskPlugin");var ya=ln;function yt(o){if(!window.isDetailPage||typeof o?.getDetailResourceBoundary!="function")return null;let e=o.getDetailResourceBoundary();return e?{...e,hostRoot:$(e.hostRoot),controller:$(e.controller),observeRoot:$(e.observeRoot),resourceRoot:$(e.resourceRoot),resourceRegion:$(e.resourceRegion),sortSelect:$(e.sortSelect),getActionTarget(t){let s=$(e.getActionTarget(t));if(!s.length||!e.actionTargetRequiresWrapper?.(t))return s;let a=s.children(".jhs-offline-actions").first();return a.length||(a=$('<span class="jhs-offline-actions"></span>').appendTo(s)),a}}:null}d(yt,"getDetailResourceAdapter");function Oh(o){if(typeof Ur=="function")return Ur(o);let e=o.explicitContext;if(e?.carNum)return{context:e,source:"explicit"};let t=typeof aa=="function"?aa(o.trigger):null;if(t)return{context:t,source:"owned-surface"};for(let[s,a]of[["list-item",o.listResolver],["native-detail",o.nativeResolver],["legacy-fallback",o.legacyResolver]]){let i=a?.();if(i?.carNum)return{context:i,source:s}}return{context:null,source:"missing"}}d(Oh,"resolveOfflineMovieContext");var dn=class dn{constructor(){this.providers=new Map,this.availabilityCache=new Map,this.unavailableReasons=[],this.positiveTtl=3e5,this.negativeTtl=2e4}register(e){if(!e?.id||!Array.isArray(e.capabilities)||typeof e.submit!="function"||typeof e.getAvailability!="function")throw new TypeError("Invalid offline provider");return this.providers.set(e.id,e),e}async getCandidates(e,{force:t=!1}={}){let s=/^ed2k:/i.test(e)?"ed2k":/^magnet:/i.test(e)?"magnet":"unknown",a=[],i=[];for(let r of this.providers.values()){if(!r.capabilities.includes(s)){i.push(`${r.name}:不支持 ${s==="unknown"?"该资源格式":s.toUpperCase()}`);continue}if(!await r.isEnabled()){i.push(`${r.name}:未启用`);continue}let n=await this.getAvailability(r,t);["ready","unknown"].includes(n.authState)?a.push({provider:r,availability:n}):i.push(`${r.name}:${n.reason||"授权不可用"}`)}return this.unavailableReasons=i,a}getUnavailableReason(){let e=[...this.unavailableReasons];return this.providers.has("123")||e.unshift("123 云盘:授权桥接插件未加载或已禁用"),e.join(";")||"离线服务插件未加载或已禁用"}async getAvailability(e,t=!1){let s=this.availabilityCache.get(e.id),a=s&&["ready","unknown"].includes(s.value.authState)?this.positiveTtl:this.negativeTtl;if(!t&&s&&Date.now()-s.time<a)return s.value;let i=await e.getAvailability({force:t});return this.availabilityCache.set(e.id,{time:Date.now(),value:i}),i}updateAvailability(e,t){this.availabilityCache.set(e,{time:Date.now(),value:t})}};d(dn,"OfflineProviderRegistry");var cn=dn,hn=class hn extends I{constructor(){super(),this.registry=new cn,this.BUTTON_COOLDOWN_MS=1800}getName(){return"UnifiedOfflinePlugin"}async initCss(){return"<style>.jhs-offline-btn.loading{cursor:wait;opacity:.65}.jhs-offline-native{margin-left:6px;padding:3px 8px}</style>"}async handle(){if(!(N||B))return;let e=await this.getRuntimeService("scope")();this.lifecycleScope=e,this.registerProviders(e),this.bindSubmit(),e.addCleanup((()=>$(document).off(".jhsUnifiedOffline"))),window.isDetailPage&&(this.injectNativeButtons(),F&&e.addCleanup(F.on("magnet-items-updated",(()=>this.injectNativeButtons()))))}registerProviders(e){let t=this.getOptionalDependency("OneTwoThreeOfflinePlugin"),s=this.getRuntimeService("offline");t&&this.registry.register({id:"123",name:"123 云盘",capabilities:["magnet"],retryPolicy:{automaticAttempts:0},isEnabled:d(async()=>be(this.getRuntimeService("settings").snapshot().enable123Offline??!0,!1),"isEnabled"),getAvailability:d(async()=>await t.getStoredToken()?{available:!0,authState:"ready",reason:"授权已同步"}:{available:!1,authState:"token-missing",reason:"尚未同步 123 授权"},"getAvailability"),submit:d(async(a,i,r={})=>{let n=await t.getStoredToken();if(e?.disposed||r.isActive?.()===!1)throw Object.assign(new Error("所属界面已关闭,未提交任务"),{code:"SUBMIT_CANCELLED"});if(!be(this.getRuntimeService("settings").snapshot().enable123Offline??!0,!1))throw Object.assign(new Error("123 离线服务已关闭,未提交任务"),{code:"SERVICE_DISABLED"});if(!n)throw Object.assign(new Error("尚未同步 123 授权"),{code:"TOKEN_MISSING"});return s.submitWithIntegration("pan123",a,{token:n,scope:e})},"submit"),openUrl:d(()=>s.getIntegrationHomeUrl("pan123"),"openUrl")}),this.registry.register({id:"115",name:"115",capabilities:["magnet","ed2k"],retryPolicy:{automaticAttempts:0},isEnabled:d(async()=>be(this.getRuntimeService("settings").snapshot().enable115Offline??!1,!1),"isEnabled"),getAvailability:d(async()=>({available:!0,authState:"unknown",reason:"提交时确认登录状态"}),"getAvailability"),submit:d(a=>s.submitWithIntegration("one115",a,{scope:e}),"submit"),openUrl:d(()=>s.getIntegrationHomeUrl("one115"),"openUrl")}),window.offlineProviderRegistry=this.registry}bindSubmit(){$(document).off("click.jhsUnifiedOffline",".jhs-offline-btn").on("click.jhsUnifiedOffline",".jhs-offline-btn",(async e=>{e.preventDefault(),e.stopPropagation();let t=$(e.currentTarget),s=t.attr("data-resource")||t.attr("data-magnet")||t.closest(".magnet-result,.item,td").find('a[href^="magnet:"],a[href^="ed2k:"]').first().attr("href");s?await this.submitResource(e,s,t):show.error("未找到可提交资源")}))}injectNativeButtons(){let e=yt(this.getRuntimeService("host"));e&&e.rows().forEach((t=>{let s=e.getResource(t),a=e.getActionTarget(t);if(!s||!a?.length||$(t).closest(".magnet-container,.jhs-review-panel,.movie-detail-container").length)return;let i=`native-${e.site}`,r=$(t).find(`.jhs-offline-btn[data-jhs-offline-owner="${i}"]`).first();$(t).find(`.jhs-offline-btn[data-jhs-offline-owner="${i}"]`).not(r).remove(),r.length||(r=$('<button type="button" class="jhs-btn jhs-btn--secondary jhs-offline-btn jhs-offline-native">离线</button>').attr("data-jhs-offline-owner",i)),r.attr("data-resource",s),a.append(r)}))}async chooseCandidate(e,t){if(t.length===1)return t[0];let s=await storageManager.getSetting("offlineProviderMode","ask"),a=t.find((i=>i.provider.id===s));return a||new Promise((i=>{let r=this.getRuntimeService("dialog"),n=$('<div class="jhs-form-dialog"><p>选择离线服务</p><div class="jhs-toolbar"></div></div>'),l=n.find(".jhs-toolbar");t.forEach((h=>l.append($('<button type="button" class="jhs-btn jhs-btn--secondary"></button>').text(`${h.provider.name} · ${h.availability.authState==="ready"?"已就绪":"状态未知"}`).on("click",(()=>{i(h),r.close(c)})))));let c=r.open({type:1,title:"选择离线服务",content:n,area:utils.getDialogArea("sm"),cancel:d(()=>i(null),"cancel"),end:d(()=>i(null),"end")})}))}getVideoInfo(e,t=null){let s=e?.[0]||e,a=this.getRuntimeService("host")?.locateListItems?.().find(r=>s&&r.contains(s));return Oh({explicitContext:t,trigger:e,listResolver:d(()=>a?Ce(a):null,"listResolver"),nativeResolver:d(()=>window.isDetailPage?this.getPageInfo():null,"nativeResolver"),legacyResolver:d(()=>this.getPageInfo?.(),"legacyResolver"),logger:d(r=>clog.warn(r),"logger")}).context}async markDownloadedAndClose(e,t){if(!e?.carNum)return!1;try{let s=this.getRuntimeService("state");await s.patch(e.carNum,{downloaded:!0},{type:"offline-mark-downloaded",record:{...e,names:e.actress||e.names||""}});let a=await s.getState?.(e.carNum);if(a&&a.stateFlags?.downloaded!==!0)throw new Error("状态回读未确认已下载")}catch(s){return clog.error("离线任务标记已下载失败",s),show.error("离线已提交,但标记已下载失败"),!1}try{let s=this.getRuntimeService("settings").snapshot().needClosePage??"yes";if(s!=="yes"&&s!==!0)return!0;if(!await utils.closePage(t))throw new Error("未找到可关闭的详情页");return!0}catch(s){return clog.error("离线任务完成后关闭详情页失败",s),show.error("已标记下载,但无法自动关闭"),!1}}async submitResource(e,t,s=$(),a=null,i=null,r={}){if(this.lifecycleScope?.disposed||s.hasClass("loading"))return;let n=s.text(),l=s[0]||e?.currentTarget,c=!!l?.isConnected,h=d(()=>{s.removeClass("loading").removeAttr("aria-busy aria-disabled").text(n)},"restoreButton"),u=!1,p=null,g=null;try{s.addClass("loading").attr({"aria-busy":"true","aria-disabled":"true"}).text("提交中");let m=await this.registry.getCandidates(t,{force:!!r.forceAvailabilityRefresh});if(!m.length&&!r.forceAvailabilityRefresh&&!this.lifecycleScope?.disposed&&(!c||l.isConnected)&&(m=await this.registry.getCandidates(t,{force:!0})),!m.length)return void show.error(`无法离线:${this.registry.getUnavailableReason?.()||"没有已启用且支持该资源的离线服务,请检查授权与设置"}`);if(this.lifecycleScope?.disposed||c&&!l.isConnected||(p=m.find((b=>b.provider.id===r.preferredProviderId))||await this.chooseCandidate(e,m),!p))return;if(!await p.provider.isEnabled())return void show.error("所选离线服务已关闭,未提交任务");if(this.lifecycleScope?.disposed||c&&!l.isConnected)return;g=this.getVideoInfo(s,a);let f=l||null;if(!g)return void show.error("无法确定影片身份,未执行离线操作");let v={root:f,layerIndex:utils.getOwningLayerIndex({root:f})};s.text("提交中"),await p.provider.submit(t,g,{isActive:d(()=>!this.lifecycleScope?.disposed&&(!c||l.isConnected),"isActive")}),u=!0,this.registry.updateAvailability(p.provider.id,{available:!0,authState:"ready",reason:"最近提交成功"});try{await this.getRuntimeService("state").appendOfflineHistory({providerId:p.provider.id,providerName:p.provider.name,resource:t,resourceType:/^ed2k:/i.test(t)?"ed2k":"magnet",carNum:g?.carNum,status:"submitted",retryOf:i})}catch(b){clog.error("离线任务已创建,但本地记录保存失败",b),show.error("任务已创建,但本地记录保存失败,请勿重复提交")}(!c||l.isConnected)&&(s.text("已提交"),show.ok(`${p.provider.name} 离线任务已创建`),utils.q(e,"是否将该作品标记为已下载?",(()=>{this.markDownloadedAndClose(g,v)})))}catch(m){if(u){clog.error("离线任务已创建,后续界面更新失败",m);return}let f=m,v=f?.code||(m==="TOKEN_EXPIRED"?"TOKEN_EXPIRED":"SUBMIT_FAILED"),b=f?.message||String(m);if(v==="SUBMIT_CANCELLED")return;if(v==="SERVICE_DISABLED")return void show.error(b);if(p){["AUTH_REQUIRED","LOGIN_REQUIRED","TOKEN_EXPIRED","TOKEN_MISSING"].includes(v)&&this.registry.updateAvailability(p.provider.id,{available:!1,authState:p.provider.id==="115"?"login-required":"token-missing",reason:b});try{await this.getRuntimeService("state").appendOfflineHistory({providerId:p.provider.id,providerName:p.provider.name,resource:t,resourceType:/^ed2k:/i.test(t)?"ed2k":"magnet",carNum:g?.carNum,status:"failed",errorCode:v,errorMessage:b,retryOf:i})}catch(w){clog.error("离线失败记录保存失败",w)}}show.error(`${p?.provider.name||""} 离线失败:${b}`)}finally{u?setTimeout(h,this.BUTTON_COOLDOWN_MS):h()}}};d(hn,"UnifiedOfflinePlugin");var ja=hn;function un(o){return T(o)?.replace(/^FC2-/i,"")||null}d(un,"normalize115Keyword");function pn(o){let e=Number(o)||0;if(!e)return"0 B";let t=["B","KB","MB","GB","TB"],s=Math.min(t.length-1,Math.floor(Math.log(e)/Math.log(1024)));return`${(e/1024**s).toFixed(s?2:0)} ${t[s]}`}d(pn,"format115Size");function Tc(o,e,t={}){let s=o.match(/\.[^.]+$/)?.[0]||"",a=o.match(/-(?:U|UC|C|4K|8K|H265|HEVC|CN|CHS|CHT)\b/gi)||[],i=t.uppercase===!1?e:e.toUpperCase();return t.keepTitle&&(i+=` ${o.replace(s,"").replace(/^.*?\s+/,"")}`),t.keepSuffix!==!1&&(i+=[...new Set(a.map((r=>r.toUpperCase())))].join("")),`${i.slice(0,t.maxLength||180)}${s}`}d(Tc,"preview115Rename");var gn=class gn extends I{constructor(){super(),this.observer=null,this.unsubscribeItems=null,this.pendingCards=new Set,this.flushTimer=null,this.lifecycleScope=null,this.concurrency=4,this.cacheMinutes=60}getName(){return"OneOneFiveMatchPlugin"}async handle(){this.parentScope=await this.getRuntimeService("scope")();let e=this.getRuntimeService("settings");this.parentScope.listen(e,"settings.changed",t=>{t.detail?.names?.some(s=>["enable115Match","oneOneFiveConcurrency","oneOneFiveCacheMinutes"].includes(s))&&this.configureMatching().catch(s=>clog.error("115 匹配设置更新失败",s))}),this.parentScope.addCleanup(()=>{this.matchGeneration++,this.stopMatching()}),await this.configureMatching()}async configureMatching(){let e=this.matchGeneration=(this.matchGeneration||0)+1;if(this.stopMatching(),!be(this.getRuntimeService("settings").snapshot().enable115Match,!1)||this.parentScope.disposed||e!==this.matchGeneration)return;let s=this.lifecycleScope=new te(`115-match:${e}`);this.releaseMatchScope=this.parentScope.addCleanup(()=>s.dispose()),await this.mountMatching(s)}stopMatching(){this.releaseMatchScope?.(),this.releaseMatchScope=null,this.lifecycleScope?.dispose(),this.lifecycleScope=null,this.unsubscribeItems?.(),this.unsubscribeItems=null,this.observer?.disconnect(),this.observer=null,this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=null,this.pendingCards.clear(),$(".jhs-115-match,.jhs-115-list-match").remove(),$("[data-jhs115-observed],[data-jhs115-state]").removeAttr("data-jhs115-observed data-jhs115-state")}async mountMatching(e){let t=this.getRuntimeService("host"),s=this.getRuntimeService("offline");if(!isDetailPage){if(await this.setupListMatching(t,e),e.disposed)return;e.ownObserver(this.observer),e.addCleanup((()=>{this.unsubscribeItems?.(),this.unsubscribeItems=null,this.flushTimer&&clearTimeout(this.flushTimer),this.flushTimer=null,this.pendingCards.clear()}));return}let a=this.getPageInfo().carNum,i=un(a);if(!i)return;$(t.locateDetailSlots().summary).append('<div class="panel-block jhs-115-match"><strong>115匹配:</strong><span>匹配中</span></div>');try{let n=Math.max(1,Number(this.getRuntimeService("settings").snapshot().oneOneFiveCacheMinutes??60)||60);if(e.disposed||this.lifecycleScope!==e)return;let l=await s.searchFiles("one115",i,{scope:e,ttlMs:n*6e4});if(e.disposed||this.lifecycleScope!==e)return;let c=$(".jhs-115-match").empty().append("<strong>115匹配:</strong>");if(!l.length)return void c.append(document.createTextNode("未匹配 "),$('<button type="button" class="jhs-btn jhs-btn--ghost">重试</button>').on("click",(()=>location.reload())));l.forEach((h=>{let u=$('<span class="jhs-115-match-row"></span>'),p=s.getPlayUrl("one115",h);p?u.append($("<a></a>").addClass("jhs-btn jhs-btn--secondary").attr({href:p,target:"_blank"}).text(`${h.name} (${pn(h.size)})`)):u.append($("<span></span>").text(`${h.name} (${pn(h.size)}) · 不可播放`)),h.fileId&&u.append($('<button type="button" class="jhs-btn jhs-btn--ghost jhs-115-rename">重命名</button>').data("match",h)),c.append(u)})),c.on("click",".jhs-115-rename",(h=>this.renameWithPreview(h,$(h.currentTarget).data("match"),a)))}catch(n){if(e.disposed||this.lifecycleScope!==e)return;$(".jhs-115-match").empty().append("<strong>115匹配:</strong>",document.createTextNode("未登录或请求失败 ")).append($("<a></a>").addClass("jhs-btn jhs-btn--ghost").attr({href:s.getIntegrationHomeUrl("one115"),target:"_blank"}).text("去登录"),$('<button type="button" class="jhs-btn jhs-btn--ghost">重试</button>').on("click",(()=>location.reload()))),clog.error("115 匹配失败",n)}}async setupListMatching(e,t){if(!F)throw new Error("JHS EventBus 尚未初始化");this.concurrency=Math.max(1,Math.min(10,Number(this.getRuntimeService("settings").snapshot().oneOneFiveConcurrency??4)||4)),this.cacheMinutes=Math.max(1,Number(this.getRuntimeService("settings").snapshot().oneOneFiveCacheMinutes??60)||60),!(t.disposed||this.lifecycleScope!==t)&&(this.observer=new IntersectionObserver((s=>{t.disposed||this.lifecycleScope!==t||(s.forEach((a=>a.isIntersecting&&(this.observer.unobserve(a.target),this.pendingCards.add(a.target)))),this.pendingCards.size&&this.scheduleFlush())}),{rootMargin:"200px"}),this.registerCards($(e.locateListRoot()).find(".item").get()),this.unsubscribeItems=F.on("list-items-added",(s=>this.registerCards(s.items||[]))))}registerCards(e){e.forEach((t=>{t.dataset.jhs115Observed!=="true"&&t.dataset.jhs115State!=="matched"&&(t.dataset.jhs115Observed="true",this.observer?.observe(t))}))}scheduleFlush(){this.flushTimer||(this.flushTimer=setTimeout((async()=>{let e=[...this.pendingCards],t=this.lifecycleScope;this.pendingCards.clear(),this.flushTimer=null,await $e(e,this.concurrency,(s=>t&&!t.disposed&&this.lifecycleScope===t?this.matchCard(s):void 0))}),50))}async matchCard(e,t=!1){let s=this.lifecycleScope;if(!s||s.disposed)return;let a=$(e),i=T(a.find(".video-title strong").first().text());if(!(!i||e.dataset.jhs115State==="pending"))try{e.dataset.jhs115State="pending";let r=this.getRuntimeService("offline"),n=await r.searchFiles("one115",un(i),{scope:s,ttlMs:this.cacheMinutes*6e4,force:t});if(s.disposed||this.lifecycleScope!==s||!e.isConnected)return;a.find(".jhs-115-list-match").remove();let l=$('<button type="button" class="jhs-btn jhs-btn--ghost jhs-115-list-match"></button>').text(n.length?`匹配${n.length}个`:"未匹配").data("matches",n);a.find(".video-title").first().prepend(l),e.dataset.jhs115State="matched",l.on("click",(c=>{if(c.preventDefault(),c.stopPropagation(),s.disposed)return;if(!n.length)return this.matchCard(e,!0);if(n.length===1)return window.open(r.getPlayUrl("one115",n[0]),"_blank");let h=n.map((u=>`<a href="${C(r.getPlayUrl("one115",u))}" target="_blank">${C(u.name)}</a>`)).join("<br>");this.getRuntimeService("dialog").open({type:1,title:`${i} 115匹配`,content:`<div class="jhs-dialog-content">${h}</div>`,area:utils.getResponsiveArea(["560px","auto"])})}))}catch(r){if(s.disposed||this.lifecycleScope!==s||!e.isConnected)return;e.dataset.jhs115State="failed",a.find(".jhs-115-list-match").remove(),a.find(".video-title").first().prepend($('<button type="button" class="jhs-btn jhs-btn--ghost jhs-115-list-match">失败·重试</button>').on("click",(n=>{n.preventDefault(),n.stopPropagation(),s.disposed||this.matchCard(e,!0)}))),clog.warn("115 单卡匹配失败",r)}}destroy(){this.matchGeneration=(this.matchGeneration||0)+1,this.stopMatching()}renameWithPreview(e,t,s){let a=Tc(t.name,s,{uppercase:!0,keepSuffix:!0});utils.q(e,`确认重命名?<br>${C(t.name)}<br>→ ${C(a)}`,(async()=>{try{await this.getRuntimeService("offline").renameFile("one115",t.fileId,a,{scope:this.lifecycleScope}),show.ok("重命名完成")}catch(i){clog.error("115 重命名失败",i),show.error("重命名失败:"+(i instanceof Error?i.message:String(i)))}}))}};d(gn,"OneOneFiveMatchPlugin");var Sa=gn;var mn=class mn extends I{constructor(){super(...arguments),this.tokenKey="jhs_123pan_author_token",this.tokenMetaKey="jhs_123pan_author_token_meta",this.syncTimer=null,this.syncFallbackMs=3e5,this.syncGeneration=0}getName(){return"OneTwoThreeOfflinePlugin"}async handle(){window.location.hostname==="yun.123pan.com"&&this.startTokenSync(await this.getRuntimeService("scope")())}startTokenSync(e){this.syncTokenOnce(),this.syncTimer&&clearInterval(this.syncTimer),this.syncTimer=setInterval((()=>this.syncTokenOnce()),this.syncFallbackMs);let t=d(()=>this.syncTokenOnce(),"e");e.addCleanup((()=>{this.syncTimer&&clearInterval(this.syncTimer),this.syncTimer=null})),e.listen(window,"storage",t),e.listen(window,"focus",t),e.listen(document,"visibilitychange",(()=>{document.hidden||this.syncTokenOnce()}))}getTokenFrom123Pan(){let e=this.getRuntimeService("storage"),t=(e.getLocal("authorToken")||"").trim();if(t)return{token:t,source:"authorToken"};try{let a=JSON.parse(e.getLocal("userInfo")||"{}");if(a.authorToken||a.token)return{token:(a.authorToken||a.token||"").trim(),source:a.authorToken?"userInfo.authorToken":"userInfo.token"}}catch(a){clog.debug("123 云盘历史用户信息解析失败,继续尝试其他凭证来源",a)}let s=document.cookie.split(";");for(let a of s){let i=a.indexOf("=");if(i<0)continue;let r=a.substring(0,i).trim(),n=a.substring(i+1);if(r&&/token/i.test(r)&&n)return{token:decodeURIComponent(n).trim(),source:`cookie.${r}`}}return{token:"",source:""}}async syncTokenOnce(){let e=++this.syncGeneration,t=this.getRuntimeService("storage"),s=this.getTokenFrom123Pan();if(!s.token)return;let a=`${this.tokenKey}_secret`,i=t.getValue(a,"");i||(i=crypto.randomUUID?.()||`${Date.now()}-${crypto.getRandomValues(new Uint32Array(4)).join("-")}`,t.setValue(a,i));let r=t.getValue(this.tokenKey,""),n=await this.getStoredToken(),l=t.getValue(this.tokenMetaKey,null);if(n===s.token&&r.startsWith("AES:")&&l&&l.source===s.source)return;let c="AES:"+await Zt(s.token,i),h=this.getTokenFrom123Pan();e!==this.syncGeneration||h.token!==s.token||h.source!==s.source||t.getValue(this.tokenKey,"")!==r||t.getValue(a,"")!==i||(t.setValue(this.tokenKey,c),t.setValue(this.tokenMetaKey,{source:s.source,updatedAt:new Date().toISOString()}),n!==s.token&&show.info(`123 云盘授权已更新:${s.source}`))}async getStoredToken(){let e=this.getRuntimeService("storage"),t=e.getValue(this.tokenKey,""),s=e.getValue(`${this.tokenKey}_secret`,"");if(typeof t!="string")return"";if(!t.startsWith("AES:"))return t;if(typeof s!="string"||!s)return"";try{return await Ze(t.slice(4),s,!1)}catch{return""}}clearStoredToken(e){this.syncGeneration++;let t=this.getRuntimeService("storage");t.setValue(this.tokenKey,""),t.setValue(this.tokenMetaKey,{source:"cleared",reason:e,updatedAt:new Date().toISOString()})}};d(mn,"OneTwoThreeOfflinePlugin");var xa=mn;function Ac(o){let e=0,t=0,s=0,a=0,i=0,r=0,n=0,l=0,c=0;for(let u of o??[]){let p=q(u?.stateFlags);e++;let g=p.blocked===!0;g&&t++;let m=!g;p.favorite&&(s++,m&&a++),p.downloaded&&(i++,m&&r++),p.watched&&(n++,m&&l++),!oe(p)&&c++}let h=e-t;return Object.freeze({total:e,blocked:t,unblocked:h,favoriteRaw:s,favoriteEffective:a,downloadedRaw:i,downloadedEffective:r,watchedRaw:n,watchedEffective:l,pending:c})}d(Ac,"computeLibraryStats");var fn=class fn{constructor(e){this.storage=e.storage,this.state=e.state}async loadLibrarySnapshot(){let[e,t,s,a]=await Promise.all([this.storage.getCarList(),this.storage.getFavoriteActressList(),this.storage.getBlacklist(),this.state.getActivityLog()]);return Object.freeze({cars:e,actresses:t,blacklist:s,activity:a})}};d(fn,"StatsRepository");var ka=fn;var vn=class vn extends I{constructor(){super(...arguments),this.statsRepository=null}getStatsRepository(){return this.statsRepository||(this.statsRepository=new ka({storage:storageManager,state:this.getRuntimeService("state")}))}getName(){return"StatsPlugin"}async initCss(){return`
            <style>
                .jhs-stats { height:100%; padding:var(--jhs-space-4); overflow:auto; }
                .jhs-stats__metrics { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); border-top:1px solid var(--jhs-border); border-left:1px solid var(--jhs-border); }
                .jhs-stats__metric { display:grid; gap:var(--jhs-space-1); padding:var(--jhs-space-4); border:0; border-right:1px solid var(--jhs-border); border-bottom:1px solid var(--jhs-border); background:var(--jhs-surface); text-align:left; }
                button.jhs-stats__metric { cursor:pointer; }
                .jhs-stats__metric strong { color:var(--jhs-text); font-size:28px; line-height:1; }
                .jhs-stats__metric span { color:var(--jhs-text-muted); font-size:var(--jhs-font-size-sm); }
                .jhs-stats__group { margin-top:var(--jhs-space-5); }
                .jhs-stats__group h3 { margin:0 0 var(--jhs-space-3); color:var(--jhs-text); font-size:var(--jhs-font-size-md); }
                .jhs-stats__rows { display:grid; gap:var(--jhs-space-2); }
                .jhs-stats__row { display:grid; grid-template-columns:90px minmax(0,1fr) 76px; align-items:center; gap:var(--jhs-space-3); min-height:32px; }
                .jhs-stats__label { overflow:hidden; color:var(--jhs-text-muted); font-size:var(--jhs-font-size-sm); text-align:right; text-overflow:ellipsis; white-space:nowrap; }
                .jhs-stats__track { height:10px; overflow:hidden; border-radius:var(--jhs-radius-pill); background:var(--jhs-surface-2); }
                .jhs-stats__bar { display:block; width:var(--jhs-value,0%); height:100%; border-radius:inherit; background:var(--jhs-bar,var(--jhs-accent)); }
                .jhs-stats__value { color:var(--jhs-text-faint); font-size:var(--jhs-font-size-xs); }
                @media (max-width:767px) { .jhs-stats__metrics { grid-template-columns:repeat(2,minmax(0,1fr)); } .jhs-stats__row { grid-template-columns:72px minmax(0,1fr) 58px; gap:var(--jhs-space-2); } }
            </style>`}async handle(){window.isListPage&&this.createBtn()}createBtn(){$("#newVideoBtn").after('<button type="button" id="statsBtn" class="jhs-btn jhs-btn--secondary"><span>统计</span></button>'),$("#statsBtn").on("click",(()=>this.openDialog()))}async openDialog(){let e=this.getRuntimeService("diagnostics").exportSnapshot(),{cars:t,actresses:s,blacklist:a,activity:i}=await this.getStatsRepository().loadLibrarySnapshot(),r=Ac(t),n=r.total,l=new Map;t.forEach((P=>{let z=String(P.names||"").replace(/([一-鿿])\s+(?=[一-鿿])/g,"$1、").split(/[,,、]+/).map((O=>O.trim())).filter(Boolean);if(P.starId){let O=`id:${P.starId}`,H=l.get(O)||{starId:P.starId,name:z[0]||P.starId,count:0};H.count++,l.set(O,H)}else z.forEach((O=>{let H=`name:${O}`,Q=l.get(H)||{starId:"",name:O,count:0};Q.count++,l.set(H,Q)}))}));let c=[...l.values()].sort(((P,z)=>z.count-P.count||P.name.localeCompare(z.name))).slice(0,10),h=c[0]?.count||1,u=this.getRuntimeService("movie").externalSiteOrigin("javDbBtn",await storageManager.getSetting()),p=r.pending,g=this.getOptionalDependency("NewVideoPlugin"),m=this.getOptionalDependency("ListPagePlugin"),f=g?await g.getPendingNewVideoTotal():0,v=m?.getCurrentPageSummary?.()||{blockedItems:0},b=[{label:"总记录",value:n,action:null},{label:"收藏",value:r.favoriteRaw,action:null},{label:"下载",value:r.downloadedRaw,action:null},{label:"已看",value:r.watchedRaw,action:null},{label:"手动屏蔽",value:r.blocked,action:null},{label:"未鉴定",value:p,action:null},{label:"收藏演员",value:s.length,action:null},{label:"黑名单演员",value:a.length,action:null},{label:"新作品待处理",value:f,action:"new-video"},{label:"活跃功能",value:e.activeFeatures.length,action:null},{label:"运行错误",value:e.errors.length,action:null}],w=[["收藏",r.favoriteEffective,r.unblocked,"var(--jhs-status-fav)"],["下载",r.downloadedEffective,r.unblocked,"var(--jhs-status-down)"],["已看",r.watchedEffective,r.unblocked,"var(--jhs-status-watch)"],["手动屏蔽",r.blocked,r.total,"var(--jhs-status-filter)"],["未鉴定",r.pending,r.unblocked,"var(--jhs-border-strong)"]],S=d((P,z,O,H,Q="",se=!1)=>`<div class="jhs-stats__row">${Q?`<a class="jhs-stats__label" href="${C(Q)}" target="_blank" rel="noopener noreferrer" title="${C(P)}">${C(P)}</a>`:`<span class="jhs-stats__label" title="${C(P)}">${C(P)}</span>`}<span class="jhs-stats__track"><span class="jhs-stats__bar" data-width="${O?Math.round(z/O*100):0}" data-color="${H}"></span></span><span class="jhs-stats__value">${z}${se&&O?` (${Math.round(z/O*100)}%)`:""}</span></div>`,"row"),j=d(P=>{let z=Date.now()-P*864e5,O={identified:0,downloaded:0,watched:0};return i.entries.filter((H=>H.commitState==="committed"&&Date.parse(H.createdAt)>=z)).forEach((H=>H.changes.filter((Q=>Q.undoState!=="reverted")).forEach((Q=>{let se=q(Q.before?.stateFlags),ge=q(Q.after?.stateFlags);!oe(se)&&oe(ge)&&O.identified++,!se.downloaded&&ge.downloaded&&O.downloaded++,!se.watched&&ge.watched&&O.watched++})))),O},"trend"),k=j(7),x=j(30),_=i.coverageStart?`活动记录仅覆盖自 ${C(i.coverageStart)} 起`:"仅统计 6.4.0 及之后产生的操作记录",E=d(P=>P.action?`<button type="button" class="jhs-btn jhs-stats__metric" data-action="${P.action}"${P.filter?` data-filter="${P.filter}"`:""}><strong>${P.value}</strong><span>${P.label}</span></button>`:`<div class="jhs-stats__metric"><strong>${P.value}</strong><span>${P.label}</span></div>`,"renderMetric"),L=`<div class="jhs-stats jhs-scrollbar jhs-ui">
            <section class="jhs-stats__group"><h3>全库概览</h3><div class="jhs-stats__metrics">${b.map(E).join("")}</div></section>
            <section class="jhs-stats__group"><h3>当前页面</h3><div class="jhs-stats__metrics">${E({label:"屏蔽项",value:v.blockedItems,action:"filter",filter:"blockedItems"})}</div></section>
            <section class="jhs-stats__group"><h3>状态分布</h3><div class="jhs-stats__rows">${w.map((P=>S(P[0],P[1],P[2],P[3],"",!0))).join("")}</div></section>
            <section class="jhs-stats__group"><h3>活动趋势</h3><p class="jhs-helper-text">${_}</p><div class="jhs-stats__metrics"><div class="jhs-stats__metric"><strong>${k.identified}</strong><span>近 7 天新增鉴定</span></div><div class="jhs-stats__metric"><strong>${k.downloaded}</strong><span>近 7 天标记下载</span></div><div class="jhs-stats__metric"><strong>${k.watched}</strong><span>近 7 天标记观看</span></div><div class="jhs-stats__metric"><strong>${x.identified}</strong><span>近 30 天新增鉴定</span></div><div class="jhs-stats__metric"><strong>${x.downloaded}</strong><span>近 30 天标记下载</span></div><div class="jhs-stats__metric"><strong>${x.watched}</strong><span>近 30 天标记观看</span></div></div></section>
            ${c.length?`<section class="jhs-stats__group"><h3>Top 10 演员</h3><div class="jhs-stats__rows">${c.map((P=>S(P.name,P.count,h,"var(--jhs-accent)",new URL(P.starId?`/actors/${encodeURIComponent(P.starId)}`:`/search?q=${encodeURIComponent(P.name)}`,u).href))).join("")}</div></section>`:""}
        </div>`,M=this.getRuntimeService("dialog");M.open({type:1,title:"统计",content:L,scrollbar:!1,ui:{size:"lg",body:"scroll"},area:utils.getDialogArea("lg"),anim:-1,success:d((P,z)=>{$(P).find(".jhs-stats__bar").each(((O,H)=>{$(H).css({"--jhs-value":`${$(H).data("width")}%`,"--jhs-bar":$(H).data("color")})})),$(P).find("button.jhs-stats__metric[data-action]").on("click",(O=>{let H=$(O.currentTarget),Q=H.data("action");if(M.close(z),Q==="new-video")return g?.openDialog?.();Q==="filter"&&m?.setQuickFilter?.(H.data("filter"))})),utils.setupEscClose(z)},"success")})}};d(vn,"StatsPlugin");var Ca=vn;var bn=class bn extends I{constructor(){super(...arguments),this.preloadDistance=500,this.currentPage=this.getInitialPageNumber(),this.pageItems=[],this.started=!1,this.liveScope=null,this.generation=0,this.container=void 0,this.loader=void 0,this.nextUrl=null,this.hasMore=!1,this.isLoading=!1}getName(){return"AutoPagePlugin"}async initCss(){return`
            <style>
                .jhs-scroll {
                    text-align: center;
                    padding-top: 20px;
                    font-size: 14px;
                }
                .jhs-scroll.waterfall-loading { color: var(--jhs-text); }
                .jhs-scroll.waterfall-error { color: var(--jhs-status-filter); cursor: pointer; }
                .jhs-scroll.waterfall-no-more { color: var(--jhs-status-down); }
            </style>
        `}async handle(){let e=this.getRuntimeService("settings"),t=await this.getRuntimeService("scope")(),s=d(a=>{a.detail?.names?.includes("autoPage")&&this.reconfigure()},"onSettingsChanged");e.addEventListener("settings.changed",s),t.addCleanup((()=>e.removeEventListener("settings.changed",s))),t.addCleanup((()=>this.stop())),this.reconfigure()}reconfigure(){return this.getRuntimeService("settings").snapshot().autoPage!=="no"?this.start():this.stop()}start(){return this.started?this.waterfallPromise||(this.waterfallPromise=this.waterfall().finally((()=>{this.waterfallPromise=null}))):(this.started=!0,this.liveScope?.dispose(),this.liveScope=new te("autopage:live"),this.generation++,this.waterfallPromise=this.waterfall().finally((()=>{this.waterfallPromise=null})),this.waterfallPromise)}stop(){this.started=!1,this.generation++,this.liveScope?.dispose(),this.liveScope=null,this.nextUrl=null,this.hasMore=!1,this.isLoading=!1,this.loader?.remove(),this.loader=void 0,this.container=void 0,this.pageItems=[]}getInitialPageNumber(){if(B){let e=Y.match(/\/(page|star\/[^/]+)\/(\d+)/);return e?parseInt(e[2],10):1}if(N){let e=Y.match(/[?&]page=(\d+)/);return e?parseInt(e[1],10):1}return 1}async waterfall(){if(!this.started||!this.liveScope||await this.shouldDisablePaging()||!this.started||!this.liveScope||this.liveScope.disposed)return;let e=this.liveScope,t=this.getSelector(),s=document.querySelector(t.boxSelector);if(!s||!s.parentNode)return void clog.error("没有找到容器节点,停止瀑布流!");this.container=s;let a=document.createElement("div");this.loader=a,a.className="jhs-scroll",s.parentNode.insertBefore(a,s.nextSibling),this.pageItems.push({page:this.currentPage,top:0,url:window.location.href}),a.addEventListener("click",(()=>{a.classList.contains("waterfall-error")&&this.loadNextPage().catch((r=>clog.error("瀑布流重试失败",r)))})),(()=>{let r=!1;e.listen(window,"scroll",(()=>{r||(r=!0,requestAnimationFrame((()=>{this.checkLoad(),this.checkScrollPosition(),r=!1})))}))})();let i=document.querySelector(t.nextPageSelector);this.nextUrl=i?.href??null,this.hasMore=!!this.nextUrl,e.ownTimeout(setTimeout((()=>{this.checkLoad()}),1e3)),this.hasMore||this.setState("waterfall-no-more","已经到底了")}async loadNextPage(){var e;if(!this.started)return;if(this.getRuntimeService("settings").snapshot().autoPage==="no")return void this.setState("waterfall-loading","");if(this.isLoading||!this.nextUrl||!this.container)return;let t=this.getOptionalDependency("ListPagePlugin");if(!t)return this.nextUrl=null,this.hasMore=!1,void this.setState("waterfall-error","列表功能已禁用,无法继续翻页");this.isLoading=!0,this.setState("waterfall-loading","加载中...");let s=this.getSelector(),a=this.generation,i=this.liveScope;try{if(!i||i.disposed||a!==this.generation)return;let r=await Ve(this.getRuntimeService("http"),this.nextUrl,i);if(!this.started||!this.liveScope||this.liveScope.disposed||a!==this.generation)return;clog.log("请求下一页内容:",this.nextUrl);let n=utils.htmlTo$dom(r);B&&n.find(".avatar-box").length>0&&n.find(".avatar-box").parent().remove();let l=n.find(this.getSelector().requestDomItemSelector),c=this.getBoxCarInfoList(),h=this.getBoxCarInfoList(l);if(this.checkDuplicateCarNumbers(c,h))return this.nextUrl=null,this.hasMore=!1,void this.setState("waterfall-error","翻页内容出现重复数据, 页码受JavDB限制, 已停止瀑布流");if(!this.started||!this.liveScope||this.liveScope.disposed||a!==this.generation)return;let u=this.container.scrollHeight;this.pageItems.push({page:this.currentPage+1,top:u,url:this.nextUrl});let p=n.find(this.getSelector().coverImgSelector);t.replaceHdImg(p),$(this.getSelector().boxSelector).append(l),this.nextUrl=(e=n.find(s.nextPageSelector))==null?void 0:e.attr("href"),this.hasMore=!!this.nextUrl;let g=n.find(".pagination");$(".pagination").replaceWith(g),this.setState("waterfall-loading",""),this.hasMore||this.setState("waterfall-no-more","已经到底了")}catch(r){this.started&&this.loader&&this.setState("waterfall-error","加载失败,点击重试"),clog.error("加载失败:",r)}finally{this.isLoading=!1}}checkScrollPosition(){let e=window.scrollY;for(let t=this.pageItems.length-1;t>=0;t--){let s=this.pageItems[t];if(e>=s.top){this.currentPage!==s.page&&(this.currentPage=s.page,this.updatePageUrl(s.url));break}}}checkLoad(){this.loader&&(this.loader.classList.contains("waterfall-error")||this.loader.getBoundingClientRect().top<window.innerHeight+this.preloadDistance&&this.loadNextPage().catch((e=>clog.error("瀑布流自动加载失败",e))))}async shouldDisablePaging(){return window.isListPage?this.getRuntimeService("settings").snapshot().autoPage==="no"||["search?q","handlePlayback=1","handleTop=1","/want_watch_videos","/watched_videos","/advanced_search?type=100"].some((t=>Y.includes(t))):!0}updatePageUrl(e){window.history.replaceState({},"",e),B&&(document.title=document.title.replace(/第\d+頁/,`第${this.currentPage}頁`))}setState(e,t){this.loader&&(this.loader.className=`jhs-scroll ${e}`,this.loader.textContent=t)}};d(bn,"AutoPagePlugin");var _a=bn;var wn=class wn extends I{getName(){return"BusDetailPagePlugin"}async initCss(){if(!window.isDetailPage)return"";$("h4:contains('推薦')").hide()}async handle(){if(window.location.href.includes("/star/")){let e=$(".avatar-box");if(e.length>0){let t=e.parent();t.css("position","initial"),t.insertBefore(t.parent())}}$(".genre a").each(((e,t)=>{let s=$(t),a=s.attr("href");if(a)try{["http:","https:"].includes(new URL(a,window.location.href).protocol)&&s.attr("target","_blank")}catch{}})),this.addCopyCarNumBtn()}addCopyCarNumBtn(){let e=null,t=document.querySelectorAll("span.header");for(let s of t)if(s.textContent.trim()==="識別碼:"){e=s;break}if(e){let s=e.nextElementSibling;if(s&&s.tagName==="SPAN"){let a=s.textContent.trim(),i=document.createElement("button");i.type="button",i.className="jhs-btn jhs-btn--secondary jhs-copy-car-number",i.textContent="复制",i.addEventListener("click",(async function(r){r.preventDefault(),await utils.copyToClipboard("番号",a)&&(this.textContent="已复制",setTimeout((()=>{this.textContent="复制"}),1500))})),s.parentNode?.insertBefore(i,s.nextSibling)}}}};d(wn,"BusDetailPagePlugin");var $a=wn;var yn=class yn extends I{getName(){return"BusNavBarPlugin"}handle(){this.getOptionalDependency("SearchByImagePlugin")&&($("#navbar > div > div > span").append(`
            <button class="jhs-btn btn btn-default jhs-layout-638cb2c9" id="search-img-btn">识图</button>
       `),$("#search-img-btn").on("click",(()=>{this.getOptionalDependency("SearchByImagePlugin")?.open?.()})))}};d(yn,"BusNavBarPlugin");var Ta=yn;var jn=class jn extends I{getName(){return"CompatibilityEnhancementsPlugin"}getStartupMode(){return"idle"}async initCss(){return Ni.isJavDB?`<style>
            .sda-content { display:none!important; }
        </style>`:""}bindImmediateEvents(){$(document).off("actress-state-changed.jhsActress").on("actress-state-changed.jhsActress",(async()=>{$(".jhs-actress-state-container").remove(),await this.decorateActresses()}))}async handle(){await this.decorateActresses(),isDetailPage&&await this.addRemoveRecord(),this.linkCommentImages()}async addRemoveRecord(){let e=this.getPageInfo().carNum;if(!e||!(await storageManager.getCarList()).some((s=>s.carNum===e)))return;let t=$('<button type="button" class="jhs-btn jhs-btn--danger jhs-remove-car">移除记录</button>');$(".jhs-detail-btn-row,.movie-info-container,.container .info").first().append(t),t.on("click",(s=>utils.q(s,`确定移除 ${C(e)} 的鉴定记录?`,(async()=>{await this.getRuntimeService("state").remove(e),t.remove(),this.getOptionalDependency("ListPagePlugin")?.showCarNumBox?.(e),show.ok("鉴定记录已移除")}))))}async decorateActresses(){let e=new Set((await storageManager.getFavoriteActressList()).map((s=>String(s.starId)))),t=new Set((await storageManager.getBlacklist()).map((s=>String(s.starId||s.id))));this.decorateCurrentActressProfile(e,t),this.decorateActressCards(e,t)}decorateCurrentActressProfile(e,t){let s=window.location.pathname.match(/^\/(?:actors|star)\/([^/?#]+)\/?$/);if(!s)return;let a=$(".actor-section-name,.star-name,h1.title").first();a.length&&this.renderActressState(a,decodeURIComponent(s[1]),e,t,"jhs-actress-profile-state")}decorateActressCards(e,t){$(".actor-box a[href], .actress-card a[href], [data-actress-card] a[href]").each(((s,a)=>{let i=zh(a);if(!i)return;let r=$(a).closest(".actor-box,.actress-card,[data-actress-card]");this.renderActressState(r,i.starId,e,t,"jhs-actress-card-state")}))}renderActressState(e,t,s,a,i){if(e.children(".jhs-actress-state-container").length)return;let r=$(`<span class="jhs-actress-state-container ${i}"></span>`);s.has(t)&&r.append('<span class="jhs-badge jhs-badge--fav">已关注</span>'),a.has(t)&&r.append('<span class="jhs-badge jhs-badge--danger">已拉黑</span>'),r.children().length&&e.append(r)}linkCommentImages(){let e=$(".preview-images img,#sample-waterfall img,.movie-gallery img");e.length&&($(".review-content").each(((t,s)=>this.linkCommentImageTextNodes(s,e.length))),$(document).off("click.jhsCommentImage",".jhs-comment-image-link").on("click.jhsCommentImage",".jhs-comment-image-link",(t=>{t.preventDefault();let s=e.eq(Number($(t.currentTarget).data("image-index")));s.length&&globalThis.showImageViewer(s[0])})))}linkCommentImageTextNodes(e,t){let s=document.createTreeWalker(e,NodeFilter.SHOW_TEXT),a=[];for(;s.nextNode();){let i=s.currentNode;!$(i.parentElement).closest("a,button,code,pre,textarea,.jhs-comment-image-link").length&&/(?:图|圖片|图片)\s*[一二三四五六七八九十\d]+/i.test(i.nodeValue||"")&&a.push(i)}a.forEach((i=>{let r=i.nodeValue||"",n=/(?:图|圖片|图片)\s*([一二三四五六七八九十\d]+)/gi,l=document.createDocumentFragment(),c=0,h;for(;h=n.exec(r);){h.index>c&&l.append(document.createTextNode(r.slice(c,h.index)));let u={一:1,二:2,三:3,四:4,五:5,六:6,七:7,八:8,九:9,十:10},p=(u[h[1]]||Number(h[1]))-1;if(p>=0&&p<t){let g=document.createElement("a");g.href="#",g.className="jhs-comment-image-link",g.dataset.imageIndex=String(p),g.textContent=h[0],l.append(g)}else l.append(document.createTextNode(h[0]));c=h.index+h[0].length}c<r.length&&l.append(document.createTextNode(r.slice(c))),i.replaceWith(l)}))}};d(jn,"CompatibilityEnhancementsPlugin");var Aa=jn;function zh(o){let e=$(o);if(e.closest('.toolbar,.tabs,.buttons,.pagination,.filter,.filters,nav,header,[role="tablist"]').length)return null;let t=new URL(e.attr("href"),window.location.href);if(t.search||t.hash)return null;let s=t.pathname.match(/^\/(?:actors|star)\/([^/]+)\/?$/);return s?{starId:decodeURIComponent(s[1]),url:t.href}:null}d(zh,"getActressIdentityFromLink");var Sn=class Sn extends I{getName(){return"DetailPageButtonPlugin"}constructor(){super(),this.answerCount=1,this.stateBinding=null,this.detailStateController=null}getDetailStateController(){return this.detailStateController||(this.detailStateController=new Lt(this.getRuntimeService("state")))}async handle(){let e=await this.getRuntimeService("scope")();this.hideVideoControls(e),window.isDetailPage&&(await this.createMenuBtn(),await this.autoRemoveNewVideoMark()),window.isDetailPage&&e.addCleanup(F?.on("car-state-changed",t=>{let s=this.getPageInfo().carNum;if(t.carNums?.includes(s))return this.showStatus(s)})||(()=>{}))}async autoRemoveNewVideoMark(){try{if(await storageManager.getSetting("autoRemoveNewVideoMarkAfterBrowse",ne)!==R)return;let t=this.getPageInfo();if(!t.carNum)return;await this.getRuntimeService("state").removeFromNewVideoList([t.carNum],"browse")}catch(e){clog.error("自动移除新作品标记失败:",e)}}async createMenuBtn(){let e=this.getPageInfo(),t=e.carNum,s=$(`
            <div class="jhs-detail-btn-row jhs-layout-e2965a97">
                <div data-jhs-state-slot></div>
                <div class="jhs-layout-1e90930a">
                    <button type="button" id="enable-magnets-filter" class="jhs-btn jhs-btn--secondary jhs-layout-5f3e3549">
                        <span id="magnets-span">关闭磁力过滤</span>
                    </button>
                    <button type="button" id="magnetSearchBtn" class="jhs-btn jhs-btn--accent ">
                        <span>磁力搜索</span>
                    </button>
                    <button type="button" id="xunLeiSubtitleBtn" class="jhs-btn jhs-btn--accent ">
                        <span>字幕 (迅雷)</span>
                    </button>
                    <button type="button" id="search-subtitle-btn" class="jhs-btn jhs-btn--accent jhs-layout-f43f0d6d">
                        <span>字幕 (SubTitleCat)</span>
                    </button>
                </div>
            </div>
        `);s.find("[data-jhs-state-slot]").replaceWith(Nt());let a=this.getOptionalDependency("DetailWorkspacePlugin")?.getSlot?.("summary-actions");a?.length?a.append(s):N?$(".tabs").after(s):B&&$("#mag-submit-show").before(s),$("#magnetSearchBtn").on("click",(async()=>{let c=this.getOptionalDependency("MagnetHubPlugin");if(!c)return void show.info("磁力搜索功能已禁用");let h=await c.createMagnetHub(e.carNum);this.getRuntimeService("dialog").open({type:1,title:"磁力搜索 "+e.carNum,content:'<div id="magnetHubBox"></div>',area:utils.getResponsiveArea(["60%","80%"]),scrollbar:!1,success:d(()=>{$("#magnetHubBox").append(h)},"success")})}));let i=this.getOptionalDependency("HighlightMagnetPlugin"),r=this.getRuntimeService("settings"),n=r.snapshot().enableMagnetsFilter??R;i||$("#enable-magnets-filter").remove(),$("#magnets-span").text(n===R?"关闭磁力过滤":"开启磁力过滤"),n===R&&i?.doFilterMagnet?.();let l=Fe({settings:r,key:"enableMagnetsFilter",fallback:ne,apply:d(c=>{let h=c===R,u=$("#magnets-span");h?(i?.doFilterMagnet?.(),u.text("关闭磁力过滤")):(i?.showAll?.(),u.text("开启磁力过滤"))},"apply"),onError:d(c=>{clog.error("磁力过滤设置保存失败,已恢复",c),show.error("磁力过滤设置保存失败,已恢复原设置")},"onError")});if($("#enable-magnets-filter").on("click",(async c=>{if(!i)return;let h=$("#magnets-span").text()==="关闭磁力过滤";await l(h?ne:R)})),$("#search-subtitle-btn").on("click",(c=>{let h=this.getRuntimeService("movie").sourceUrls({carNum:t},["subtitlecat"])[0]?.url;h&&utils.openPage(h,t,!1,c)})),$("#xunLeiSubtitleBtn").on("click",(()=>this.searchXunLeiSubtitle(t))),!t)return $("#filterBtn, #favoriteBtn, #hasDownBtn, #hasWatchBtn, #magnetSearchBtn, #xunLeiSubtitleBtn, #search-subtitle-btn").prop("disabled",!0).attr("title","番号不可用"),void clog.warn("详情操作不可用:番号不可用");this.stateBinding=this.getDetailStateController().bind({root:document,carNum:t,activityType:"detail-state",getRecord:d(()=>this.getStateRecord(),"getRecord")})}async showStatus(e){return this.getDetailStateController().render({root:document,carNum:e})}getStateRecord(){let e=this.getPageInfo();return{carNum:e.carNum,url:e.url,names:e.actress,publishTime:e.publishTime}}getStateBinding(){if(this.stateBinding)return this.stateBinding;let e=this.getPageInfo();return this.stateBinding={root:document,layerIndex:null,carNum:T(e.carNum),getRecord:d(()=>this.getStateRecord(),"getRecord"),activityType:"detail-state",selectors:{}}}async favoriteOne(e){return this.getDetailStateController().requestToggle(this.getStateBinding(),"favorite",e)}async hasDownOne(e){return this.getDetailStateController().requestToggle(this.getStateBinding(),"downloaded",e)}async hasWatchOne(e){return this.getDetailStateController().requestToggle(this.getStateBinding(),"watched",e)}async searchXunLeiSubtitle(e){let t=this.getRuntimeService("dialog"),s=this.getRuntimeService("subtitle"),a=await this.getRuntimeService("scope")(),i=loading();try{let r=await s.search("xunlei",{carNum:e},{scope:a});r&&r.length!==0?t.open({type:1,title:"迅雷字幕",content:`
                    <div class="jhs-layout-8ddc7c91">
                        <div id="xunlei-table-container" class="jhs-layout-583c2485"></div>
                    </div>
                `,scrollbar:!1,area:utils.getResponsiveArea(["60%","70%"]),anim:-1,success:d((n,l)=>{ze(globalThis.Tabulator,"#xunlei-table-container",{pagination:!1,layout:"fitColumns",placeholder:"暂无数据",virtualDom:!0,data:r,responsiveLayout:"collapse",responsiveLayoutCollapse:!0,columnDefaults:{headerHozAlign:"center",hozAlign:"center"},columns:[{title:"文件名",field:"name",headerSort:!1,responsive:0},{title:"类型",field:"extension",headerSort:!1,responsive:0},{title:"操作",responsive:0,headerSort:!1,formatter:d((c,h,u)=>{let p=c.getData();return u((()=>{let g=c.getElement().querySelector(".subtitle-preview-btn"),m=c.getElement().querySelector(".subtitle-download-btn");g&&g.addEventListener("click",(async f=>{let v=e+"."+p.extension;this.previewSubtitle(p,v)})),m&&m.addEventListener("click",(async f=>{let v=e+"."+p.extension,b=await s.download("xunlei",p,{scope:a});utils.download(b,v)}))})),`
                                        <button type="button" class="jhs-btn jhs-btn--secondary subtitle-preview-btn">预览</button>
                                        <button type="button" class="jhs-btn jhs-btn--primary subtitle-download-btn">下载</button>
                                    `},"formatter")}]}),utils.setupEscClose(l)},"success")}):show.error("迅雷中找不到相关字幕!")}catch(r){clog.error(r),show.error(r)}finally{i.close()}}async filterOne(e,t){return e&&e.preventDefault(),this.getDetailStateController().requestToggle(this.getStateBinding(),"blocked",e)}hideVideoControls(e){let t=$(document);t.off("mouseenter.jhsDetailVideo").on("mouseenter.jhsDetailVideo","#preview-video",(s=>{$(s.currentTarget).prop("controls",!0)})),e.addCleanup((()=>t.off("mouseenter.jhsDetailVideo")))}async previewSubtitle(e,t){if(!e?.url)return void clog.error("未提供文件URL");let s=String(e.extension||"").toLowerCase();if(s==="ass"||s==="srt")try{let a=this.getRuntimeService("dialog"),i=await this.getRuntimeService("scope")(),r=await this.getRuntimeService("subtitle").download("xunlei",e,{scope:i}),n="字幕预览";s==="ass"?n="ASS字幕预览 - "+t:s==="srt"&&(n="SRT字幕预览 - "+t);let l=r.split(`
`),c="",h=String(l.length).length;l.forEach(((p,g)=>{let m=String(g+1).padStart(h," ");c+=`<span class="jhs-code-line-number">${m}. </span>${C(p)}
`}));let u=c;a.open({type:1,title:n,area:utils.getResponsiveArea(["80%","80%"]),scrollbar:!1,content:`<div class="jhs-code-viewer">${u}</div>`,btn:["下载","关闭"],btn1:d(function(p,g,m){return utils.download(r,t),!1},"btn1")})}catch(a){show.error(`预览失败: ${a instanceof Error?a.message:String(a)}`),clog.error("预览字幕文件出错:",a)}else show.error("仅支持预览ASS和SRT字幕文件")}};d(Sn,"DetailPageButtonPlugin");var Pa=Sn;var xn=class xn extends I{getName(){return"DetailPagePlugin"}constructor(){super()}handle(){isDetailPage&&$(".video-meta-panel a").each(((e,t)=>{let s=$(t),a=s.attr("href");if(a)try{["http:","https:"].includes(new URL(a,window.location.href).protocol)&&s.attr("target","_blank")}catch{}}))}};d(xn,"DetailPagePlugin");var Ia=xn;var kn=class kn extends I{constructor(){super(),this.hostRoot=null,this.resourceObserver=null,this.scheduledResourceFrame=null,this.cancelScheduledResourceFrame=null,this.lifecycleScope=null}getName(){return"DetailWorkspacePlugin"}async initCss(){return`<style>
            .jhs-detail-workspace { display:grid; width:min(100%,1440px); min-width:0; margin:0 auto; padding:var(--jhs-space-6); gap:var(--jhs-space-5); box-sizing:border-box; background:var(--jhs-bg); color:var(--jhs-text); }
            .jhs-detail-workspace__section { display:none; min-width:0; overflow:hidden; border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); background:var(--jhs-surface); }
            .jhs-detail-workspace__section.has-content { display:block; }
            .jhs-detail-workspace__header { padding:var(--jhs-space-4) var(--jhs-space-5); border-bottom:1px solid var(--jhs-border); background:var(--jhs-surface-2); }
            .jhs-detail-workspace__header h2 { margin:0; color:var(--jhs-text); font-size:var(--jhs-font-size-lg); }
            .jhs-detail-workspace__content { min-width:0; padding:var(--jhs-space-5); }
            .jhs-detail-workspace__content:empty { display:none; }
            .jhs-detail-workspace .jhs-detail-btn-row { display:flex; flex-wrap:wrap; gap:var(--jhs-space-2); margin-top:var(--jhs-space-4); }
            .jhs-detail-workspace [data-jhs-section="gallery"] .jhs-detail-workspace__content { overflow-x:auto; }
            .jhs-detail-host-workspace { color:var(--jhs-text); }
            .jhs-detail-owned-slot { min-width:0; box-sizing:border-box; padding:var(--jhs-space-4); border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); background:var(--jhs-surface); }
            .jhs-detail-owned-slot:empty { display:none; }
            .jhs-detail-owned-slot--summary-actions { margin-block:var(--jhs-space-5); }
            .jhs-detail-post-resource { display:grid; min-width:0; gap:var(--jhs-space-5); margin-block:var(--jhs-space-5); }
            .jhs-detail-host-workspace .jhs-detail-btn-row { margin:0!important; }
            .jhs-detail-host-action { display:inline-flex!important; min-height:var(--jhs-control-height)!important; align-items:center!important; justify-content:center!important; padding:0 var(--jhs-space-3)!important; border:1px solid var(--jhs-border)!important; border-radius:var(--jhs-radius-sm)!important; background:var(--jhs-surface)!important; color:var(--jhs-text)!important; box-shadow:none!important; font:inherit!important; font-size:var(--jhs-font-size-sm)!important; font-weight:600!important; line-height:1!important; text-decoration:none!important; }
            .jhs-detail-host-action:hover { border-color:var(--jhs-accent)!important; background:var(--jhs-surface-2)!important; color:var(--jhs-accent)!important; }
            .jhs-offline-actions { display:inline-flex; align-items:center; gap:var(--jhs-space-2); margin-left:var(--jhs-space-2); vertical-align:middle; }
            [data-jhs-workspace-site="javdb"] [data-jhs-magnets] { container:jhs-magnets / inline-size; min-width:0; }
            [data-jhs-workspace-site="javdb"] [data-jhs-host-region="resources"] { margin:0; min-width:0; }
            [data-jhs-workspace-site="javdb"] [data-jhs-host-region="resources"] > .column { padding:0; min-width:0; }
            [data-jhs-workspace-site="javdb"] [data-jhs-resource-surface] { margin:0; padding:var(--jhs-space-4); box-sizing:border-box; min-width:0; border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); background:var(--jhs-surface); color:var(--jhs-text); }
            [data-jhs-workspace-site="javdb"] [data-jhs-resource-body] { padding:0; border:0; background:transparent; color:inherit; }
            [data-jhs-workspace-site="javdb"] [data-jhs-magnets] > .magnet-sort { margin-bottom:var(--jhs-space-3); }
            [data-jhs-workspace-site="javdb"] #magnets-content [data-jhs-magnet-row] { display:grid; grid-template-columns:minmax(0,1fr); grid-template-areas:"info" "date" "actions"; gap:var(--jhs-space-2); align-items:center; margin:0; padding:var(--jhs-space-3); box-sizing:border-box; border-bottom:1px solid var(--jhs-border); background:transparent; }
            [data-jhs-workspace-site="javdb"] #magnets-content [data-jhs-magnet-row]:last-child { border-bottom:0; }
            [data-jhs-workspace-site="javdb"] [data-jhs-magnet-part="info"] .name { color:var(--jhs-text); font-size:var(--jhs-font-size-md); font-weight:600; }
            [data-jhs-workspace-site="javdb"] [data-jhs-magnet-part="date"] { color:var(--jhs-text-muted); font-size:var(--jhs-font-size-sm); }
            [data-jhs-workspace-site="javdb"] [data-jhs-magnet-part] { width:auto!important; min-width:0; max-width:100%; margin:0!important; padding:0; }
            [data-jhs-workspace-site="javdb"] [data-jhs-magnet-part="info"] { grid-area:info; overflow-wrap:anywhere; }
            [data-jhs-workspace-site="javdb"] [data-jhs-magnet-part="date"] { grid-area:date; white-space:nowrap; }
            [data-jhs-workspace-site="javdb"] [data-jhs-magnet-part="actions"] { grid-area:actions; display:flex; flex-wrap:nowrap; align-items:center; gap:var(--jhs-space-2); }
            [data-jhs-workspace-site="javdb"] [data-jhs-magnet-part="actions"] > :is(a,button) { display:inline-flex; flex:0 0 auto; align-items:center; justify-content:center; box-sizing:border-box; height:var(--jhs-control-height)!important; min-height:var(--jhs-control-height)!important; margin:0!important; padding:0 var(--jhs-space-3)!important; border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-sm)!important; background:var(--jhs-surface); color:var(--jhs-text); font-size:var(--jhs-font-size-sm); line-height:1!important; }
            @container jhs-magnets (min-width:768px) {
                [data-jhs-workspace-site="javdb"] #magnets-content [data-jhs-magnet-row] { grid-template-columns:minmax(0,1fr) max-content max-content; grid-template-areas:"info date actions"; gap:var(--jhs-space-4); }
            }
            @container jhs-magnets (max-width:767px) {
                [data-jhs-workspace-site="javdb"] [data-jhs-magnet-part="actions"] > :is(a,button) { height:44px!important; min-height:44px!important; }
            }
            @media (pointer:coarse) {
                [data-jhs-workspace-site="javdb"] [data-jhs-magnet-part="actions"] > :is(a,button) { height:44px!important; min-height:44px!important; }
            }
        </style>`}async handle(){if(!window.isDetailPage)return;this.lifecycleScope=await this.getRuntimeService("scope")();let e=utils.loopDetector((()=>!!this.getHostAdapter()),(()=>this.ensureWorkspace()),40,2500,!0,this.lifecycleScope);this.lifecycleScope.addCleanup(e),this.lifecycleScope.addCleanup((()=>{this.cancelScheduledResourceFrame?.(),this.scheduledResourceFrame=null,this.cancelScheduledResourceFrame=null}))}getHostAdapter(){let e=this.getRuntimeService("host"),t=e?.locateDetailRoot?.();return t?{site:e.site||"unknown",root:$(t)}:null}ensureWorkspace(){let e=this.getHostAdapter();if(!e)return $();let t=e.root;return t.attr("data-jhs-workspace-ready")||(t.attr({"data-jhs-workspace-ready":"true","data-jhs-workspace-site":e.site}).addClass("jhs-detail-host-workspace jhs-ui"),e.site==="javdb"?(t.children("h2,.video-meta-panel").attr("data-jhs-host-region","summary"),t.children(".columns").filter(((s,a)=>$(a).find(".tile-images,.preview-images").length>0)).attr("data-jhs-host-region","gallery"),t.children(".columns").filter(((s,a)=>$(a).find("#magnets-content").length>0)).attr("data-jhs-host-region","resources"),this.normalizeHostActions(t.find(".video-meta-panel").first())):(t.children("h3,.row.movie").attr("data-jhs-host-region","summary"),yt(this.getRuntimeService("host"))?.resourceRegion?.attr("data-jhs-host-region","resources"),t.children().filter(((a,i)=>$(i).is("#sample-waterfall")||$(i).find("#sample-waterfall").length>0)).attr("data-jhs-host-region","gallery"),this.normalizeHostActions(t.find(".info").first())),this.ensureOwnedSlots(t),this.adoptExistingOwnedPanels(t)),this.hostRoot=t,this.ensureOwnedSlots(t),this.placeOwnedSlots(),this.bindResourceLifecycle(),t}getSlot(e){return this.ensureWorkspace().find(`[data-jhs-slot="${e}"]`).first()}ensureOwnedSlots(e=this.hostRoot){if(!e?.length)return;e.children('[data-jhs-slot="summary-actions"]').length||e.append('<div class="jhs-detail-owned-slot jhs-detail-owned-slot--summary-actions" data-jhs-slot="summary-actions"></div>');let t=e.children('[data-jhs-slot-group="post-resource"]').first();t.length||(t=$('<div class="jhs-detail-post-resource" data-jhs-slot-group="post-resource"></div>').appendTo(e)),t.children('[data-jhs-slot="reviews"]').length||t.append('<section class="jhs-detail-owned-slot jhs-detail-owned-slot--reviews" data-jhs-slot="reviews"></section>'),t.children('[data-jhs-slot="related"]').length||t.append('<section class="jhs-detail-owned-slot jhs-detail-owned-slot--related" data-jhs-slot="related"></section>')}placeOwnedSlots(){let e=this.hostRoot,t=yt(this.getRuntimeService("host"));if(!e?.length)return;this.ensureOwnedSlots(e);let s=e.children('[data-jhs-slot="summary-actions"]').first(),a=e.children('[data-jhs-slot-group="post-resource"]').first(),i=e.attr("data-jhs-workspace-site")==="javdb"?e.children(".video-meta-panel").first():e.children(".row.movie").first();i.length&&s.insertAfter(i),t?.resourceRegion?.length&&a.insertAfter(t.resourceRegion)}adoptExistingOwnedPanels(e){[[".jhs-detail-btn-row","summary-actions"],[".jhs-related-panel","related"],[".jhs-review-panel","reviews"]].forEach((([t,s])=>{let a=e.find(`[data-jhs-slot="${s}"]`).first();e.find(t).filter(((i,r)=>!$(r).closest("[data-jhs-slot]").length)).each(((i,r)=>a.append(r)))}))}normalizeHostActions(e){let t=new Set(["想看","看过","看過","存入清单","存入清單","下载","下載","订正","訂正"]);e.find("a, button").filter(((s,a)=>!$(a).is(".jhs-btn, [id^='jhs-']")&&t.has($(a).text().replace(/\s+/g," ").trim()))).addClass("jhs-detail-host-action")}isJhsOnlyMutation(e){if($(e.target).closest(".jhs-offline-actions,.jhs-select-control,.jhs-magnet-score").length)return!0;let t=[...e.addedNodes,...e.removedNodes].filter((s=>s.nodeType===Node.ELEMENT_NODE));return t.length>0&&t.every((s=>{let a=s;return a.matches?.(".jhs-offline-btn,.jhs-offline-actions,.jhs-magnet-score,.jhs-select-control")||a.closest?.(".jhs-offline-actions,.jhs-select-control")}))}bindResourceLifecycle(){let e=yt(this.getRuntimeService("host"));if(!e)return;if(this.resourceObserver&&this.resourceObserver.root===e.observeRoot[0])return void this.scheduleResourceUpdate();if(this.resourceObserver&&this.lifecycleScope?.releaseObserver(this.resourceObserver),!this.lifecycleScope)return;let t=this.lifecycleScope.observe(e.observeRoot[0],(s=>{s.every((a=>this.isJhsOnlyMutation(a)))||this.scheduleResourceUpdate()}),{childList:!0,subtree:!0});t.root=e.observeRoot[0],this.resourceObserver=t,e.sortSelect.length&&e.sortSelect.addClass("jhs-select-source")&&K.enhance(e.controller),this.scheduleResourceUpdate()}scheduleResourceUpdate(){if(this.scheduledResourceFrame!==null)return;let e=typeof window.requestAnimationFrame=="function",t=e?window.requestAnimationFrame.bind(window):(s=>Number(setTimeout(s)));this.scheduledResourceFrame=t((()=>{this.scheduledResourceFrame=null,this.cancelScheduledResourceFrame=null;let s=yt(this.getRuntimeService("host"));s&&(s.prepareLayout?.(),this.placeOwnedSlots(),s.sortSelect.length&&(s.sortSelect.addClass("jhs-select-source"),K.enhance(s.controller),K.refresh(s.sortSelect)),F&&F.emit("magnet-items-updated",{site:s.site,resourceRoot:s.resourceRoot[0],rows:s.rows()},{broadcast:!1}))})),this.cancelScheduledResourceFrame=()=>{this.scheduledResourceFrame!==null&&(e?window.cancelAnimationFrame?.(this.scheduledResourceFrame):clearTimeout(this.scheduledResourceFrame))}}};d(kn,"DetailWorkspacePlugin");var Ra=kn;var Cn=class Cn extends I{getName(){return"Fc2NavigationPlugin"}async handle(){if(!window.isListPage)return;let e=this.getOptionalDependency("Fc2Plugin");if(!e)return;let t=this.getRuntimeService("host"),s=await this.getRuntimeService("scope")(),a=t?.locateListRoot?.()??null,i=null,r=d(async()=>{let h=t?.locateListRoot?.();if(!h)return;let u=$(h).first();u.length&&(await this.protectFc2Navigation(u,e).catch(p=>clog.warn("FC2 导航保护初始化失败",p)),this.bindFc2Navigation(u,e),i!==h&&(i=h,s.addCleanup(()=>{u.off(".jhsFc2Navigation"),u.find('.item a[data-jhs-fc2-primary="true"]').off(".jhsFc2Navigation")})))},"ensureAttached");await r();let n=null,l=d(()=>{n==null&&(n=setTimeout(()=>{n=null,r().catch(h=>clog.warn("FC2 动态导航保护失败",h))},80))},"reprotect");s.addCleanup(()=>{n!=null&&(clearTimeout(n),n=null)});let c=F.on("list-items-added",h=>{h?.items?.length&&l()});s.addCleanup(c),a&&typeof MutationObserver<"u"&&s.observe(a,h=>{h.some(u=>u.addedNodes.length)&&l()},{childList:!0,subtree:!1})}async protectFc2Navigation(e,t){for(let s of e.find(".item").toArray()){let a=$(s);if(a.attr("data-jhs-fc2-protected")!=="true")try{let{carNum:i,aHref:r,fc2Source:n}=Ce(a);if(!i?.includes("FC2-")||!r)continue;let l=n||await t.resolveFc2Source({url:r})||"",c=a.find("a").first();if(!c.length)continue;a.attr({"data-jhs-original-url":r,"data-jhs-fc2-source":l,"data-jhs-fc2-protected":"true"}),c.attr("data-jhs-fc2-primary","true")}catch(i){clog.warn("FC2 导航保护初始化失败",i)}}}bindFc2Navigation(e,t){let s='.item a[data-jhs-fc2-primary="true"]',a=d(async i=>{if(i.type==="auxclick"&&i.button!==1||i.type==="click"&&i.button&&i.button!==0||i.shiftKey||i.altKey||$(i.target).closest("div.meta-buttons,[class^='jhs-match-']").length)return;let r=$(i.currentTarget).closest(".item"),n=!!(i.ctrlKey||i.metaKey||i.button===1),l=d((p,g,m)=>{clog.error("打开 FC2 详情失败,回退原始链接",m),n?utils.openPage(p,g,!0,{event:i,newTab:!0}):window.location.href=p},"fallbackToNative"),c,h,u;try{let p=Ce(r);c=p.carNum,h=r.attr("data-jhs-original-url")||p.aHref,u=p.fc2Source}catch(p){if(h=r.attr("data-jhs-original-url")||r.find("a").first().attr("href"),c=r.find(".video-title strong").first().text().trim(),!h)return;i.preventDefault(),i.stopPropagation(),l(h,c,p);return}if(!(!c?.includes("FC2-")||!h)){i.preventDefault(),i.stopPropagation();try{let p=await t.resolveMovieIdForRecord(c,h),g=u||await t.resolveFc2Source({url:h})||"";n?await t.openFc2Page(p,c,h,{event:i,newTab:!0},{source:g}):t.openFc2Dialog(p,c,h,{source:g})}catch(p){l(h,c,p)}}},"handleNavigation");e.off("click.jhsFc2Navigation auxclick.jhsFc2Navigation",s),e.find(s).each((i,r)=>{$(r).off("click.jhsFc2Navigation auxclick.jhsFc2Navigation").on("click.jhsFc2Navigation auxclick.jhsFc2Navigation",a)})}};d(Cn,"Fc2NavigationPlugin");var Ea=Cn;var _n=class _n extends I{getName(){return"FoldCategoryPlugin"}async initCss(){let e=await storageManager.getSetting();return`
            <style>
                #tags a.tag, .tags a.tag {
                    position:relative;
                }
                .highlight-btn {
                    position: absolute;
                    top: -10px;
                    right: -10px;
                    background-color: var(--jhs-status-down);
                    color: var(--jhs-status-down-on);
                    border: none;
                    border-radius: 50%;
                    width: 24px;
                    height: 24px;
                    font-size: 14px;
                    line-height: 24px;
                    text-align: center;
                    cursor: pointer;
                    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
                    display: none;
                    z-index: var(--jhs-z-dropdown);
                }
                /* 当父元素被高亮时,按钮变为其他颜色 */
                .highlighted .highlight-btn {
                    background-color: var(--jhs-status-watch);
                }
                /* 高亮状态下的标签样式 */
                .highlighted {
                    /* 浅黄色 */
                    border: ${e.highlightedTagNumber||1}px solid ${e.highlightedTagColor||"var(--jhs-status-filter)"};
                }
            </style>
        `}async handle(){let e=await this.getRuntimeService("scope")();window.isListPage&&(Y.includes("advanced_search")||(this.highlightTag(),utils.loopDetector((()=>$("#waitCheckBtn").length),(()=>{this.createFoldBtn()}),1,1e4,!0,e),$("#tags .tag-category .tag-expand").each(((t,s)=>{$(s).parent().hasClass("collapse")&&s.click()}))))}readTagName(e){return $(e).clone().find(".highlight-btn").remove().end().text().trim().replace(/\s*\(\d+\)$/,"")}highlightTag(){(async()=>{let e=await storageManager.getHighlightedTags(),t=$("#tags a.tag, .tags a.tag");e&&e.forEach((s=>{t.filter(((a,i)=>this.readTagName(i)===s)).addClass("highlighted")}))})().catch((e=>clog.error("分类高亮恢复失败",e))),$(document).off(".jhsHighlight").on("mouseenter.jhsHighlight","#tags a.tag, .tags a.tag",(e=>{let t=$(e.currentTarget);if(t.find(".highlight-btn").length)return;let s=$('<button class="jhs-btn highlight-btn" title="高亮显示">★</button>');t.append(s),s.fadeIn(0)})).on("mouseleave.jhsHighlight","#tags a.tag, .tags a.tag",(e=>{let t=$(e.currentTarget).find(".highlight-btn");t.fadeOut(0,(()=>t.remove()))})).on("click.jhsHighlight",".highlight-btn",(async e=>{e.stopPropagation(),e.preventDefault();let t=$(e.currentTarget).closest("a.tag"),s=this.readTagName(t[0]),a=await storageManager.getHighlightedTags();a.includes(s)?(a=a.filter((i=>i!==s)),t.removeClass("highlighted")):(a.push(s),t.addClass("highlighted")),await storageManager.setHighlightedTags(a)}))}async createFoldBtn(){let e=$("#tags"),t=$("#tags dl div.tag.is-info").map(((h,u)=>$(u).text().replaceAll(`
`,"").replaceAll(" ",""))).get().join(" ");if(!t)return;$(".tabs").append(`
            <div class="jhs-layout-8453d189">
                <div>已选分类: <span id="jhs-check-tag">${t}</span></div>
                <button type="button" class="jhs-btn jhs-btn--ghost jhs-layout-3a1fc324 jhs-fold-category-btn">
                    <span></span>
                    <i class="jhs-layout-78fa54ea"></i>
                </button>

            </div>
        `);let s=$("h2.section-title");if(s.length>0&&(s.append(`
                <div class="jhs-fold-category-box">
                    <button type="button" class="jhs-btn jhs-btn--ghost jhs-layout-2100e73d jhs-fold-category-btn">
                        <span></span>
                        <i class="jhs-layout-78fa54ea"></i>
                    </button>
                </div>
            `),e=$("section > div > div.box")),!e)return;let a=this.getRuntimeService("settings"),i=$(".jhs-fold-category-btn"),r=a.snapshot().foldCategoryCollapsed===!0,[n,l]=r?["展开","icon-angle-double-down"]:["折叠","icon-angle-double-up"];i.find("span").text(n).end().find("i").attr("class",l),window.location.href.includes("noFold=1")||e[r?"hide":"show"]();let c=Fe({settings:a,key:"foldCategoryCollapsed",fallback:!1,apply:d(h=>{r=h===!0;let[u,p]=r?["展开","icon-angle-double-down"]:["折叠","icon-angle-double-up"];i.find("span").text(u).end().find("i").attr("class",p),e[r?"hide":"show"]()},"apply"),onError:d(h=>{clog.error("分类折叠设置保存失败,已恢复",h),show.error("分类折叠设置保存失败,已恢复原设置")},"onError")});i.on("click",(async h=>{h.preventDefault(),await c(!r)}))}};d(_n,"FoldCategoryPlugin");var Da=_n;var $n=class $n extends I{async handle(){if(!window.isDetailPage)return;let e=this.getRuntimeService("settings"),t=await this.getRuntimeService("scope")();if(!this._settingsListenerBound){this._settingsListenerBound=!0;let s=d(a=>{a.detail?.names?.includes("enableMagnetsFilter")&&this.reconfigure()},"onSettingsChanged");e.addEventListener("settings.changed",s),t.addCleanup((()=>{e.removeEventListener("settings.changed",s),this._settingsListenerBound=!1}))}t.addCleanup(F?.on("magnet-items-updated",(()=>this.reconfigure()))||(()=>{})),this.reconfigure()}reconfigure(){let e=(this.getRuntimeService("settings").snapshot().enableMagnetsFilter??R)===R;e?this.doFilterMagnet():this.showAll(),$("#magnets-span").text(e?"关闭磁力过滤":"开启磁力过滤"),$("#enable-magnets-filter").attr("aria-pressed",String(e))}async initCss(){return"<style>.jhs-magnet-score{display:inline-flex;align-items:center;gap:3px;margin-left:6px;padding:1px 6px;border-radius:10px;font-size:11px;font-weight:600;vertical-align:middle;cursor:help}</style>"}getName(){return"HighlightMagnetPlugin"}doFilterMagnet(){let e=this.getRuntimeService("host")?.getDetailResourceBoundary?.();if(!e)return void this.updateFilterHint(!1);let t=e.rows(),s=[],a=!1;t.forEach((i=>{let r=e.getTitleTarget(i);if(!r)return;let n=$(r),l=n.text().toLowerCase(),c=this.getQualitySignals(l,e.hasSubtitleTag(i));$(i).removeClass("high-quality").show().addClass("magnet-row"),l.includes("4k")&&n.css("color","var(--jhs-status-filter-text)"),c.highQuality&&(a=!0,$(i).addClass("high-quality")),this.injectScoreBadge(n,n.text()),s.push(i)})),a&&s.forEach((i=>$(i).hasClass("high-quality")||$(i).hide())),this.updateFilterHint(a)}injectScoreBadge(e,t){try{if(e.find(".jhs-magnet-score").length>0)return;let s=ls({title:t||"",seeders:0}),a=s.total,i=a>=70?"高":a>=40?"中":"低",r=a>=70?"var(--jhs-status-down)":a>=40?"var(--jhs-status-watch)":"var(--jhs-surface-2)",n=a>=70?"var(--jhs-status-down-on)":a>=40?"var(--jhs-status-watch-on)":"var(--jhs-text-muted)",l=`分辨率:${s.resolution}/25 字幕:${s.subtitle}/20 做种:${s.seeders}/35 新鲜度:${s.freshness}/15`,c=$(`<span class="jhs-magnet-score" title="${l}">${i} ${a}</span>`).css({color:n,backgroundColor:r});e.append(c)}catch(s){clog.debug("磁力评分徽章注入失败,已忽略",s)}}getQualitySignals(e,t=!1){return zr(e,t)}updateFilterHint(e){$("#enable-magnets-filter").removeClass("do-hide").attr("data-tip",e?"仅显示识别到的高质量或字幕磁力":"未识别到可过滤项,当前未隐藏磁力")}showAll(){$("#enable-magnets-filter").removeClass("do-hide").removeAttr("data-tip");let e=this.getRuntimeService("host")?.getDetailResourceBoundary?.();e?.rows().forEach((t=>{$(t).removeClass("high-quality").show();let s=e.getTitleTarget(t);s&&$(s).css("color","").find(".jhs-magnet-score").remove()}))}};d($n,"HighlightMagnetPlugin");var Na=$n;var Tn=class Tn extends EventTarget{constructor(e){super(),this.keyOf=e,this.mode="explicit",this.selected=new Set,this.excluded=new Set}set(e,t){let s=this.keyOf(e),a=this.mode==="all-filtered"?this.excluded:this.selected;this.mode==="all-filtered"?t?a.delete(s):a.add(s):t?a.add(s):a.delete(s),this.emit()}selectAllFiltered(){this.mode="all-filtered",this.selected.clear(),this.excluded.clear(),this.emit()}clear(){this.mode="explicit",this.selected.clear(),this.excluded.clear(),this.emit()}has(e){let t=this.keyOf(e);return this.mode==="all-filtered"?!this.excluded.has(t):this.selected.has(t)}values(e){return this.mode==="all-filtered"?e.filter(t=>!this.excluded.has(this.keyOf(t))):e.filter(t=>this.selected.has(this.keyOf(t)))}snapshot(){return Object.freeze({mode:this.mode,selected:[...this.selected],excluded:[...this.excluded]})}emit(){this.dispatchEvent(new CustomEvent("selection.changed",{detail:this.snapshot()}))}};d(Tn,"SelectionModel");var La=Tn;var An=class An extends La{constructor(){super(e=>ee(e?.carNum)??String(e?.id??""))}};d(An,"HistorySelectionModel");var Ba=An;var Pn=class Pn{constructor(e){this.storage=e.storage,this.state=e.state}list(){return this.storage.getCarList()}activity(){return this.state.getActivityLog()}offline(){return this.state.getOfflineHistory()}undo(e){return this.state.undoTransaction(e)}remove(e){return this.state.remove(e)}toggle(e,t,s){return this.state.toggle(e,t,s)}patch(e,t,s){return this.state.patch(e,t,s)}removeOffline(e){return this.state.removeOfflineHistory(e)}};d(Pn,"HistoryRepository");var Ma=Pn;function Uh(o){let e=String(o||""),t=e.indexOf("-");if(t===-1)return document.createTextNode(e);let s=document.createElement("span"),a=document.createElement("button");return a.type="button",a.className="jhs-btn jhs-btn--ghost jhs-btn--sm table-link-param",a.textContent=e.substring(0,t+1),s.appendChild(a),s.appendChild(document.createTextNode(e.substring(t+1))),s}d(Uh,"buildCarNumCell");function Fh(o){let e=document.createElement("span");return String(o||"").split(" ").filter(t=>t.trim()!=="").forEach(t=>{let s=document.createElement("button");s.type="button",s.className="jhs-btn jhs-btn--ghost jhs-btn--sm table-link-param",s.textContent=t,e.appendChild(s)}),e}d(Fh,"buildNamesCell");function Vh(o){let e=document.createElement("div");e.className="action-btns",e.dataset.carNum=String(o.carNum||""),e.dataset.href=o.url?String(o.url):"";let t=document.createElement("button");t.type="button",t.className="jhs-btn jhs-btn--secondary history-detailBtn";let s=document.createElement("span");s.textContent="查看",t.appendChild(s),e.appendChild(t);let a=document.createElement("div");a.className="sub-btns";let i=document.createElement("button");i.type="button",i.className="jhs-btn jhs-btn--ghost sub-btns-toggle",i.setAttribute("aria-haspopup","menu"),i.setAttribute("aria-expanded","false");let r=document.createElement("span");r.textContent="更多操作",i.appendChild(r),a.appendChild(i);let n=document.createElement("div");n.className="sub-btns-menu",n.setAttribute("role","menu");let l=[["history-editBtn","编辑",""],["history-deleteBtn","移除","jhs-btn--danger"],["history-hasWatchBtn",ve,""],["history-hasDownBtn",fe,""],["history-favoriteBtn",Le,""],["history-filterBtn",Ne,""]];for(let[c,h,u]of l){let p=document.createElement("button");p.type="button",p.className=`jhs-btn jhs-btn--ghost ${c}`,p.setAttribute("role","menuitem"),u&&p.classList.add(u),p.textContent=h,n.appendChild(p)}return a.appendChild(n),e.appendChild(a),e}d(Vh,"buildActionButtons");function Hh(o){return`
            <div class="jhs-layout-8cddc29a">
                <div class="jhs-layout-da303dcf">
                    <label class="jhs-layout-27f87d75">番号:</label>
                    <input type="text" id="edit-carNum" class="jhs-field jhs-history-edit-field" readonly>
                </div>
                <div class="jhs-layout-da303dcf">
                    <label class="jhs-layout-27f87d75">演员 (用空格隔开):</label>
                    <textarea id="edit-names" class="jhs-textarea jhs-history-edit-field"></textarea>
                </div>
                <fieldset class="jhs-layout-da303dcf"><legend class="jhs-layout-27f87d75">状态:</legend>
                    <label class="jhs-option-row">收藏 <input type="checkbox" id="edit-favorite" class="mini-switch" ${o.favorite?"checked":""}></label>
                    <label class="jhs-option-row">已下载 <input type="checkbox" id="edit-downloaded" class="mini-switch" ${o.downloaded?"checked":""}></label>
                    <label class="jhs-option-row">已观看 <input type="checkbox" id="edit-watched" class="mini-switch" ${o.watched?"checked":""}></label>
                    <label class="jhs-option-row">屏蔽 <input type="checkbox" id="edit-blocked" class="mini-switch" ${o.blocked?"checked":""}></label>
                </fieldset>
                <div class="jhs-layout-da303dcf">
                    <label class="jhs-layout-27f87d75">链接:</label>
                    <input type="text" id="edit-url" class="jhs-field jhs-history-edit-field">
                </div>
                <div class="jhs-layout-da303dcf">
                    <label class="jhs-layout-27f87d75">备注:</label>
                    <textarea id="edit-remark" class="jhs-textarea jhs-history-edit-field"></textarea>
                </div>
            </div>
        `}d(Hh,"buildEditRecordForm");var In=class In extends I{constructor(){super(...arguments),this.tableObj=null,this.historyRoot=null,this.historySelectionModel=new Ba,this._historyRepository=null,this.historySorters=[],this.historyFilteredCount=0,this.historySelectionSyncing=!1,this.allCount=0,this.filterCount=0,this.favoriteCount=0,this.hasDownCount=0,this.hasWatchCount=0,this.waitCheckCount=0}getName(){return"HistoryPlugin"}getSourceLabel(e){if(!e)return"";let t=this.getRuntimeService("movie"),s=this.getRuntimeService("settings").snapshot();if(t.matchesProviderUrl("av123",e))return"123AV";try{let a=new URL(e).origin;if(a===t.externalSiteOrigin("javDbBtn",s))return"JavDB";if(a===t.externalSiteOrigin("javBusBtn",s))return"JavBus"}catch{}return e.includes("javdb")?"JavDB":e.includes("javbus")?"JavBus":e.includes("123av")?"123AV":"其他"}get historyRepository(){return this._historyRepository||(this._historyRepository=new Ma({storage:storageManager,state:this.getRuntimeService("state")}))}async initCss(){return`
            <style>
                .jhs-history-layout { display:flex; flex-direction:column; flex:1; height:100%; min-height:0; min-width:0; box-sizing:border-box; padding:var(--jhs-space-3) var(--jhs-space-4); overflow:hidden; }
                .jhs-history-layout > :not(#table-container) { flex-shrink:0; }
                .jhs-history-dialog #filterBox, .jhs-history-dialog #allSelectBox { display:flex; align-items:center; flex-wrap:wrap; gap:var(--jhs-space-2); margin-bottom:var(--jhs-space-2); }
                .jhs-history-selection-summary { color:var(--jhs-text-muted); font-size:var(--jhs-font-size-sm); }
                .jhs-history-select-all { width:18px; height:18px; accent-color:var(--jhs-accent); cursor:pointer; }
                .jhs-history-dialog #table-container { flex:1; min-height:0; overflow-x:hidden; }
                .sub-btns { position:relative; display:inline-block; }
                .sub-btns-menu { position:absolute; top:calc(100% + var(--jhs-space-1)); right:0; z-index:var(--jhs-z-popover); display:none; min-width:156px; padding:var(--jhs-space-1); overflow:hidden; border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); background:var(--jhs-surface); box-shadow:var(--jhs-shadow-md); }
                .sub-btns-menu.show { display:grid !important; gap:var(--jhs-space-1); }
                .sub-btns-menu .jhs-btn { width:100%; justify-content:flex-start; }
                .table-link-param { cursor:pointer; }
                .action-btns { display:flex; justify-content:center; gap:var(--jhs-space-2); }
                .jhs-history-edit-field { width:100%; padding:8px; border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-sm); }
                .jhs-history-edit-field[readonly] { background:var(--jhs-input-bg); }
                textarea.jhs-history-edit-field { min-height:60px; overflow-y:hidden; }
            </style>`}handleResize(){let e=d((t,s)=>s.children.length>0,"hasButton");$(".navbar-search").is(":hidden")?($(".historyBtnBox").filter(e).show(),$(".historyBtnBox").filter(((t,s)=>!e(t,s))).hide(),$(".miniHistoryBtnBox").hide()):($(".historyBtnBox").hide(),$(".miniHistoryBtnBox").show())}async handle(){N&&($(".navbar-end").prepend(`<div class="navbar-item has-sub-btns is-hoverable historyBtnBox">
                    <button type="button" id="historyBtn" class="jhs-btn navbar-link nav-btn jhs-nav-btn">鉴定记录</button>
                </div>`),$(".navbar-search").css("margin-left","0").before(`
                <div class="navbar-item miniHistoryBtnBox">
                    <button type="button" id="miniHistoryBtn" class="jhs-btn navbar-link nav-btn jhs-nav-btn">鉴定记录</button>
                </div>
            `),this.handleResize(),$(window).resize((()=>{this.handleResize()})),$("#historyBtn,#miniHistoryBtn").on("click",(e=>this.openHistory()))),B&&this.createBusButton().catch(e=>clog.warn("鉴定记录入口创建失败",e))}async createBusButton(){if(!await new Promise(t=>{let s=Date.now(),a=setInterval((()=>{if($("#setting-btn").length&&$("#top-right-box").length)return clearInterval(a),t(!0);Date.now()-s>=2500&&(clearInterval(a),t(!1))}),25)}))return void clog.warn("鉴定记录入口未创建:JavBus 顶部工具区未就绪");$("#top-right-box").append('<button type="button" id="historyBtn" class="jhs-btn jhs-btn--secondary">鉴定记录</button>'),$("#historyBtn,#miniHistoryBtn").on("click",(t=>this.openHistory()))}openHistory(){let e=`
            <div class="jhs-history-layout jhs-history-dialog">
                 <div id="filterBox" class="jhs-layout-53809f1e">
                    <select id="dataType" class="jhs-select-source">
                        <option value="all" selected>所有</option>
                        <option value="waitCheck">待鉴定</option>
                        <option value="filter">${et}</option>
                        <option value="favorite">${tt}</option>
                        <option value="hasDown">${fe}</option>
                        <option value="hasWatch">${ve}</option>
                    </select>
                    <input id="searchCarNum" type="text" placeholder="搜索番号|演员" class="jhs-field">
                    <button type="button" id="clearSearchbtn" class="jhs-btn jhs-btn--secondary jhs-layout-21a4fe43">重置</button>
                </div>
                <div id="allSelectBox" class="jhs-layout-66253c00">
                    <button type="button" class="jhs-btn jhs-btn--dark multiple-history-deleteBtn jhs-layout-7daea5fa"> <span>移除</span> </button>
                    <button type="button" class="jhs-btn jhs-btn--watch multiple-history-hasWatchBtn jhs-layout-2e003268">标记观看</button>
                    <button type="button" class="jhs-btn jhs-btn--down multiple-history-hasDownBtn jhs-layout-2e003268">标记下载</button>
                    <button type="button" class="jhs-btn jhs-btn--fav multiple-history-favoriteBtn jhs-layout-2e003268">标记收藏</button>
                    <button type="button" class="jhs-btn jhs-btn--filter multiple-history-filterBtn jhs-layout-2e003268">标记屏蔽</button>
                </div>
                <div id="table-container"></div>
            </div>
        `;e=e.replace('<div id="filterBox"','<div id="historyViewTabs" class="jhs-segmented" role="tablist"><button type="button" class="jhs-btn jhs-segmented__item active" data-history-view="state">作品状态</button><button type="button" class="jhs-btn jhs-segmented__item" data-history-view="activity">操作记录</button><button type="button" class="jhs-btn jhs-segmented__item" data-history-view="offline">离线任务</button></div><div id="filterBox"'),this.getRuntimeService("dialog").open({type:1,title:"鉴定记录",ui:{body:"table"},content:e,scrollbar:!1,shadeClose:!0,area:utils.getDialogArea("xl"),anim:-1,success:d(async t=>{let s=$(t);this.historyRoot=s,s.find("#allSelectBox").prepend('<span id="historySelectionSummary" class="jhs-history-selection-summary" role="status" aria-live="polite"></span>'),this.resetHistorySelection(!1),K.enhance(s),await this.loadTableData(),s.on("click.jhsHistory","#clearSearchbtn",(async a=>{s.find("#searchCarNum").val(""),K.setValue(s.find("#dataType"),"all"),await this.reloadTable(),s.find("#allSelectBox").hide()})).on("focusout.jhsHistory keydown.jhsHistory","#searchCarNum",(async a=>{if(a.type==="focusout"||a.key==="Enter"){if(a.key==="Enter"&&a.preventDefault(),a.type==="keydown"&&a.key!=="Enter")return;await this.reloadTable()}})).on("click.jhsHistory",".table-link-param",(async a=>{let i=$(a.currentTarget);s.find("#searchCarNum").val(i.text()),await this.reloadTable()})).on("change.jhsHistory","#dataType",(async()=>{await this.reloadTable()})).on("click.jhsHistory","[data-history-view]",(async a=>{let i=$(a.currentTarget).data("history-view");s.find("[data-history-view]").removeClass("active"),$(a.currentTarget).addClass("active"),await this.showHistoryView(i)})).on("click",".jhs-undo-activity",(async a=>{try{let i=await this.historyRepository.undo($(a.currentTarget).data("transaction"));show.info(`撤销完成:${i.reverted.length} 项成功,${i.conflicts.length} 项冲突`),await this.renderActivityHistory()}catch(i){clog.error("撤销失败:",i),show.error("撤销失败,请稍后重试")}})).on("click",".jhs-copy-offline",(async a=>{await utils.copyToClipboard("离线资源",$(a.currentTarget).data("resource"))})).on("click",".jhs-retry-offline",(async a=>{let i=$(a.currentTarget).data("id"),r=(await this.historyRepository.offline()).find(l=>l.id===i),n=this.getOptionalDependency("UnifiedOfflinePlugin");r&&n&&await n.submitResource(a,r.resource,$(a.currentTarget),{carNum:r.carNum},r.id,{forceAvailabilityRefresh:!0,preferredProviderId:r.providerId}),await this.renderOfflineHistory()})).on("click",".jhs-open-offline",(async a=>{let i=$(a.currentTarget).data("id"),r=(await this.historyRepository.offline()).find(c=>c.id===i),n=this.getOptionalDependency("UnifiedOfflinePlugin")?.registry?.providers?.get(r?.providerId),l=n?.openUrl?.();l&&window.open(l,"_blank","noopener,noreferrer")})).on("click",".jhs-delete-offline",(async a=>{await this.historyRepository.removeOffline($(a.currentTarget).data("id")),await this.renderOfflineHistory()})),this.bindHistoryActions(s)},"success"),end:d(()=>{this.resetHistorySelection(),this.historyRoot?.off(".jhsHistory"),this.historyRoot=null,this.tableObj&&(this.tableObj.destroy(),this.tableObj=null)},"end")})}async showHistoryView(e){let t=e==="state";return this.resetHistorySelection(),this.historyRoot?.find("#filterBox,#allSelectBox").toggle(t),this.tableObj?.destroy(),this.tableObj=null,t?this.loadTableData():e==="activity"?this.renderActivityHistory():this.renderOfflineHistory()}async renderActivityHistory(){let e=await this.historyRepository.activity(),t=this.historyRoot.find("#table-container").empty();if(!e.entries.length)return void t.html('<div class="jhs-state jhs-state--empty">暂无操作记录</div>');e.entries.slice().reverse().forEach(s=>{let a=s.changes.filter(r=>r.undoState==="reverted").length,i=s.changes.filter(r=>r.undoState==="conflict").length;t.append($('<article class="jhs-card"></article>').append($("<strong></strong>").text(`${s.type} · ${s.changes.length} 项`),$("<p></p>").text(`${new Date(s.createdAt).toLocaleString()} · 已撤销 ${a} · 冲突 ${i}`),$("<p></p>").text(s.changes.map(r=>r.carNum).join("、")),$('<button type="button" class="jhs-btn jhs-btn--secondary jhs-undo-activity">撤销可恢复项</button>').attr("data-transaction",s.id).prop("disabled",s.commitState!=="committed"||a===s.changes.length)))})}async renderOfflineHistory(){let e=await this.historyRepository.offline(),t=this.historyRoot.find("#table-container").empty();if(!e.length)return void t.html('<div class="jhs-state jhs-state--empty">暂无离线任务</div>');e.slice().reverse().forEach(s=>{let a=this.getOptionalDependency("UnifiedOfflinePlugin"),i=a?.registry?.providers?.get?.(s.providerId),r=$('<div class="jhs-toolbar"></div>').append($('<button type="button" class="jhs-btn jhs-copy-offline">复制资源</button>').attr("data-resource",s.resource));a&&i&&r.append($('<button type="button" class="jhs-btn jhs-retry-offline">重试</button>').attr("data-id",s.id)),i&&typeof i.openUrl=="function"&&r.append($('<button type="button" class="jhs-btn jhs-open-offline">打开服务</button>').attr("data-id",s.id)),r.append($('<button type="button" class="jhs-btn jhs-btn--danger jhs-delete-offline">移除记录</button>').attr("data-id",s.id)),t.append($('<article class="jhs-card"></article>').append($("<strong></strong>").text(`${s.providerName||s.providerId} · ${s.status}`),$("<p></p>").text(`${s.carNum||"未关联番号"} · ${new Date(s.createdAt).toLocaleString()}${s.retryOf?` · 重试自 ${s.retryOf}`:""}`),$("<p></p>").text(s.errorMessage||s.resource),r))})}async reloadTable(e=!0){e&&this.resetHistorySelection(),await this.tableObj?.setPage(1)}normalizeHistoryCarNum(e){return T(e)||String(e||"").trim().toUpperCase()}isHistoryAllFiltered(){return this.historySelectionModel.mode==="all-filtered"}resetHistorySelection(e=!0){if(this.historySelectionModel.clear(),e&&this.tableObj){this.historySelectionSyncing=!0;try{this.tableObj.deselectRow()}finally{this.historySelectionSyncing=!1}}this.updateHistorySelectionUi()}createHistorySelectAllCheckbox(){let e=document.createElement("input");return e.type="checkbox",e.className="jhs-history-select-all",e.setAttribute("aria-label","选择当前筛选条件下的全部记录"),e.addEventListener("change",(()=>{e.checked?(this.historySelectionModel.selectAllFiltered(),this.syncHistoryPageSelection()):this.resetHistorySelection()})),e}syncHistoryPageSelection(){if(!this.tableObj||!this.isHistoryAllFiltered())return void this.updateHistorySelectionUi();let e=this.tableObj.getData?.()||[],t=e.filter((s=>this.historySelectionModel.has(s))).map((s=>s.carNum));this.historySelectionSyncing=!0;try{this.tableObj.deselectRow(),t.length&&this.tableObj.selectRow(t)}finally{this.historySelectionSyncing=!1}this.updateHistorySelectionUi()}updateHistoryRowSelection(e,t){if(this.historySelectionSyncing)return void this.updateHistorySelectionUi();let s=e?.getData?.();s&&this.historySelectionModel.set(s,t),this.updateHistorySelectionUi()}getHistorySelectionSummary(){if(this.isHistoryAllFiltered()){let t=this.historySelectionModel.excluded.size,s=Math.max(0,this.historyFilteredCount-t);return{count:s,text:t?`已选择当前筛选结果 ${s} 条,已排除 ${t} 条`:`已选择当前筛选结果 ${s} 条`}}let e=this.historySelectionModel.selected.size;return{count:e,text:`已选择当前页 ${e} 条`}}updateHistorySelectionUi(){if(!this.historyRoot)return;let e=this.getHistorySelectionSummary(),t=this.historyRoot.find("#allSelectBox"),s=this.historyRoot.find("#filterBox");this.historyRoot.find("#historySelectionSummary").text(e.text),e.count>0?(s.hide(),t.show()):(s.show(),t.hide()),this.historyRoot.find(".jhs-history-select-all").each(((a,i)=>{i.checked=this.isHistoryAllFiltered(),i.indeterminate=this.isHistoryAllFiltered()?this.historySelectionModel.excluded.size>0:e.count>0}))}async getHistoryBatchSelection(){if(!this.isHistoryAllFiltered())return this.historySelectionModel.values(this.tableObj?.getData?.()||[]);let e=await this.getFilteredHistoryData(this.historySorters),t=new Set(e.map(s=>this.normalizeHistoryCarNum(s.carNum)));for(let s of this.historySelectionModel.excluded)t.has(s)||this.historySelectionModel.excluded.delete(s);return this.historyFilteredCount=e.length,this.historySelectionModel.values(e)}bindHistoryActions(e){e.on("click.jhsHistory",(function(t){if(t.target.closest(".sub-btns-toggle")){let s=t.target.closest(".sub-btns-toggle"),a=s.closest(".sub-btns").querySelector(".sub-btns-menu");e.find(".sub-btns-menu.show").each(((i,r)=>{r!==a&&(r.classList.remove("show"),r.previousElementSibling?.setAttribute("aria-expanded","false"))})),a.classList.toggle("show"),s.setAttribute("aria-expanded",String(a.classList.contains("show")))}else e.find(".sub-btns-menu.show").each(((s,a)=>{a.classList.remove("show"),a.previousElementSibling?.setAttribute("aria-expanded","false")}))})),e.on("keydown.jhsHistory",".sub-btns",(t=>{let s=$(t.currentTarget).find(".sub-btns-menu"),a=s.find('[role="menuitem"]'),i=a.index(document.activeElement);if(t.key==="Escape")return t.preventDefault(),s.removeClass("show"),$(t.currentTarget).find(".sub-btns-toggle").attr("aria-expanded","false").trigger("focus");if(!["ArrowDown","ArrowUp","Home","End"].includes(t.key)||!s.hasClass("show"))return;t.preventDefault();let r=t.key==="Home"?0:t.key==="End"?a.length-1:t.key==="ArrowDown"?(i+1+a.length)%a.length:(i-1+a.length)%a.length;a.eq(r).trigger("focus")})),e.on("click.jhsHistory",".history-deleteBtn, .history-filterBtn, .history-favoriteBtn, .history-hasDownBtn, .history-hasWatchBtn, .history-detailBtn",(t=>{t.preventDefault(),t.stopPropagation();let s=$(t.currentTarget),a=s.closest(".action-btns"),i=a.attr("data-car-num"),r=a.attr("data-href"),n=d(async l=>{try{let c=ke(l);if(!c)throw new TypeError(`无效历史状态操作: ${l}`);await this.historyRepository.toggle(i,c,{type:"history-state",record:{carNum:i,url:r}}),await this.reloadTable()}catch(c){clog.error("历史记录操作失败:",c),show.error("操作失败")}},"s");if(s.hasClass("history-filterBtn")){let l=this.tableObj?.getRow(i)?.getData();q(l?.stateFlags).blocked?n(ce):utils.q(t,`是否屏蔽${C(i)}?`,(()=>n(ce)))}else s.hasClass("history-favoriteBtn")?n(ue):s.hasClass("history-hasDownBtn")?n(pe):s.hasClass("history-hasWatchBtn")?n(me):s.hasClass("history-deleteBtn")?this.handleDelete(t,i):s.hasClass("history-detailBtn")&&this.handleClickDetail(t,{carNum:i,url:r}).catch((l=>clog.error("历史详情打开失败",l)))})),e.on("click.jhsHistory",".multiple-history-deleteBtn, .multiple-history-filterBtn, .multiple-history-favoriteBtn, .multiple-history-hasDownBtn, .multiple-history-hasWatchBtn",(async t=>{t.preventDefault(),t.stopPropagation();let s=$(t.currentTarget),a=await this.getHistoryBatchSelection(),i="",r="";if(s.hasClass("multiple-history-filterBtn")?(i="屏蔽",r=ce):s.hasClass("multiple-history-favoriteBtn")?(i="收藏",r=ue):s.hasClass("multiple-history-hasDownBtn")?(i="已下载",r=pe):s.hasClass("multiple-history-hasWatchBtn")?(i="已观看",r=me):s.hasClass("multiple-history-deleteBtn")&&(i="移除",r="delete"),!a.length)return void show.info("请先选择要处理的记录");let n=this.isHistoryAllFiltered()?this.historySelectionModel.excluded.size?`当前筛选结果中已选择 ${a.length} 条,排除 ${this.historySelectionModel.excluded.size} 条`:`当前筛选结果中已选择全部 ${a.length} 条`:`当前页已选择 ${a.length} 条`;utils.q(t,`${n},是否标记为${i}?`,(async()=>{let l=loading();try{if(r==="delete"){let c=a.map(u=>u.carNum),h=await this.historyRepository.remove(c);if(!h.changed.length)return void show.error("提供的番号中没有一个存在于列表中。");show.ok(`已成功删除 ${h.changed.length} 个番号`)}else{let c=ke(r);if(!c)throw new TypeError(`无效历史批量操作: ${r}`);await this.historyRepository.patch(a.map((h=>h.carNum)),{[c]:!0},{type:"history-batch-state",records:a}),show.ok("操作成功")}this.resetHistorySelection(),await this.reloadTable(!1)}catch(c){clog.error(c),show.error("操作失败,请稍后重试")}finally{l.close()}}))}))}async getFilteredHistoryData(e=this.historySorters){let t=await this.historyRepository.list();this.allCount=t.length,this.filterCount=0,this.favoriteCount=0,this.hasDownCount=0,this.hasWatchCount=0,this.waitCheckCount=0,t.forEach(l=>{let c=q(l.stateFlags);c.blocked&&this.filterCount++,c.favorite&&this.favoriteCount++,c.downloaded&&this.hasDownCount++,c.watched&&this.hasWatchCount++,oe(c)||this.waitCheckCount++}),this.historyRoot.find('#dataType option[value="all"]').text(`所有 (${this.allCount})`),this.historyRoot.find('#dataType option[value="waitCheck"]').text(`待鉴定 (${this.waitCheckCount})`),this.historyRoot.find('#dataType option[value="filter"]').text(`${et} (${this.filterCount})`),this.historyRoot.find('#dataType option[value="favorite"]').text(`${tt} (${this.favoriteCount})`),this.historyRoot.find('#dataType option[value="hasDown"]').text(`${fe} (${this.hasDownCount})`),this.historyRoot.find('#dataType option[value="hasWatch"]').text(`${ve} (${this.hasWatchCount})`);let s=String(this.historyRoot.find("#dataType").val()||"all"),i={filter:"blocked",favorite:"favorite",hasDown:"downloaded",hasWatch:"watched"}[s],r=s==="all"?t:s==="waitCheck"?t.filter((l=>!oe(l.stateFlags))):i?t.filter((l=>q(l.stateFlags)[i])):t,n=String(this.historyRoot.find("#searchCarNum").val()||"").trim();if(n){let l=n.toLowerCase().replace("-c","").replace("-uc","").replace("-4k","");r=r.filter(c=>{let h=c.carNum.toLowerCase().includes(l),u=(c.names?c.names:"").toLowerCase().includes(l);return h||u})}if(e&&e.length>0){let l=e[0],c=l.field,h=l.dir;r.sort(((u,p)=>{let g=u[c],m=p[c],f=g==null||g==="",v=m==null||m==="";return f&&!v?1:!f&&v?-1:f&&v?0:g<m?h==="asc"?-1:1:g>m?h==="asc"?1:-1:0}))}return r}async getDataList(e,t,s){this.historySorters=Array.isArray(s)?s.map(c=>({...c})):[];let a=await this.getFilteredHistoryData(this.historySorters),i=a.length,r=Math.ceil(i/t),n=(e-1)*t,l=n+t;return this.historyFilteredCount=i,{maxPage:r,dataList:a.slice(n,l),totalCount:i}}async loadTableData(){this.tableObj=ze(globalThis.Tabulator,this.historyRoot.find("#table-container").get(0),{layout:"fitColumns",placeholder:"暂无数据",virtualDom:!0,pagination:!0,paginationMode:"remote",sortMode:"remote",ajaxURL:"queryRealm",dataLoader:!1,ajaxRequestFunc:d(async(e,t,s)=>{let a=s.page,i=s.size,r=s.sort;return await this.getDataList(a,i,r)},"ajaxRequestFunc"),dataReceiveParams:{last_page:"maxPage",last_row:"totalCount",data:"dataList"},paginationSize:50,paginationSizeSelector:[50,100,1e3],paginationCounter:d((e,t,s,a,i)=>`共 ${a} 条记录`,"paginationCounter"),responsiveLayout:"collapse",responsiveLayoutCollapse:!0,columnDefaults:{headerHozAlign:"center",hozAlign:"center"},selectableRowsPersistence:!1,index:"carNum",columns:[{formatter:"rowSelection",titleFormatter:d(()=>this.createHistorySelectAllCheckbox(),"titleFormatter"),hozAlign:"center",headerSort:!1,responsive:0,width:40,cellClick:d((e,t)=>{t.getRow().toggleSelect()},"cellClick")},{title:"番号",field:"carNum",width:120,sorter:"string",responsive:0,formatter:d(e=>Uh(e.getData().carNum),"formatter")},{title:"演员",field:"names",minWidth:200,sorter:"string",responsive:5,headerSort:!0,formatter:d(e=>Fh(e.getData().names),"formatter")},{title:"创建时间",field:"createDate",width:170,sorter:"string",responsive:4},{title:"修改时间",field:"updateDate",width:170,sorter:"string",responsive:4},{title:"发行时间",field:"publishTime",width:170,sorter:"string",responsive:4},{title:"来源",field:"url",width:80,sorter:"string",responsive:5,hozAlign:"left",formatter:d((e,t,s)=>{let a=e.getData().url;return a?`<span class="jhs-badge jhs-badge--neutral">${this.getSourceLabel(a)}</span>`:""},"formatter")},{title:"状态",field:"stateFlags",width:220,sorter:!1,responsive:1,headerSort:!1,formatter:d((e,t,s)=>{let a=q(e.getData().stateFlags);return[[a.blocked,"filter",et],[a.favorite,"fav",tt],[a.downloaded,"down",fe],[a.watched,"watch",ve]].filter((n=>n[0])).map((n=>`<span class="jhs-badge jhs-badge--soft jhs-badge--${n[1]}">${n[2]}</span>`)).join(" ")||'<span class="jhs-badge jhs-badge--neutral">待鉴定</span>'},"formatter")},{title:"备注",field:"remark",width:100,sorter:"string",responsive:6},{title:"操作",sorter:"string",minWidth:150,cssClass:"action-cell-dropdown",responsive:0,headerSort:!1,formatter:d((e,t,s)=>{let a=e.getData(),i=Vh(a);return s((()=>{i.querySelector(".history-editBtn")?.addEventListener("click",(r=>{this.editRecord(a)}))})),i},"formatter")}],initialSort:[{column:"updateDate",dir:"desc"}]}),this.tableObj.on("dataProcessing",(()=>{this.historySelectionSyncing=!0})),this.tableObj.on("dataProcessed",(()=>{this.historySelectionSyncing=!1,this.isHistoryAllFiltered()?this.syncHistoryPageSelection():this.updateHistorySelectionUi()})),this.tableObj.on("rowSelected",(e=>{this.updateHistoryRowSelection(e,!0)})),this.tableObj.on("rowDeselected",(e=>{this.updateHistoryRowSelection(e,!1)})),this.tableObj.on("rowSelectionChanged",(()=>{this.updateHistorySelectionUi()})),this.tableObj.on("rowDblClick",(function(e,t){t.toggleSelect()}))}handleDelete(e,t){utils.q(e,`是否移除${C(t)}?`,(async()=>{try{await this.historyRepository.remove(t),this.getOptionalDependency("ListPagePlugin")?.showCarNumBox?.(t),await this.reloadTable()}catch(s){clog.error("移除历史记录失败:",s),show.error("移除失败,请稍后重试")}}))}async handleClickDetail(e,t){if(t.carNum.includes("FC2-")){let s=this.getOptionalDependency("Fc2Plugin");if(!s)return t.url?void utils.openPage(t.url,t.carNum,!1,e):void show.info("FC2 详情功能已禁用");let a=await s.resolveFc2Source(t),i=await s.resolveMovieIdForRecord(t.carNum,t.url);N?s.openFc2Dialog(i,t.carNum,t.url,{source:a}):B&&await s.openFc2Page(i,t.carNum,t.url,{newTab:!0},{source:a});return}if(N){if(!t.url)return void window.open("/search?q="+t.carNum,"_blank");utils.openPage(t.url,t.carNum,!1,e)}if(B){if(!t.url)return void show.info("该记录没有来源链接");t.url.includes("javdb")?window.open(t.url,"_blank"):utils.openPage(t.url,t.carNum,!1,e)}}async editRecord(e){let t=e.carNum,s=e.names||"",a=e.url||"",i=e.remark||"",r=q(e.stateFlags),n=$(),l=Hh(r),c=this.getRuntimeService("dialog");c.open({type:1,title:`编辑记录: ${t}`,area:utils.getDialogArea("sm"),content:l,btn:["保存","取消"],success:d((h,u)=>{n=$(h),n.find("#edit-carNum").val(t),n.find("#edit-names").val(s),n.find("#edit-url").val(a),n.find("#edit-remark").val(i);let p=d(f=>{f.css("height","auto"),f.css("height",f[0].scrollHeight+15+"px")},"resize"),g=n.find("#edit-names");g.on("input",(f=>p($(f.currentTarget)))),p(g);let m=n.find("#edit-remark");m.on("input",(f=>p($(f.currentTarget)))),p(m)},"success"),yes:d(async h=>{let u=String(n.find("#edit-names").val()||"").trim(),p=String(n.find("#edit-url").val()||"").trim(),g=String(n.find("#edit-remark").val()||"").trim(),m={favorite:n.find("#edit-favorite").prop("checked"),downloaded:n.find("#edit-downloaded").prop("checked"),watched:n.find("#edit-watched").prop("checked"),blocked:n.find("#edit-blocked").prop("checked")},f=d(async()=>{await this.historyRepository.patch(e.carNum,m,{type:"history-edit",replaceMetadata:!0,record:{...e,names:u,url:p,remark:g}}),this.tableObj.setData(),c.close(h)},"save");if(!r.blocked&&m.blocked)return utils.q(null,`是否屏蔽${C(e.carNum)}?`,(()=>{f()})),!1;await f()},"yes")})}};d(In,"HistoryPlugin");var Oa=In;var Rn=class Rn extends I{constructor(){super(),this.ownedRankingSortOverride=null}getName(){return"ListPageButtonPlugin"}async handle(){if(!window.isListPage||We()||window.location.search.includes("handleTop=1"))return;let e=await this.getRuntimeService("scope")(),t=this.getRuntimeService("settings");await this.createMenuBtn(e),this.bindEvent();let s=d(a=>{a.detail?.names?.includes("autoPage")&&this.syncSortUi().catch(r=>clog.error("排序状态同步失败",r))},"onSettingsChanged");t.addEventListener("settings.changed",s),e.addCleanup((()=>t.removeEventListener("settings.changed",s))),await this.syncSortUi()}async mountOwnedRankingControls(e=null){let t=e?.length?e:$(".jhs-hitshow-heading");if(!t.length||$("#waitCheckBtn").length)return;let s=await this.getRuntimeService("scope")();await this.createMenuBtn(s,t),this.bindEvent(),await this.syncSortUi()}async syncSortUi(){let t=this.getRuntimeService("settings").snapshot().autoPage??R,s=this.supportsLiveSorting(),a=$("#sort-toggle-btn");if(!a.length)return;let i=$(".jhs-sort-menu");if(t===R&&!s){a.prop("disabled",!0).attr("title","瀑布流模式仅支持默认排序"),$("#jhs-sort-current").text("默认(瀑布流)"),i.find(".jhs-sort-option").attr("aria-checked","false"),i.find('[data-sort-method="default"]').attr("aria-checked","true"),await this.sortItems("default");return}let r=this.activeSortMethod(),n={default:"默认",rateCount:"评价人数",date:"时间"},l=Object.prototype.hasOwnProperty.call(n,r)?n[r]:n.default;a.prop("disabled",!1).attr("title","选择列表排序方式"),$("#jhs-sort-current").text(l),i.find(".jhs-sort-option").attr("aria-checked","false"),i.find(`[data-sort-method="${r}"]`).attr("aria-checked","true"),await this.sortItems()}async createMenuBtn(e,t=null){let s=!!this.getOptionalDependency("NewVideoPlugin"),a=!!this.getOptionalDependency("BlacklistPlugin"),i=!!this.getOptionalDependency("ListPagePlugin");if(N){let l=Y.includes("/actors/"),c=$(".main-tabs, .tabs"),h="加入黑名单",u="jhs-btn--filter",p=null;if(l){c=$(".toolbar, .section-addition").filter(":last");let v=await storageManager.getBlacklist(),b=this.getActressPageInfo();v.find(w=>w.starId===b.starId)&&(h="已加入黑名单",u="jhs-btn--muted")}else Y.includes("/tags")&&utils.loopDetector((()=>$("#jhs-check-tag").text().trim()),(async()=>{let v=$("#addBlacklistBtn");v.attr("data-tip","将当前分类标签加入到黑名单, 后续有作品更新也会纳入屏蔽中");let b=$("#jhs-check-tag").text().trim();if(!b)return;let w="no-"+b;p=(await storageManager.getBlacklist()).find(j=>j.starId===w),p&&(v.addClass("jhs-btn--muted").removeClass("jhs-btn--filter"),$("#addBlacklistBtn span").text("已加入黑名单"))}),20,1e4,!0,e);Y.includes("advanced_search")&&(c=t?.length?t:$("h2.section-title"));let m=this.activeSortMethod(),f="当前排序方式: "+(m==="rateCount"?"评价人数":m==="date"?"时间":"默认");c.append(`
                <div class="jhs-list-btn-row">
                    <button type="button" id="waitCheckBtn" class="jhs-btn jhs-btn--secondary"><span>打开待鉴定</span></button>
                    ${l&&a?`
<button type="button" id="addBlacklistBtn" class="jhs-btn ${u}" data-tip="将演员加入黑名单, 后续有作品更新也会纳入屏蔽中"><span>${h}</span></button>
<button type="button" id="filterAllVideo" class="jhs-btn jhs-btn--watch" data-tip="一键屏蔽已选分类的视频列表至鉴定记录中"><span>批量屏蔽</span></button>
`:""}
                    ${i?`
<button type="button" id="favoriteAllVideo" class="jhs-btn jhs-btn--fav" data-tip="收藏当前搜索全部分页中符合当前筛选的作品"><span>批量收藏</span></button>
<button type="button" id="hasDownAllVideo" class="jhs-btn jhs-btn--down" data-tip="标记当前搜索全部分页中符合当前筛选的作品为已下载"><span>批量标记已下载</span></button>
`:""}
                    ${Y.includes("/tags")&&a?`
<button type="button" id="addBlacklistBtn" class="jhs-btn ${u}" data-tip="将演员加入黑名单, 后续有作品更新也会纳入屏蔽中"><span>${h}</span></button>
`:""}
                </div>
                <div class="jhs-list-btn-row">
                    ${s?'<button type="button" id="newVideoBtn" class="jhs-btn jhs-btn--secondary"><span>新作品检测 (<span id="newVideoCount">0</span>)</span></button>':""}
                    ${a?'<button type="button" id="blacklistBtn" class="jhs-btn jhs-btn--secondary"><span>演员黑名单</span></button>':""}
                    ${ms||!this.supportsSorting()?"":this.sortMenuHtml(m,f)}
                </div>
            `)}if(B){let l=Y.includes("/star/"),c="加入黑名单",h="jhs-btn--filter";if(l){let p=await storageManager.getBlacklist(),g=this.getActressPageInfo();p.find(m=>m.starId===g.starId)&&(c="已加入黑名单",h="jhs-btn--muted")}let u=this.activeSortMethod();$(".masonry").parent().prepend(`
                <div class="jhs-list-btn-row">
                    <button type="button" id="waitCheckBtn" class="jhs-btn jhs-btn--secondary"><span>打开待鉴定</span></button>
                    ${l&&a?`
                        <button type="button" id="addBlacklistBtn" class="jhs-btn ${h}" data-tip="将演员加入黑名单, 后续有作品更新也会纳入屏蔽中"><span>${c}</span></button>
                        <button type="button" id="filterAllVideo" class="jhs-btn jhs-btn--watch" data-tip="一键屏蔽已选分类的视频列表至鉴定记录中"><span>批量屏蔽</span></button>
                    `:""}${i?`
                        <button type="button" id="favoriteAllVideo" class="jhs-btn jhs-btn--fav" data-tip="收藏当前搜索全部分页中符合当前筛选的作品"><span>批量收藏</span></button>
                        <button type="button" id="hasDownAllVideo" class="jhs-btn jhs-btn--down" data-tip="标记当前搜索全部分页中符合当前筛选的作品为已下载"><span>批量标记已下载</span></button>
                    `:""}${!l&&a?'<button type="button" id="blacklistBtn" class="jhs-btn jhs-btn--secondary"><span>演员黑名单</span></button>':""}
                    ${this.supportsSorting()?this.sortMenuHtml(u):""}
                </div>
            `)}$("#waitCheckBtn > span").text("开始鉴定");let r=$("#newVideoCount").detach(),n=$("#newVideoBtn > span");n.length&&n.empty().append(document.createTextNode("新作品 ("),r,document.createTextNode(")"))}sortMenuHtml(e,t="选择列表排序方式"){let s={default:"默认",rateCount:"评价人数",date:"时间"},a=typeof e=="string"&&e in s?e:"default",i=s[a];return`<div class="jhs-sort-control"><button type="button" id="sort-toggle-btn" class="jhs-btn jhs-btn--secondary" aria-haspopup="menu" aria-expanded="false" title="${t}"><span id="jhs-sort-current">${i}</span></button><div class="jhs-popover jhs-sort-menu" role="menu" aria-label="排序方式">${Object.entries(s).map((([r,n])=>`<button type="button" class="jhs-btn jhs-btn--ghost jhs-sort-option" role="menuitemradio" aria-checked="${r===e?"true":"false"}" data-sort-method="${r}" tabindex="-1">${n}</button>`)).join("")}</div></div>`}bindEvent(){$("#waitCheckBtn").on("click",(s=>{this.openWaitCheck().catch((a=>clog.error("待鉴定列表打开失败",a)))})),$("#newVideoBtn").on("click",(s=>{this.getOptionalDependency("NewVideoPlugin")?.openDialog?.()})),$("#blacklistBtn").on("click",(s=>{this.getOptionalDependency("BlacklistPlugin")?.openBlacklistDialog?.()})),this.bindSortMenu();let e=this.getOptionalDependency("BlacklistPlugin"),t=this.getOptionalDependency("ListPagePlugin");$("#addBlacklistBtn").on("click",(async s=>{await e?.addBlacklist?.(s)})),$("#filterAllVideo").on("click",(async s=>{let a=N?$(".actor-section-name"):$(".avatar-box .photo-info .pb10");if(a.length===0)return void show.error("获取演员名称失败");let i=a.text().trim().split(",")[0];this.loadObj=loading();try{await e?.filterAllVideo?.(i)}catch(r){clog.error(r)}finally{this.loadObj.close()}})),$("#favoriteAllVideo").on("click",(async s=>{let a=this.buildBatchScope();this.loadObj=loading();try{await t?.batchSaveAllVideos?.(a,ue)}catch(i){clog.error(i)}finally{this.loadObj.close()}})),$("#hasDownAllVideo").on("click",(async s=>{let a=this.buildBatchScope();this.loadObj=loading();try{await t?.batchSaveAllVideos?.(a,pe)}catch(i){clog.error(i)}finally{this.loadObj.close()}}))}bindSortMenu(){let e=$(".jhs-sort-control");if(!e.length)return;let t=e.find("#sort-toggle-btn"),s=e.find(".jhs-sort-menu"),a=d((i=!1)=>{s.removeClass("is-open"),t.attr("aria-expanded","false"),i&&t.trigger("focus")},"close");t.on("click",(i=>{i.preventDefault(),i.stopPropagation();let r=!s.hasClass("is-open");s.toggleClass("is-open",r),t.attr("aria-expanded",String(r)),r&&s.find('[aria-checked="true"]').trigger("focus")})),s.on("click",".jhs-sort-option",(async i=>{let r=$(i.currentTarget),n=r.data("sort-method"),l=s.find('.jhs-sort-option[aria-checked="true"]').first(),c=$("#jhs-sort-current").text();s.find(".jhs-sort-option").attr("aria-checked","false"),r.attr("aria-checked","true"),$("#jhs-sort-current").text(r.text()),a(!0);try{await this.selectSortMethod(n)}catch(h){s.find(".jhs-sort-option").attr("aria-checked","false"),l.attr("aria-checked","true"),$("#jhs-sort-current").text(c),clog.error("排序设置保存失败,已恢复",h),show.error("排序设置保存失败,已恢复原设置")}})).on("keydown",".jhs-sort-option",(i=>{let r=s.find(".jhs-sort-option"),n=r.index(i.currentTarget);if(i.key==="Escape")return i.preventDefault(),a(!0);if(!["ArrowDown","ArrowUp","Home","End"].includes(i.key))return;i.preventDefault();let l=i.key==="Home"?0:i.key==="End"?r.length-1:i.key==="ArrowDown"?(n+1)%r.length:(n-1+r.length)%r.length;r.eq(l).trigger("focus")})),$(document).off("click.jhsSortMenu").on("click.jhsSortMenu",(i=>{$(i.target).closest(e).length||a()}))}async sortItems(e){let t=this.supportsLiveSorting();if(!this.supportsSorting())return;let s=this.getRuntimeService("settings").snapshot().autoPage??R;if(ms||s===R&&!t&&e!=="default")return;let a=e||this.activeSortMethod();if(!a)return;let i=this.getSelector(),r=$(i.boxSelector),n=$(i.itemSelector);n.each(((h,u)=>{$(u).attr("data-original-index")||$(u).attr("data-original-index",h)}));let l=n.get().map(((h,u)=>{let p=$(h),g=Number(p.attr("data-original-index"))||0;if(a==="default")return{element:h,key:g,originalIndex:g,index:u};if(a==="rateCount"){let v=Number(p.attr("data-jhs-rate-count")),b=p.find(".score").text().replaceAll(",","").match(/(?:由\s*)?(\d+)\s*人(?:评价)?/);return{element:h,key:Number.isFinite(v)?v:b?Number(b[1]):0,originalIndex:g,index:u}}let m=p.attr("data-jhs-publish-time")||p.find(".meta").text().trim()||p.find("date").filter(((v,b)=>/^\d{4}-\d{1,2}-\d{1,2}$/.test($(b).text().trim()))).first().text().trim(),f=Date.parse(m);return{element:h,key:Number.isFinite(f)?f:0,originalIndex:g,index:u}}));l.sort(((h,u)=>a==="default"?h.key-u.key:u.key-h.key||h.originalIndex-u.originalIndex||h.index-u.index));let c=l.map(h=>h.element);a==="default"?$(c).appendTo(r):r.empty().append(c)}isHitShowPage(){return We(window.location)}isOwnedRankingPage(){return this.isHitShowPage()||window.location.search.includes("handleTop=1")}activeSortMethod(){return this.isOwnedRankingPage()?this.ownedRankingSortOverride||"default":this.getRuntimeService("settings").snapshot().sortMethod||"default"}async selectSortMethod(e){if(this.isOwnedRankingPage()){this.ownedRankingSortOverride=e,await this.sortItems(e);return}await this.getRuntimeService("settings").set("sortMethod",e),await this.sortItems()}isFc2ListPage(){return N&&window.location.pathname==="/advanced_search"&&new URLSearchParams(window.location.search).get("type")==="3"}supportsSorting(){return this.supportsLiveSorting()?!0:!(N&&(Y.includes("handle")||Y.includes("advanced_search")))}supportsLiveSorting(){return this.isOwnedRankingPage()||this.isFc2ListPage()}buildBatchScope(){if(!(N?Y.includes("/actors/"):Y.includes("/star/")))return{kind:"search",displayName:"当前搜索条件",recordName:""};let t=this.getActressPageInfo();return{kind:"actor",displayName:t?.name||"",recordName:t?.name||""}}async openWaitCheck(){let e=this.getSelector(),t=await storageManager.getSetting("waitCheckCount",5),s=0,a=this.getOptionalDependency("ListPagePlugin");if(!a)return void show.info("列表功能已禁用");for(let i of $(e.itemSelector).toArray()){if(s>=t)break;let r=$(i),n=q(JSON.parse(r.attr("data-jhs-flags")||"{}")),l=JSON.parse(r.attr("data-jhs-visibility")||"{}");oe(n)||ft(n,l)||(await a.openMovieDetail(r,{autoplay:!0,newTab:!1}),s++)}s===0&&show.info("没有需鉴定的视频")}};d(Rn,"ListPageButtonPlugin");var za=Rn;function Ua(){if(!F)throw new Error("List EventBus 未初始化");return F}d(Ua,"getListEventBus");function qh(o){return o?.jquery?o:$(o)}d(qh,"normalizeCard");var Wh=new Set(["tagPosition","defaultQuickFilterTab"]),jt={IS_FILTERED:{text:et,color:"var(--jhs-status-filter)",on:"var(--jhs-status-filter-on)",reasonType:"单番号屏蔽",isCounted:!0,countKey:"currentPageFilterCount"},IS_FAVORITE:{text:tt,color:"var(--jhs-status-fav)",on:"var(--jhs-status-fav-on)",reasonType:"",isCounted:!0,countKey:"currentPageFavoriteCount"},IS_HAS_DOWN:{text:fe,color:"var(--jhs-status-down)",on:"var(--jhs-status-down-on)",reasonType:"",isCounted:!0,countKey:"currentPageHasDownCount"},IS_HAS_WATCH:{text:ve,color:"var(--jhs-status-watch)",on:"var(--jhs-status-watch-on)",reasonType:"",isCounted:!0,countKey:"currentPageHasWatchCount"},IS_KEYWORD_FILTER:{text:"关键词屏蔽",color:"var(--jhs-status-filter)",on:"var(--jhs-status-filter-on)",reasonType:"",isCounted:!0,countKey:"currentPageKeywordFilterCount"},IS_ACTOR_FILTER:{text:"男演员屏蔽",color:"var(--jhs-status-filter)",on:"var(--jhs-status-filter-on)",reasonType:"",isCounted:!0,countKey:"currentPageActorFilterCount"},IS_ACTRESS_FILTER:{text:"女演员屏蔽",color:"var(--jhs-status-filter)",on:"var(--jhs-status-filter-on)",reasonType:"",isCounted:!0,countKey:"currentPageActorFilterCount"},IS_WAIT_CHECK:{text:"",color:"",on:"",reasonType:"",isCounted:!0,countKey:"currentPageWaitCheckCount"}},En=class En extends I{async initCss(){return"<style>.jhs-status-tags{position:absolute;z-index:var(--jhs-z-content);top:5px;display:flex;flex-wrap:wrap;gap:4px;max-width:90%}.jhs-status-tags--right{right:0;justify-content:flex-end}.jhs-status-tags--left{left:0}.status-tag{padding:0 5px;border-radius:10px}.status-tag .tag{color:inherit!important}.jhs-jump-page-input{width:60px;margin-left:10px}.jhs-jump-page-btn{margin-left:5px}.jhs-quick-filter{display:flex;align-items:center;gap:var(--jhs-space-1);min-width:0}.jhs-quick-filter__more{position:relative}.jhs-quick-filter__menu{min-width:190px}.jhs-filter-menu__separator{height:1px;margin:var(--jhs-space-1) 0;background:var(--jhs-border)}.jhs-batch-progress{position:fixed;right:16px;bottom:16px;z-index:var(--jhs-z-modal);display:flex;align-items:center;gap:var(--jhs-space-2);padding:var(--jhs-space-2) var(--jhs-space-3);border:1px solid var(--jhs-border);border-radius:var(--jhs-radius-md);background:var(--jhs-surface);color:var(--jhs-text);box-shadow:0 4px 16px rgba(0,0,0,.18)}.jhs-btn.jhs-batch-busy{opacity:.55;cursor:not-allowed}</style>"}constructor(){super(...arguments),this.currentPageFilterCount=0,this.currentPageFavoriteCount=0,this.currentPageHasDownCount=0,this.currentPageHasWatchCount=0,this.currentPageKeywordFilterCount=0,this.currentPageActorFilterCount=0,this.currentPageWaitCheckCount=0,this.currentPageTotalCount=0,this.filterContext=null,this.pendingItems=new Set,this.processTimer=null,this.hdImageObserver=null,this.hdPendingCleanups=new Map,this.hoverPreviewState=null,this.writeQueue=Promise.resolve(),this.itemIndex=new Map,this.recountFrame=null,this.$currentImage=null,this.translationGeneration=0,this.listGeneration=0,this.filterRevision=0,this.refreshRunning=!1,this.refreshDirty=!1,this.refreshAllRequested=!1,this.refreshVisibilityRequested=!1,this.refreshItems=new Set,this.refreshPromise=null}getName(){return"ListPagePlugin"}async handle(){if(!window.isListPage)return;let e=await this.getRuntimeService("scope")(),t=this.getRuntimeService("settings"),s=d(n=>{(n.detail?.names||[]).includes("hoverBigImg")&&this.configureHoverPreview(t.snapshot().hoverBigImg==="yes"?"yes":"no")},"onSettingsChanged");t.addEventListener("settings.changed",s),e.addCleanup((()=>t.removeEventListener("settings.changed",s)));let a=d(async(n={})=>{let l=n?.changedNames;l&&!l.some(c=>Wh.has(c))||await this.requestListRefresh({reason:"event-refresh",full:!0})},"refreshAll");if(["legacy-refresh","blacklist-rules-changed","filter-rules-changed","settings-changed"].forEach((n=>e.addCleanup(Ua().on(n,a)))),e.addCleanup(Ua().on("car-state-changed",(async n=>{let l=this.getIndexedItems(n.carNums||[]);await this.requestListRefresh({items:l,reason:"car-state-changed",full:!0})}))),We())return;let i=t.snapshot().hoverBigImg;this.configureHoverPreview(i===R?"yes":"no"),this.cleanRepeatId(),this.replaceHdImg(),this.addJumpPageControl(),this.fixBusTitleBox();let r=this.advanceListGeneration();await this.doFilter(r),await this.createQuickFilter(),this.reconcileListItems(null,r),await this.bindClick(),this.rememberTagExpand(),$(this.getSelector().itemSelector).attr("data-jhs-processed","true"),this.rebuildItemIndex(),await Ua().emit("list-items-added",{items:$(this.getSelector().itemSelector).toArray()},{broadcast:!1}),this.checkDom(e),e.addCleanup((()=>{this.processTimer&&clearTimeout(this.processTimer),this.processTimer=null,this.pendingItems.clear(),this.hdImageObserver?.disconnect(),this.hdImageObserver=null,this.hdPendingCleanups.forEach((n=>n())),this.hdPendingCleanups.clear(),this.configureHoverPreview("no"),this.recountFrame&&(globalThis.cancelAnimationFrame?.(this.recountFrame)??clearTimeout(this.recountFrame)),this.recountFrame=null,this.advanceListGeneration(),this.refreshDirty=!1,this.refreshAllRequested=!1,this.refreshVisibilityRequested=!1,this.refreshItems.clear(),$(this.getSelector().boxSelector).off(".jhsMovieDetail .jhsListVideo .jhsListMenu"),$("#jhs-quick-filter").off(),this.itemIndex.clear()}))}advanceListGeneration(){return this.listGeneration+=1,this.captureListRevision()}captureListRevision(){return`${this.listGeneration}:${this.filterRevision}`}isCurrentListGeneration(e){return e===this.captureListRevision()}recordListPhase(e,t=null){let s=globalThis.__jhsBrowserDiagnostics;if(!s)return;let a=s.listPhases||(s.listPhases=[]);a.push({phase:e,generation:this.listGeneration,filterRevision:this.filterRevision,activeQuickFilter:this.activeQuickFilter||"waitCheck",itemCount:t??$(this.getSelector().itemSelector).length}),a.length>200&&a.splice(0,a.length-200)}reconcileListItems(e,t){return this.isCurrentListGeneration(t)?(this.applyVisibility(e),!0):!1}requestListRefresh({items:e=null,reason:t="refresh",full:s=!1,visibilityOnly:a=!1}={}){if((s||e!==null)&&this.advanceListGeneration(),this.refreshDirty=!0,s?this.refreshAllRequested=!0:a?this.refreshVisibilityRequested=!0:(e||[]).forEach(r=>this.refreshItems.add(r)),this.recordListPhase("refresh-request:"+t),this.refreshRunning)return this.refreshPromise;this.refreshRunning=!0;let i=d(async()=>{try{for(;this.refreshDirty;){let r=this.refreshAllRequested,n=this.refreshVisibilityRequested&&!r,l=[...this.refreshItems];this.refreshDirty=!1,this.refreshAllRequested=!1,this.refreshVisibilityRequested=!1,this.refreshItems.clear();let c=this.captureListRevision();this.recordListPhase("refresh-start",r?null:l.length);let h;if(r?(this.filterContext=null,storageManager._invalidateCache(storageManager.car_list_key),h=await this.doFilter(c)):n?h=!0:h=await this.doFilterItems(l.filter(u=>u.isConnected),c),!this.isCurrentListGeneration(c)){this.refreshDirty=!0,this.refreshAllRequested=!0;continue}if(h!==!1&&this.reconcileListItems(r?null:l,c),r){let u=this.getOptionalDependency("HistoryPlugin");u?.tableObj&&u.tableObj.setData()}this.recordListPhase("refresh-end")}return!0}finally{this.refreshRunning=!1,this.refreshPromise=null}},"run");return this.refreshPromise=i()}async createQuickFilter(){if($("#jhs-quick-filter").length)return;let e=this.getSelector(),t=mt.map((c=>`<button type="button" role="tab" class="jhs-btn jhs-segmented__item" aria-selected="false" tabindex="-1" data-jhs-filter="${c}">${Re[c]}</button>`)).join(""),s=Gt.map(((c,h)=>`${h===1?'<div class="jhs-filter-menu__separator" role="separator"></div>':""}<button type="button" role="menuitemradio" class="jhs-btn jhs-btn--ghost jhs-filter-option" aria-checked="false" tabindex="-1" data-jhs-filter="${c}">${Re[c]}</button>`)).join(""),a=`<div id="jhs-quick-filter" class="jhs-quick-filter">
                <div class="jhs-quick-filter__primary jhs-segmented" role="tablist" aria-label="状态筛选">${t}</div>
                <div class="jhs-quick-filter__more">
                    <button type="button" class="jhs-btn jhs-btn--secondary jhs-quick-filter__toggle" aria-haspopup="menu" aria-expanded="false"><span class="jhs-quick-filter__label">更多筛选</span> ▾</button>
                    <div class="jhs-popover jhs-commandbar__menu jhs-quick-filter__menu" role="menu" aria-label="更多筛选">${s}</div>
                </div>
            </div>`;N?$(e.boxSelector).before(a):B&&$(".masonry").before(a);let i=$("#jhs-quick-filter"),r=i.find(".jhs-quick-filter__toggle"),n=i.find(".jhs-quick-filter__menu"),l=d((c=!1)=>{n.removeClass("is-open"),r.attr("aria-expanded","false"),c&&r.trigger("focus")},"closeMenu");i.on("click",".jhs-segmented__item",(c=>this.setQuickFilter($(c.currentTarget).data("jhs-filter")))).on("keydown",".jhs-segmented__item",(c=>{if(!["ArrowLeft","ArrowRight","Home","End"].includes(c.key))return;c.preventDefault();let h=i.find(".jhs-segmented__item"),u=h.index(c.currentTarget),p=c.key==="Home"?0:c.key==="End"?h.length-1:c.key==="ArrowRight"?(u+1)%h.length:(u-1+h.length)%h.length;h.eq(p).trigger("click").trigger("focus")})).on("click",".jhs-filter-option",(c=>{this.setQuickFilter($(c.currentTarget).data("jhs-filter")),l(!0)})).on("keydown",".jhs-filter-option",(c=>{let h=n.find(".jhs-filter-option"),u=h.index(c.currentTarget);if(c.key==="Escape")return c.preventDefault(),l(!0);if(!["ArrowDown","ArrowUp","Home","End"].includes(c.key))return;c.preventDefault();let p=c.key==="Home"?0:c.key==="End"?h.length-1:c.key==="ArrowDown"?(u+1)%h.length:(u-1+h.length)%h.length;h.eq(p).trigger("focus")})),r.on("click",(c=>{c.preventDefault(),c.stopPropagation();let h=!n.hasClass("is-open");n.toggleClass("is-open",h),r.attr("aria-expanded",String(h)),h&&(n.find('[aria-checked="true"]').first().length?n.find('[aria-checked="true"]').first():n.find(".jhs-filter-option").first()).trigger("focus")})),$(document).off("click.jhsQuickFilter").on("click.jhsQuickFilter",(c=>{$(c.target).closest(i).length||l()})),this.activeQuickFilter||(this.activeQuickFilter=Te(await storageManager.getSetting("defaultQuickFilterTab","waitCheck"))),this.applyVisibility(),this.syncQuickFilterUi()}applyVisibility(e=null){let t=this.activeQuickFilter||"waitCheck",s=this.getSelector().itemSelector,a=e?$(e):$(s);this.recordListPhase("applyVisibility",a.length),a.each(((i,r)=>{let n=$(r),l=q(JSON.parse(n.attr("data-jhs-flags")||"{}")),c=JSON.parse(n.attr("data-jhs-visibility")||"{}"),h=n.attr("data-jhs-recent")==="yes";xl({filter:t,flags:l,visibilityReasons:c,recent:h})?n.show():n.hide()}))}setQuickFilter(e,{syncUi:t=!0}={}){this.filterRevision+=1,this.activeQuickFilter=Te(e),this.recordListPhase("setQuickFilter"),this.requestListRefresh({reason:"quick-filter",visibilityOnly:!0})?.catch(s=>clog.error("列表筛选刷新失败",s)),this.reconcileListItems(null,this.captureListRevision()),t&&this.syncQuickFilterUi()}syncQuickFilterUi(){let e=Te(this.activeQuickFilter),t=mt.includes(e),s=$("#jhs-quick-filter"),a=s.find(".jhs-segmented__item"),i=s.find(".jhs-filter-option");a.removeClass("active").attr({"aria-selected":"false",tabindex:"-1"}),t?a.filter(`[data-jhs-filter="${e}"]`).addClass("active").attr({"aria-selected":"true",tabindex:"0"}):a.first().attr("tabindex","0"),i.attr("aria-checked","false").filter(`[data-jhs-filter="${e}"]`).attr("aria-checked","true"),s.find(".jhs-quick-filter__label").text(t?"更多筛选":`筛选:${Re[e]}`),$(".jhs-mobile-filter-label").text(`筛选:${Re[e]}`),$(".jhs-mobile-filter-option").attr("aria-checked","false").filter(`[data-jhs-filter="${e}"]`).attr("aria-checked","true")}rememberTagExpand(){if(!window.location.href.includes("actors"))return;let e=$(".tag-expand");if(e.length===0)return;let t=this.getRuntimeService("storage"),s="jhs_tag_expand",a=t.getLocal(s)==="true",i=$(".actor-tags .content");a&&i.hasClass("collapse")&&e[0].click(),e.on("click",(function(){let r=!$(".actor-tags .content").hasClass("collapse");clog.debug("触发"),t.setLocal(s,r.toString())}))}checkDom(e=null){if(!window.isListPage||We()||window.location.search.includes("handleTop=1"))return;let t=this.getSelector(),s=document.querySelector(t.boxSelector);if(!s)return void clog.error("没有找到容器节点!");e&&e.observe(s,(a=>{for(let i of a){this.removeIndexedItems(i.removedNodes),i.addedNodes.length&&(this.advanceListGeneration(),this.recordListPhase("dom-added",i.addedNodes.length));for(let r of i.addedNodes){if(r.nodeType!==Node.ELEMENT_NODE)continue;let n=r;n.matches?.(t.itemSelector)&&n.dataset.jhsProcessed!=="true"&&this.pendingItems.add(n),n.querySelectorAll?.(t.itemSelector).forEach(l=>{l.dataset.jhsProcessed!=="true"&&this.pendingItems.add(l)})}}this.pendingItems.size&&(this.processTimer&&clearTimeout(this.processTimer),this.processTimer=setTimeout((()=>{let i=[...this.pendingItems].filter(n=>n.isConnected&&n.dataset.jhsProcessed!=="true"),r=this.captureListRevision();this.pendingItems.clear(),this.processTimer=null,i.length&&this.processAddedItems(i,r).catch(n=>clog.error("列表增量处理失败",n))}),100))}),{childList:!0,subtree:!1})}async processAddedItems(e,t=this.captureListRevision()){let s=this.getSelector(),a=e.flatMap(r=>[...r.querySelectorAll(s.coverImgSelector)]);this.replaceHdImg(a),this.addJumpPageControl(),this.fixBusTitleBox(e),await this.requestListRefresh({items:e,reason:"dom-added"})&&(await this.getOptionalDependency("ListPageButtonPlugin")?.sortItems?.(),await this.getOptionalDependency("CoverButtonPlugin")?.addSvgBtn?.(e),e.forEach(r=>r.dataset.jhsProcessed="true"),this.indexItems(e),await Ua().emit("list-items-added",{items:e},{broadcast:!1}),this.getOptionalDependency("AutoPagePlugin")?.checkLoad?.())}rebuildItemIndex(){this.itemIndex.clear();let e=$(this.getSelector().itemSelector).toArray();this.indexItems(e),this.recordListPhase("rebuildItemIndex",e.length)}indexItems(e){e.forEach(t=>{try{let s=T(this.findCarNumAndHref($(t)).carNum);if(!s)return;let a=this.itemIndex.get(s)||new Set;a.add(t),this.itemIndex.set(s,a)}catch(s){clog.debug("列表项索引跳过无效卡片",s)}})}removeIndexedItems(e){let t=new Set;Array.from(e||[]).forEach(s=>{let a=s;s.nodeType===Node.ELEMENT_NODE&&(t.add(a),a.querySelectorAll?.(this.getSelector().itemSelector).forEach(i=>t.add(i)))}),t.size&&this.itemIndex.forEach(((s,a)=>{s.forEach(i=>{t.has(i)&&s.delete(i)}),s.size||this.itemIndex.delete(a)}))}getIndexedItems(e){let t=new Set;return e.map(T).forEach(s=>{if(!s)return;let a=this.itemIndex.get(s);a?.forEach(i=>i.isConnected?t.add(i):a.delete(i)),a&&!a.size&&this.itemIndex.delete(s)}),[...t]}fixBusTitleBox(e=null){B&&(e?$(e).toArray():$(this.getSelector().itemSelector).toArray()).forEach(t=>{var s;let a=$(t);if(a.find(".avatar-box").length>0)return;let i=((s=a.find("img").attr("title"))==null?void 0:s.trim())||"";a.find(".photo-info span:first").contents().first().wrap(`<span class="video-title" title="${i}">${i}</span>`),a.find("br").remove()})}cleanRepeatId(){if(!B)return;$("#waterfall_h").removeAttr("id").attr("id","no-page");let e=$('[id="waterfall"]');e.length!==0&&e.each(((t,s)=>{let a=$(s);a.hasClass("masonry")||(a.children().insertAfter(a),a.remove())}))}async doFilter(e=this.captureListRevision()){return this.doFilterItems(null,e)}async doFilterItems(e=null,t=this.captureListRevision()){if(!window.isListPage)return!1;let s=e?$(e).toArray():$(this.getSelector().itemSelector).toArray();if(!s.length)return!0;let a=await this.filterMovieList(s,t);return a&&B&&setTimeout((()=>{this.getOptionalDependency("BusImgPlugin")?.logImageHeightsByRow?.(this.getRuntimeService("settings").snapshot()).catch(i=>clog.error("JavBus图片高度修正失败",i))})),a}async yieldListFrame(){await new Promise(e=>{window.requestAnimationFrame?window.requestAnimationFrame((()=>setTimeout(e))):setTimeout(e)})}async createEvaluationContext(){return is(await this.getFilterContext())}async getFilterContext(){if(this.filterContext)return this.filterContext;let[e,t,s,a,i,r]=await Promise.all([storageManager.getTitleFilterKeyword(),storageManager.getBlacklistMap(),storageManager.getBlacklistCarList(),storageManager.getSetting(),storageManager.getCarMap(),this.getRuntimeService("state").getActivityLog()]),n=new Map,l=new Map,c=new Set,h=Date.now()-7*864e5;r.entries.filter(u=>u.commitState==="committed"&&Date.parse(u.createdAt)>=h).forEach(u=>{u.changes.filter(p=>p.undoState!=="reverted"&&p.fields?.some(g=>g.startsWith("stateFlags."))).forEach(p=>c.add(p.carNum))});for(let u of s){let p=t.get(u.starId)?.role;if(!p){clog.error("黑名单数据源丢失演员信息",u);continue}let g=p===Me?n:l,m=T(u.carNum);g.has(m)||g.set(m,u.names)}return this.filterContext={titleKeywords:e,settings:a,carMap:i,recentCarNums:c,actorCarNumToNameMap:n,actressCarNumToNameMap:l}}collectCurrentPageSummary(){let e={total:0,pending:0,blockedItems:0,favorite:0,downloaded:0,watched:0,debug:{manualBlocked:0,keywordBlocked:0,actorBlocked:0,actressBlocked:0}};return $(this.getSelector().itemSelector).each(((t,s)=>{let a=$(s);if(B&&a.find(".avatar-box").length>0)return;let i=q(JSON.parse(a.attr("data-jhs-flags")||"{}")),r=JSON.parse(a.attr("data-jhs-visibility")||"{}"),n=ft(i,r);e.total++,i.favorite&&e.favorite++,i.downloaded&&e.downloaded++,i.watched&&e.watched++,n&&e.blockedItems++,!oe(i)&&!n&&e.pending++,i.blocked&&e.debug.manualBlocked++,r.keyword&&e.debug.keywordBlocked++,r.actorBlacklist&&e.debug.actorBlocked++,r.actressBlacklist&&e.debug.actressBlocked++})),e}getCurrentPageSummary(){return this.collectCurrentPageSummary()}recountStatuses(){let e=this.collectCurrentPageSummary();return this.currentPageFilterCount=e.debug.manualBlocked,this.currentPageFavoriteCount=e.favorite,this.currentPageHasDownCount=e.downloaded,this.currentPageHasWatchCount=e.watched,this.currentPageKeywordFilterCount=e.debug.keywordBlocked,this.currentPageActorFilterCount=e.debug.actorBlocked+e.debug.actressBlocked,this.currentPageWaitCheckCount=e.pending,this.currentPageTotalCount=e.total,e}scheduleRecount(){if(this.recountFrame)return;let e=window.requestAnimationFrame||(t=>setTimeout(t,0));this.recountFrame=e((()=>{this.recountFrame=null,this.recountStatuses()}))}async translateListItems(e){if((this.getRuntimeService("settings").snapshot().translateTitle??R)!==R)return;let t=0,s=null;await $e(e,3,(async(a,i)=>{try{i>0&&i%8===0&&await this.yieldListFrame(),await this.translate(qh(a))}catch(r){t++,s??(s=r)}})),t&&clog.error(`列表标题翻译失败 ${t} 项`,s)}async filterMovieList(e,t=this.captureListRevision()){if(this.recordListPhase("doFilter-start",e.length),!this.isCurrentListGeneration(t))return!1;let s=this.activeQuickFilter||"waitCheck";utils.time("累计耗费时间"),utils.time("读取数据耗时");let{titleKeywords:a,settings:i,carMap:r,recentCarNums:n,actorCarNumToNameMap:l,actressCarNumToNameMap:c}=await this.getFilterContext(),h=utils.time("读取数据耗时");if(!this.isCurrentListGeneration(t))return!1;let u=is({titleKeywords:a,settings:i,carMap:r,recentCarNums:n,actorCarNumToNameMap:l,actressCarNumToNameMap:c});utils.time("组装数据耗时");let p=utils.time("组装数据耗时"),g=i?.tagPosition||"rightTop";this.currentPageFilterCount=0,this.currentPageFavoriteCount=0,this.currentPageHasDownCount=0,this.currentPageHasWatchCount=0,this.currentPageKeywordFilterCount=0,this.currentPageActorFilterCount=0,this.currentPageWaitCheckCount=0,this.currentPageTotalCount=0,utils.time("处理页面耗时");let m=[];for(let b=0;b<e.length;b++){if(!this.isCurrentListGeneration(t))return!1;b>0&&b%12==0&&await this.yieldListFrame();let w=$(e[b]);if(B&&w.find(".avatar-box").length>0)continue;let{carNum:S,title:j}=this.findCarNumAndHref(w),{flags:k,visibilityReasons:x,hardHidden:_}=rs({carNum:S,title:j},u,{filter:s}),E=x.keyword?Cr(u.titleKeywords,j,S):null;w.attr("data-jhs-flags",JSON.stringify(k)).attr("data-jhs-visibility",JSON.stringify(x)).attr("data-jhs-recent",n.has(S)?R:ne).attr("data-jhs-tag-position",g);let L=JSON.stringify({flags:k,visibilityReasons:x,P:g});if(w.attr("data-jhs-state-signature")!==L){w.attr("data-jhs-state-signature",L),w.find(".jhs-status-tags").remove();let M=[[k.blocked,jt.IS_FILTERED,"单番号屏蔽"],[k.favorite,jt.IS_FAVORITE,""],[k.downloaded,jt.IS_HAS_DOWN,""],[k.watched,jt.IS_HAS_WATCH,""],[x.keyword,jt.IS_KEYWORD_FILTER,E||"未知"],[x.actorBlacklist,jt.IS_ACTOR_FILTER,l.get(S)||""],[x.actressBlacklist,jt.IS_ACTRESS_FILTER,c.get(S)||""]].filter(P=>P[0]);if(M.length){let P=$(`<span class="jhs-status-tags ${g==="rightTop"?"jhs-status-tags--right":"jhs-status-tags--left"}"></span>`);if(M.forEach((([,z,O])=>{let H=$(`<span class="jhs-badge ${N?"jhs-badge--success":"jhs-badge--neutral"} status-tag" data-tip="${C(O)}" title="">${C(z.text)}</span>`);H.css({color:z.on,backgroundColor:z.color}),P.append(H)})),N)w.find(".tags").append(P);else if(B){let z=w.find(".item-tag");z.length?z.append(P):w.find(".photo-info > span > div").append(P)}}}_||m.push(w)}this.scheduleRecount(),this.translateListItems(m).catch(b=>clog.error("列表页翻译任务失败",b)),this.recordListPhase("doFilter-end",e.length);let f=utils.time("处理页面耗时"),v=utils.time("累计耗费时间");clog.html(`
            <table class="countTable jhs-layout-b12542a5">
                <tr>
                    <td colspan="2" class="jhs-count-table__cell">${h}</td>
                    <td colspan="2" class="jhs-count-table__cell">${p}</td>
                </tr>

                <tr>
                    <td colspan="2" class="jhs-count-table__cell">${f}</td>
                    <td colspan="2" class="jhs-count-table__cell">${v}</td>
                </tr>
                <tr>
                    <td class="jhs-count-table__head">项目</td>
                    <td class="jhs-count-table__head">数量</td>
                    <td class="jhs-count-table__head">项目</td>
                    <td class="jhs-count-table__head">数量</td>
                </tr>

                <tr>
                    <td class="jhs-count-table__cell">屏蔽单番号</td>
                    <td class="jhs-count-table__cell"><strong>${this.currentPageFilterCount}</strong></td>
                     <td class="jhs-count-table__cell">收藏</td>
                    <td class="jhs-count-table__cell"><strong>${this.currentPageFavoriteCount}</strong></td>
                </tr>

                <tr>
                    <td class="jhs-count-table__cell">屏蔽演员</td>
                    <td class="jhs-count-table__cell"><strong>${this.currentPageActorFilterCount}</strong></td>
                    <td class="jhs-count-table__cell">已下载</td>
                    <td class="jhs-count-table__cell"><strong>${this.currentPageHasDownCount}</strong></td>
                </tr>

                <tr>
                    <td class="jhs-count-table__cell">屏蔽关键词</td>
                    <td class="jhs-count-table__cell"><strong>${this.currentPageKeywordFilterCount}</strong></td>
                    <td class="jhs-count-table__cell">已观看</td>
                    <td class="jhs-count-table__cell"><strong>${this.currentPageHasWatchCount}</strong></td>
                </tr>

                <tr>
                    <td class="jhs-count-table__cell">待鉴定</td>
                    <td class="jhs-count-table__cell"><strong>${this.currentPageWaitCheckCount}</strong></td>
                    <td class="jhs-count-table__cell"></td>
                    <td class="jhs-count-table__cell"></td>
                </tr>

                <tr>
                    <td class="jhs-count-table__cell"><strong>总数</strong></td>
                    <td class="jhs-count-table__cell"><strong>${this.currentPageTotalCount}</strong></td>
                </tr>
            </table>
        `)}async batchSaveAllVideos(e,t,{filter:s=this.activeQuickFilter||"waitCheck",confirm:a=!0,root:i=null}={}){let r=ke(t);if(!r)throw new TypeError(`不支持的状态操作: ${t}`);let n=Te(s),l=Re[n],c=e?.kind==="actor",h=c?String(e.recordName||""):"",u=We(window.location)||window.location.search.includes("handleTop=1"),p=u?n==="all"?"将处理当前榜单页内的所有作品,包括屏蔽项。":`将处理当前榜单页内符合「${l}」筛选的作品。`:n==="all"?"将处理当前搜索全部分页的所有作品,包括屏蔽项。":`将处理当前搜索全部分页中符合「${l}」筛选的作品。`;if(a&&!await new Promise(w=>utils.q(null,p,()=>w(!0),()=>w(!1))))return{cancelled:!0};let g=Fs();if(!g)return show.error("已有批量任务正在执行"),{cancelled:!0,busy:!0};let m,f=d(b=>{let w=m?.find(".jhs-batch-progress__label");w&&w.length?w.text(b):clog.debug(b)},"setProgress"),v=d(({page:b,scanned:w,matched:S})=>{f(`已扫描 ${b} 页 · 匹配 ${S} 项`),clog.debug(`批量扫描第 ${b} 页 · 已扫描 ${w} · 匹配 ${S}`)},"onProgress");try{let b=await this.getRuntimeService("scope")(),w=await this.createEvaluationContext(),S=d(()=>oc(g)||!!b?.disposed,"isCancelled");m=this.showBatchProgress(g),this.setBatchButtonsDisabled(!0);let j=await Us({startDom:i?$(i):$(document),currentUrl:u||i?null:window.location.href,firstPageUrl:u||i?null:this.getRuntimeService("host")?.resolveFirstPageUrl?.(window.location.href)??window.location.href,itemSelector:this.getSelector().requestDomItemSelector,nextPageSelector:this.getSelector().nextPageSelector,fetchHtml:d(async x=>Ve(this.getRuntimeService("http"),x,b),"fetchHtml"),parseItem:d(x=>{let _=Ce(x);return c?_:{..._,names:ic(x)}},"parseItem"),evaluate:d(x=>rs({carNum:x.carNum,title:x.title||""},w,{filter:n}),"evaluate"),isCancelled:S,onProgress:v});if(S())return m?.remove(),{cancelled:!0};m?.find("#jhs-batch-cancel").prop("disabled",!0).attr("title","正在写入,无法取消"),f("正在写入,无法取消…");let k=0;for(let x=0;x<j.length&&!S();x+=75){let _=j.slice(x,x+75);await this.getRuntimeService("state").patch(_.map(E=>E.carNum),{[r]:!0},{type:"actor-page-batch-state",records:_.map(E=>({carNum:E.carNum,url:E.url||"",names:E.names??h,publishTime:E.publishTime||"",fc2Source:E.fc2Source}))}),k+=_.length,f(`已更新 ${k}/${j.length} 项`)}return f(`批量完成:匹配 ${j.length} 项 · 已更新 ${k} 项`),setTimeout(()=>m?.remove(),1800),{matched:j.length,updated:k}}catch(b){throw clog.error("批量操作失败:",b),f("批量操作失败"),m?.addClass("jhs-batch-progress--error"),setTimeout(()=>m?.remove(),2500),b}finally{Dt(g)&&Vs(g),this.setBatchButtonsDisabled(!1)}}setBatchButtonsDisabled(e){$("#favoriteAllVideo, #hasDownAllVideo, #filterAllVideo").attr("aria-disabled",String(e)).toggleClass("jhs-batch-busy",e)}showBatchProgress(e){let t=$("#jhs-batch-progress");return t.length||(t=$('<div id="jhs-batch-progress" class="jhs-ui jhs-batch-progress" role="status"></div>').appendTo("body"),t.append('<button type="button" class="jhs-btn jhs-btn--secondary jhs-btn--sm" id="jhs-batch-cancel">取消</button>')),t.find("#jhs-batch-cancel").off("click").on("click",()=>lc(e)),t.find(".jhs-batch-progress__label").remove().end().prepend($('<span class="jhs-batch-progress__label"></span>').text("正在扫描…")),t}async bindClick(){let e=this.getSelector();this.bindMovieDetailNavigation(e.boxSelector),$(e.boxSelector).off("click.jhsListVideo").on("click.jhsListVideo",".item video",(async t=>{let s=t.currentTarget;s.paused?await de(s,{context:"列表视频",notify:!0}):s.pause(),t.preventDefault(),t.stopPropagation()})),$(e.boxSelector).off("contextmenu.jhsListMenu").on("contextmenu.jhsListMenu",".item img, .item video",(async t=>{try{t.preventDefault();let s=$(t.target).closest(".item"),{carNum:a,url:i,publishTime:r,fc2Source:n}=this.findCarNumAndHref(s),l=N?$(".actor-section-name"):$(".avatar-box .photo-info .pb10"),c="";l.length&&(c=l.text().trim().split(",")[0].replace("(無碼)","")),utils.q(t,`是否屏蔽番号 ${C(a)}?`,(async()=>{try{c||(c=await this.parseActressName(i)),await this.getRuntimeService("state").patch(a,{blocked:!0},{record:{carNum:a,url:i,names:c,publishTime:r,fc2Source:n}}),show.ok("操作成功")}catch(h){clog.error("屏蔽操作失败:",h),show.error("操作失败")}}))}catch(s){clog.error("右键菜单处理失败:",s)}}))}async openMovieDetail(e,{event:t=null,autoplay:s=!1,newTab:a=!1}={}){let i=e?.jquery?e:$(e),{carNum:r,aHref:n}=this.findCarNumAndHref(i);if(!r||!n)return;let l=a||!!t&&(t.ctrlKey||t.metaKey||t.button===1);if(r.includes("FC2-"))return;let c=new URL(n,window.location.origin);s&&c.searchParams.set("autoPlay","1"),utils.openPage(c.href,r,!0,{event:t,newTab:l}),this.$currentImage=null}bindMovieDetailNavigation(e){let t=$(e),s=".item img, .item .video-title";t.off("click.jhsMovieDetail auxclick.jhsMovieDetail",s).on("click.jhsMovieDetail auxclick.jhsMovieDetail",s,(a=>{a.type==="auxclick"&&a.button!==1||a.type==="click"&&a.button&&a.button!==0||a.shiftKey||a.altKey||$(a.target).closest("div.meta-buttons,[class^='jhs-match-']").length||(a.preventDefault(),a.stopPropagation(),this.openMovieDetail($(a.currentTarget).closest(".item"),{event:a}).catch((i=>clog.error("打开影片详情失败",i))))}))}async parseActressName(e){let t=null;if(await storageManager.getSetting("enableSaveActressCarInfo",ne)===R){clog.debug("鉴定补录演员信息-已启用, 开始解析详情页"),clog.debug("开始解析演员详情页",e);let s=await this.getRuntimeService("scope")(),a=await Ve(this.getRuntimeService("http"),e,s),i=utils.htmlTo$dom(a);N?t=i.find(".female").prev().map(((r,n)=>$(n).text())).get().join(" "):B&&(t=i.find('span[onmouseover*="star_"] a').map(((r,n)=>$(n).text())).get().join(" ")),clog.debug("解析到名称:",t)}return t}findCarNumAndHref(e){try{return Ce(e)}catch(t){throw show.error("提取番号信息失败"),t}}showCarNumBox(e){let t=this.getRuntimeService("host").locateListItems().find(s=>$(s).find(".video-title strong").text()===e);if(t){let s=$(t);s.attr("data-hide")==="yes"&&(s.show(),s.removeAttr("data-hide"))}}_replaceSingleHdImg(e){if(e.dataset.hdReplaced==="true")return;let t=e.currentSrc||e.src,s=e.dataset.full||t;if(N)/jdbstatic\.com|javdb\.com/i.test(t)&&(s=s.replace("thumbs","covers"),e.dataset.full=s,e.dataset.hdReplaced="true",e.title="");else if(B){let a=/\/(imgs|pics)\/(thumb|thumbs)\//,i=/(\.jpg|\.jpeg|\.png)$/i;a.test(t)?(s=s.replace(a,"/$1/cover/").replace(i,"_b$1"),e.dataset.full=s,e.dataset.hdReplaced="true",e.dataset.title=e.title,e.title=""):/ps(\.jpg|\.jpeg|\.png)$/i.test(t)&&(s=s.replace(/ps(\.jpg|\.jpeg|\.png)$/i,"pl$1"),e.dataset.full=s,e.dataset.hdReplaced="true",e.dataset.title=e.title,e.title="")}e.dataset.hdReplaced!=="true"||s===t||(e.src=s,e.onerror=function(){this.src!==t&&(this.src=t),this.onerror=null})}_scheduleHdUpgrade(e){if(e.dataset.hdReplaced==="true"||e.dataset.jhsHdPending==="true")return;if(e.complete)return void this._replaceSingleHdImg(e);e.dataset.jhsHdPending="true";let t=d(()=>{e.removeEventListener("load",t),e.removeEventListener("error",t),delete e.dataset.jhsHdPending,this.hdPendingCleanups.delete(e),this._replaceSingleHdImg(e)},"finish"),s=d(()=>{e.removeEventListener("load",t),e.removeEventListener("error",t),delete e.dataset.jhsHdPending},"cleanup");this.hdPendingCleanups.set(e,s),e.addEventListener("load",t,{once:!0}),e.addEventListener("error",t,{once:!0})}replaceHdImg(e){if(e&&typeof e.jquery=="string"&&(e=e.toArray()),e||(e=document.querySelectorAll(this.getSelector().coverImgSelector)),!e.length)return;let t=Array.from(e).filter(s=>s.dataset.hdReplaced!=="true"&&s.dataset.jhsHdObserved!=="true");"IntersectionObserver"in window&&!this.hdImageObserver&&(this.hdImageObserver=new IntersectionObserver((s=>{s.forEach((a=>{let i=a.target;a.isIntersecting&&(this.hdImageObserver?.unobserve(i),delete i.dataset.jhsHdObserved,this._scheduleHdUpgrade(i))}))}),{rootMargin:"200px"}));for(let s of t)s.decoding="async",this.hdImageObserver?(s.dataset.jhsHdObserved="true",this.hdImageObserver.observe(s)):this._scheduleHdUpgrade(s)}configureHoverPreview(e){let t=window;this.hoverPreviewState===e&&(e==="no"||t.imageHoverPreviewObj)||(t.imageHoverPreviewObj&&(t.imageHoverPreviewObj.destroy?.(),t.imageHoverPreviewObj=null),e==="yes"&&(t.imageHoverPreviewObj=new ImageHoverPreview({selector:this.getSelector().coverImgSelector})),this.hoverPreviewState=e)}applyTranslatedTitle(e,t,s){let a=e.find(".video-title");N?(a.contents().each(((i,r)=>{r.nodeType!==3||(r.textContent||"").trim()===""||(r.textContent||"").includes(s)||(r.textContent=" "+t+" ")})),a.attr("title",t)):a.text(t),e.attr("data-jhs-translation-key",s)}invalidateTranslations(){this.translationGeneration++}async translate(e){let t=e?.jquery?e:$(e);if(!t.length)return;let s,a,i=t.find(".video-title");if(N?(s=i.contents().filter(((h,u)=>u.nodeType===3&&(u.textContent||"").trim()!=="")).text().trim(),a=t.find(".video-title strong").text().trim()):(s=(t.find("img").attr("data-title")||"").trim(),a=(t.find("a").attr("href")||"").split("/").filter(Boolean).pop()?.trim()),!s||!a)return;let r=this.translationGeneration,n=this.getRuntimeService("settings"),l=await this.getRuntimeService("scope")(),c=await this.getRuntimeService("translation").translate(s,{cacheAlias:a,scope:l});r!==this.translationGeneration||(n?.snapshot?.().translateTitle??R)!==R||this.applyTranslatedTitle(t,c,a)}async revertTranslation(){$(this.getSelector().itemSelector).toArray().forEach(e=>{let t=$(e),s=t.find(".box").attr("title")||t.find(".video-title").attr("title")||t.find("img").attr("data-title"),a;N&&(a=t.find(".video-title strong").text().trim());let i=t.find(".video-title");i.contents().each(((r,n)=>{n.nodeType!==3||!s||(n.textContent||"").trim()===""||a&&(n.textContent||"").includes(a)||(n.textContent=" "+s+" ")})),i.removeAttr("title")})}addJumpPageControl(){let e="gemini-jump-page-control";if($("#"+e).length>0||$(".pagination-link.is-current").length===0)return;let t=utils.getUrlParam(Y,"page")||1,s=$('<input type="number" class="jhs-field jhs-jump-page-input">',{id:"jumpPageInput",placeholder:"页码",min:"1",value:t+1}),a=$('<button type="button" class="jhs-btn jhs-btn--secondary jhs-jump-page-btn">',{text:"跳转"}),i=$("<li>",{id:e}).append(s).append(a);$(".pagination-list").append(i);let r=d(()=>{let n=parseInt(s.val(),10);if(isNaN(n)||n<1)return void s.focus();let l=new URL(window.location.href);l.searchParams.set("page",n.toString()),window.location.href=l.toString()},"s");a.on("click",r),s.on("keypress",(function(n){n.which===13&&(r(),n.preventDefault())}))}};d(En,"ListPagePlugin");var Fa=En;var Dn=class Dn extends I{constructor(){super(...arguments),this._fabGeneration=0,this._commandBarSources=[]}getName(){return"MobileBottomBarPlugin"}shouldSkipOnMobile(){return!1}async initCss(){return`
            /* FAB 浮动操作按钮 */
            #jhs-fab {
                position: fixed;
                bottom: calc(24px + env(safe-area-inset-bottom, 0px));
                right: 20px;
                width: 56px;
                height: 56px;
                border: 0;
                border-radius: 50%;
                background: var(--jhs-accent);
                color: var(--jhs-accent-text-on);
                font-size: 26px;
                font-family: inherit;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                z-index: var(--jhs-z-fab);
                box-shadow: var(--jhs-shadow-md);
                transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1), box-shadow 0.3s;
                -webkit-tap-highlight-color: transparent;
                user-select: none;
                -webkit-user-select: none;
            }
            html.jhs-fab-mounted {
                scroll-padding-bottom: calc(104px + env(safe-area-inset-bottom, 0px));
            }
            #jhs-fab-safe-area {
                display: block;
                width: 100%;
                height: calc(104px + env(safe-area-inset-bottom, 0px));
                clear: both;
                visibility: hidden;
                pointer-events: none;
            }
            #jhs-fab:active {
                transform: scale(0.9);
            }
            #jhs-fab.jhs-fab-open {
                transform: rotate(135deg);
                background: var(--jhs-accent-hover);
                color: var(--jhs-accent-text-on);
                box-shadow: var(--jhs-shadow-md);
            }

            /* FAB 遮罩 */
            .jhs-fab-backdrop {
                position: fixed;
                inset: 0;
                background: rgba(0,0,0,0.25);
                backdrop-filter: blur(2px);
                -webkit-backdrop-filter: blur(2px);
                z-index: var(--jhs-z-fab-backdrop);
                opacity: 0;
                pointer-events: none;
                transition: opacity 0.3s;
            }
            .jhs-fab-backdrop.jhs-fab-backdrop-visible {
                opacity: 1;
                pointer-events: auto;
            }

            /* FAB 菜单 */
            .jhs-fab-menu {
                position: fixed;
                bottom: calc(92px + env(safe-area-inset-bottom, 0px));
                right: 16px;
                z-index: var(--jhs-z-fab-menu);
                display: flex;
                flex-direction: column;
                gap: 10px;
                align-items: flex-end;
                opacity: 0;
                transform: translateY(16px) scale(0.92);
                pointer-events: none;
                transition: opacity 0.25s, transform 0.25s cubic-bezier(0.32, 0.72, 0, 1);
            }
            .jhs-fab-menu.jhs-fab-menu-open {
                opacity: 1;
                transform: translateY(0) scale(1);
                pointer-events: auto;
            }

            /* FAB 菜单分组 */
            .jhs-fab-group {
                display: flex;
                flex-direction: column;
                gap: 10px;
                align-items: flex-end;
            }
            .jhs-fab-divider {
                width: 32px;
                height: 2px;
                background: var(--jhs-border);
                border-radius: 1px;
                align-self: flex-end;
                margin: 2px 0;
            }

            /* FAB 菜单项 */
            .jhs-fab-menu-item {
                display: flex;
                align-items: center;
                gap: 10px;
                padding: 10px 16px;
                background: var(--jhs-surface);
                border: 1px solid var(--jhs-border);
                border-radius: 24px;
                box-shadow: var(--jhs-shadow-md);
                cursor: pointer;
                white-space: nowrap;
                min-height: 44px;
                font-size: 14px;
                font-family: inherit;
                font-weight: 500;
                color: var(--jhs-text);
                opacity: 0;
                transform: translateY(8px) scale(0.92);
                transition: opacity 0.2s, transform 0.2s cubic-bezier(0.32, 0.72, 0, 1), background 0.15s;
                -webkit-tap-highlight-color: transparent;
                user-select: none;
                -webkit-user-select: none;
            }
            .jhs-fab-menu-item.jhs-fab-item-visible {
                opacity: 1;
                transform: translateY(0) scale(1);
                transition: opacity 0.2s ease, transform 0.2s cubic-bezier(0.32, 0.72, 0, 1), background 0.15s;
            }
            .jhs-fab-menu-item:active {
                transform: scale(0.95);
                background: var(--jhs-surface-2);
            }

            /* FAB 状态色块 */
            .jhs-fab-status-dot {
                width: 8px;
                height: 8px;
                border-radius: 50%;
                flex-shrink: 0;
                background: var(--jhs-border-strong);
            }

            .jhs-page-commandbar {
                display: flex;
                align-items: center;
                justify-content: space-between;
                overflow: visible;
                gap: var(--jhs-space-3);
                width: 100%;
                margin: var(--jhs-space-3) 0;
            }
            .jhs-commandbar__left, .jhs-commandbar__right,
            .jhs-commandbar__primary, .jhs-commandbar__filters,
            .jhs-commandbar__context, .jhs-commandbar__view {
                display: flex;
                align-items: center;
                gap: var(--jhs-space-1);
                min-width: 0;
                white-space: nowrap;
            }
            .jhs-commandbar__left { flex: 1 1 auto; overflow:visible; }
            .jhs-commandbar__right { flex: 0 0 auto; overflow:visible; }
            .jhs-commandbar__filters { overflow:visible; }
            .jhs-commandbar__batch, .jhs-commandbar__more, .jhs-sort-control { position:relative; }
            .jhs-commandbar__menu { min-width:220px; }
            .jhs-commandbar__menu .jhs-btn, .jhs-sort-menu .jhs-btn { width:100%; justify-content:flex-start; }
            .jhs-commandbar__sort-label { color:var(--jhs-text-muted); font-size:14px; }
            .jhs-mobile-filter-menu, .jhs-mobile-sort-menu { display:none; min-width:220px; padding:var(--jhs-space-2); border:1px solid var(--jhs-border); border-radius:var(--jhs-radius-md); background:var(--jhs-surface); box-shadow:var(--jhs-shadow-md); }
            .jhs-fab-menu:is(.jhs-fab-filter-open,.jhs-fab-sort-open) > .jhs-fab-group, .jhs-fab-menu:is(.jhs-fab-filter-open,.jhs-fab-sort-open) > .jhs-fab-divider { display:none; }
            .jhs-fab-menu.jhs-fab-filter-open > .jhs-mobile-filter-menu, .jhs-fab-menu.jhs-fab-sort-open > .jhs-mobile-sort-menu { display:grid; gap:var(--jhs-space-1); }
            .jhs-mobile-filter-menu .jhs-btn, .jhs-mobile-sort-menu .jhs-btn { width:100%; justify-content:flex-start; }
            @media (max-width: 1023px) {
                .jhs-page-commandbar { flex-wrap:wrap; overflow:visible; }
                .jhs-commandbar__left, .jhs-commandbar__right { flex-wrap:wrap; overflow:visible; }
                .jhs-commandbar__left { flex-basis:100%; }
                .jhs-commandbar__right { margin-left:auto; }
            }
            @media (max-width: 767px) {
                .jhs-page-commandbar { display: none; }
            }
        `}async handle(){let e=this.getRuntimeService("profile");(await this.getRuntimeService("scope")()).listen(e,"profile.changed",()=>this.syncSurfaces()),this.syncSurfaces()}mountBottomBar(){if($("#jhs-fab").length)return;document.documentElement.classList.add("jhs-fab-mounted");let e=$('<div class="jhs-fab-backdrop"></div>').appendTo("body"),t=this.createMenu();$("body").append(t);let s=$('<button type="button" id="jhs-fab" class="jhs-btn" aria-label="打开 JHS 工具" aria-controls="jhs-fab-menu" aria-haspopup="menu" aria-expanded="false">+</button>').appendTo("body");$('<div id="jhs-fab-safe-area" aria-hidden="true"></div>').appendTo("body"),this.bindEvents(s,e)}unmountBottomBar(){this._fabGeneration++,$("#jhs-fab, #jhs-fab-menu, #jhs-fab-safe-area, .jhs-fab-backdrop").remove(),document.documentElement.classList.remove("jhs-fab-mounted")}async afterPluginsReady(){this.syncSurfaces()}syncSurfaces(){let e=this.getRuntimeService("profile").current()==="compact",t=this.getOptionalDependency("SettingPlugin");e?(this.unmountDesktopCommandBar(),t?.unmountDesktopSettingNav?.(),this.mountBottomBar()):(this.unmountBottomBar(),this.mountDesktopCommandBar(),t?.mountDesktopSettingNav?.())}mountDesktopCommandBar(){if(!window.isListPage)return;let e=$("#jhs-page-commandbar");e.length?this.collectCommandControls(e):this.buildCommandBar()}collectCommandControls(e){let t=d(p=>{let g=$(p).first();return!g.length||!!g.closest("#jhs-page-commandbar").length},"isCollected"),s=d(p=>{(this._commandBarSources||(this._commandBarSources=[])).push({element:p,parent:null,next:null})},"remember"),a=e.find(".jhs-commandbar__left"),i=e.find(".jhs-commandbar__right");if(!a.length||!i.length)return;!e.find(".jhs-commandbar__primary").length&&!t("#waitCheckBtn")&&a.append('<div class="jhs-commandbar__primary"></div>');let r=e.find(".jhs-commandbar__primary");["#waitCheckBtn","#newVideoBtn","#historyBtn"].forEach((p=>{if(t(p))return;let g=$(p).first();g.length&&(s(g[0]),g.attr("class","jhs-btn jhs-btn--secondary").removeAttr("role tabindex").detach().appendTo(r))})),r.children().length&&a.append(r),!e.find(".jhs-commandbar__more").length&&!["#statsBtn","#blacklistBtn"].every(t)&&e.find(".jhs-commandbar__left").append('<div class="jhs-commandbar__more"><button type="button" class="jhs-btn jhs-btn--secondary jhs-commandbar__menu-toggle" aria-haspopup="menu" aria-controls="jhs-commandbar-more-menu" aria-expanded="false">更多</button><div id="jhs-commandbar-more-menu" class="jhs-popover jhs-commandbar__menu" role="menu"></div></div>');let n=e.find(".jhs-commandbar__more");["#statsBtn","#blacklistBtn"].forEach((p=>{if(t(p))return;let g=$(p).first();g.length&&(s(g[0]),g.attr({class:"jhs-btn jhs-btn--ghost",role:"menuitem",tabindex:"-1"}).detach().appendTo(n.find(".jhs-commandbar__menu")))})),n.find(".jhs-commandbar__menu").children().length&&n.appendTo(a);let l=$("#jhs-quick-filter").first();l.length&&!l.closest("#jhs-page-commandbar").length&&(s(l[0]),a.append($('<div class="jhs-commandbar__filters"></div>').append(l.detach())));let c=$("#addBlacklistBtn").first();c.length&&!c.closest("#jhs-page-commandbar").length&&(s(c[0]),c.attr("class","jhs-btn jhs-btn--secondary").removeAttr("role tabindex").detach().appendTo($('<div class="jhs-commandbar__context"></div>').appendTo(i)));let h=$(".jhs-sort-control").first();if(h.length&&!h.closest("#jhs-page-commandbar").length){let p=$('<label class="jhs-commandbar__view"><span class="jhs-commandbar__sort-label">排序</span></label>');s(h[0]),h.detach().appendTo(p),i.append(p)}!e.find(".jhs-commandbar__batch").length&&!["#filterAllVideo","#favoriteAllVideo","#hasDownAllVideo"].every(t)&&i.append('<div class="jhs-commandbar__batch"><button type="button" class="jhs-btn jhs-btn--secondary jhs-commandbar__menu-toggle" aria-haspopup="menu" aria-controls="jhs-commandbar-batch-menu" aria-expanded="false">批量操作</button><div id="jhs-commandbar-batch-menu" class="jhs-popover jhs-commandbar__menu" role="menu"></div></div>');let u=e.find(".jhs-commandbar__batch");["#filterAllVideo","#favoriteAllVideo","#hasDownAllVideo"].forEach((p=>{if(t(p))return;let g=$(p).first();g.length&&(s(g[0]),g.attr({class:"jhs-btn jhs-btn--ghost",role:"menuitem",tabindex:"-1"}).detach().appendTo(u.find(".jhs-commandbar__menu")))})),u.find(".jhs-commandbar__menu").children().length&&u.appendTo(i),e.find(".jhs-commandbar__more, .jhs-commandbar__batch").each(((p,g)=>{let m=$(g);if(m.data("jhsCommandbarBound"))return;m.data("jhsCommandbarBound",!0);let f=m.find(".jhs-commandbar__menu-toggle"),v=m.find(".jhs-commandbar__menu");f.on("click",(b=>{b.stopPropagation();let w=!v.hasClass("is-open");e.find(".jhs-commandbar__menu").removeClass("is-open"),e.find(".jhs-commandbar__menu-toggle").attr("aria-expanded","false"),v.toggleClass("is-open",w),f.attr("aria-expanded",String(w)),w&&v.children().first().trigger("focus")})),v.on("keydown","[role='menuitem']",(b=>{let w=v.find("[role='menuitem']"),S=w.index(b.currentTarget);if(b.key==="Escape")return b.preventDefault(),v.removeClass("is-open"),f.attr("aria-expanded","false").trigger("focus");if(b.key==="Tab")return v.removeClass("is-open"),void f.attr("aria-expanded","false");if(!["ArrowDown","ArrowUp","Home","End"].includes(b.key))return;b.preventDefault();let j=b.key==="Home"?0:b.key==="End"?w.length-1:b.key==="ArrowDown"?(S+1)%w.length:(S-1+w.length)%w.length;w.eq(j).trigger("focus")})).on("click","[role='menuitem']",(()=>{v.removeClass("is-open"),f.attr("aria-expanded","false").trigger("focus")}))})),$(document).off("click.jhsCommandbar").on("click.jhsCommandbar",(p=>{$(p.target).closest(".jhs-commandbar__more, .jhs-commandbar__batch").length||(e.find(".jhs-commandbar__menu").removeClass("is-open"),e.find(".jhs-commandbar__menu-toggle").attr("aria-expanded","false"))})),$(".historyBtnBox").each(((p,g)=>{g.children.length||(g.style.display="none")})),this.getOptionalDependency("ListPagePlugin")?.syncQuickFilterUi?.()}collectDesktopCommandSources(){let e=["#waitCheckBtn","#newVideoBtn","#historyBtn","#statsBtn","#blacklistBtn","#jhs-quick-filter","#addBlacklistBtn",".jhs-sort-control","#filterAllVideo","#favoriteAllVideo","#hasDownAllVideo"],t=[];for(let s of e){let a=$(s).first();a.length&&(a.closest("#jhs-page-commandbar, #jhs-commandbar-parking").length||t.push({element:a[0],parent:null,next:null}))}return t}unmountDesktopCommandBar(){let e=$("#jhs-commandbar-parking");e.length||(e=$('<div id="jhs-commandbar-parking" hidden></div>').appendTo("body"));let t=new Set((this._commandBarSources||[]).map(a=>a.element));for(let a of this.collectDesktopCommandSources())t.has(a.element)||this._commandBarSources.push(a);let s=[...this._commandBarSources||[]];for(let a of s){let i=a.element;i?.isConnected&&e.append(i)}this._commandBarSources=[],$("#jhs-page-commandbar").remove(),$(document).off("click.jhsCommandbar")}buildCommandBar(){if(!window.isListPage||$("#jhs-page-commandbar").length)return;this._commandBarSources=[];let e=$(`
            <div id="jhs-page-commandbar" class="jhs-page-commandbar jhs-ui" role="toolbar" aria-label="JHS 页面工具">
                <div class="jhs-commandbar__left"></div>
                <div class="jhs-commandbar__right"></div>
            </div>`),t=N?$(this.getSelector().boxSelector).first():$(".masonry").first();if(!t.length)return void clog.warn("JHS 页面工具栏未创建:列表容器尚未就绪");t.before(e),this.collectCommandControls(e)}getCarNum(){try{return this.getRuntimeService("host").readMovieRef?.()?.carNum||null}catch(e){clog.debug("移动端详情番号解析失败,已回退",e)}return null}createMenu(){let e=d((m,f,v="")=>`<button type="button" role="menuitem" class="jhs-btn jhs-fab-menu-item" data-action="${m}" ${v}>${f}</button>`,"item"),t=d(m=>`<div class="jhs-fab-group">${m}</div>`,"group"),s='<div class="jhs-fab-divider" role="separator"></div>',a=!!this.getOptionalDependency("ListPageButtonPlugin"),i=!!this.getOptionalDependency("ListPagePlugin"),r=!!this.getOptionalDependency("NewVideoPlugin"),n=!!this.getOptionalDependency("BlacklistPlugin"),l=!!this.getOptionalDependency("SettingPlugin"),c=!!this.getOptionalDependency("DetailPageButtonPlugin"),h=!!this.getOptionalDependency("HighlightMagnetPlugin"),u=!!this.getOptionalDependency("MagnetHubPlugin"),p=!!this.getOptionalDependency("HistoryPlugin"),g;if(window.isListPage){let m=this.getOptionalDependency("ListPageButtonPlugin")?.activeSortMethod?.()??this.getRuntimeService("settings").snapshot().sortMethod,f={default:"默认",rateCount:"评价人数",date:"时间"},v=typeof m=="string"&&m in f?m:"default",b=f[v],w=Te(this.getOptionalDependency("ListPagePlugin")?.activeQuickFilter),S=[...mt,...Gt].map(((k,x)=>`${x===mt.length?'<div class="jhs-filter-menu__separator" role="separator"></div>':""}<button type="button" role="menuitemradio" class="jhs-btn jhs-btn--ghost jhs-mobile-filter-option" aria-checked="${k===w}" tabindex="-1" data-jhs-filter="${k}">${Re[k]}</button>`)).join(""),j=Object.entries(f).map((([k,x])=>`<button type="button" role="menuitemradio" class="jhs-btn jhs-btn--ghost jhs-mobile-sort-option" aria-checked="${k===v}" tabindex="-1" data-jhs-sort="${k}">${x}</button>`)).join("");g=t((a?e("check","开始鉴定"):"")+(r?e("newVideo","新作品"):"")+(n?e("blacklist","黑名单"):"")+(p?e("history","鉴定记录"):"")+(a?e("sort",`排序: ${b}`,'aria-haspopup="menu" aria-expanded="false"'):"")+(i?e("quickFilter",`<span class="jhs-mobile-filter-label">筛选:${Re[w]}</span>`,'aria-haspopup="menu" aria-expanded="false"'):""))+s+t(e("logger","运行日志")+(l?e("setting","设置"):""))+(i?`<div class="jhs-mobile-filter-menu" role="menu" aria-label="列表筛选">${S}</div>`:"")+(a?`<div class="jhs-mobile-sort-menu" role="menu" aria-label="列表排序">${j}</div>`:"")}else window.isDetailPage?g=t(c?[{action:"filter",icon:Ne,label:"屏蔽",key:"filter"},{action:"fav",icon:Le,label:"收藏",key:"fav"},{action:"down",icon:fe,label:"已下载",key:"down"},{action:"watch",icon:ve,label:"已观看",key:"watch"}].map((f=>e(f.action,`<span class="jhs-fab-status-dot" data-status-key="${f.key}"></span>${f.icon}`,`aria-label="${f.label}" aria-pressed="false" data-label="${f.label}"`))).join(""):"")+s+t((h?e("magnetFilter","磁力过滤"):"")+(u?e("magnet","磁力搜索"):"")+(c?e("subtitle","字幕"):""))+s+t(e("logger","运行日志")+(l?e("setting","设置"):"")):g=t(e("logger","运行日志")+(l?e("setting","设置"):""));return $(`<div id="jhs-fab-menu" class="jhs-fab-menu" role="menu" aria-hidden="true">${g}</div>`)}async refreshDetailStatus(){try{let e=this.getCarNum();if(!e)return;let t=await storageManager.getCar(e),s=$(".jhs-fab-menu"),a={filter:"var(--jhs-status-filter)",fav:"var(--jhs-status-fav)",down:"var(--jhs-status-down)",watch:"var(--jhs-status-watch)"},i=q(t?.stateFlags),r=new Set;i.blocked&&r.add("filter"),i.favorite&&r.add("fav"),i.downloaded&&r.add("down"),i.watched&&r.add("watch"),s.find(".jhs-fab-status-dot").each(((n,l)=>{let c=String($(l).data("status-key")||""),h=$(l).closest(".jhs-fab-menu-item");r.has(c)?($(l).css({background:a[c]||"var(--jhs-border-strong)"}),h.attr("aria-pressed","true")):($(l).css({background:"var(--jhs-border-strong)"}),h.attr("aria-pressed","false"))}))}catch(e){clog.warn("移动端详情状态刷新失败",e)}}bindEvents(e,t){let s=$(".jhs-fab-menu"),a=s.find(".jhs-mobile-filter-menu"),i=s.find(".jhs-mobile-sort-menu"),r=s.find('[data-action="quickFilter"]'),n=s.find('[data-action="sort"]'),l=d((p=!1)=>{s.removeClass("jhs-fab-filter-open"),r.attr("aria-expanded","false"),p&&r.trigger("focus")},"closeFilterMenu"),c=d((p=!1)=>{s.removeClass("jhs-fab-sort-open"),n.attr("aria-expanded","false"),p&&n.trigger("focus")},"closeSortMenu"),h=d((p=!1)=>{this._fabGeneration++,l(),c(),e.removeClass("jhs-fab-open").attr("aria-expanded","false"),s.removeClass("jhs-fab-menu-open").attr("aria-hidden","true"),t.removeClass("jhs-fab-backdrop-visible"),s.find(".jhs-fab-menu-item").removeClass("jhs-fab-item-visible"),p&&e.trigger("focus")},"closeMenu"),u=d(()=>{if(e.hasClass("jhs-fab-open"))h();else{if(e.addClass("jhs-fab-open").attr("aria-expanded","true"),s.addClass("jhs-fab-menu-open").attr("aria-hidden","false"),t.addClass("jhs-fab-backdrop-visible"),window.isListPage){let v=this.getOptionalDependency("ListPageButtonPlugin")?.activeSortMethod?.()??this.getRuntimeService("settings").snapshot().sortMethod,b={default:"默认",rateCount:"评价人数",date:"时间"},w=typeof v=="string"&&v in b?v:"default",S=b[w];s.find('[data-action="sort"]').text(`排序: ${S}`),this.getOptionalDependency("ListPagePlugin")?.syncQuickFilterUi?.()}window.isDetailPage&&this.refreshDetailStatus().catch((v=>clog.warn("移动端详情状态刷新失败",v)));let g=++this._fabGeneration,m=this,f=s.find(".jhs-fab-menu-item");f.first().trigger("focus"),f.each(((v,b)=>{let w=$(b);setTimeout(()=>{g===m._fabGeneration&&w.addClass("jhs-fab-item-visible")},30+v*35)}))}},"toggleMenu");e.on("click",u),t.on("click",(()=>h(!0))),s.on("keydown",".jhs-fab-menu-item",(p=>{let g=s.find(".jhs-fab-menu-item"),m=g.index(p.currentTarget);if(p.key==="Escape")return p.preventDefault(),h(!0);if(!["ArrowDown","ArrowUp","Home","End"].includes(p.key))return;p.preventDefault();let f=p.key==="Home"?0:p.key==="End"?g.length-1:p.key==="ArrowDown"?(m+1)%g.length:(m-1+g.length)%g.length;g.eq(f).trigger("focus")})),a.on("keydown",".jhs-mobile-filter-option",(p=>{let g=a.find(".jhs-mobile-filter-option"),m=g.index(p.currentTarget);if(p.key==="Escape")return p.preventDefault(),l(!0);if(!["ArrowDown","ArrowUp","Home","End"].includes(p.key))return;p.preventDefault();let f=p.key==="Home"?0:p.key==="End"?g.length-1:p.key==="ArrowDown"?(m+1)%g.length:(m-1+g.length)%g.length;g.eq(f).trigger("focus")})).on("click",".jhs-mobile-filter-option",(p=>{p.stopPropagation(),this.getOptionalDependency("ListPagePlugin")?.setQuickFilter?.($(p.currentTarget).data("jhs-filter")),h(!0)})),i.on("keydown",".jhs-mobile-sort-option",(p=>{let g=i.find(".jhs-mobile-sort-option"),m=g.index(p.currentTarget);if(p.key==="Escape")return p.preventDefault(),c(!0);if(!["ArrowDown","ArrowUp","Home","End"].includes(p.key))return;p.preventDefault();let f=p.key==="Home"?0:p.key==="End"?g.length-1:p.key==="ArrowDown"?(m+1)%g.length:(m-1+g.length)%g.length;g.eq(f).trigger("focus")})).on("click",".jhs-mobile-sort-option",(async p=>{p.stopPropagation();let g=$(p.currentTarget).data("jhs-sort"),m=i.find('.jhs-mobile-sort-option[aria-checked="true"]').first();i.find(".jhs-mobile-sort-option").attr("aria-checked","false"),$(p.currentTarget).attr("aria-checked","true");try{await this.getOptionalDependency("ListPageButtonPlugin")?.selectSortMethod?.(g)}catch(v){i.find(".jhs-mobile-sort-option").attr("aria-checked","false"),m.attr("aria-checked","true"),clog.error("排序设置保存失败,已恢复",v),show.error("排序设置保存失败,已恢复原设置");return}let f={default:"默认",rateCount:"评价人数",date:"时间"};s.find('[data-action="sort"]').text(`排序: ${f[String(g)]??g}`),h(!0)})),s.on("click",".jhs-fab-menu-item",p=>{let g=$(p.currentTarget).data("action");if(g==="quickFilter"){p.stopPropagation(),s.addClass("jhs-fab-filter-open"),r.attr("aria-expanded","true");let m=a.find('[aria-checked="true"]');return void(m.length?m.first():a.find(".jhs-mobile-filter-option").first()).trigger("focus")}if(g==="sort"){p.stopPropagation(),s.addClass("jhs-fab-sort-open"),n.attr("aria-expanded","true");let m=i.find('[aria-checked="true"]');return void(m.length?m.first():i.find(".jhs-mobile-sort-option").first()).trigger("focus")}h(!0),this.handleAction(g).catch((m=>clog.error(`移动端操作 ${g||"unknown"} 失败`,m)))})}async handleAction(e){switch(e){case"check":await this.getOptionalDependency("ListPageButtonPlugin")?.openWaitCheck?.();break;case"newVideo":this.getOptionalDependency("NewVideoPlugin")?.openDialog?.();break;case"blacklist":this.getOptionalDependency("BlacklistPlugin")?.openBlacklistDialog?.();break;case"history":await this.getOptionalDependency("HistoryPlugin")?.openHistory?.();break;case"sort":break;case"filter":$("#filterBtn").length&&$("#filterBtn").click();break;case"fav":$("#favoriteBtn").length&&$("#favoriteBtn").click();break;case"down":$("#hasDownBtn").length&&$("#hasDownBtn").click();break;case"watch":$("#hasWatchBtn").length&&$("#hasWatchBtn").click();break;case"magnetFilter":$("#enable-magnets-filter").length&&$("#enable-magnets-filter").click();break;case"magnet":$("#magnetSearchBtn").length&&$("#magnetSearchBtn").click();break;case"subtitle":$("#search-subtitle-btn").length&&$("#search-subtitle-btn").click();break;case"setting":await this.getOptionalDependency("SettingPlugin")?.openQuickSetting();break;case"logger":clog.openDialog?.();break}}};d(Dn,"MobileBottomBarPlugin");var Va=Dn;var Nn=class Nn extends I{getName(){return"NavBarPlugin"}async initCss(){return`
            .highlight-red {
    /* 核心要求:高亮红色文本 */
    color: var(--jhs-status-filter) !important;

    /* 建议:增加字体加粗,效果更明显 */
    font-weight: bold;

    /* 建议:增加背景色,效果更突出 */
    /* background-color: yellow; */
}
        `}handle(){if(this.margeNav(),this.hookSearch(),this.hookOldSearch(),this.toggleOtherNavItem(),$(window).resize(this.toggleOtherNavItem),K.enhance("#search-box"),window.location.href.includes("/search")){let e=new URLSearchParams(window.location.search),t=e.get("q"),s=e.get("f");$("#search-keyword").val(t),s&&K.setValue("#search-type",s),t&&this.highlightKeyword(t)}}highlightKeyword(e){let t=e.trim();if(!t)return;let s=t.toLowerCase();$(".video-title strong, .actor-box strong").each(((a,i)=>{let r=$(i);r.text().toLowerCase().includes(s)&&r.addClass("highlight-red")}))}hookSearch(){let e=!!this.getOptionalDependency("SearchByImagePlugin");$("#navbar-menu-hero").after(`
            <div class="navbar-menu jhs-ui" id="search-box">
                <div class="navbar-start jhs-layout-d9caa2c0">
                    <select id="search-type" class="jhs-select-source">
                        <option value="all">影片</option>
                        <option value="actor">演员</option>
                        <option value="series">系列</option>
                        <option value="maker">片商</option>
                        <option value="director">导演</option>
                        <option value="code">番号</option>
                        <option value="list">清单</option>
                    </select>
                    <input id="search-keyword" type="text" placeholder="输入影片番号、演员名等关键词进行检索" class="jhs-field">
                    <a href="/advanced_search?noFold=1" title="高级检索" class="jhs-btn jhs-btn--secondary"><span>...</span></a>
                    `+(e?'<button type="button" id="search-img-btn" class="jhs-btn jhs-btn--secondary">识图</button>':"")+`
                    <button type="button" id="search-btn" class="jhs-btn jhs-btn--primary">检索</button>
                </div>
            </div>
        `),$("#search-keyword").on("paste",(t=>{let s=t.originalEvent?.clipboardData?.items||[];for(let a=0;a<s.length;a++)if(s[a].type.indexOf("image")!==-1){let i=s[a].getAsFile();$("#search-keyword").blur();let r=this.getOptionalDependency("SearchByImagePlugin");return r?void r.open((()=>{r.handleImageFile(i),r.resetSearchUI()})):void show.info("以图识图功能已禁用")}})).on("keypress",(t=>{t.key==="Enter"&&setTimeout((()=>{$("#search-btn").click()}),0)})),$("#search-btn").on("click",(t=>{let s=$("#search-keyword").val(),a=$("#search-type").val();s!==""&&(window.location.href.includes("/search")?window.location.href="/search?q="+encodeURIComponent(String(s))+"&f="+encodeURIComponent(String(a)):window.open("/search?q="+encodeURIComponent(String(s))+"&f="+encodeURIComponent(String(a))))})),e&&$("#search-img-btn").on("click",(()=>{this.getOptionalDependency("SearchByImagePlugin")?.open?.()}))}hookOldSearch(){let e=!!this.getOptionalDependency("SearchByImagePlugin");if(!e)return;let t=document.querySelector(".search-image");if(!t)return;let s=t.cloneNode(!0);t.parentNode?.replaceChild(s,t),$("#button-search-image").attr("data-tooltip","以图识图"),e&&$(".search-image").on("click",(a=>{this.getOptionalDependency("SearchByImagePlugin")?.open?.()}))}margeNav(){$('a[href*="/feedbacks/new"]').remove(),$('a[href*="theporndude.com"]').remove();let e=$('<div class="navbar-item has-dropdown is-hoverable"><a class="navbar-link">其它</a><div class="navbar-dropdown is-boxed"></div></div>'),t=e.find(".navbar-dropdown");t.append($('<a class="navbar-item" href="/feedbacks/new" target="_blank">反饋</a>')),this.getRuntimeService("movie").externalNavigationLinks().forEach((s=>t.append($("<a></a>").addClass("navbar-item").attr({href:s.url,rel:"nofollow noopener",target:"_blank"}).text(s.label)))),$('a.navbar-link[href="/makers"]').parent().after(e)}toggleOtherNavItem(){let e=$("#search-box"),t=$("#search-bar-container");$(window).width()>1600?(e.show(),t.hide()):(e.hide(),t.show())}};d(Nn,"NavBarPlugin");var Ha=Nn;var Ln=class Ln extends I{constructor(){super(...arguments),A(this,"flag",null)}getName(){return"WantAndWatchedVideosPlugin"}async handle(){window.location.href.includes("/want_watch_videos")&&($("h3").append('<button type="button" class="jhs-btn jhs-btn--primary jhs-layout-481ed7e7" id="wantWatchBtn">导入至 JHS</button>'),$("#wantWatchBtn").on("click",(e=>{this.flag="favorite",this.importWantWatchVideos(e,"是否将想看的影片导入到 JHS 收藏?")}))),window.location.href.includes("/watched_videos")&&($("h3").append('<button type="button" class="jhs-btn jhs-btn--primary jhs-layout-481ed7e7" id="wantWatchBtn">导入至 JHS</button>'),$("#wantWatchBtn").on("click",(e=>{this.flag="watched",this.importWantWatchVideos(e,"是否将看过的影片导入到 JHS 已观看?")})))}importWantWatchVideos(e,t){utils.q(null,`${t} <br/> <span class="jhs-task-emphasis">执行此功能前请记得备份数据</span>`,(async()=>{let s=loading();try{let a=await this.parseMovieList();show.ok(`导入完成:成功 ${a.imported},失败 ${a.failed},共 ${a.pages} 页`)}catch(a){clog.error(a),show.error(`导入失败:${a instanceof Error?a.message:String(a)}`)}finally{s.close()}}))}async parseMovieList(e=null,t={imported:0,failed:0,pages:0}){let s,a;e?(s=e.find(this.getSelector().itemSelector),a=e.find(".pagination-next").attr("href")):(s=$(this.getSelector().itemSelector),a=$(".pagination-next").attr("href")),t.pages++,show.info(`正在导入第 ${t.pages} 页`);for(let l of s){let c=$(l),h=c.find("a").attr("href"),u=c.find(".video-title strong").text().trim(),p=c.find(".meta").text().trim();if(h&&u)try{this.flag&&await this.getRuntimeService("state").patch(u,{[this.flag]:!0},{type:"javdb-list-import",record:{carNum:u,url:h,names:"",publishTime:p}}),t.imported++}catch(g){t.failed++,clog.error(`保存失败 [${u}]:`,g)}}if(!a)return t;await utils.sleep(1e3);let i=await this.getRuntimeService("scope")(),r=await Ve(this.getRuntimeService("http"),new URL(a,window.location.href),i),n=utils.htmlTo$dom(r);return this.parseMovieList(n,t)}};d(Ln,"WantAndWatchedVideosPlugin");var qa=Ln;var Bn=class Bn extends I{getName(){return"SubTitleCatPlugin"}handle(){$(".t-banner-inner").hide(),$("#navbar").hide();let e=(new URLSearchParams(window.location.search).get("search")||"").toLowerCase(),t=$(".sub-table tr td a").toArray(),s=0;t.forEach((r=>{let n=$(r);n.text().toLowerCase().includes(e)?s++:n.parent().parent().hide()})),s===0&&show.error("该番号无字幕!");let a=$(".sec-title"),i=String(a.html()||"").replace(/^\d+/,String(s));a.html(i)}};d(Bn,"SubTitleCatPlugin");var Wa=Bn;var Mn=class Mn extends I{getName(){return"TranslatePlugin"}async initCss(){return`
            <style>
                .translated-title { margin-top:var(--jhs-space-2); color:var(--jhs-text); font-size:clamp(16px,1.5vw,18px); font-weight:500; line-height:1.5; }
                .translated-title.is-error { color:var(--jhs-danger); }
            </style>`}async handle(){let e=this.getRuntimeService("settings"),t=await this.getRuntimeService("scope")();if(!this._settingsListenerBound){this._settingsListenerBound=!0;let s=d(a=>{a.detail?.names?.includes("translateTitle")&&this.reconfigure()},"onSettingsChanged");e.addEventListener("settings.changed",s),t.addCleanup((()=>{e.removeEventListener("settings.changed",s),this._settingsListenerBound=!1}))}this.reconfigure()}reconfigure(){(this.getRuntimeService("settings").snapshot().translateTitle??R)===R?this.applyTranslation():(this.getOptionalDependency("ListPagePlugin")?.invalidateTranslations?.(),this.revertTranslation())}async applyTranslation(){if(isDetailPage)return this.translate();if(!window.isListPage)return;let e=this.getOptionalDependency("ListPagePlugin");if(!e?.translateListItems||typeof e.getSelector!="function")return;let t=$(e.getSelector().itemSelector).toArray();await e.translateListItems(t)}revertTranslation(){$(".translated-title").remove(),this.getOptionalDependency("ListPagePlugin")?.revertTranslation?.()}async translate(e,t=!0,s={}){let a=this.getRuntimeService("settings");if((a.snapshot().translateTitle??R)!==R)return;B&&(t=!1);let i=await this.getRuntimeService("scope")(),r=e??this.getPageInfo().carNum;await Ys({root:s.root,carNum:r,translation:this.getRuntimeService("translation"),scope:i,isActive:d(()=>(a.snapshot().translateTitle??R)===R,"isActive")})}};d(Mn,"TranslatePlugin");var Ja=Mn;var V=d((o,e,t,s,a,i=[],r={})=>ul({id:o,featureId:e,legacyPluginId:t.legacyPluginId??t.name,plugin:t,sites:s,order:a,requires:i,routes:r.routes??(e==="detail"?["detail","owned-detail"]:[]),surfaces:r.surfaces??(e==="detail"?["detail-page"]:[])}),"manifest"),Ka=Object.freeze([V("list.core","list",Fa,["javdb","javbus"],{javdb:1,javbus:1},[Z.host,y.translation,y.http,y.storage,y.state,y.settings]),V("list.auto-page","list",_a,["javdb","javbus"],{javdb:2,javbus:5},[y.http,y.settings]),V("detail.fc2-owned","detail",Xs,["javdb"],{javdb:3},[y.movie,y.magnet,y.dialog,y.translation,y.settings,y.storage,y.screenshot,y.review,y.related,y.state],{routes:["list","detail","owned-detail"],surfaces:["list-card","detail-page"]}),V("detail.fc2-navigation","detail",Ea,["javdb"],{javdb:4},[Z.host],{routes:["list"],surfaces:["list-card"]}),V("list.fold-category","list",Da,["javdb"],{javdb:5},[y.settings]),V("list.actions","list",za,["javdb","javbus"],{javdb:5,javbus:2},[y.settings]),V("library.history","library",Oa,["javdb","javbus"],{javdb:6,javbus:4},[y.dialog,y.movie,y.settings,y.state]),V("settings.core","settings",zs,["javdb","javbus"],{javdb:7,javbus:3},[Z.host,y.diagnostics,y.profile,y.webdav,y.dialog,y.storage,y.settings,y.cache,y.http,y.offline,y.magnet,y.movie,y.state,y.translation,Qe.settings]),V("identity.javdb-navigation","identity",Ha,["javdb"],{javdb:8},[y.movie]),V("discovery.hit-show","discovery",ea,["javdb"],{javdb:9},[Z.host,y.movie,y.settings,y.cache]),V("discovery.top250","discovery",la,["javdb"],{javdb:10},[Z.host,y.dialog,y.account,y.credential]),V("identity.image-search","identity",Is,["javdb","javbus"],{javdb:11,javbus:6},[y.dialog,y.storage,y.imageSearch]),V("detail.cover-state-actions","detail",ma,["javdb","javbus"],{javdb:12,javbus:8},[y.storage,y.settings,y.movie,y.state],{routes:["list","detail","owned-detail"],surfaces:["list-card","detail-page"]}),V("detail.fc2-lookup","detail",Gs,["javdb"],{javdb:13},[Z.host,y.movie,y.translation,y.settings]),V("detail.javdb-native","detail",Ia,["javdb"],{javdb:14}),V("detail.workspace","detail",Ra,["javdb","javbus"],{javdb:15,javbus:11},[Z.host]),V("detail.reviews","detail",oa,["javdb","javbus"],{javdb:16,javbus:13},[Z.host,y.review,y.movie,y.settings,y.storage]),V("detail.related","detail",na,["javdb"],{javdb:17},[Z.host,y.related,y.settings]),V("detail.page-state-actions","detail",Pa,["javdb","javbus"],{javdb:18,javbus:12},[y.movie,y.dialog,y.subtitle,y.state,y.settings]),V("detail.native-magnets","detail",Na,["javdb","javbus"],{javdb:19,javbus:15},[Z.host,y.settings]),V("detail.javdb-preview","detail",fa,["javdb"],{javdb:20},[y.storage,y.settings,y.movie,y.dialog]),V("library.keyword-filter","library",Ws,["javdb","javbus"],{javdb:21,javbus:14}),V("identity.actress-info","identity",Ps,["javdb"],{javdb:22},[y.actressInfo,y.settings]),V("detail.external-sites","detail",ra,["javdb","javbus"],{javdb:23,javbus:19},[Z.host,y.movie,y.storage,y.settings]),V("external-bridge.translation","external-bridge",Ja,["javdb","javbus"],{javdb:24,javbus:20},[y.translation,y.settings]),V("library.state-actions","library",qa,["javdb"],{javdb:25},[y.http,y.state]),V("detail.external-magnets","detail",ia,["javdb","javbus"],{javdb:26,javbus:17},[y.storage,y.http,y.magnet]),V("detail.screenshot","detail",va,["javdb","javbus"],{javdb:27,javbus:18},[y.screenshot,y.settings]),V("library.blacklist","library",qs,["javdb","javbus"],{javdb:28,javbus:21},[Z.host,y.dialog,y.storage,y.http,y.state]),V("library.favorite-actresses","library",da,["javdb"],{javdb:29}),V("discovery.new-video","discovery",ba,["javdb"],{javdb:30},[y.dialog,y.storage,y.actressInfo,y.movie,y.state]),V("discovery.scheduler","discovery",ya,["javdb","javbus"],{javdb:31,javbus:22},[y.storage,y.http,y.actressInfo,y.movie,y.state]),V("stats.dashboard","stats",Ca,["javdb","javbus"],{javdb:32,javbus:23},[y.diagnostics,y.dialog,y.movie,y.state]),V("responsive-shell.bottom-bar","responsive-shell",Va,["javdb","javbus"],{javdb:33,javbus:24},[Z.host,y.settings,y.profile]),V("external-bridge.115-match","external-bridge",Sa,["javdb","javbus"],{javdb:34,javbus:25},[Z.host,y.dialog,y.offline,y.settings]),V("external-bridge.offline","external-bridge",ja,["javdb","javbus"],{javdb:35,javbus:26},[Z.host,y.dialog,y.offline,y.state,y.settings]),V("compatibility.enhancements","compatibility",Aa,["javdb","javbus"],{javdb:36,javbus:27},[y.state]),V("identity.javbus-navigation","identity",Ta,["javbus"],{javbus:7}),V("detail.javbus-images","detail",ha,["javbus"],{javbus:9}),V("detail.javbus-native","detail",$a,["javbus"],{javbus:10}),V("detail.javbus-preview","detail",ga,["javbus"],{javbus:16},[y.settings,y.storage,y.movie]),V("external-bridge.123pan","external-bridge",xa,["javdb","javbus","123pan"],{javdb:0,javbus:0,"123pan":1},[y.storage]),V("external-bridge.javtrailers","external-bridge",ta,["javtrailers"],{javtrailers:1}),V("external-bridge.subtitle","external-bridge",Wa,["subtitlecat"],{subtitlecat:1})]),Pc=new Set,Ic=new Set;for(let o of Ka){if(Pc.has(o.id))throw new Error(`Duplicate contribution id: ${o.id}`);if(Ic.has(o.legacyPluginId))throw new Error(`Duplicate legacy plugin contribution: ${o.legacyPluginId}`);Pc.add(o.id),Ic.add(o.legacyPluginId)}function Rc(o,e,t){o.setDependencyDeclarations(wl),e.setContributionManifests?.(Ka),o.setCatalogDescriptors(Ka.filter(s=>s.sites.includes(t)).map(s=>({name:s.legacyPluginId,disableable:e.isFeatureDisableable(s.featureId)}))),Ka.filter(s=>s.sites.includes(t)&&e.isContributionEnabled(s.featureId,s.id,s.legacyPluginId)).sort((s,a)=>Number(s.order[t])-Number(a.order[t])).forEach(s=>{let a=e.resolveDeclaredDependencies(s.requires),i={};i.scope=()=>e.getContributionScope(s.featureId,s.id,s.legacyPluginId);let r=new Map([[Z.host,"host"],[y.diagnostics,"diagnostics"],[y.review,"review"],[y.related,"related"],[y.movie,"movie"],[y.magnet,"magnet"],[y.settings,"settings"],[y.cache,"cache"],[y.http,"http"],[y.profile,"profile"],[y.actressInfo,"actressInfo"],[y.imageSearch,"imageSearch"],[y.screenshot,"screenshot"],[y.translation,"translation"],[y.subtitle,"subtitle"],[y.account,"account"],[y.webdav,"webdav"],[y.credential,"credential"],[y.storage,"storage"],[y.state,"state"],[y.offline,"offline"],[y.dialog,"dialog"],[Qe.settings,"settingsRegistry"]]);for(let n of s.requires){let l=r.get(n);if(!l)throw new Error(`Legacy contribution ${s.id} has no runtime name for ${String(n)}`);i[l]=a[n]}o.register(s.plugin,i,{disableable:e.isFeatureDisableable(s.featureId)})})}d(Rc,"registerSitePlugins");function Ec(o,e){for(let t of["pluginManager","utils","gmHttp","storageManager","stateService","jhsEventBus","clog","show","loading"]){if(o[t]==null)throw new Error(`Compatibility facade is missing ${t}`);e[t]=o[t]}return Object.freeze(Object.fromEntries(Object.keys(o).map(t=>[t,e[t]])))}d(Ec,"attachCompatibilityFacade");function He(o,e,t){if(!o||typeof o!="object")throw new TypeError(`${e} implementation is required`);for(let s of t)if(typeof o[s]!="function")throw new TypeError(`${e}.${s} is required`);return o}d(He,"assertPort");var qe=Object.freeze({navigation:["open","assign","replace"],http:["request"],storage:["get","set","remove","keys","getLocal","setLocal","removeLocal","getValue","setValue","removeValue"],dialog:["open","close","confirm","alert"],style:["register","remove"]});var On=class On{constructor(e={}){this.location=e.location??window.location,this.openWindow=e.open??window.open.bind(window),He(this,"NavigationPort",qe.navigation)}open(e,t={}){return t.newTab?this.openWindow(e,"_blank","noopener"):this.assign(e)}assign(e){this.location.assign(e)}replace(e){this.location.replace(e)}};d(On,"BrowserNavigationAdapter");var Ga=On;var zn=class zn{constructor(e=document){this.document=e}register(e,t){if(this.document.getElementById(e))throw new Error(`Duplicate style: ${e}`);let s=this.document.createElement("style");return s.id=e,s.textContent=t,this.document.head.append(s),()=>s.remove()}remove(e){this.document.getElementById(e)?.remove()}};d(zn,"BrowserStyleAdapter");var Qa=zn;var Un=class Un{constructor(e,t,s,a,i=()=>{}){this.forage=e,this.localStore=t,this.gmGetValue=s,this.gmSetValue=a,this.gmDeleteValue=i}get(e){return this.forage.getItem(e)}async set(e,t){await this.forage.setItem(e,t)}async remove(e){await this.forage.removeItem(e)}keys(){return this.forage.keys()}getLocal(e){return this.localStore.getItem(e)}setLocal(e,t){this.localStore.setItem(e,t)}removeLocal(e){this.localStore.removeItem(e)}getValue(e,t){return this.gmGetValue(e,t)}setValue(e,t){this.gmSetValue(e,t)}removeValue(e){this.gmDeleteValue(e)}};d(Un,"IndexedDbStorageAdapter");var Ya=Un;var Fn=class Fn{constructor(e){this.layer=e}open(e){return this.layer.open(this.withDefaultLayer(e))}close(e){this.layer.close(e)}confirm(e,t,s){return this.layer.confirm(e,this.withDefaultLayer(t),s)}alert(e,t){return this.layer.alert(e,this.withDefaultLayer(t))}withDefaultLayer(e={}){let t={zIndex:J.layer,...e};return e.ui?kt(t,globalThis.utils):t}};d(Fn,"LayerDialogAdapter");var Za=Fn;var Vn=class Vn{constructor(e,t=globalThis.fetch?.bind(globalThis)??null){if(typeof e!="function")throw new TypeError("GM_xmlhttpRequest is required");this.requestImplementation=e,this.fetchImplementation=t}request(e){return e.transport==="native-fetch"&&this.fetchImplementation?this.requestWithNativeFetch(e).catch((t=>{if(t instanceof D&&t.code==="ABORTED")throw t;return this.requestWithUserscript(e)})):this.requestWithUserscript(e)}async requestWithNativeFetch(e){let t=new AbortController,s=!1,a=Math.max(0,Number(e.nativeTimeout)||0),i=d(()=>t.abort(),"onAbort"),r=a>0?setTimeout((()=>{s=!0,t.abort()}),a):null;e.signal?.addEventListener("abort",i,{once:!0});try{e.signal?.aborted&&t.abort();let n=await this.fetchImplementation(e.url,{method:e.method??"GET",headers:e.headers,body:e.body,signal:t.signal}),l=await n.text(),c=e.responseType==="json"?JSON.parse(l):l;return{status:n.status,data:c,responseText:l,finalUrl:n.url||e.url,responseHeaders:[...n.headers.entries()].map((h=>h.join(": "))).join(`\r
`)}}catch(n){throw e.signal?.aborted?new D("ABORTED","网络请求已取消",{source:"UserscriptHttpAdapter",cause:n}):s?new D("TIMEOUT","原生网络请求超时",{source:"UserscriptHttpAdapter",cause:n,retryable:!0}):new D("NETWORK_ERROR","原生网络请求失败",{source:"UserscriptHttpAdapter",cause:n,retryable:!0})}finally{r!==null&&clearTimeout(r),e.signal?.removeEventListener("abort",i)}}requestWithUserscript(e){return new Promise((t,s)=>{let a=!1,i,r=d((l,c)=>{a||(a=!0,e.signal?.removeEventListener("abort",n),l(c))},"finish"),n=d(()=>{i?.abort?.(),r(s,new D("ABORTED","网络请求已取消",{source:"UserscriptHttpAdapter"}))},"onAbort");i=this.requestImplementation({...e.requestOptions,method:e.method??"GET",url:e.url,headers:e.headers,data:e.body,responseType:e.responseType,timeout:e.timeout,onload:d(l=>r(t,{status:l.status,data:l.response??l.responseText,responseText:l.responseText??"",finalUrl:l.finalUrl||e.url,responseHeaders:l.responseHeaders??""}),"onload"),onerror:d(l=>r(s,new D("NETWORK_ERROR","网络请求失败",{source:"UserscriptHttpAdapter",cause:l,retryable:!0})),"onerror"),ontimeout:d(()=>r(s,new D("TIMEOUT","网络请求超时",{source:"UserscriptHttpAdapter",retryable:!0})),"ontimeout"),onabort:d(()=>r(s,new D("ABORTED","网络请求已取消",{source:"UserscriptHttpAdapter"})),"onabort")}),e.signal?.aborted?n():e.signal?.addEventListener("abort",n,{once:!0})})}};d(Vn,"UserscriptHttpAdapter");var Xa=Vn;async function Dc(o){let e=await globalThis.crypto.subtle.digest("SHA-256",new TextEncoder().encode(o));return Array.from(new Uint8Array(e),(t=>t.toString(16).padStart(2,"0"))).join("")}d(Dc,"digestKey");var Hn=class Hn{constructor(e={}){this.namespaceVersion=e.namespaceVersion??2,this.diagnostics=e.diagnostics??null,this.storage=e.storage??null,this.publicCache=new Map,this.sessionCaches=new Map,this.publicReads=new Map,this.publicGenerations=new Map,this.publicNamespaces=new Set(["default"]),this.publicWritesSincePrune=0,this.pruneScheduled=!1,this.pruneRunning=!1,this.prunePromise=null}get publicGeneration(){return this.publicGenerations.get("default")||0}generation(e){return this.publicGenerations.get(e)||0}get publicPrefix(){return this._publicPrefix("default")}_publicPrefix(e="default"){return`jhs_http_public_cache:v${this.namespaceVersion}:${encodeURIComponent(e)}:`}storeFor(e,t=""){if(e==="public")return this.publicCache;if(e==="session"){if(!t)throw new TypeError("sessionScopeId is required for session cache");let s=this.sessionCaches.get(t);return s||this.sessionCaches.set(t,s=new Map),s}return null}async get(e,t,s){arguments.length===2&&(s=t,t=e,e="default"),e=String(e||"default"),this.publicNamespaces.add(e);let a=this.storeFor(s.scope,s.sessionScopeId),i=`${e}:${this.namespaceVersion}:${t}`,r=Date.now(),n=this.storage,l=a?.get(i);if(l&&l.expiresAt>r)return this.diagnostics?.recordCache(!0),{hit:!0,value:l.value,negative:l.negative};if(l&&a?.delete(i),s.scope!=="public"||!n)return this.diagnostics?.recordCache(!1),{hit:!1,value:void 0,negative:!1};let c=`${e}:${t}`,h=this.publicReads.get(c);if(h)return h;let u=this.generation(e),p=(async()=>{let g=this._publicPrefix(e)+await Dc(t),m;try{m=await n.get(g)}catch{return this.diagnostics?.recordCache(!1),{hit:!1,value:void 0,negative:!1}}if(m?.version!==this.namespaceVersion||!Number.isFinite(m?.expiresAt)||m.expiresAt<=r)return m&&await n.remove(g).catch(()=>{}),this.diagnostics?.recordCache(!1),{hit:!1,value:void 0,negative:!1};if(u!==this.generation(e))return this.diagnostics?.recordCache(!1),{hit:!1,value:void 0,negative:!1};let f={value:m.value,expiresAt:m.expiresAt,negative:m.negative===!0};return this.publicCache.set(i,f),this.diagnostics?.recordCache(!0),{hit:!0,value:f.value,negative:f.negative}})().finally(()=>{this.publicReads.get(c)===p&&this.publicReads.delete(c)});return this.publicReads.set(c,p),p}async set(e,t,s,a){arguments.length===3&&(a=s,s=t,t=e,e="default"),e=String(e||"default"),this.publicNamespaces.add(e);let i=Math.min(2592e6,Math.max(0,Number(a.ttlMs)||0));if(!i||a.scope==="public"&&a.generation!=null&&a.generation!==this.generation(e))return;let r={value:s,expiresAt:Date.now()+i,negative:a.negative??!1},n=this.storeFor(a.scope,a.sessionScopeId),l=`${e}:${this.namespaceVersion}:${t}`,c=this.storage;if(a.scope!=="public"||!c){n?.set(l,r);return}if(a.generation!=null&&a.generation!==this.generation(e))return;let h=this._publicPrefix(e)+await Dc(t);if(!(a.generation!=null&&a.generation!==this.generation(e)))try{if(a.generation!=null&&a.generation!==this.generation(e))return;if(await c.set(h,{version:this.namespaceVersion,...r,lastUsed:Date.now()}),a.generation!=null&&a.generation!==this.generation(e)){await c.remove(h).catch(()=>{});return}n?.set(l,r),this.publicWritesSincePrune++,this.schedulePublicPrune()}catch{}}schedulePublicPrune(){if(!this.storage||this.publicWritesSincePrune<64||this.pruneScheduled||this.pruneRunning)return this.prunePromise;this.pruneScheduled=!0;let e=d(async()=>{this.pruneScheduled=!1,this.pruneRunning=!0,this.publicWritesSincePrune=0;try{await this.prunePublic()}catch{}finally{this.pruneRunning=!1,this.prunePromise=null,this.schedulePublicPrune()}},"run");return this.prunePromise=Promise.resolve().then(e),this.prunePromise}async waitForPrune(){await this.prunePromise?.catch(()=>{})}async prunePublic(){if(!this.storage)return;let e;try{e=await this.storage.keys()}catch{return}let t=Date.now(),s=[];for(let a of e.filter(i=>i.startsWith("jhs_http_public_cache:v"))){let i=await this.storage.get(a).catch(()=>null);if(!i||i.version!==this.namespaceVersion||!Number.isFinite(i.expiresAt)||i.expiresAt<=t){await this.storage.remove(a).catch(()=>{});continue}s.push({key:a,lastUsed:Number(i.lastUsed)||0})}if(s.length>500){s.sort((a,i)=>a.lastUsed-i.lastUsed);for(let a of s.slice(0,s.length-500))await this.storage.remove(a.key).catch(()=>{})}}async clearNamespace(e){e=String(e||"default"),this.publicGenerations.set(e,this.generation(e)+1);for(let a of this.publicCache.keys())a.startsWith(`${e}:`)&&this.publicCache.delete(a);for(let a of this.publicReads.keys())a.startsWith(`${e}:`)&&this.publicReads.delete(a);await this.waitForPrune();let t=this.storage;if(!t)return;let s;try{s=await t.keys()}catch{return}await Promise.all(s.filter((a=>a.startsWith(this._publicPrefix(e)))).map((a=>t.remove(a).catch(()=>{}))))}async clearAll(){let e=new Set(this.publicNamespaces);for(let t of e)await this.clearNamespace(t);if(this.publicCache.clear(),this.publicReads.clear(),this.sessionCaches.clear(),this.storage)try{let t=this.storage,s=`jhs_http_public_cache:v${this.namespaceVersion}:`,a=await t.keys();await Promise.all(a.filter(i=>i.startsWith(s)).map(i=>t.remove(i).catch(()=>{})))}catch{}}async clearPublic(){return this.clearAll()}async invalidateNamespace(){return this.clearAll()}};d(Hn,"CacheService");var ei=Hn;var qn=class qn{constructor(e,t){this.integrations=e,this.cache=t}profileUrl(e){for(let t of this.integrations.list("person.actress-info")){let s=this.integrations.getAdapter(t.id);if(typeof s.profileUrl=="function")return s.profileUrl(e)}return""}async lookup(e,t={}){let s=String(e).trim()==="三上悠亞"?"三上悠亜":String(e).trim();if(!s)return null;let a=`actress-info:${s}`,i=await this.cache.get("actress-info",a,{scope:"public"});if(i.hit)return i.value;let r=this.cache.generation("actress-info");for(let n of this.integrations.list("person.actress-info")){let l=this.integrations.getAdapter(n.id);if(typeof l.lookup!="function")continue;let c=await l.lookup(s,t);return await this.cache.set("actress-info",a,c,{scope:"public",ttlMs:6048e5,negative:!c,generation:r}),c}return null}async movies(e,t,s={}){let a=this.integrations.list("actor.movies").find(r=>r.id===e);if(!a)return[];let i=this.integrations.getAdapter(a.id);return typeof i?.listActorMovies=="function"?i.listActorMovies(t,s):[]}async collection(e,t,s={}){let a=this.integrations.list("actor.collection").find(r=>r.id===e);if(!a)throw new TypeError(`Actor collection provider is unavailable: ${e}`);let i=this.integrations.getAdapter(a.id);if(typeof i?.listActorCollection!="function")throw new TypeError(`Actor collection is unavailable: ${e}`);return i.listActorCollection(t,s)}async uncollect(e,t,s={}){let a=this.integrations.list("actor.uncollect").find(r=>r.id===e);if(!a)throw new TypeError(`Actor provider is unavailable: ${e}`);let i=this.integrations.getAdapter(a.id);if(typeof i?.uncollectActor!="function")throw new TypeError(`Actor uncollect is unavailable: ${e}`);return i.uncollectActor(t,s)}getAvatarSources(){return Object.freeze(this.integrations.list("person.avatar-search").flatMap(e=>{let t=this.integrations.getAdapter(e.id);return typeof t?.getSources=="function"?t.getSources():[]}))}async searchAvatars(e,t,s={}){for(let a of this.integrations.list("person.avatar-search")){let i=this.integrations.getAdapter(a.id);if(i?.getSources?.().some(r=>r.id===t))return i.searchAvatars(e,{...s,sourceId:t})}return[]}placeholderUrl(e){let t=this.integrations.getAdapter(e);return typeof t?.actorPlaceholderUrl=="function"?t.actorPlaceholderUrl():""}};d(qn,"ActressInfoService");var ti=qn;var Jh=/^(?:authorization|cookie|set-cookie|password|token|secret|credential)$/i;function Wn(o,e=""){return Jh.test(e)?"[redacted]":Array.isArray(o)?o.map(t=>Wn(t)):o&&typeof o=="object"?Object.fromEntries(Object.entries(o).map(([t,s])=>[t,Wn(s,t)])):typeof o!="string"?o:o.replace(/(https?:\/\/)([^\s/@:]+):([^\s/@]+)@/gi,"$1[redacted]@")}d(Wn,"sanitize");var Jn=class Jn{constructor(e={}){this.startedAt=performance.now(),this.activeFeatures=new Set,this.activeContributions=new Set,this.startupTimings=new Map,this.scopes=new Map,this.requestStats={consumers:0,underlying:0},this.cacheStats={hits:0,misses:0},this.providerHealth=new Map,this.errors=[],this.browserMetadata=null,this.legacyPlugins=[],this.legacyPluginDescriptors=[],this.legacyStartup=null,this.legacyTimings=[],this.legacyHttp=e.legacyHttp??null,this.networkController=null}recordStartup(e,t){this.startupTimings.set(e,t)}setFeature(e,t){t?this.activeFeatures.add(e):this.activeFeatures.delete(e)}setContribution(e,t){t?this.activeContributions.add(e):this.activeContributions.delete(e)}updateScope(e){this.scopes.set(e.id,Object.freeze({...e}))}updateRequests(e,t){this.requestStats={consumers:e,underlying:t}}recordCache(e){e?this.cacheStats.hits+=1:this.cacheStats.misses+=1}updateProvider(e,t){this.providerHealth.set(e,Object.freeze({...t}))}recordError(e){let t=e&&typeof e=="object"&&"toJSON"in e&&typeof e.toJSON=="function"?e.toJSON():e instanceof Error?{message:e.message}:e&&typeof e=="object"?{...e}:{message:String(e)};this.errors.push({...Wn(t),timestamp:new Date().toISOString()}),this.errors.length>100&&this.errors.shift()}setBrowserMetadata(e){this.browserMetadata=Object.freeze({...e})}setLegacyRuntime(e,t,s){this.legacyPluginDescriptors=e.map(a=>Object.freeze({...a})),this.legacyPlugins=e.map(a=>a.name),this.legacyStartup=Object.freeze({...t}),this.legacyTimings=s.map(a=>Object.freeze({...a}))}clearErrors(){this.errors=[]}setNetworkController(e){this.networkController=e}getNetworkDiagnostics(){let e=this.networkController??this.legacyHttp;return Object.freeze({circuitBreakers:e?.getCircuitBreakerStatus?.()??{},domainStats:e?.getDomainStats?.()??{}})}resetCircuitBreaker(e){(this.networkController??this.legacyHttp)?.resetCircuitBreaker?.(e)}resetAllCircuitBreakers(){(this.networkController??this.legacyHttp)?.resetAllCircuitBreakers?.()}clearDomainStats(){(this.networkController??this.legacyHttp)?.clearDomainStats?.()}exportSnapshot(){let e=[...this.scopes.values()];return Object.freeze({activeFeatures:[...this.activeFeatures],activeContributions:[...this.activeContributions],startupTimings:Object.fromEntries(this.startupTimings),activeScopes:e,globalListeners:e.filter(t=>t.id==="app:root").reduce((t,s)=>t+Number(s.listeners??0),0),observers:e.reduce((t,s)=>t+Number(s.observers??0),0),requestConsumers:this.requestStats.consumers,underlyingRequests:this.requestStats.underlying,cacheHits:this.cacheStats.hits,cacheMisses:this.cacheStats.misses,providerHealth:Object.fromEntries(this.providerHealth),errors:this.errors.map(t=>({...t})),legacyPlugins:[...this.legacyPlugins],legacyPluginDescriptors:this.legacyPluginDescriptors.map(t=>({...t})),legacyStartup:this.legacyStartup,legacyTimings:this.legacyTimings.map(t=>({...t})),browser:this.browserMetadata,uptimeMs:performance.now()-this.startedAt})}};d(Jn,"DiagnosticsService");var si=Jn;var Kn=class Kn{constructor(e){this.port=He(e,"DialogPort",qe.dialog)}open(e){return this.port.open(e)}close(e){return this.port.close(e)}confirm(e,t,s){return this.port.confirm(e,t,s)}alert(e,t){return this.port.alert(e,t)}};d(Kn,"DialogService");var ai=Kn;var Kh=[/^10\./,/^127\./,/^169\.254\./,/^192\.168\./,/^172\.(?:1[6-9]|2\d|3[01])\./,/^0\./];function Gh(o){let e=o.replace(/^\[|\]$/g,"").toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="::1"?!0:e.includes(":")?e.startsWith("fc")||e.startsWith("fd")||e.startsWith("fe8")||e.startsWith("fe9")||e.startsWith("fea")||e.startsWith("feb"):Kh.some(t=>t.test(e))}d(Gh,"isPrivateLiteral");var Gn=class Gn{constructor(e={}){this.localOrigins=new Set,this.replaceLocalOrigins(e.localOrigins??[])}authorizeLocalOrigin(e){this.localOrigins.add(new URL(e).origin)}replaceLocalOrigins(e){let t=new Set(e.map(s=>new URL(s).origin));this.localOrigins=t}assertAllowed(e,t){let s;try{s=e instanceof URL?e:new URL(e)}catch(a){throw new D("INVALID_URL","外部地址无效",{source:"ExternalUrlPolicy",cause:a})}if(!new Set(["http:","https:"]).has(s.protocol))throw new D("INVALID_URL","仅允许 HTTP/HTTPS 地址",{source:"ExternalUrlPolicy"});if(t.expectedOrigin&&s.origin!==new URL(t.expectedOrigin).origin)throw new D("INVALID_URL","地址离开已声明的精确 origin",{source:"ExternalUrlPolicy"});if(t.trustClass==="builtin-public"){if(s.protocol!=="https:"||!(t.hosts??[]).some(a=>s.hostname===a||s.hostname.endsWith(`.${a}`)))throw new D("INVALID_URL","地址不在 Integration manifest 允许范围",{source:"ExternalUrlPolicy"})}else if(t.trustClass==="custom-public"){if(s.protocol!=="https:"||Gh(s.hostname))throw new D("INVALID_URL","自定义公开来源必须使用公网 HTTPS",{source:"ExternalUrlPolicy"})}else if(t.trustClass==="user-local"){let a=t.expectedOrigin?new URL(t.expectedOrigin).origin:s.origin;if(!this.localOrigins.has(a)||s.origin!==a)throw new D("INVALID_URL","本地来源未获得精确 origin 授权",{source:"ExternalUrlPolicy"})}else throw new D("INVALID_URL","未知 URL trust class",{source:"ExternalUrlPolicy"});return s}assertFinalUrl(e,t){return this.assertAllowed(e,t)}};d(Gn,"ExternalUrlPolicy");var ii=Gn;function hs(o){if(o==null||typeof o!="object")return JSON.stringify(o);if(Array.isArray(o))return`[${o.map(hs).join(",")}]`;let e=o;return`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${hs(e[t])}`).join(",")}}`}d(hs,"stableSerialize");async function Nc(o){let e=new TextEncoder().encode(o),t=await crypto.subtle.digest("SHA-256",e);return[...new Uint8Array(t)].map(s=>s.toString(16).padStart(2,"0")).join("")}d(Nc,"sha256");function Qh(o){let e=new URL(o),t=[...e.searchParams.entries()].sort(([s,a],[i,r])=>s.localeCompare(i)||a.localeCompare(r));e.search="";for(let[s,a]of t)e.searchParams.append(s,a);return e.hash="",e.href}d(Qh,"canonicalizeUrl");function Yh(o,e=0){if(typeof o!="string"||!o)return!1;let t=o.toLowerCase(),s=/<title[^>]*>\s*just a moment(?:\.\.\.)?\s*<\/title>/i.test(o),a=/id=["']challenge-form["']/i.test(o),i=t.includes("cf-chl-")||t.includes("cf_chl_opt"),r=t.includes("/cdn-cgi/challenge-platform/")||t.includes("challenge-platform");return s||a&&(i||r)||[403,429,503].includes(e)&&i&&r}d(Yh,"isCloudflareChallenge");function Zh(o,e){return o<=0?Promise.resolve():new Promise((t,s)=>{let i=setTimeout(d(()=>{e?.removeEventListener("abort",r),t()},"finish"),o),r=d(()=>{clearTimeout(i),s(new D("ABORTED","请求已取消",{source:"HttpService"}))},"onAbort");e?.addEventListener("abort",r,{once:!0}),Promise.resolve().then(()=>e?.aborted&&r())})}d(Zh,"waitForRetry");async function Xh(o){let e=String(o.method??"GET").toUpperCase(),t=Object.fromEntries(Object.entries(o.headers??{}).map(([r,n])=>[r.toLowerCase(),String(n)])),s=[...new Set((o.varyHeaders??[]).map(r=>String(r).toLowerCase()))].sort(),a=Object.fromEntries(s.map(r=>[r,t[r]??""])),i={providerId:String(o.providerId),cacheNamespace:String(o.cacheNamespace??o.providerId??"default"),method:e,canonicalUrl:Qh(o.url),bodyHash:await Nc(hs(o.body??null)),responseType:String(o.responseType??"text"),cacheScope:String(o.cacheScope??"none"),varyHeadersHash:await Nc(hs(a)),sessionScopeId:o.cacheScope==="session"?String(o.sessionScopeId??""):""};if(i.cacheScope==="session"&&!i.sessionScopeId)throw new TypeError("sessionScopeId is required for session requests");return Object.freeze(i)}d(Xh,"createRequestKey");var Qn=class Qn{constructor(e,t,s={}){this.port=e,this.urlPolicy=t,this.diagnostics=s.diagnostics??null,this.cache=s.cache??null,this.settings=s.settings??null,this.inflight=new Map,this.circuitBreakers=new Map,this.domainStats=new Map}async request(e,t){t?.assertActive();let s=String(e.method??"GET").toUpperCase();if(this.settings){let m=this.settings.snapshot();e={...e,timeout:e.timeout??Math.max(1e3,Math.min(12e4,Number(m.httpTimeout)||5e3)),retryCount:e.retryCount??(["GET","HEAD"].includes(s)?Math.max(1,Math.min(10,Math.trunc(Number(m.httpRetryCount)||3)))-1:0),circuitThreshold:e.circuitThreshold??Number(m.circuitBreakerThreshold??3),circuitCooldownMs:e.circuitCooldownMs??Number(m.circuitBreakerCooldown??6e4)}}let a=e.cacheScope??"none";if(s!=="GET"&&a!=="none")throw new TypeError("Mutation requests cannot use generic cache/dedupe");let i=e.urlPolicy,r=this.urlPolicy.assertAllowed(e.url,i);if(s!=="GET"||a==="none")return this.executeUnderlying({...e,method:s,url:r.href,signal:t?.signal},i);let n=String(e.cacheNamespace??e.providerId??"default"),l=await Xh({...e,method:s,url:r.href,cacheScope:a,cacheNamespace:n});t?.assertActive();let c=hs(l),h={scope:a,sessionScopeId:e.sessionScopeId};if(s==="GET"&&a!=="none"&&this.cache){let m=await this.cache.get(n,c,h);if(t?.assertActive(),m.hit)return m.value}let u=a==="public"&&this.cache?this.cache.generation(n):void 0,p=JSON.stringify([c,u??null]),g=this.inflight.get(p);if(!g){let m=new AbortController;g={controller:m,consumers:0,promise:Promise.resolve()},g.promise=this.executeUnderlying({...e,method:s,url:r.href,signal:m.signal},i).then(async f=>(this.cache&&(u==null||u===this.cache.generation(n))&&await this.cache.set(n,c,f,{...h,ttlMs:e.ttlMs??0,negative:e.negative===!0,generation:u}),f)).finally(()=>{this.inflight.get(p)===g&&this.inflight.delete(p),this.updateDiagnostics()}),this.inflight.set(p,g)}return this.consume(g,t)}async executeUnderlying(e,t){let s=new URL(e.url).hostname,a=Math.max(0,Math.min(9,Math.trunc(Number(e.retryCount??0)||0))),i=new Set((e.acceptableStatuses??[]).map(c=>Number(c)).filter(Number.isFinite)),r=this.ensureCircuit(s,e),n=!1,l=null;for(let c=0;c<=a;c+=1){if(e.signal?.aborted){l=new D("ABORTED","请求已取消",{source:e.providerId});break}let h=n?null:this.checkCircuit(s);if(h){l=new D("CIRCUIT_OPEN",`站点 ${s} 已熔断,${h.remaining}秒后重试`,{source:e.providerId,details:{domain:s,remainingSeconds:h.remaining}});break}r.state==="half-open"&&(r.probing=!0,n=!0);try{let u=await this.port.request(e);if(this.urlPolicy.assertFinalUrl(u.finalUrl||e.url,t),Yh(u.responseText??u.data,u.status))throw new D("CF_BLOCKED",`Cloudflare challenge blocked: ${s}`,{source:e.providerId,details:{domain:s,status:Number(u.status)||0,contentLength:String(u.responseText??"").length}});if(i.has(Number(u.status)))return this.recordSuccess(s),u;if(u.status>=400){let p=[401,403].includes(u.status)?"AUTH_REQUIRED":u.status===404?"NOT_FOUND":u.status===429?"RATE_LIMITED":"NETWORK_ERROR";throw new D(p,`HTTP ${u.status}`,{source:e.providerId,retryable:u.status===429||u.status>=500,details:{status:u.status,domain:s}})}return this.recordSuccess(s),u}catch(u){let p=D.from(u,e.providerId);if(this.recordAttempt(s,!0),l=p,!p.retryable||c>=a||p.code==="CF_BLOCKED")break;try{await Zh(Number(e.retryDelayMs??250)*(c+1),e.signal)}catch(g){l=D.from(g,e.providerId);break}}}throw l&&["NETWORK_ERROR","TIMEOUT","CF_BLOCKED"].includes(l.code)&&this.recordBreakerFailure(s,e),n&&(r.probing=!1),this.diagnostics?.recordError(l),l}ensureCircuit(e,t={}){let s=this.circuitBreakers.get(e);return s?(t.circuitCooldownMs!=null&&(s.cooldownMs=Math.max(1e3,Number(t.circuitCooldownMs)||6e4)),t.circuitThreshold!=null&&(s.threshold=Math.max(1,Number(t.circuitThreshold)||3))):(s={state:"closed",failCount:0,openTime:0,cooldownMs:Math.max(1e3,Number(t.circuitCooldownMs??6e4)||6e4),threshold:Math.max(1,Number(t.circuitThreshold??3)||3),probing:!1},this.circuitBreakers.set(e,s)),s}checkCircuit(e){let t=this.circuitBreakers.get(e);if(!t)return null;if(t.state==="open"){let s=Date.now()-t.openTime;if(s<t.cooldownMs)return{state:"open",remaining:Math.ceil((t.cooldownMs-s)/1e3)};t.state="half-open",t.failCount=0,t.probing=!1}return t.state==="half-open"&&t.probing?{state:"half-open",remaining:0}:null}recordSuccess(e){let t=this.circuitBreakers.get(e);t&&(t.state="closed",t.failCount=0,t.probing=!1),this.recordAttempt(e,!1)}recordAttempt(e,t){let s=this.domainStats.get(e)??{count:0,errors:0,lastUsed:0};s.count+=1,s.errors+=t?1:0,s.lastUsed=Date.now(),this.domainStats.set(e,s)}recordBreakerFailure(e,t={}){let s=this.ensureCircuit(e,t);s.failCount+=1,(s.state==="half-open"||s.failCount>=s.threshold)&&(s.state="open",s.openTime=Date.now(),s.probing=!1)}recordFailure(e,t={}){this.recordAttempt(e,!0),this.recordBreakerFailure(e,t)}getCircuitBreakerStatus(){return Object.fromEntries([...this.circuitBreakers].map(([e,t])=>[e,{...t}]))}getDomainStats(){return Object.fromEntries([...this.domainStats].map(([e,t])=>[e,{...t}]))}resetCircuitBreaker(e){this.circuitBreakers.delete(e)}resetAllCircuitBreakers(){this.circuitBreakers.clear()}clearDomainStats(){this.domainStats.clear()}consume(e,t){e.consumers+=1;let s=!1,a={release:d(()=>{s||(s=!0,e.consumers-=1,e.consumers===0&&!this.isSettled(e)&&e.controller.abort(),this.updateDiagnostics())},"release")},i;try{i=t?.ownRequestConsumer(a)}catch(l){throw a.release(),e.promise.catch(()=>{}),l}this.updateDiagnostics();let r=d(()=>{},"removeAbortListener");return(t?Promise.race([e.promise,new Promise((l,c)=>{let h=d(()=>c(new D("ABORTED","LifecycleScope 已释放",{source:t.id})),"onAbort");t.signal.addEventListener("abort",h,{once:!0}),r=d(()=>t.signal.removeEventListener("abort",h),"removeAbortListener")})]):e.promise).finally(()=>{r(),i?.(),a.release()})}isSettled(e){return![...this.inflight.values()].includes(e)}updateDiagnostics(){let e=[...this.inflight.values()].reduce((t,s)=>t+s.consumers,0);this.diagnostics?.updateRequests(e,this.inflight.size)}};d(Qn,"HttpService");var ri=Qn;var Yn=class Yn{constructor(e){this.integrations=e}async resolve(e,t={}){let s=this.integrations.list("image.search-targets")[0];if(!s)throw new D("UNSUPPORTED","以图识图 Integration 不可用",{source:"ImageSearchService"});let a=this.integrations.getAdapter(s.id),i=String(e||"");if(i.startsWith("data:"))i=await a.upload(i,t);else{let r;try{r=new URL(i)}catch(n){throw new D("INVALID_URL","图片 URL 无效",{source:"ImageSearchService",cause:n})}if(!["http:","https:"].includes(r.protocol))throw new D("INVALID_URL","图片 URL 必须使用 HTTP/HTTPS",{source:"ImageSearchService"});i=r.href}return Object.freeze({imageUrl:i,targets:a.createTargets(i)})}};d(Yn,"ImageSearchService");var ni=Yn;var Zn=class Zn{constructor(e){this.port=He(e,"NavigationPort",qe.navigation)}open(e,t){return this.port.open(String(e),t)}assign(e){return this.port.assign(String(e))}replace(e){return this.port.replace(String(e))}};d(Zn,"NavigationService");var oi=Zn;var Xn=class Xn{constructor(e,t=null){this.providers=e,this.integrations=t}async search(e,t={}){let s=[];for(let a of await this.providers.getAvailable("magnet",t))try{let i=await a.search(e,t);this.providers.updateHealth(a.id,{ok:!0}),Array.isArray(i)&&s.push(...i)}catch(i){this.providers.updateHealth(a.id,{ok:!1,error:i instanceof Error?i.message:String(i)})}return s}async listNative(e,t={}){let s=typeof e.providerId=="string"?e.providerId:"javdb",a=(this.integrations?.list("movie.magnets")??[]).find(r=>r.id===s);if(!a)return[];let i=this.integrations?.getAdapter(a.id);return typeof i?.listMagnets=="function"?i.listMagnets(e,t):[]}getBuiltInSources(){return(this.integrations?.list("magnet.search")??[]).flatMap(e=>{let t=this.integrations?.getAdapter(e.id);return typeof t?.getSources=="function"?t.getSources():[]})}async searchSource(e,t,s={}){for(let a of this.integrations?.list("magnet.search")??[]){let i=this.integrations?.getAdapter(a.id);if(i?.getSources?.().some(r=>r.id===e))return i.search(e,t,s)}return[]}getSourceTargetUrl(e,t,s={}){for(let a of this.integrations?.list("magnet.search")??[]){let i=this.integrations?.getAdapter(a.id);if(i?.getSources?.().some(r=>r.id===e))return i.targetUrl(e,t,s)}return null}assess(e){return yc(e)}};d(Xn,"MagnetService");var li=Xn;var eo=class eo{constructor(e=null){this.integrations=e}normalize(e){return ee(e)}firstValid(...e){for(let t of e){let s=this.normalize(t);if(s)return s}return null}async resolve(e,t={}){let s=this.normalize(e.carNum);if(!s)return null;let a=this.integrations?.list("movie.search")??[],i=typeof e.providerId=="string"?e.providerId:null,r=i?a.filter(n=>n.id===i):[...a].sort((n,l)=>+(l.id==="javdb")-+(n.id==="javdb"));for(let n of r){let l=this.integrations?.getAdapter(n.id);if(typeof l?.resolveMovie!="function")continue;let c=await l.resolveMovie({...e,carNum:s},t);if(c)return c}return Object.freeze({...e,carNum:s})}async detail(e,t={}){let s=this.integrations?.list("movie.detail")??[],a=typeof e.providerId=="string"?e.providerId:e.movieId?"javdb":null,i=a?s.filter(r=>r.id===a):s;for(let r of i){let n=this.integrations?.getAdapter(r.id);if(typeof n?.getDetail=="function")return n.getDetail(e,t)}return null}async rankings(e={}){for(let t of this.integrations?.list("movie.ranking")??[]){let s=this.integrations?.getAdapter(t.id);if(typeof s?.listRankings=="function")return s.listRankings(e)}return[]}async catalog(e,t={},s={}){let a=(this.integrations?.list("movie.catalog")??[]).find(r=>r.id===e);if(!a)throw new TypeError(`Movie catalog provider is unavailable: ${e}`);let i=this.integrations?.getAdapter(a.id);if(typeof i?.listCatalog!="function")throw new TypeError(`Movie catalog operation is unavailable: ${e}`);return i.listCatalog(t,s)}async people(e,t,s={}){let a=(this.integrations?.list("movie.credits")??[]).find(r=>r.id===e);if(!a)return Object.freeze({actors:Object.freeze([]),seller:null});let i=this.integrations?.getAdapter(a.id);return typeof i?.getPeople=="function"?i.getPeople(t,s):Object.freeze({actors:Object.freeze([]),seller:null})}async images(e,t,s={}){let a=(this.integrations?.list("movie.images")??[]).find(r=>r.id===e);if(!a)return[];let i=this.integrations?.getAdapter(a.id);return typeof i?.getImages=="function"?i.getImages(t,s):[]}async preview(e,t,s={}){let a=(this.integrations?.list("movie.preview")??[]).find(r=>r.id===e);if(!a)throw new TypeError(`Movie preview provider is unavailable: ${e}`);let i=this.integrations?.getAdapter(a.id);if(typeof i?.getPreviewForMovie!="function")throw new TypeError(`Movie preview operation is unavailable: ${e}`);return i.getPreviewForMovie(t,s)}sourceUrls(e,t){return Object.freeze(t.map(s=>{try{let a=this.integrations?.getAdapter(s),i=typeof a?.detailUrl=="function"?a.detailUrl(e):null;return i?Object.freeze({providerId:s,url:i}):null}catch{return null}}).filter(Boolean))}searchUrl(e,t){try{let s=this.integrations?.getAdapter(e);return typeof s?.searchUrl=="function"?s.searchUrl(t):null}catch{return null}}providerOrigin(e){try{let t=this.integrations?.getAdapter(e);return typeof t?.origin=="function"?t.origin():null}catch{return null}}matchesProviderUrl(e,t){try{let s=this.integrations?.getAdapter(e);return typeof s?.matchesUrl=="function"&&s.matchesUrl(t)}catch{return!1}}externalSites(e={}){let t=(this.integrations?.list("movie.external-sites")??[])[0],s=t&&this.integrations?.getAdapter(t.id);return typeof s?.getSites=="function"?s.getSites(e):[]}externalSiteOrigin(e,t={}){return this.externalSites(t).find(s=>s.id===e)?.baseUrl||""}async searchExternalSite(e,t,s={}){let a=(this.integrations?.list("movie.external-sites")??[])[0],i=a&&this.integrations?.getAdapter(a.id);return typeof i?.searchSite!="function"?Object.freeze({searchUrl:"",matches:Object.freeze([])}):i.searchSite(e,t,s)}externalNavigationLinks(){let e=(this.integrations?.list("navigation.external")??[])[0],t=e&&this.integrations?.getAdapter(e.id);return typeof t?.getNavigationLinks=="function"?t.getNavigationLinks():[]}};d(eo,"MovieIdentityService");var ci=eo;var to=class to{constructor(e,t){this.providers=e,this.integrations=t}submitWithIntegration(e,t,s={}){let a=this.integrations.getAdapter(e);if(typeof a.submit!="function")throw new TypeError(`Integration ${e} does not support offline submission`);return a.submit(t,s)}checkAccount(e,t={}){let s=this.integrations.getAdapter(e);if(typeof s.checkAccount!="function")throw new TypeError(`Integration ${e} does not support account checks`);return s.checkAccount(t)}searchFiles(e,t,s={}){let a=this.integrations.getAdapter(e);if(typeof a.searchFiles!="function")throw new TypeError(`Integration ${e} does not support file search`);return a.searchFiles(t,s)}renameFile(e,t,s,a={}){let i=this.integrations.getAdapter(e);if(typeof i.renameFile!="function")throw new TypeError(`Integration ${e} does not support file rename`);return i.renameFile(t,s,a)}getPlayUrl(e,t){let s=this.integrations.getAdapter(e);return typeof s.getPlayUrl=="function"?s.getPlayUrl(t):null}getIntegrationHomeUrl(e){let t=this.integrations.getAdapter(e);if(typeof t.homeUrl!="string")throw new TypeError(`Integration ${e} does not declare a home URL`);return t.homeUrl}async submit(e,t={}){let s=await this.providers.getAvailable("offline",t),a=[];for(let i of s)try{let r=await i.submit(e,t);return this.providers.updateHealth(i.id,{ok:!0}),r}catch(r){a.push(r),this.providers.updateHealth(i.id,{ok:!1,error:r instanceof Error?r.message:String(r)})}throw new AggregateError(a,s.length?"所有离线 Provider 均失败":"没有可用的离线 Provider")}};d(to,"OfflineService");var di=to;var so=class so extends EventTarget{constructor(e){super(),this.window=e.windowRuntime??window,this.scope=e.scope,this.settings=e.settings??null,this.coarseQuery=this.window.matchMedia("(any-pointer: coarse)"),this.profile=this.calculate(),this.started=!1}calculate(){let e=this.window.innerWidth,t=(this.settings?.snapshot()??{}).mobileMode;if(t==="on")return"compact";if(t==="off")return e>=1200?"wide":"regular";let s=Math.min(this.window.innerWidth,this.window.innerHeight);return e<=767||this.coarseQuery.matches&&s<=480?"compact":e>=1200?"wide":"regular"}start(){if(this.started)return;this.started=!0;let e=d(()=>{let t=this.calculate();if(t===this.profile)return;let s=this.profile;this.profile=t,this.dispatchEvent(new CustomEvent("profile.changed",{detail:Object.freeze({previous:s,profile:t})}))},"update");this.scope.listen(this.window,"resize",e,{passive:!0}),this.scope.listen(this.window,"orientationchange",e,{passive:!0}),this.scope.listen(this.coarseQuery,"change",e),this.settings&&this.scope.listen(this.settings,"settings.changed",e),e()}current(){return this.profile}};d(so,"ProfileService");var hi=so;var ao=class ao{constructor(e){this.integrations=e}async list(e,t={}){for(let s of this.integrations.list("movie.related")){let a=this.integrations.getAdapter(s.id);if(typeof a.listRelated=="function")return a.listRelated(e,t)}return[]}};d(ao,"RelatedService");var ui=ao;var io=class io{constructor(e){this.integrations=e}async list(e,t={}){for(let s of this.integrations.list("movie.reviews")){let a=this.integrations.getAdapter(s.id);if(typeof a.listReviews=="function")return a.listReviews(e,t)}return[]}};d(io,"ReviewService");var pi=io;var Ut="javstore",Lc=new Set([Ut]),ro=class ro{constructor(e,t=null){this.providers=e,this.integrations=t}isEnabled(e){return e?.enableLoadScreenShot!=="no"}parseScreenshotProviders(e){if(Array.isArray(e))return e;if(typeof e=="string")try{let t=JSON.parse(e);return Array.isArray(t)?t:[]}catch{return[]}return[]}getScreenshotSettings(e){return{mode:e?.screenshotMode==="manual"?"manual":"auto",providers:this.parseScreenshotProviders(e?.screenshotProviders)}}getEnabledProviders(e){let t=this.parseScreenshotProviders(e?.screenshotProviders);return Ls.map(s=>({...s,...t.find(a=>a?.id===s.id)||{}})).filter(s=>s.enabled!==!1).sort((s,a)=>Number(s.priority??100)-Number(a.priority??100))}async resolve(e,t={}){if(t.settings&&!t.allowWhenDisabled&&!this.isEnabled(t.settings))return null;let s=t.settings?this.getEnabledProviders(t.settings):null,a=s?new Set(s.map(i=>i.id)):null;if(s&&!s.length)return null;if(t.providerId){if(a&&!a.has(t.providerId))return null;let i=this.providers.get?.(t.providerId);return i?i.enabled===!1||!i.capabilities?.includes("screenshot")?null:this.resolveFromProvider(i,e,t):this.resolveIntegration(t.providerId,e,t)}for(let i of await this.providers.getAvailable("screenshot",t)){if(a&&!a.has(i.id))continue;let r=await this.resolveFromProvider(i,e,t);if(r)return r}return a&&!a.has(Ut)?null:this.resolveIntegration(Ut,e,t)}async resolveFromProvider(e,t,s){try{let a=await e.resolve(t,s);if(this.providers.updateHealth(e.id,{ok:!0}),a)return a}catch(a){this.providers.updateHealth(e.id,{ok:!1,error:a instanceof Error?a.message:String(a)})}return null}async resolveIntegration(e,t,s){if(!Lc.has(e)||s.settings&&!s.allowWhenDisabled&&!this.isEnabled(s.settings))return null;let a=this.integrations?.list("movie.images")?.find(n=>n.id===e);if(!a)return null;let i=this.integrations?.getAdapter(a.id);if(typeof i?.getImages!="function")return null;let r=await i.getImages(t,s);return Array.isArray(r)&&r.length?r:null}getSearchUrl(e,t=null){if(!Lc.has(Ut)||t&&!this.isEnabled(t)||t&&!this.getEnabledProviders(t).some(s=>s.id===Ut))return null;for(let s of this.integrations?.list("movie.images")??[]){if(s.id!==Ut)continue;let a=this.integrations?.getAdapter(s.id);if(typeof a?.getSearchUrl=="function")return a.getSearchUrl(e)}return null}};d(ro,"ScreenshotService");var gi=ro;var no="translation_cache_v2",oo="translation:v1:",lo=class lo{constructor(e,t=null){this.integrations=e,this.storage=t,this.memoryCache=new Map,this.inflight=new Map,this.legacyCache=null,this.hydrationPromise=null,this.cacheGeneration=0,this.persistTimer=null}cacheKey(e,t,s){return`${oo}${t}:${s}:${e}`}readLegacyCache(){if(this.legacyCache!==null)return this.legacyCache;try{let e=JSON.parse(this.storage?.getLocal?.("jhs_translate")||"{}");this.legacyCache=e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{this.legacyCache={}}return this.legacyCache}hydrate(){if(this.hydrationPromise)return this.hydrationPromise;let e=this.cacheGeneration;return this.hydrationPromise=(async()=>{if(!this.storage)return;let t=this.storage,s=[],a=!1;try{let i=await t.get(no);for(let[n,l]of Object.entries(i?.entries||{}))e===this.cacheGeneration&&typeof l?.value=="string"&&Number(l.expiresAt)>Date.now()?this.memoryCache.set(n,{value:l.value,expiresAt:Number(l.expiresAt),lastUsed:Number(l.lastUsed)||Date.now()}):a=!0;let r=await t.keys();for(let n of r.filter((l=>l.startsWith(oo)))){let l=await t.get(n);e===this.cacheGeneration&&typeof l?.value=="string"&&Number(l.expiresAt)>Date.now()&&this.memoryCache.set(n,{value:l.value,expiresAt:Number(l.expiresAt),lastUsed:Number(l.lastUsed)||Date.now()}),s.push(n),a=!0}e===this.cacheGeneration&&(this.prune()||a)&&this.persistNow(e).then((()=>Promise.all(s.map((n=>t.remove(n)))))).catch((()=>{}))}catch{}})()}prune(){let e=Date.now(),t=!1;for(let[a,i]of this.memoryCache)i.expiresAt<=e&&(this.memoryCache.delete(a),t=!0);let s=this.memoryCache.size-1e3;if(s>0)for(let[a]of[...this.memoryCache].sort(((i,r)=>i[1].lastUsed-r[1].lastUsed)).slice(0,s))this.memoryCache.delete(a),t=!0;return t}schedulePersist(){if(!this.storage||this.persistTimer!==null)return;let e=this.cacheGeneration;this.persistTimer=setTimeout((()=>{this.persistTimer=null,this.persistNow(e).catch((()=>{}))}),300)}async persistNow(e=this.cacheGeneration){!this.storage||e!==this.cacheGeneration||(this.prune(),await this.storage.set(no,{version:2,entries:Object.fromEntries(this.memoryCache)}))}remember(e,t,s=this.cacheGeneration){if(s===this.cacheGeneration){let a=Date.now();this.memoryCache.set(e,{value:t,expiresAt:a+2592e6,lastUsed:a}),this.prune(),this.schedulePersist()}return t}async clearCache(){if(this.cacheGeneration+=1,this.persistTimer!==null&&clearTimeout(this.persistTimer),this.persistTimer=null,this.memoryCache.clear(),this.legacyCache={},this.storage?.removeLocal?.("jhs_translate"),this.storage){let e=this.storage;try{let t=await e.keys();await e.remove(no),await Promise.all(t.filter((s=>s.startsWith(oo))).map((s=>e.remove(s))))}catch{}}this.hydrationPromise=Promise.resolve()}async inspectCache(){return await this.hydrate(),this.prune(),{version:2,size:this.memoryCache.size,entries:Object.fromEntries(this.memoryCache)}}async translate(e,t={}){let s=t.sourceLanguage??"ja",a=t.targetLanguage??"zh-CN",i=this.cacheKey(e,s,a),r=this.cacheGeneration,n=this.memoryCache.get(i);if(n?.expiresAt>Date.now())return n.lastUsed=Date.now(),this.schedulePersist(),n.value;n&&this.memoryCache.delete(i);let l=t.cacheAlias&&this.readLegacyCache()[t.cacheAlias];if(s==="ja"&&a==="zh-CN"&&typeof l=="string"&&l)return this.remember(i,l,r);if(await this.hydrate(),n=this.memoryCache.get(i),n?.expiresAt>Date.now())return n.lastUsed=Date.now(),this.schedulePersist(),n.value;let c=this.inflight.get(i);if(c)return c;let h=(async()=>{let u=this.integrations.list("text.translate")[0],p=u&&this.integrations.getAdapter(u.id);if(typeof p?.translate!="function")throw new TypeError(u?`Translation operation is unavailable: ${u.id}`:"Translation provider is unavailable");let g=await p.translate(e,{...t,sourceLanguage:s,targetLanguage:a});return typeof g=="string"?this.remember(i,g,r):g})().finally((()=>this.inflight.delete(i)));return this.inflight.set(i,h),h}};d(lo,"TranslationService");var mi=lo;var co=class co{constructor(e){this.integrations=e}async search(e,t,s={}){let a=this.integrations.list("subtitle.search").find(r=>r.id===e);if(!a)return[];let i=this.integrations.getAdapter(a.id);return typeof i?.search=="function"?i.search(t,s):[]}async download(e,t,s={}){let a=this.integrations.list("subtitle.download").find(r=>r.id===e);if(!a)throw new TypeError(`Subtitle provider is unavailable: ${e}`);let i=this.integrations.getAdapter(a.id);if(typeof i?.download!="function")throw new TypeError(`Subtitle download is unavailable: ${e}`);return i.download(t,s)}};d(co,"SubtitleService");var fi=co;var ho=class ho{constructor(e){this.integrations=e}async login(e,t,s={}){let a=this.integrations.list("account.login").find(r=>r.id===e);if(!a)throw new TypeError(`Account provider is unavailable: ${e}`);let i=this.integrations.getAdapter(a.id);if(typeof i?.login!="function")throw new TypeError(`Account login is unavailable: ${e}`);return i.login(t,s)}};d(ho,"AccountService");var vi=ho;var uo=class uo extends EventTarget{constructor(e,t={}){super(),this.storage=e,this.validators=t.validators??{},this.normalizers=t.normalizers??{},this.afterPersist=t.afterPersist??null,this.snapshotValue=Object.freeze({}),this.writeChain=Promise.resolve()}async load(e="setting"){return this._enqueue(()=>this._withSettingLock(()=>this._readSnapshot(e)))}async refresh(e="setting"){return this._enqueue(()=>this._withSettingLock(async()=>{let t=this.snapshotValue,s=await this._readSnapshot(e),i=[...new Set([...Object.keys(t),...Object.keys(s)])].filter(r=>t[r]!==s[r]);return i.length&&this.dispatchEvent(new CustomEvent("settings.changed",{detail:Object.freeze({name:i.length===1?i[0]:null,value:void 0,names:Object.freeze([...i]),snapshot:s})})),s}))}snapshot(){return this.snapshotValue}waitForIdle(){return this.writeChain}async set(e,t,s="setting"){return this.update(a=>{a[e]=t},s)}async patch(e,t="setting"){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError("Settings patch must be an object");return this.update(s=>{Object.assign(s,e)},t)}async replace(e,t="setting"){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError("Settings replacement must be an object");return this.update(s=>{for(let a of Object.keys(s))delete s[a];Object.assign(s,e)},t)}async unset(e,t="setting"){let s=Array.isArray(e)?e:[e];if(!s.every(a=>typeof a=="string"&&a))throw new TypeError("unset names must be non-empty strings");return this.update(a=>{for(let i of s)delete a[i]},t)}async update(e,t="setting"){if(typeof e!="function")throw new TypeError("Settings update mutator must be a function");return this._enqueue(()=>this._withSettingLock(async()=>{let s=await this.storage.get(t),a=s&&typeof s=="object"&&!Array.isArray(s)?s:{},i={...a},r=e(i);if(r&&typeof r=="object"&&typeof r.then=="function")throw new TypeError("Settings update mutator must be synchronous");for(let[h,u]of Object.entries(this.normalizers))Object.prototype.hasOwnProperty.call(i,h)&&typeof u=="function"&&(i[h]=u(i[h]));let n=Object.freeze(i),l=[...new Set([...Object.keys(a),...Object.keys(n)])].filter(h=>a[h]!==n[h]);for(let h of l){let u=this.validators[h];if(u&&Object.prototype.hasOwnProperty.call(n,h)&&!u(n[h]))throw new TypeError(`Invalid setting: ${h}`)}let c=Object.freeze([...l]);if(!c.length)return this.snapshotValue=n,n;if(await this.storage.set(t,n),this.snapshotValue=n,c.length){let h=c.length===1?c[0]:null;this.dispatchEvent(new CustomEvent("settings.changed",{detail:Object.freeze({name:h,value:h?n[h]:void 0,names:c,snapshot:n})}))}try{await this.afterPersist?.(n,c)}catch(h){typeof globalThis.clog?.error=="function"&&globalThis.clog.error("[settings] afterPersist failed (ignored)",h)}return n}))}async _readSnapshot(e){let t=await this.storage.get(e);return this.snapshotValue=Object.freeze(t&&typeof t=="object"&&!Array.isArray(t)?{...t}:{}),this.snapshotValue}_enqueue(e){let t=this.writeChain.then(e);return this.writeChain=t.then(()=>{},()=>{}),t}async _withSettingLock(e){let t=globalThis.navigator?.locks;return t?.request?t.request("jhs_setting_lock",()=>e()):e()}};d(uo,"SettingsService");var bi=uo;var po=class po{constructor(e){this.port=He(e,"StoragePort",qe.storage)}get(e){return this.port.get(e)}set(e,t){return this.port.set(e,t)}remove(e){return this.port.remove(e)}keys(){return this.port.keys()}getLocal(e){return this.port.getLocal(e)}setLocal(e,t){return this.port.setLocal(e,t)}removeLocal(e){return this.port.removeLocal(e)}getValue(e,t){return this.port.getValue(e,t)}setValue(e,t){return this.port.setValue(e,t)}removeValue(e){return this.port.removeValue(e)}};d(po,"StorageService");var wi=po;var mo=class mo{constructor(e,t,s,a){this.http=e,this.baseUrl=new URL(t.endsWith("/")?t:`${t}/`),this.username=s,this.password=a,this.folderName=null}authHeaders(){let e=new TextEncoder().encode(`${this.username}:${this.password}`),t="";for(let s of e)t+=String.fromCharCode(s);return{Authorization:`Basic ${btoa(t)}`,Depth:"1"}}async request(e,t,s={},a,i={}){let r=new URL(t.replace(/^\/+/,""),this.baseUrl),n=await this.http.request({providerId:"webdav",method:e,url:r.href,headers:{...this.authHeaders(),...s},body:a,responseType:"text",cacheScope:"none",...i,urlPolicy:{trustClass:"user-local",expectedOrigin:this.baseUrl.origin}});return n.data??n.responseText??""}async ensureFolder(e){await this.request("MKCOL",e,{},void 0,{acceptableStatuses:[405,409]})}async backup(e,t,s){await this.ensureFolder(e),await this.request("PUT",`${e}/${t}`,{"Content-Type":"text/plain"},s)}async getFileList(e){let t=String(await this.request("PROPFIND",e,{"Content-Type":"application/xml"},'<?xml version="1.0"?><d:propfind xmlns:d="DAV:"><d:prop><d:displayname/><d:getcontentlength/><d:creationdate/><d:getlastmodified/><d:iscollection/></d:prop></d:propfind>')),s=new DOMParser().parseFromString(t,"text/xml").getElementsByTagNameNS("DAV:","response"),a=[];for(let i=1;i<s.length;i++){let r=s[i],n=d(u=>r.getElementsByTagNameNS("DAV:",u)[0]?.textContent||"","node"),l=n("href"),c=n("displayname")||decodeURIComponent(l.replace(/\/$/,"").split("/").pop()||""),h=n("getcontentlength");h!=="0"&&a.push({fileId:c,name:c,size:Number(h),createTime:n("creationdate")||n("getlastmodified")})}return a.reverse()}async deleteFile(e){await this.request("DELETE",`${this.folderName}/${encodeURI(e)}`,{"Cache-Control":"no-cache"})}async getBackupList(e){return this.folderName=e,await this.ensureFolder(e),this.getFileList(e)}async getFileContent(e){return String(await this.request("GET",`${this.folderName}/${e}`,{Accept:"application/octet-stream"}))}};d(mo,"WebDavClient");var go=mo,fo=class fo{constructor(e,t=void 0,s=void 0){this.http=e,this.credential=t,this.settings=s}createClient(e){return new go(this.http,e.url,e.username,e.password)}async getProfile(){let e=this.settings?.snapshot?.()||{},t=this.credential?await this.credential.get("jhs_webdav_password"):"";return{url:String(e.webDavUrl||""),username:String(e.webDavUsername||""),password:t}}async saveProfile(e={}){if(!this.settings||!this.credential)throw new Error("WebDAV 配置服务未初始化");let t=await this.getProfile(),s=Object.prototype.hasOwnProperty.call(e,"password");s&&await this.credential.set("jhs_webdav_password",String(e.password||""));try{await this.settings.update(a=>{for(let i of["url","username"])Object.prototype.hasOwnProperty.call(e,i)&&(a[i==="url"?"webDavUrl":"webDavUsername"]=String(e[i]||""))})}catch(a){throw s&&await this.credential.set("jhs_webdav_password",t.password),a}return this.getProfile()}};d(fo,"WebDavService");var yi=fo;var Pe=Object.freeze({installationSecret:"jhs_credential_install_secret",webDavPassword:"jhs_webdav_password",javdbToken:"jhs_appAuthorization"}),vo=class vo{constructor(e,t=globalThis.localStorage){this.storage=e,this.legacyStorage=t,this.cleanupValues=new Map,this.cleanupTargets=new Map}async installationSecret(){return String(await this.storage.getValue(Pe.installationSecret,"")||this.legacyStorage?.getItem?.(Pe.installationSecret)||"x7k9p3")}generateSecret(){return btoa(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(32))))}async decodeLegacy(e,t){let s=e.replace(/^AES:/,""),a=e.startsWith("AES:");try{a||(a=/^[A-Za-z0-9+/]+={0,2}$/.test(s)&&atob(s).length>=28)}catch{}return a?Ze(s,t||await this.installationSecret()):e}async decode(e){if(e&&typeof e=="object"){if(e.schema===2&&typeof e.id=="string"&&e.deleted===!0&&!Object.hasOwn(e,"secret")&&!Object.hasOwn(e,"ciphertext"))return"";if(e.schema!==2||typeof e.id!="string"||typeof e.secret!="string"||typeof e.ciphertext!="string")throw new Error("凭证格式无效");return Ze(e.ciphertext,e.secret,!1)}let t=String(e||"");return t?this.decodeLegacy(t):""}async get(e){try{return await this.decode(await this.storage.getValue(e,""))}catch{return""}}async set(e,t){let s=String(t||"");if(!s)return await this.remove(e),"";let a=this.generateSecret(),i={schema:2,id:crypto.randomUUID(),secret:a,ciphertext:await Zt(s,a)};await this.storage.setValue(e,i);let r=await this.storage.getValue(e,"");if(JSON.stringify(r)!==JSON.stringify(i)||await this.decode(r)!==s)throw new Error("凭证存储回读校验失败");return s}async remove(e){let t={schema:2,id:crypto.randomUUID(),deleted:!0};await this.storage.setValue(e,t);let s=await this.storage.getValue(e,"");if(JSON.stringify(s)!==JSON.stringify(t)||await this.decode(s)!=="")throw new Error("凭证删除回读校验失败")}async migrateLegacy(e,t={}){let s=this.legacyStorage?.getItem?.(Pe.installationSecret)||"",a=d(p=>this.decodeLegacy(p,s),"decodeLegacy"),i=[],r={},n=[],l=e?.snapshot?.()||{},c=this.legacyStorage?.getItem?.(Pe.javdbToken)||"",h=String(l.webDavPassword||"");for(let[p,g]of[[Pe.javdbToken,c],[Pe.webDavPassword,h]]){let m;try{m=await this.storage.getValue(p,"")}catch{i.push({key:p,code:"CREDENTIAL_MIGRATION_READ_FAILED"});continue}if(!m&&!g||m&&typeof m=="object"&&(p===Pe.javdbToken||!g||m.deleted===!0))continue;let f,v;try{f=m?await this.decode(m):await a(g),m&&typeof m=="string"&&p===Pe.javdbToken&&(f=await a(f)),v=g?await a(g):""}catch{i.push({key:p,code:"LEGACY_CREDENTIAL_UNREADABLE"});continue}try{(!m||typeof m=="string")&&await this.set(p,f)}catch{i.push({key:p,code:"CREDENTIAL_MIGRATION_WRITE_FAILED"});continue}g&&f===v&&await this.get(p)===f&&(this.cleanupTargets.set(p,f),p===Pe.webDavPassword&&(r.webDavPassword=g))}let u=await this.validateLegacyCleanup({settingKeys:Object.keys(r),settingValues:r,pageKeys:n});return t.deferCleanup||(u.settingKeys.length&&e?.update&&await e.update(p=>{for(let g of u.settingKeys)p[g]===r[g]&&delete p[g]}),await this.cleanupLegacyPageStorage(u.pageKeys,e)),{migrated:!!(c||h||s),cleanup:u,issues:i}}async validateLegacyCleanup(e){let t=[];if(!globalThis.navigator?.locks?.request)return{...e,settingKeys:t};for(let s of e.settingKeys||[])s==="webDavPassword"&&this.cleanupTargets.has(Pe.webDavPassword)&&await this.get(Pe.webDavPassword)===this.cleanupTargets.get(Pe.webDavPassword)&&t.push(s);return{...e,settingKeys:t}}async cleanupLegacyPageStorage(e=[],t=null){this.cleanupValues.clear(),this.cleanupTargets.clear()}};d(vo,"CredentialService");var ji=vo;var bo=class bo{constructor(e){this.port=He(e,"StylePort",qe.style)}register(e,t){return this.port.register(e,t)}remove(e){return this.port.remove(e)}};d(bo,"StyleRegistry");var Si=bo;var wo=class wo{constructor(){this.owners=new Map,this.handlers=new Map,this.activateOwner=null,this.ownerEnabled=new Map}setOwnerEnabled(e,t){if(!this.owners.has(e))throw new Error(`Unknown command owner: ${e}`);this.ownerEnabled.set(e,t)}isAvailable(e){return this.owners.has(e)&&this.ownerEnabled.get(e)!==!1}setActivator(e){this.activateOwner=e}registerOwner(e,t){let s=this.owners.get(e);if(s&&s!==t)throw new Error(`Duplicate command owner: ${e}`);this.owners.set(e,t)}registerHandler(e,t,s){if(this.owners.get(e)!==s)throw new Error(`Feature ${s} does not own command ${e}`);if(this.handlers.has(e))throw new Error(`Duplicate command handler: ${e}`);this.handlers.set(e,t)}async execute(e,...t){let s=this.owners.get(e);if(!s)throw new Error(`Unknown command: ${e}`);if(!this.handlers.has(e)){if(!this.activateOwner)throw new Error("Command activator is not configured");await this.activateOwner(s)}let a=this.handlers.get(e);if(!a)throw new Error(`Feature ${s} did not register ${e}`);return a(...t)}};d(wo,"CommandRegistry");var xi=wo;var yo=class yo{constructor(e=null){this.values=new Map,this.diagnostics=e}register(e,t){if(typeof e!="symbol")throw new TypeError("Dependency token must be a symbol");if(this.values.has(e)){let s=new D("DUPLICATE_TOKEN",`Duplicate dependency token: ${String(e)}`,{source:"DependencyContainer"});throw this.diagnostics?.recordError?.(s),s}return this.values.set(e,t),this}resolveDeclared(e){let t=Object.create(null),s=new Set;for(let a of e){if(s.has(a)){let i=new D("DUPLICATE_TOKEN",`Duplicate declared dependency: ${String(a)}`,{source:"DependencyContainer"});throw this.diagnostics?.recordError?.(i),i}if(s.add(a),!this.values.has(a)){let i=new D("MISSING_DEPENDENCY",`Missing declared dependency: ${String(a)}`,{source:"DependencyContainer"});throw this.diagnostics?.recordError?.(i),i}Object.defineProperty(t,a,{value:this.values.get(a),enumerable:!0})}return Object.freeze(t),new Proxy(t,{get:d((a,i,r)=>{if((typeof i=="symbol"?Symbol.keyFor(i):null)?.startsWith("jhs.")&&!s.has(i)){let l=new D("UNDECLARED_DEPENDENCY",`Undeclared dependency access: ${String(i)}`,{source:"DependencyContainer"});throw this.diagnostics?.recordError?.(l),l}return Reflect.get(a,i,r)},"get")})}};d(yo,"DependencyContainer");var ki=yo;var jo=class jo{constructor(e){this.container=e.container,this.commands=e.commands,this.diagnostics=e.diagnostics,this.disabled=new Set(_t(e.disabled)),this.site=e.site??"unknown",this.route=e.route??"unknown",this.manifests=new Map,this.contributionOwners=new Map,this.contributionManifests=new Map,this.activations=new Map,this.contributionScopes=new Map,this.commands.setActivator(t=>this.activate(t).then(()=>{}))}setContributionManifests(e){this.contributionManifests=new Map(e.map(t=>[t.id,t]))}activeSurfaces(){return this.route==="list"?new Set(["global","list","list-page","list-card"]):this.route==="detail"||this.route==="owned-detail"?new Set(["global","detail","detail-page",this.route]):new Set(["global",this.route])}register(e){let t=Ie(e);if(this.manifests.has(t.id))throw new Error(`Duplicate feature: ${t.id}`);for(let s of t.contributes){let a=this.contributionOwners.get(s);if(a)throw new Error(`Duplicate contribution ownership: ${s} (${a}, ${t.id})`)}this.manifests.set(t.id,t);for(let s of t.contributes)this.contributionOwners.set(s,t.id);for(let s of t.providesCommands)this.commands.registerOwner(s,t.id),this.commands.setOwnerEnabled(s,this.isEligible(t))}isEligible(e){return!(e.kind!=="system"&&this.disabled.has(e.id)||e.sites.length&&!e.sites.includes(this.site)||e.routes.length&&!e.routes.includes(this.route))}isContributionEnabled(e,t,s){let a=this.manifests.get(e);if(!a||a.sites.length&&!a.sites.includes(this.site)||!a.contributes.includes(t)||a.kind!=="system"&&this.disabled.has(a.id))return!1;if(a.kind==="system")return!0;let i=this.contributionManifests.get(t);return i?.routes?.length&&!i.routes.includes(this.route)||i?.surfaces?.length&&!i.surfaces.some(r=>this.activeSurfaces().has(r))?!1:!this.disabled.has(t)&&!this.disabled.has(s)}isFeatureDisableable(e){let t=this.manifests.get(e);if(!t)throw new Error(`Unknown feature: ${e}`);return t.kind!=="system"&&t.disableable!==!1}resolveDeclaredDependencies(e){return this.container.resolveDeclared(e)}async getScope(e){return(await this.activate(e)).scope}getContributionScope(e,t,s){if(!this.isContributionEnabled(e,t,s))return Promise.reject(new Error(`Contribution is disabled or ineligible: ${t}`));let a=this.contributionScopes.get(t);return(!a||a.disposed)&&(a=new te(`contribution:${t}`,{onChange:d(i=>this.diagnostics.updateScope(i),"onChange")}),this.contributionScopes.set(t,a)),Promise.resolve(a)}activate(e){let t=this.activations.get(e);if(t)return t;let s=this.manifests.get(e);if(!s)return Promise.reject(new Error(`Unknown feature: ${e}`));if(!this.isEligible(s))return Promise.reject(new Error(`Feature is disabled or ineligible: ${e}`));let a=this.activateManifest(s);return this.activations.set(e,a),a.catch(()=>this.activations.delete(e)),a}async activateManifest(e){let t=performance.now(),s=new te(`feature:${e.id}`,{onChange:d(a=>this.diagnostics.updateScope(a),"onChange")});try{let a=this.container.resolveDeclared(e.requires),i=Object.freeze(e.contributes.filter(n=>!this.disabled.has(n))),r=await e.activate(a,Object.freeze({scope:s,enabledContributions:i,route:this.route}));for(let n of e.providesCommands){let l=r?.commands?.[n];if(typeof l!="function")throw new Error(`Feature ${e.id} did not provide command ${n}`);this.commands.registerHandler(n,l,e.id)}return this.diagnostics.setFeature(e.id,!0),i.forEach(n=>this.diagnostics.setContribution(n,!0)),this.diagnostics.recordStartup(e.id,performance.now()-t),Object.freeze({manifest:e,scope:s,enabledContributions:i,dispose:d(()=>{r?.dispose?.();for(let n of e.contributes){let l=this.contributionScopes.get(n);l&&(l.dispose(),this.contributionScopes.delete(n))}s.dispose(),this.diagnostics.setFeature(e.id,!1),i.forEach(n=>this.diagnostics.setContribution(n,!1)),this.activations.delete(e.id)},"dispose")})}catch(a){throw s.dispose(),this.diagnostics.recordError(a),a}}async start(){for(let e of this.manifests.values())this.isEligible(e)&&(e.startup==="eager"?await this.activate(e.id):e.startup==="idle"&&(globalThis.requestIdleCallback??(s=>setTimeout(s,0)))(()=>{this.activate(e.id).catch(()=>{})}))}getActiveFeatureIds(){return[...this.activations.keys()]}};d(jo,"FeatureRuntime");var Ci=jo;var So=class So{constructor(e=null){this.providers=new Map,this.health=new Map,this.diagnostics=e}register(e){if(!e||typeof e.id!="string"||!Array.isArray(e.capabilities))throw new TypeError("Provider requires id and capabilities");if(this.providers.has(e.id))throw new Error(`Duplicate provider: ${e.id}`);return this.providers.set(e.id,Object.freeze({priority:0,enabled:!0,...e})),e}get(e){return this.providers.get(e)??null}list(e){return[...this.providers.values()].filter(t=>t.enabled!==!1&&t.capabilities.includes(e)).sort((t,s)=>Number(s.priority??0)-Number(t.priority??0))}async getAvailable(e,t){let s=[];for(let a of this.list(e))(typeof a.isAvailable!="function"||await a.isAvailable(t))&&s.push(a);return s}updateHealth(e,t){if(!this.providers.has(e))throw new Error(`Unknown provider: ${e}`);this.health.set(e,Object.freeze({...t,updatedAt:Date.now()})),this.diagnostics?.updateProvider(e,t)}getHealth(e){return this.health.get(e)??null}};d(So,"ProviderRegistry");var _i=So;var Bc=Object.freeze({none:{cacheScope:"none",ttlMs:0},"public-1d":{cacheScope:"public",ttlMs:864e5},"public-5m":{cacheScope:"public",ttlMs:3e5},"public-7d":{cacheScope:"public",ttlMs:6048e5},"external-detail-v1":{cacheScope:"public",ttlMs:6048e5,cacheNamespace:"external-detail-v1"},"screenshot-7d":{cacheScope:"public",ttlMs:6048e5,cacheNamespace:"screenshot"},"session-configured":{cacheScope:"session",ttlMs:36e5},"source-configured":{cacheScope:"public",ttlMs:216e5,cacheNamespace:"source",getOnly:!0}});function eu(o,e,t={}){let s=o.cachePolicy==="none"?"none":o.cachePolicy?.[e],a={...Bc[s]||Bc.none};return a.getOnly&&String(t.method||"GET").toUpperCase()!=="GET"?Object.freeze({cacheScope:"none",ttlMs:0}):(delete a.getOnly,s==="session-configured"&&(a.sessionScopeId=String(t.sessionScopeId||`${o.id}-session`)),Object.freeze(a))}d(eu,"resolveIntegrationCachePolicy");function tu(o,e){let t=d((a,i={})=>eu(e,a,i),"policyFor"),s=d(a=>{if(a.capability&&e.capabilities.includes(a.capability))return a.capability;if(e.capabilities.length===1)return e.capabilities[0];let i=String(a.providerId||"");return e.capabilities.find(r=>i.includes(String(r).split(".").pop()||""))||e.capabilities[0]},"inferCapability");return Object.freeze({request(a,i,r){let n=typeof a=="string",l=n?a:s(a),c=n?i||{}:a||{},h=n?r:i;if(!e.capabilities.includes(l))throw new TypeError(`Integration ${e.id} does not declare capability ${l}`);let u=t(l,c),p={...c,...u};return delete p.capability,o.request(p,h)}})}d(tu,"createIntegrationRequestFacade");var xo=class xo{constructor(e,t){this.container=e,this.diagnostics=t,this.manifests=new Map,this.adapters=new Map}register(e){try{let t=W(e);if(this.manifests.has(t.id))throw new Error(`Duplicate integration: ${t.id}`);this.manifests.set(t.id,t)}catch(t){throw this.diagnostics.recordError(t),t}}list(e){return[...this.manifests.values()].filter(t=>t.capabilities.includes(e))}getAdapter(e){let t=this.adapters.get(e);if(t)return t;let s=this.manifests.get(e);if(!s)throw new Error(`Unknown integration: ${e}`);try{let a=this.container.resolveDeclared(s.requires),i=Object.create(null);for(let l of s.requires)Object.defineProperty(i,l,{value:l===y.http?tu(a[l],s):a[l],enumerable:!0});Object.freeze(i);let r=s.createClient(i),n=s.createAdapter(r,i);return this.adapters.set(e,n),n}catch(a){throw this.diagnostics.recordError(a),a}}};d(xo,"IntegrationRegistry");var $i=xo;var su=new Set(["live","nextNavigation","manual"]),au=new Set(["boolean","select","number","text","password","json"]),iu=new Set(["full","quick"]);function ru(o){if(!o||typeof o!="object"||Array.isArray(o))throw new TypeError("Setting descriptor must be an object");let e=String(o.key??o.id??"");if(!e)throw new TypeError("Setting descriptor requires key (or id)");if(!o.owner)throw new TypeError(`Setting descriptor requires owner: ${e}`);let t=String(o.type??(o.defaultValue!=null&&typeof o.defaultValue=="boolean"?"boolean":"text"));if(!au.has(t))throw new TypeError(`Setting descriptor has invalid type: ${e} (${t})`);let s=o.effect??"live";if(!su.has(s))throw new TypeError(`Setting descriptor has invalid effect: ${e} (${s})`);let a=Array.isArray(o.surfaces)?[...new Set(o.surfaces)].filter(i=>iu.has(i)):[];if(o.surfaces!=null&&!Array.isArray(o.surfaces))throw new TypeError(`Setting descriptor surfaces must be an array: ${e}`);return Object.freeze({...o,key:e,owner:String(o.owner),label:String(o.label??o.key??e),description:o.description==null?"":String(o.description),type:t,effect:s,surfaces:Object.freeze(a),validate:typeof o.validate=="function"?o.validate:null,normalize:typeof o.normalize=="function"?o.normalize:null,contribution:o.contribution==null?void 0:String(o.contribution)})}d(ru,"normalizeSettingDescriptor");var ko=class ko{constructor(){this.descriptors=new Map}register(e){let t=ru(e);if(this.descriptors.has(t.key))throw new Error(`Duplicate setting descriptor: ${t.key}`);return this.descriptors.set(t.key,t),this}list(e={}){let t=e.surfaces;return[...this.descriptors.values()].filter(s=>!(s.contribution&&e.disabledContributions?.has(s.contribution)||t&&t.length&&!s.surfaces.includes(t[0])&&!t.some(a=>s.surfaces.includes(a))))}get(e){return this.descriptors.get(e)??null}isValid(e,t){let s=this.descriptors.get(e);return s&&typeof s.validate=="function"?s.validate(t)===!0:!0}normalizers(){return Object.fromEntries([...this.descriptors.values()].filter(e=>typeof e.normalize=="function").map(e=>[e.key,e.normalize]))}};d(ko,"SettingsRegistry");var Ti=ko;function Mc(o){let e={type:"boolean",effect:"live"},t="yes",s="no",a=d((r,n,l,c={})=>o.register({key:r,owner:n,label:l,...e,defaultValue:c.defaultValue??t,...c}),"toggle"),i=d((r,n,l,c)=>{let h=Number(r);return Number.isFinite(h)?Math.min(c,Math.max(l,Math.round(h))):n},"normalizeInteger");a("enableScreenSvg","ScreenshotFeature","列表长缩略图",{description:"在列表卡片上显示长缩略图按钮;手动点击仍遵守截图来源白名单。",surfaces:["full"],defaultValue:t}),a("enableLoadScreenShot","ScreenshotFeature","长缩略图",{description:"在详情页与 FC2 页面自动加载长缩略图及对应截图来源请求。",surfaces:["full","quick"]}),a("enablePreviewVideo","PreviewVideoFeature","预览视频",{description:"预览视频总开关。关闭后 JavDB/JavBus 详情与列表卡片的预览入口、播放器与 DMM 请求全部消失。",surfaces:["full","quick"]}),a("enableLoadPreviewVideo","PreviewVideoFeature","DMM 高画质增强",{description:"解析更高画质的 DMM 预览视频;关闭后仍可使用宿主原生预览,但不发起 DMM 请求。",surfaces:["full","quick"],indent:!0}),a("enableVideoSvg","CoverButtonFeature","卡片播放视频",{description:"在列表卡片上显示播放视频按钮。",surfaces:["full"]}),a("enableHandleSvg","CoverButtonFeature","卡片鉴定处理",{description:"在列表卡片上显示鉴定处理菜单。",surfaces:["full"]}),a("enableSiteSvg","CoverButtonFeature","卡片第三方网站",{description:"在列表卡片上显示第三方网站菜单。",surfaces:["full"]}),a("enableCopySvg","CoverButtonFeature","卡片复制",{description:"在列表卡片上显示复制菜单。",surfaces:["full"]}),a("autoPage","AutoPageFeature","瀑布流",{description:"连续加载列表;启用后普通列表只支持默认排序。",surfaces:["full","quick"]}),a("translateTitle","TranslateFeature","标题翻译",{description:"翻译列表和详情页标题。",surfaces:["full","quick"]}),a("hoverBigImg","ListImageFeature","悬浮大图",{description:"鼠标悬停封面时显示大图。",surfaces:["full","quick"],defaultValue:s}),o.register({key:"defaultQuickFilterTab",owner:"ListPageFeature",label:"列表默认筛选",description:"进入列表页时默认选中的筛选标签,修改后下次进入列表生效。",type:"select",defaultValue:"waitCheck",effect:"nextNavigation",surfaces:["full"],options:Object.freeze([{value:"all",label:"全部"},{value:"waitCheck",label:"待鉴定"},{value:"favorite",label:"收藏"},{value:"hasDown",label:"下载"},{value:"hasWatch",label:"已看"},{value:"blockedItems",label:"屏蔽项"}])}),a("enableLoadReview","ReviewFeature","评论",{description:"在详情页与 FC2 页面加载评论;显式关闭 no 时保持关闭。",surfaces:["full","quick"]}),a("enableLoadOtherSite","OtherSiteFeature","外部站点",{description:"在详情页提供第三方站点入口。",surfaces:["full","quick"]}),a("enableLoadActressInfo","ActressInfoFeature","演员信息",{description:"在详情页与演员页展示演员资料。",surfaces:["full","quick"]}),a("enableMagnetsFilter","MagnetFeature","磁力质量过滤",{description:"在资源列表中过滤低质量磁力。",surfaces:["full"]}),a("needClosePage","WorkflowFeature","鉴定后立即关闭",{description:"完成鉴定后关闭当前详情窗口。",surfaces:["full","quick"]}),a("enableVerticalModel","LayoutFeature","竖图模式",{description:"使用竖图比例的列表卡片布局。",surfaces:["full","quick"],defaultValue:s}),o.register({key:"mobileMode",owner:"LayoutFeature",label:"移动模式",type:"select",defaultValue:"auto",effect:"live",surfaces:["full"],options:Object.freeze([{value:"auto",label:"自动检测"},{value:"on",label:"强制开启"},{value:"off",label:"强制关闭"}])}),o.register({key:"themeMode",owner:"ThemeFeature",label:"主题",type:"select",defaultValue:"light",effect:"live",surfaces:["full"],options:Object.freeze([{value:"light",label:"浅色"},{value:"dark",label:"深色"},{value:"auto",label:"跟随系统"}])}),o.register({key:"containerColumns",owner:"LayoutFeature",label:"列表列数",type:"number",defaultValue:5,effect:"live",surfaces:["full"]}),o.register({key:"containerWidth",owner:"LayoutFeature",label:"列表宽度",type:"number",defaultValue:100,effect:"live",surfaces:["full"]}),o.register({key:"screenshotMode",owner:"ScreenshotFeature",label:"截图来源模式",type:"select",defaultValue:"auto",effect:"manual",surfaces:["full"],options:Object.freeze([{value:"auto",label:"自动选择"},{value:"manual",label:"手动选择"}])}),o.register({key:"screenshotProviders",owner:"ScreenshotFeature",label:"截图来源",type:"json",defaultValue:[],effect:"manual",surfaces:["full"]}),o.register({key:"enableClog",owner:"CoreFeature",label:"日志",type:"select",defaultValue:t,effect:"live",surfaces:["full"],options:Object.freeze([{value:t,label:"开启"},{value:s,label:"关闭"}])}),o.register({key:"videoMuted",owner:"PreviewVideoFeature",label:"视频默认静音",type:"boolean",defaultValue:!0,effect:"live",surfaces:[]}),a("enable123Offline","OfflineFeature","123 云盘离线",{description:"支持 Magnet,需要先在 123 云盘页面同步授权。",surfaces:["full"],section:"cloud",defaultValue:!0,normalize:d(r=>be(r,!1),"normalize")}),a("enable115Offline","OfflineFeature","115 离线下载",{description:"支持 Magnet 与 ED2K。",surfaces:["full"],section:"cloud",defaultValue:!1,normalize:d(r=>be(r,!1),"normalize")}),o.register({key:"offlineProviderMode",owner:"OfflineFeature",label:"默认服务",description:"选择离线提交时优先使用的服务。",type:"select",defaultValue:"ask",effect:"live",surfaces:["full"],section:"cloud",options:Object.freeze([{value:"ask",label:"每次询问"},{value:"123",label:"优先 123"},{value:"115",label:"优先 115"}]),normalize:d(r=>["ask","123","115"].includes(String(r))?String(r):"ask","normalize")}),a("enable115Match","OfflineFeature","115 文件匹配",{description:"根据当前番号查找网盘中已存在的视频。",surfaces:["full"],section:"cloud",defaultValue:!1,normalize:d(r=>be(r,!1),"normalize")}),a("enable115LoginRedirect","OfflineFeature","未登录时提供登录入口",{description:"提交失败时显示 115 登录地址。",surfaces:["full"],section:"cloud",defaultValue:!1,normalize:d(r=>be(r,!1),"normalize")}),o.register({key:"oneOneFiveConcurrency",owner:"OfflineFeature",label:"匹配并发数",description:"控制 115 文件匹配的并发请求数,范围 1–10。",type:"number",defaultValue:4,effect:"live",surfaces:["full"],section:"cloud",min:1,max:10,step:1,normalize:d(r=>i(r,4,1,10),"normalize")}),o.register({key:"oneOneFiveCacheMinutes",owner:"OfflineFeature",label:"匹配缓存(分钟)",description:"设置 115 匹配结果缓存时间,范围 1–1440 分钟。",type:"number",defaultValue:60,effect:"live",surfaces:["full"],section:"cloud",min:1,max:1440,step:1,normalize:d(r=>i(r,60,1,1440),"normalize")})}d(Mc,"registerDefaultSettings");function Oc(o){let e=new si({legacyHttp:o.legacyHttp}),t=new te("app:root",{onChange:d(De=>e.updateScope(De),"onChange")}),s=new ki(e),a=new Ga,i=new Xa(o.gmRequest),r=new Ya(o.storageForage,o.localStorage,o.gmGetValue,o.gmSetValue,o.gmDeleteValue),n=new Za(o.layer),l=new Qa,c=new ii({localOrigins:o.localOrigins}),h=new oi(a),u=new wi(r),p=new ei({diagnostics:e,storage:u}),g=new ai(n),m=new Si(l),f=new Ti;Mc(f);let v=new bi(u,{afterPersist:d(async(De,U)=>{o.legacyStorage?.invalidateSettingCache?.(),await o.eventBus?.emit?.("settings-changed",{changedNames:U,source:"service"})},"afterPersist"),normalizers:f.normalizers()}),b=new ri(i,c,{diagnostics:e,cache:p,settings:v});e.setNetworkController(b);let w=new ji(u,o.localStorage),S=new yi(b,w,v);t.listen(v,"settings.changed",De=>{if(!(De.detail?.names??[]).includes("trustedLocalOrigins"))return;let X=v.snapshot().trustedLocalOrigins;c.replaceLocalOrigins(Array.isArray(X)?X:[])}),o.eventBus&&t.addCleanup(o.eventBus.on("settings-changed",async(De,U)=>{let X=U.originId!==o.eventBus.originId,ie=U.originId===o.eventBus.originId&&U.payload?.source==="legacy";!X&&!ie||(o.legacyStorage?.invalidateSettingCache?.(),await v.refresh())})),typeof window<"u"&&t.listen(window,"pageshow",async()=>{o.legacyStorage?.invalidateSettingCache?.(),await v.refresh()});let j=new hi({scope:t,settings:v}),k=new xi,x=new _i(e),_=new $i(s,e),E=new ci(_),L=new ti(_,p),M=new ni(_),P=new pi(_),z=new ui(_),O=new li(x,_),H=new gi(x,_),Q=new mi(_,u),se=new fi(_),ge=new vi(_),Ee=new di(x,_);s.register(Z.navigation,a).register(Z.http,i).register(Z.storage,r).register(Z.dialog,n).register(Z.style,l).register(y.diagnostics,e).register(y.urlPolicy,c).register(y.navigation,h).register(y.http,b).register(y.storage,u).register(y.webdav,S).register(y.credential,w).register(y.dialog,g).register(y.settings,v).register(y.cache,p).register(y.profile,j).register(y.state,o.stateService).register(y.movie,E).register(y.actressInfo,L).register(y.imageSearch,M).register(y.review,P).register(y.related,z).register(y.magnet,O).register(y.screenshot,H).register(y.offline,Ee).register(y.translation,Q).register(y.subtitle,se).register(y.account,ge).register(Qe.command,k).register(Qe.provider,x).register(Qe.integration,_).register(Qe.settings,f),o.hostAdapter&&s.register(Z.host,o.hostAdapter),o.hostAdapters?.javdb&&s.register(Z.javdbHost,o.hostAdapters.javdb),o.hostAdapters?.javbus&&s.register(Z.javbusHost,o.hostAdapters.javbus);let nt=new Ci({container:s,commands:k,diagnostics:e,disabled:o.disabled,site:o.site,route:o.route});return s.register(Qe.feature,nt),Object.freeze({rootScope:t,container:s,ports:Object.freeze({navigationPort:a,httpPort:i,storagePort:r,dialogPort:n,stylePort:l}),services:Object.freeze({diagnostics:e,urlPolicy:c,navigation:h,http:b,storage:u,webdav:S,credential:w,dialog:g,styles:m,settings:v,cache:p,profile:j,state:o.stateService,movie:E,actressInfo:L,imageSearch:M,review:P,related:z,magnet:O,screenshot:H,translation:Q,subtitle:se,account:ge,offline:Ee}),registries:Object.freeze({commands:k,providers:x,integrations:_,settings:f,features:nt})})}d(Oc,"createAppContext");var Uk=Object.freeze({censored:"censored",uncensored:"uncensored"});function Ai(o){if(typeof o.carNum!="string"||!o.carNum)throw new TypeError("MovieRef.carNum is required");return Object.freeze({...o})}d(Ai,"defineMovieRef");function Ft(o){if(typeof o.carNum!="string"||!o.carNum)throw new TypeError("MovieDetail.carNum is required");return Object.freeze({...o})}d(Ft,"defineMovieDetail");function Co(o){if(typeof o=="string")return new DOMParser().parseFromString(o,"text/html");if(typeof o?.querySelectorAll=="function")return o;let e=o?.[0]??o?.get?.(0);if(typeof e?.querySelectorAll=="function")return e;throw new TypeError("123AV document is invalid")}d(Co,"resolveDocument");function _o(o,e="https://123av.com"){let t=new Map;if(typeof o?.find!="function"){for(let a of Co(o).querySelectorAll(".card")){let i=a.querySelector('a.card__link[href*="/cn/v/fc2-ppv-"]'),r=i?.getAttribute("href"),n=i?.textContent?.trim()??"",l=n.match(/FC2-PPV-(\d+)/i);if(!r||!l)continue;let c=`FC2-${l[1]}`,h=new URL(r,e);h.hash="",t.set(c,{imgSrc:a.querySelector("img.card__img[src]")?.getAttribute("src")||"",carNum:c,href:h.href,title:n.replace(/^FC2-PPV-\d+\s*[—–-]\s*/i,"").trim(),preview:a.querySelector(".card__poster[data-preview]")?.getAttribute("data-preview")||null})}return[...t.values()]}let s=globalThis.jQuery??globalThis.$??o.constructor;return o.find(".card").each(((a,i)=>{let r=s(i),n=r.find('a.card__link[href*="/cn/v/fc2-ppv-"]').first(),l=n.attr("href"),c=n.text().trim(),h=c.match(/FC2-PPV-(\d+)/i);if(!l||!h)return;let u=`FC2-${h[1]}`,p=new URL(l,e);p.hash="",t.set(u,{imgSrc:r.find("img.card__img[src]").first().attr("src")||"",carNum:u,href:p.href,title:c.replace(/^FC2-PPV-\d+\s*[—–-]\s*/i,"").trim(),preview:r.find(".card__poster[data-preview]").first().attr("data-preview")||null})})),[...t.values()]}d(_o,"parse123AvCards");function zc(o){let e=new Map;return o.flat().forEach((t=>e.set(t.carNum,t))),[...e.values()]}d(zc,"merge123AvCards");function Uc(o,e="https://123av.com"){if(typeof o?.find!="function"){let i=Co(o),r=i.querySelector('a[rel="last"]')?.getAttribute("href");if(r){let c=Number.parseInt(new URL(r,e).searchParams.get("page")??"",10);if(Number.isFinite(c))return c}let n=Number.parseInt(i.querySelector("input.pager__input[max]")?.getAttribute("max")??"",10);if(Number.isFinite(n))return n;let l=i.querySelector(".pager__total")?.textContent?.match(/(\d[\d,]*)/);return l?Number.parseInt(l[1].replaceAll(",",""),10):null}let t=o.find('a[rel="last"]').first().attr("href");if(t){let i=Number.parseInt(new URL(t,e).searchParams.get("page")??"",10);if(Number.isFinite(i))return i}let s=Number.parseInt(o.find("input.pager__input[max]").first().attr("max"),10);if(Number.isFinite(s))return s;let a=o.find(".pager__total").first().text().match(/(\d[\d,]*)/);return a?Number.parseInt(a[1].replaceAll(",",""),10):null}d(Uc,"parse123AvSourceMaxPage");function Fc(o,e){let t=new URL(e).pathname.match(/fc2-ppv-(\d+)/i),s=t?t[1]:null,a=typeof o?.find=="function"?null:Co(o),i=a?a.querySelector("h1.watch__title")?.textContent?.trim()??"":o.find("h1.watch__title").first().text().trim(),r=s?i.replace(new RegExp(`^FC2-PPV-${s}\\s*[—–-]\\s*`,"i"),"").trim():i,l=(a?a.body?.textContent??"":o.find("body").text()).match(/发布日期\s*(\d{4}-\d{2}-\d{2})/)?.[1]||"";return{id:s,publishDate:l,title:r,moviePoster:null}}d(Fc,"parse123AvVideoInfo");var Pi="https://123av.com";function nu(o){try{let e=new URL(String(o||Pi));return e.protocol!=="https:"?Pi:e.origin}catch{return Pi}}d(nu,"normalizeBaseOrigin");function ou(o,e=null){let t=d(()=>nu(e?.snapshot().av123Url),"baseOrigin"),s=d((a,i,r="movie.detail")=>{let n=new URL(a).origin,l=n===Pi;return o.request({providerId:"av123",capability:r,method:"GET",url:a,responseType:"text",requestOptions:{cookiePartition:{topLevelSite:n}},urlPolicy:l?{trustClass:"builtin-public",hosts:["123av.com"],expectedOrigin:n}:{trustClass:"custom-public",expectedOrigin:n}},i)},"request");return Object.freeze({contracts:["MovieRef","MovieDetail"],origin:t,searchUrl(a){let i=ee(a?.carNum);return i?`${t()}/cn/search?keyword=${encodeURIComponent(i)}`:null},detailUrl(a){let i=ee(a.carNum)?.match(/^FC2-(\d+)$/)?.[1];return a.url?new URL(a.url).href:i?`${t()}/cn/v/fc2-ppv-${i}`:null},matchesUrl(a){try{let i=new URL(a);return i.origin===t()||/^\/cn\/v\/fc2-ppv-\d+\/?$/i.test(i.pathname)}catch{return!1}},async listCatalog(a={},i={}){let r=Math.max(1,Number(a.page)||1),n=String(a.keyword||"").trim(),c=(n?[r]:[r*2-1,r*2]).map(m=>n?`${t()}/cn/search?keyword=${encodeURIComponent(n)}&page=${m}`:`${t()}/cn/makers/fc2?page=${m}`),h=await Promise.all(c.map(m=>s(m,i.scope,n?"movie.search":"movie.catalog"))),u=h.map((m,f)=>_o(m.data,m.finalUrl||c[f])),p=zc(u).map(m=>Object.freeze({carNum:m.carNum,title:m.title,url:m.href,imageUrl:m.imgSrc?new URL(m.imgSrc,t()).href:null,previewUrl:m.preview?new URL(m.preview,t()).href:null,providerId:"av123"})),g=h.length?Uc(h[0].data,h[0].finalUrl||c[0]):null;return Object.freeze({items:p,maxPage:g?n?g:Math.ceil(g/2):null})},async resolveMovie(a,i={}){let r=ee(a.carNum);if(!r)return null;let n=this.searchUrl({carNum:r});if(!n)return null;let l=await s(n,i.scope,"movie.search"),c=_o(l.data,l.finalUrl||n).find(h=>ee(h.carNum)===r);return c?Ai({carNum:r,url:c.href,providerId:"av123"}):null},async getDetail(a,i={}){let r=ee(a.carNum),n=r?.match(/^FC2-(\d+)$/)?.[1];if(!r||!a.url&&!n)throw new TypeError("123AV movie reference is invalid");let l=new URL(a.url||`${t()}/cn/v/fc2-ppv-${n}`).href,c=await s(l,i.scope),h=Fc(c.data,c.finalUrl||l);if(!h.title)throw new TypeError("123AV detail is malformed");return Ft({carNum:r,title:h.title,releaseDate:h.publishDate||null,url:c.finalUrl||l,providerId:"av123"})}})}d(ou,"create123AvAdapter");var Vc=W({id:"av123",trustClass:"builtin-public",hosts:["123av.com"],capabilities:["movie.search","movie.detail","movie.catalog"],requires:[y.http,y.settings],createClient:d(o=>Object.freeze({http:o[y.http],settings:o[y.settings]}),"createClient"),createAdapter:d(o=>ou(o.http,o.settings),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.search":"public-7d","movie.detail":xe.externalDetail,"movie.catalog":"public-7d"},quality:"silver"});function lu(o){if(typeof o=="string")return new DOMParser().parseFromString(o,"text/html");if(typeof o?.querySelector=="function")return o;let e=o?.[0]??o?.get?.(0);if(typeof e?.querySelector=="function")return e;throw new TypeError("DMM preview document is invalid")}d(lu,"resolveDocument");function Hc(o,e){let t=lu(o),s=t.querySelector("[data-video-url]")?.getAttribute("data-video-url")??t.querySelector("video source[src]")?.getAttribute("src");if(!s)throw new TypeError("DMM preview URL is missing");let a=new URL(s,e);if(a.protocol!=="https:")throw new TypeError("DMM preview must use HTTPS");return Object.freeze({url:a.href})}d(Hc,"parseDmmPreview");function qc(o,e,t){if(o?.result?.result_count===0&&!Array.isArray(o.result.items))return Object.freeze([]);if(!o||typeof o!="object"||!o.result||!Array.isArray(o.result.items))throw new we("dmm","INVALID_RESPONSE","DMM API 返回结构无效");let s=e.toLowerCase(),a=s.replace(/-/g,""),i=t.toLowerCase().replace(/-/g,"");return Object.freeze(o.result.items.flatMap(r=>{let n=String(r?.content_id??""),l=String(r?.maker_product??"");return!n.toLowerCase().includes(i)&&l.toLowerCase()!==s&&!n.toLowerCase().includes(a)?[]:[Object.freeze({serviceCode:String(r.service_code??""),floorCode:String(r.floor_code??""),contentId:n,pageUrl:new URL(String(r.URL)).href})]}).slice(0,2))}d(qc,"parseDmmItemCandidates");function Wc(o,e){if(typeof o!="string")throw new we("dmm","PARSE_ERROR","解析播放页内容失败, 非文本内容",{url:e});if(o.includes("このサービスはお住まいの地域からは"))throw new we("dmm","REGION_BLOCKED","DMM 预览源不可用,请将 DMM 域名分流到日本 IP",{url:e});let t=o.match(/const\s+args\s+=\s+(.*);/);if(!t)throw new we("dmm","PARSE_ERROR","未在脚本中找到 const args = ... 变量",{url:e});let s;try{({bitrates:s}=JSON.parse(t[1]))}catch(i){throw new we("dmm","PARSE_ERROR",`解析播放器脚本 JSON 失败: ${i instanceof Error?i.message:String(i)}`,{cause:i,url:e})}if(!Array.isArray(s))throw new we("dmm","PARSE_ERROR","解析画质链接失败: bitrates 字段不是一个数组或不存在",{url:e});let a={};for(let i of s){let r=i?.src;if(typeof r!="string"||!r.endsWith(".mp4"))continue;let n=new URL(r,e);if(n.protocol!=="https:")continue;let l=n.pathname.match(/\/([^/]+)\.mp4$/)?.[1];l&&!a[l]&&(a[l]=n.href)}if(Object.keys(a).length===0)throw new we("dmm","PARSE_ERROR","未找到匹配要求的预览画质视频",{url:e});return Object.freeze(a)}d(Wc,"parseDmmPlayerSources");var $o=["dmm.co.jp","dmm.com"];function cu(o){return Object.freeze({contracts:["MoviePreview"],searchUrl(e){return`https://www.dmm.co.jp/search/=/searchstr=${encodeURIComponent(String(e.carNum??""))}`},async getPreview(e,t={}){let s=new URL(e.url),a=await o.request({providerId:"dmm",capability:"movie.preview",method:"GET",url:s.href,responseType:"text",urlPolicy:{trustClass:"builtin-public",hosts:["dmm.co.jp"]}},t.scope);return Hc(a.data,a.finalUrl||s.href)},async getPreviewForMovie(e,t={}){let s=String(e.carNum),a=s.replace(/-/g,""),i=[s.replace("-","00"),s,a],r=this.searchUrl(e),n=[],l=null,c=!1;for(let p of i){let g=`https://api.dmm.com/affiliate/v3/ItemList?${new URLSearchParams({api_id:"UrwskPfkqQ0DuVry2gYL",affiliate_id:"10278-996",output:"json",site:"FANZA",sort:"match",keyword:p})}`;try{let m=await o.request({providerId:"dmm",capability:"movie.preview",method:"GET",url:g,responseType:"json",urlPolicy:{trustClass:"builtin-public",hosts:$o}},t.scope);if(n=qc(m.data,s,p),c=!0,n.length)break}catch(m){l=m;break}}if(!n.length){if(!c&&l)throw l;return Object.freeze({sources:null,pageUrl:r,searchUrl:r,matchType:"none"})}let h=n.map(async p=>{let g=`https://www.dmm.co.jp/service/digitalapi/-/html5_player/=/cid=${encodeURIComponent(p.contentId)}/mtype=AhRVShI_/service=${encodeURIComponent(p.serviceCode)}/floor=${encodeURIComponent(p.floorCode)}/mode=/`,m=await o.request({providerId:"dmm",capability:"movie.preview",method:"GET",url:g,responseType:"text",headers:{"accept-language":"ja-JP,ja;q=0.9",Cookie:"age_check_done=1"},urlPolicy:{trustClass:"builtin-public",hosts:$o}},t.scope);return Wc(m.data,m.finalUrl||g)}),u;try{u=await Promise.any(h)}catch(p){let g=p instanceof AggregateError?p.errors:[p];throw g.find(m=>m?.code==="REGION_BLOCKED")??g[0]??p}return Object.freeze({sources:u,pageUrl:n.length>1?r:n[0].pageUrl,searchUrl:r,matchType:n.length>1?"multiple":"single"})}})}d(cu,"createDmmAdapter");var Jc=W({id:"dmm",trustClass:"builtin-public",hosts:$o,capabilities:["movie.preview"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>cu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.preview":"none"},quality:"silver"});var Kc=Object.freeze([Object.freeze({id:"javTrailersBtn",name:"javTrailers",settingKey:"javTrailersUrl",defaultBaseUrl:"https://javtrailers.com",itemSelector:".videos-list .video-link",textSelector:"p.card-text",hrefSelector:null,searchPath:d(o=>`/search/${o}`,"searchPath")}),Object.freeze({id:"jableBtn",name:"jable",settingKey:"jableUrl",defaultBaseUrl:"https://jable.tv",itemSelector:"#list_videos_videos_list_search_result .detail .title a",textSelector:null,hrefSelector:null,searchPath:d(o=>`/search/${o}/`,"searchPath")}),Object.freeze({id:"avgleBtn",name:"avgle",settingKey:"avgleUrl",defaultBaseUrl:"https://jav.rs",itemSelector:".text-secondary",textSelector:null,hrefSelector:null,searchPath:d(o=>`/vod/search.html?wd=${o}`,"searchPath")}),Object.freeze({id:"missAvBtn",name:"missAv",settingKey:"missAvUrl",defaultBaseUrl:"https://missav.live",itemSelector:".text-secondary",textSelector:null,hrefSelector:null,searchPath:d(o=>`/search/${o}`,"searchPath")}),Object.freeze({id:"supJavBtn",name:"supJav",settingKey:"supJavUrl",defaultBaseUrl:"https://supjav.com",itemSelector:".posts post",textSelector:null,hrefSelector:null,titleAttribute:!0,searchPath:d(o=>`/?s=${o}`,"searchPath")}),Object.freeze({id:"javDbBtn",name:"javDb",settingKey:"javDbUrl",defaultBaseUrl:"https://javdb.com",itemSelector:".movie-list .item",textSelector:".video-title",hrefSelector:"a",searchPath:d(o=>`/search?q=${o}`,"searchPath")}),Object.freeze({id:"javBusBtn",name:"javBus",settingKey:"javBusUrl",defaultBaseUrl:"https://www.javbus.com",itemSelector:".container h3",textSelector:null,hrefSelector:null,directDetail:!0,searchPath:d(o=>`/${o}`,"searchPath")})]);function Gc(o,e){let t=new URL(e[o.settingKey]||o.defaultBaseUrl).origin;return Object.freeze({id:o.id,name:o.name,baseUrl:t,searchUrl:d(s=>new URL(o.searchPath(encodeURIComponent(s)),`${t}/`).href,"searchUrl")})}d(Gc,"siteDefinition");function du(o,e,t,s){if(typeof o!="string")throw new D("INVALID_RESPONSE","外部站点响应不是 HTML",{source:e.id});let a=new DOMParser().parseFromString(o,"text/html"),i=[];for(let r of a.querySelectorAll(e.itemSelector)){let n=e.textSelector?r.querySelector(e.textSelector):r;if((e.titleAttribute?r.getAttribute("title")||"":n?.textContent?.trim()||"").toLowerCase().includes(t.toLowerCase()))if(e.directDetail)i.push(new URL(`/${encodeURIComponent(t)}`,`${s}/`).href);else{let c=e.hrefSelector?r.querySelector(e.hrefSelector):r,h=c?.getAttribute("href");if(!h)throw new D("PARSE_ERROR","外部站点结果缺少链接",{source:e.id});i.push(new URL(h,`${s}/`).href)}}return Object.freeze([...new Set(i)])}d(du,"parseExternalSiteResults");function hu(o){return Object.freeze({contracts:["ExternalSiteResult"],getSites(e={}){return Object.freeze(Kc.map(t=>Gc(t,e)))},getNavigationLinks:d(()=>Object.freeze([Object.freeze({id:"theporndude",label:"ThePornDude",url:"https://theporndude.com/zh"})]),"getNavigationLinks"),async searchSite(e,t,s={}){let a=Kc.find(u=>u.id===e);if(!a)throw new D("UNSUPPORTED",`未知外部站点:${e}`,{source:"external-sites"});let i=Gc(a,s.settings||{}),r=i.searchUrl(t),n=new URL(r),l=new URL(a.defaultBaseUrl).hostname.replace(/^www\./,""),c=n.hostname===l||n.hostname.endsWith(`.${l}`)?{trustClass:"builtin-public",hosts:[l],expectedOrigin:n.origin}:{trustClass:"custom-public",expectedOrigin:n.origin},h=await o.request({capability:"movie.external-sites",providerId:`external-site:${e}`,method:"GET",url:r,responseType:"text",urlPolicy:c},s.scope);return Object.freeze({searchUrl:r,matches:du(h.data,a,t,i.baseUrl)})}})}d(hu,"createExternalSitesAdapter");var Qc=W({id:"external-sites",trustClass:"builtin-public",hosts:["javtrailers.com","jable.tv","jav.rs","missav.live","supjav.com","javdb.com","javbus.com","theporndude.com"],capabilities:["movie.external-sites","navigation.external"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>hu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.external-sites":"public-1d","navigation.external":"none"},quality:"silver"});function Yc(o){if(typeof o=="string")return new DOMParser().parseFromString(o,"text/html");if(typeof o?.querySelector=="function")return o;let e=o?.[0]??o?.get?.(0);if(typeof e?.querySelector=="function")return e;throw new TypeError("FC2PPVDB detail document is invalid")}d(Yc,"resolveDocument");function Zc(o,e){let t=new URL(e).pathname.match(/(?:articles?|videos?)\/(\d+)/i)?.[1],s=ee(t?`FC2-${t}`:""),a=Yc(o).querySelector("h1")?.textContent?.trim()??"";if(!s||!a)throw new TypeError("FC2PPVDB detail is malformed");return Ft({carNum:s,title:a,url:new URL(e).href})}d(Zc,"parseFc2PpvDbDetail");function Xc(o,e){let t=Yc(o),s=new URL(e),a=[...t.querySelectorAll("div")],i=a.find(h=>h.textContent?.trim().startsWith("女優:")),r=a.find(h=>h.textContent?.trim().startsWith("販売者:")),n=[...i?.querySelectorAll("a[href]")??[]].map(h=>Object.freeze({name:h.textContent?.trim()||"",url:new URL(h.getAttribute("href")||"",s).href})).filter(h=>h.name),l=r?.querySelector("a[href]"),c=l?Object.freeze({name:l.textContent?.trim()||"",url:new URL(l.getAttribute("href")||"",s).href}):null;return Object.freeze({actors:Object.freeze(n),seller:c})}d(Xc,"parseFc2PpvDbPeople");function uu(o){let e=d(s=>{let a=String(s.carNum||"").match(/^(?:FC2-)?(?:PPV-)?(\d+)$/i)?.[1];if(!a)throw new TypeError("FC2PPVDB movie identifier is invalid");return new URL(s.url||`https://fc2ppvdb.com/articles/${a}`)},"resolveUrl"),t=d((s,a,i="movie.detail")=>o.request({capability:i,providerId:"fc2ppvdb",method:"GET",url:s.href,responseType:"text",urlPolicy:{trustClass:"builtin-public",hosts:["fc2ppvdb.com"]}},a),"request");return Object.freeze({contracts:["MovieDetail","MovieCredits"],detailUrl(s){return e(s).href},async getDetail(s,a={}){let i=e(s),r=await t(i,a.scope,"movie.detail");return Zc(r.data,r.finalUrl||i.href)},async getPeople(s,a={}){let i=e(s),r=await t(i,a.scope,"movie.credits");return Xc(r.data,r.finalUrl||i.href)}})}d(uu,"createFc2PpvDbAdapter");var ed=W({id:"fc2ppvdb",trustClass:"builtin-public",hosts:["fc2ppvdb.com"],capabilities:["movie.detail","movie.credits"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>uu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.detail":xe.externalDetail,"movie.credits":xe.externalDetail},quality:"silver"});function td(o,e){let t=new DOMParser().parseFromString(o,"text/html"),s=new Set;for(let a of t.querySelectorAll(".items_article_SampleImagesArea img[src]")){let i=new URL(a.getAttribute("src")||"",e);i.protocol==="https:"&&s.add(i.href)}return Object.freeze([...s].map(a=>Object.freeze({url:a,providerId:"fc2content"})))}d(td,"parseFc2ContentImages");function pu(o){return Object.freeze({contracts:["Screenshot"],detailUrl(e){let t=String(e.carNum||"").match(/^(?:FC2-)?(?:PPV-)?(\d+)$/i)?.[1];return t?`https://adult.contents.fc2.com/article/${t}/`:null},async getImages(e,t={}){let s=String(e.carNum||"").match(/^(?:FC2-)?(?:PPV-)?(\d+)$/i)?.[1];if(!s)return[];let a=`https://adult.contents.fc2.com/article/${s}/`,i=await o.request({providerId:"fc2content",capability:"movie.images",method:"GET",url:a,responseType:"text",headers:{referer:a},urlPolicy:{trustClass:"builtin-public",hosts:["adult.contents.fc2.com"]}},t.scope);return td(i.data,i.finalUrl||a)}})}d(pu,"createFc2ContentAdapter");var sd=W({id:"fc2content",trustClass:"builtin-public",hosts:["adult.contents.fc2.com"],capabilities:["movie.images"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>pu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.images":xe.externalDetail},quality:"silver"});function ad(o){if(!o||typeof o!="object"||Array.isArray(o))throw new TypeError("Translation response is invalid");let e=o.translation;if(typeof e!="string"||!e.trim())throw new TypeError("Translation text is missing");return e}d(ad,"parseGoogleTranslation");var gu="https://translate-pa.googleapis.com/v1/translate";function mu(o){return Object.freeze({contracts:["Translation"],async translate(e,t={}){if(!String(e||"").trim())throw new TypeError("Translation text cannot be empty");let s=new URL(gu);s.search=new URLSearchParams({"params.client":"gtx",dataTypes:"TRANSLATION",key:"AIzaSyDLEeFI5OtFBwYBIoK_jj5m32rZK5CkCXA","query.sourceLanguage":t.sourceLanguage??"ja","query.targetLanguage":t.targetLanguage??"zh-CN","query.text":e}).toString();let a=await o.request({providerId:"google-translate",capability:"text.translate",method:"GET",url:s.href,responseType:"json",transport:"native-fetch",nativeTimeout:1500,timeout:5e3,urlPolicy:{trustClass:"builtin-public",hosts:["translate-pa.googleapis.com"]}},t.scope);return ad(a.data)}})}d(mu,"createGoogleTranslateAdapter");var id=W({id:"google-translate",trustClass:"builtin-public",hosts:["translate-pa.googleapis.com"],capabilities:["text.translate"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>mu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"text.translate":"none"},quality:"silver"});var To=Object.freeze([Object.freeze({id:"jsdelivr",name:"jsDelivr (全球CDN)",catalogUrl:"https://cdn.jsdelivr.net/gh/gfriends/gfriends/Filetree.json",contentBaseUrl:"https://cdn.jsdelivr.net/gh/gfriends/gfriends/Content/",recommended:!0}),Object.freeze({id:"github-raw",name:"GitHub Raw (备用)",catalogUrl:"https://raw.githubusercontent.com/gfriends/gfriends/master/Filetree.json",contentBaseUrl:"https://raw.githubusercontent.com/gfriends/gfriends/master/Content/",recommended:!1})]);function fu(o,e){let t=o?.Content;if(!t||typeof t!="object"||Array.isArray(t))throw new D("INVALID_RESPONSE","头像数据源缺少 Content",{source:"gfriends"});let s=new Map;for(let[a,i]of Object.entries(t))if(!(!i||typeof i!="object"||Array.isArray(i)))for(let[r,n]of Object.entries(i)){if(typeof n!="string")continue;let l=r.replace(/\.jpg$/i,"").split("-")[0];if(l.startsWith("AI-Fix-")&&(l=l.slice(7)),l=l.toLowerCase().trim(),!l)continue;let c=n.indexOf("?"),h=c>=0?n.slice(0,c):n,u=c>=0?n.slice(c):"",p=`${e}${encodeURIComponent(a)}/${encodeURIComponent(h)}${u}`,g=s.get(l)||[];g.includes(p)||g.push(p),s.set(l,g)}return s}d(fu,"parseGfriendsCatalog");function vu(o){return Object.freeze({contracts:["ActorAvatar"],getSources:d(()=>Object.freeze(To.map(e=>Object.freeze({id:e.id,name:e.name,recommended:e.recommended}))),"getSources"),async searchAvatars(e,t={}){let s=To.find(n=>n.id===(t.sourceId||To[0].id));if(!s)throw new D("UNSUPPORTED",`未知头像数据源:${t.sourceId}`,{source:"gfriends"});let a=await o.request({providerId:`gfriends:${s.id}`,capability:"person.avatar-search",method:"GET",url:s.catalogUrl,responseType:"json",timeout:2e4,urlPolicy:{trustClass:"builtin-public",hosts:[new URL(s.catalogUrl).hostname]}},t.scope),i=fu(a.data,s.contentBaseUrl),r=new Set;return e.map(n=>String(n).toLowerCase().trim()).filter(Boolean).forEach(n=>i.get(n)?.forEach(l=>r.add(l))),Object.freeze([...r])}})}d(vu,"createGfriendsAdapter");var rd=W({id:"gfriends",trustClass:"builtin-public",hosts:["cdn.jsdelivr.net","raw.githubusercontent.com"],capabilities:["person.avatar-search"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>vu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"person.avatar-search":"public-7d"},quality:"silver"});var nd=W({id:"host-list",trustClass:"builtin-public",hosts:["javdb.com","javbus.com"],capabilities:["host.list.parse"],requires:[],createClient:d(()=>Object.freeze({id:"host-list"}),"createClient"),createAdapter:d(()=>Object.freeze({contracts:["MovieRef"]}),"createAdapter"),createHostAdapter:null,cachePolicy:"none",quality:"bronze"});var bu="https://api.imgur.com/3/image",wu="d70305e7c3ac5c6",yu=Object.freeze({trustClass:"builtin-public",hosts:["imgur.com","google.com","yandex.ru"]}),ju=Object.freeze([Object.freeze({id:"google-legacy",name:"Google旧版",urlTemplate:"https://www.google.com/searchbyimage?image_url={imageUrl}&client=firefox-b-d",iconUrl:"https://www.google.com/favicon.ico"}),Object.freeze({id:"google-lens",name:"Google",urlTemplate:"https://lens.google.com/uploadbyurl?url={imageUrl}",iconUrl:"https://www.google.com/favicon.ico"}),Object.freeze({id:"yandex",name:"Yandex",urlTemplate:"https://yandex.ru/images/search?rpt=imageview&url={imageUrl}",iconUrl:"https://yandex.ru/favicon.ico"})]);function Su(o){let e=o;if(typeof e=="string")try{e=JSON.parse(e)}catch(s){throw new D("INVALID_RESPONSE","Imgur 返回了无效 JSON",{source:"image-search",cause:s})}let t=e;if(t?.success&&typeof t?.data?.link=="string"&&/^https:\/\//i.test(t.data.link))return t.data.link;throw new D("INVALID_RESPONSE",String(t?.data?.error||"Imgur 上传响应无效"),{source:"image-search"})}d(Su,"parseImgurUpload");function xu(o){let e=o.match(/^data:(image\/[a-z0-9.+-]+);base64,([a-z0-9+/=\s]+)$/i);if(!e)throw new D("INVALID_RESPONSE","无效的 Base64 图片数据",{source:"image-search"});let t=atob(e[2].replace(/\s/g,"")),s=new Uint8Array(t.length);for(let i=0;i<t.length;i+=1)s[i]=t.charCodeAt(i);let a=new FormData;return a.append("image",new Blob([s],{type:e[1]}),"jhs-image"),a}d(xu,"dataUrlToFormData");function ku(o){return Object.freeze({contracts:["ImageUrl","ImageSearchTarget"],async upload(e,t={}){let s=await o.request({providerId:"image-search",capability:"image.upload",method:"POST",url:bu,body:xu(e),headers:{Authorization:`Client-ID ${wu}`},responseType:"json",urlPolicy:yu,timeout:3e4},t.scope);return Su(s.data)},createTargets(e){let t=encodeURIComponent(e);return Object.freeze(ju.map(s=>Object.freeze({id:s.id,name:s.name,url:s.urlTemplate.replace("{imageUrl}",t),iconUrl:s.iconUrl})))}})}d(ku,"createImageSearchAdapter");var od=W({id:"image-search",trustClass:"builtin-public",hosts:["imgur.com","google.com","yandex.ru"],capabilities:["image.upload","image.search-targets"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>ku(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"image.upload":"none","image.search-targets":"none"},quality:"silver"});var ld=0,Ii="";function Ao(){let o=Math.floor(Date.now()/1e3);if(Ii&&o-ld<=20)return Ii;let e=globalThis.md5;if(typeof e!="function")throw new Error("Missing userscript vendor runtime: md5");return ld=o,Ii=`${o}.lpw6vgqzsp.${e(`${o}71cf27bb3c0bcdf207b64abecddc970098c7421ee7203b9cdae54478478a199e7d5a6e1a57691123c1a931c057842fb73ba3b3c83bcd69c17ccf174081e3d8aa`)}`,Ii}d(Ao,"createJavDbSignature");var cd="https://jdforrepam.com";function Cu(o,e=Ao,t=null){let s=d(i=>{let r=new URL(i).origin,n=new URL(i).hostname;return n==="javdb.com"||n.endsWith(".javdb.com")?{trustClass:"builtin-public",hosts:["javdb.com"],expectedOrigin:r}:{trustClass:"custom-public",expectedOrigin:r}},"hostPolicy"),a=d(async(i,r,n={},l={},c="movie.detail")=>{let h=new URL(i,cd);return Object.entries(r).forEach(([p,g])=>h.searchParams.set(p,String(g))),(await o.request({providerId:"javdb",capability:c,method:"GET",url:h.href,responseType:"json",headers:{jdSignature:e(),...l},urlPolicy:{trustClass:"builtin-public",hosts:["jdforrepam.com"]}},n.scope)).data},"request");return Object.freeze({contracts:["MovieRef","MovieDetail","Actor","Magnet","Review","RelatedList","AccountSession"],actorPlaceholderUrl:d(()=>"https://c0.jdbstatic.com/images/actor_unknow.jpg","actorPlaceholderUrl"),async login(i,r={}){let n=new URL("/api/v1/sessions",cd);Object.entries({username:i.username,password:i.password,device_uuid:"04b9534d-5118-53de-9f87-2ddded77111e",device_name:"iPhone",device_model:"iPhone",platform:"ios",system_version:"17.4",app_version:"official",app_version_number:"1.9.29",app_channel:"official"}).forEach(([h,u])=>n.searchParams.set(h,u));let c=(await o.request({providerId:"javdb",capability:"account.login",method:"POST",url:n.href,responseType:"json",headers:{"user-agent":"Dart/3.5 (dart:io)","accept-language":"zh-TW","content-type":"multipart/form-data; boundary=--dio-boundary-2210433284",jdsignature:e()},urlPolicy:{trustClass:"builtin-public",hosts:["jdforrepam.com"]}},r.scope)).data;if(c?.success===0)return Object.freeze({success:!1,token:null,message:String(c.message||"登录失败")});if(c?.success!==1||typeof c?.data?.token!="string")throw new D("INVALID_RESPONSE",String(c?.message||"JavDB 登录响应无效"),{source:"javdb"});return Object.freeze({success:!0,token:c.data.token,message:String(c.message||"")})},async listActorMovies(i,r={}){let n=new URL(i.baseUrl||"https://javdb.com").origin,l=new URL(`/actors/${encodeURIComponent(i.actorId)}?t=d`,n),c=await o.request({providerId:"javdb-host",capability:"actor.movies",method:"GET",url:l.href,responseType:"text",urlPolicy:s(n)},r.scope);if(typeof t?.parseActorMovies!="function")throw new TypeError("JavDB HostAdapter parser is unavailable");return t.parseActorMovies(c.data,c.finalUrl||l.href)},async listActorCollection(i,r={}){let n=new URL(i.baseUrl||"https://javdb.com").origin,l=new URL(i.pageUrl||"/users/collection_actors",n),c=await o.request({providerId:"javdb-host",capability:"actor.collection",method:"GET",url:l.href,responseType:"text",urlPolicy:s(n)},r.scope);if(typeof t?.parseActorCollection!="function")throw new TypeError("JavDB HostAdapter collection parser is unavailable");return t.parseActorCollection(c.data,c.finalUrl||l.href)},async uncollectActor(i,r={}){let n=new URL(i.baseUrl||"https://javdb.com").origin,l=new URL(`/actors/${encodeURIComponent(i.actorId)}/uncollect`,n),c=await o.request({providerId:"javdb-host",capability:"actor.uncollect",method:"POST",url:l.href,body:"null",responseType:"text",headers:{"Content-Type":"application/json","x-csrf-token":i.csrfToken},urlPolicy:s(n)},r.scope);return Object.freeze({success:typeof c.data=="string"&&c.data.includes("removeClass")})},async resolveMovie(i,r={}){let n=ee(i.carNum);if(!n)return null;let l=await a("/api/v2/search",{q:n,page:1,type:"movie",limit:20,movie_type:"all",from_recent:"false",movie_filter_by:"all",movie_sort_by:"relevance"},r,{"user-agent":"Dart/3.5 (dart:io)","accept-language":"zh-TW",host:"jdforrepam.com"},"movie.search");if(!Array.isArray(l?.data?.movies))throw new Error(l?.message||"JavDB search response is invalid");let c=l.data.movies.find(h=>ee(h.number)===n);return c?.id?Object.freeze({carNum:n,movieId:String(c.id),providerId:"javdb"}):null},async getDetail(i,r={}){let n=String(i.movieId||"").trim();if(!n)throw new TypeError("JavDB movie id is required");let l=await a(`/api/v4/movies/${encodeURIComponent(n)}`,{},r,{},"movie.detail"),c=l?.data?.movie;if(!c?.number)throw new Error(l?.message||"JavDB detail response is invalid");let h=Array.isArray(c.preview_images)?c.preview_images.map(p=>String(p.large_url||"").replace(/https:\/\/[^/]+\/rhe951l4q/,"https://c0.jdbstatic.com")).filter(Boolean):[],u=c.cover_url?String(c.cover_url).replace(/https:\/\/[^/]+\/rhe951l4q/,"https://c0.jdbstatic.com"):"";return Object.freeze({movieId:String(c.id||n),carNum:ee(c.number),title:String(c.title||c.origin_title||""),originalTitle:String(c.origin_title||c.title||""),coverUrl:u||null,actors:Array.isArray(c.actors)?c.actors.map(p=>Object.freeze({id:String(p.id),name:String(p.name||""),gender:Number(p.gender)})):[],duration:Number(c.duration)||null,score:Number(c.score)||0,releaseDate:c.release_date||null,watchedCount:Number(c.watched_count)||0,imageUrls:Object.freeze(h),providerId:"javdb"})},async listMagnets(i,r={}){let n=String(i.movieId||"").trim();if(!n)return[];let l=await a(`/api/v1/movies/${encodeURIComponent(n)}/magnets`,{},r,{},"movie.magnets");if(!Array.isArray(l?.data?.magnets))throw new Error(l?.message||"JavDB magnet response is invalid");return l.data.magnets.map(c=>Object.freeze({hash:String(c.hash||""),title:String(c.name||""),hasHdTag:!!c.hd,hasSubtitleTag:!!c.cnsub,createdAt:c.created_at||null,seeders:Number(c.seeders)||0,sizeMb:Number(c.size)||0,fileCount:Number(c.files_count)||0,providerId:"javdb"}))},async listRankings(i={}){let r=await a("/api/v1/rankings/playback",{period:i.period||"daily",filter_by:i.filter||"high_score"},i,{},"movie.ranking");if(!Array.isArray(r?.data?.movies))throw new Error(r?.message||"JavDB ranking response is invalid");return r.data.movies.map(n=>Object.freeze({movieId:String(n.id),carNum:ee(n.number),title:String(n.origin_title||""),coverUrl:String(n.cover_url||"").replace(/https:\/\/[^/]+\/rhe951l4q/,"https://c0.jdbstatic.com"),releaseDate:n.release_date||null,hasSubtitle:!!n.has_cnsub,magnetCount:Number(n.magnets_count)||0,newMagnets:!!n.new_magnets,providerId:"javdb"}))},async listReviews(i,r={}){let n=String(i.movieId||"").trim();if(!n)return[];let l=await a(`/api/v1/movies/${encodeURIComponent(n)}/reviews`,{page:r.page??1,sort_by:"hotly",limit:r.limit??20},r,{},"movie.reviews");if(!Array.isArray(l?.data?.reviews))throw new Error(l?.message||"JavDB review response is invalid");return l.data.reviews.map(c=>Object.freeze({author:String(c.username||"匿名用户"),content:String(c.content||""),score:Number(c.score)||0,createdAt:c.created_at||null,likes:Number(c.likes_count)||0}))},async listRelated(i,r={}){let n=String(i.movieId||"").trim();if(!n)return[];let l=await a("/api/v1/lists/related",{movie_id:n,page:r.page??1,limit:r.limit??20},r,{},"movie.related");if(!Array.isArray(l?.data?.lists))throw new Error(l?.message||"JavDB related response is invalid");return l.data.lists.map(c=>Object.freeze({id:String(c.id),name:String(c.name||"未命名清单"),movieCount:Number(c.movies_count)||0,collectionCount:Number(c.collections_count)||0,viewCount:Number(c.views_count)||0,createdAt:c.created_at||null}))}})}d(Cu,"createJavDbAdapter");var dd=W({id:"javdb",trustClass:"builtin-public",hosts:["javdb.com","jdforrepam.com","c0.jdbstatic.com"],capabilities:["movie.search","movie.detail","movie.magnets","movie.ranking","movie.state","movie.reviews","movie.related","actor.lookup","actor.movies","actor.collection","actor.uncollect","actor.avatar-placeholder","account.login"],requires:[y.http,Z.javdbHost],createClient:d(o=>Object.freeze({http:o[y.http],hostAdapter:o[Z.javdbHost]}),"createClient"),createAdapter:d(o=>Cu(o.http,Ao,o.hostAdapter),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.search":"public-7d","movie.detail":xe.externalDetail,"movie.magnets":"public-1d","movie.ranking":"public-1d","movie.state":"none","movie.reviews":"public-1d","movie.related":"public-1d","actor.lookup":"none","actor.movies":"public-5m","actor.collection":"none","actor.uncollect":"none","actor.avatar-placeholder":"none","account.login":"none"},quality:"silver"});function hd(o){if(typeof o=="string")return new DOMParser().parseFromString(o,"text/html");if(typeof o?.querySelector=="function")return o;let e=o?.[0]??o?.get?.(0);if(typeof e?.querySelector=="function")return e;throw new TypeError("JavBus document is invalid")}d(hd,"resolveDocument");function _u(o,e){if(typeof o?.find=="function")return ee(o.find("span.header:contains('識別碼:')").parent().text().replace("識別碼:",""))??ee(new URL(e).pathname.split("/").filter(Boolean).pop());let s=[...hd(o).querySelectorAll("span.header")].find(a=>a.textContent?.includes("識別碼"));return ee(s?.parentElement?.textContent?.replace("識別碼:",""))??ee(new URL(e).pathname.split("/").filter(Boolean).pop())}d(_u,"readMovieRef");function $u(o,e){let t=_u(o,e);if(!t)throw new TypeError("JavBus movie identifier is missing");return Ai({carNum:t,url:new URL(e).href})}d($u,"parseJavBusMovieRef");function ud(o,e){let t=$u(o,e),s=typeof o?.find=="function"?null:hd(o),a=s?s.querySelector("h3")?.textContent?.trim()||t.carNum:o.find("h3").first().text().trim()||t.carNum,i=s?s.querySelector(".bigImage img[src], a.bigImage img[src]")?.getAttribute("src"):o.find(".bigImage img[src], a.bigImage img[src]").first().attr("src");return Ft({...t,title:a,coverUrl:i?new URL(i,e).href:null,providerId:"javbus"})}d(ud,"parseJavBusMovieDetail");function Tu(o){return Object.freeze({contracts:["MovieDetail","Screenshot"],async getDetail(e,t={}){let s=ee(e.carNum);if(!s)throw new TypeError("JavBus movie reference is invalid");let a=new URL(e.url||`https://www.javbus.com/${encodeURIComponent(s)}`).href,i=await o.request({providerId:"javbus",capability:"movie.detail",method:"GET",url:a,responseType:"text",urlPolicy:{trustClass:"builtin-public",hosts:["javbus.com"]}},t.scope);return ud(i.data,i.finalUrl||a)},async getImages(e,t={}){let s=await this.getDetail(e,t);return s.coverUrl?[Object.freeze({url:s.coverUrl,providerId:"javbus"})]:[]}})}d(Tu,"createJavBusAdapter");var pd=W({id:"javbus",trustClass:"builtin-public",hosts:["javbus.com"],capabilities:["movie.detail","movie.images"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>Tu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.detail":xe.externalDetail,"movie.images":xe.externalDetail},quality:"silver"});function Au(o){let e=d((t,s)=>o.request({providerId:"javstore",capability:"movie.images",method:"GET",url:t,responseType:"text",urlPolicy:{trustClass:"builtin-public",hosts:["javstore.net"]}},s),"request");return Object.freeze({contracts:["Screenshot"],getSearchUrl(t){return`https://javstore.net/search?q=${encodeURIComponent(t.carNum||"")}`},async getImages(t,s={}){let a=this.getSearchUrl(t),i=await e(a,s.scope),r=Cc(i.data,t.carNum,i.finalUrl||a);if(!r.length)return[];for(let n of r)try{let l=await e(n,s.scope),c=_c(l.data,l.finalUrl||n);if(c)return[Object.freeze({url:c,providerId:"javstore"})]}catch(l){if(!(l&&typeof l=="object"&&"code"in l&&l.code==="NOT_FOUND"))throw l}return[]}})}d(Au,"createJavStoreAdapter");var gd=W({id:"javstore",trustClass:"builtin-public",hosts:["javstore.net"],capabilities:["movie.images"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>Au(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.images":"screenshot-7d"},quality:"silver"});var md=W({id:"javtrailers",trustClass:"builtin-public",hosts:["javtrailers.com"],capabilities:["movie.preview"],requires:[Z.http,y.urlPolicy],createClient:d(()=>Object.freeze({id:"javtrailers"}),"createClient"),createAdapter:d(()=>Object.freeze({contracts:["MoviePreview"]}),"createAdapter"),createHostAdapter:null,cachePolicy:"none",quality:"bronze"});var Pu="https://115.com",Iu=Object.freeze({trustClass:"builtin-public",hosts:["115.com"]});function Ru(o){if(typeof o!="string")return o;try{return JSON.parse(o)}catch{return{state:!1,error_msg:/login|登录|sign in|未授权|授权|expire|expired|token|cookie/i.test(o)?"115 未登录":"115 返回异常响应"}}}d(Ru,"parsePayload");function Eu(o){let e=String(o).toLowerCase();return/未登录|请登录|登录|login|sign|授权|过期|token|cookie|uid|身份|auth|expire|needlogin|need login/i.test(e)?"AUTH_REQUIRED":/已存在|重复|exists|duplicate|already|same|conflict|exist/i.test(e)?"TASK_EXISTS":"OPERATION_FAILED"}d(Eu,"classify115OfflineError");function Du(o){let e=o;if(!e||!Array.isArray(e.data))throw new D("INVALID_RESPONSE","115 文件搜索响应无效",{source:"one115"});return Object.freeze(e.data.map(t=>{let s=String(t.n||t.file_name||"");return Object.freeze({folderId:String(t.pid||t.cid||""),fileId:t.fid?String(t.fid):null,videoId:String(t.pc||t.pick_code||""),name:s,size:Number(t.s||t.size)||0,createTime:String(t.t||t.create_time||""),isVideo:/\.(mp4|mkv|avi|mov|flv|wmv|ts|m2ts)$/i.test(s)})}).filter(t=>t.isVideo))}d(Du,"normalize115SearchResults");function Nu(o){let e=d((t,s={})=>o.request({providerId:"one115",capability:s.capability||"account.status",method:s.method||"GET",url:t,body:s.body,headers:s.headers,responseType:s.responseType||"json",urlPolicy:Iu},s.scope),"request");return Object.freeze({contracts:["AccountStatus","CloudFile","OfflineSubmission"],homeUrl:Pu,async checkAccount(t={}){let a=(await e("https://webapi.115.com/offine/downpath",{capability:"account.status",scope:t.scope})).data;return Object.freeze({authenticated:!!(a?.state&&a?.data?.length)})},async searchFiles(t,s={}){let a=new URL("https://webapi.115.com/files/search");a.searchParams.set("search_value",t),a.searchParams.set("offset",String(s.offset??0)),a.searchParams.set("limit",String(s.limit??50));let i=await e(a.href,{capability:"file.search",scope:s.scope,force:s.force});return Du(i.data)},async submit(t,s={}){if(!/^magnet:/i.test(t)&&!/^ed2k:/i.test(t))throw new D("UNSUPPORTED","Unsupported offline URL",{source:"one115"});let i=(await e(`https://115.com/?ct=offline&ac=space&_=${Date.now()}`,{capability:"offline.submit",scope:s.scope})).data;if(!i?.sign)throw new D("AUTH_REQUIRED","115 未登录或离线空间信息获取失败",{source:"one115"});let r=new URLSearchParams({url:t,wp_path_id:s.folderId||"",uid:String(i.uid||""),sign:i.sign,time:String(i.time||"")}).toString(),n=await e("https://115.com/web/lixian/?ct=lixian&ac=add_task_url",{capability:"offline.submit",scope:s.scope,method:"POST",body:r,responseType:"text",headers:{"Content-Type":"application/x-www-form-urlencoded"}}),l=Ru(n.data);if(!l||l.state===!1||l.state===0){let c=String(l?.error_msg||l?.error||l?.msg||"115 离线任务创建失败"),h=Eu(c);throw new D(h,c,{source:"one115",details:{state:l?.state??null}})}if(l.state!==!0&&l.state!==1)throw new D("INVALID_RESPONSE","115 未返回明确的离线任务创建成功状态",{source:"one115"});return Object.freeze({success:!0,taskId:String(l.task_id||l.info_hash||"")})},async renameFile(t,s,a={}){let i=new URLSearchParams({fid:t,file_name:s}).toString(),n=(await e("https://webapi.115.com/files/edit",{capability:"file.rename",scope:a.scope,method:"POST",body:i,responseType:"json",headers:{"Content-Type":"application/x-www-form-urlencoded"}})).data;if(!n||n.state===!1||n.state===0)throw new D("OPERATION_FAILED",String(n?.error||n?.error_msg||"115 重命名失败"),{source:"one115"});return Object.freeze({success:!0})},getPlayUrl(t){return t?.videoId?`https://115.com/?ct=play&pickcode=${encodeURIComponent(t.videoId)}`:null}})}d(Nu,"createOne115Adapter");var fd=W({id:"one115",trustClass:"builtin-public",hosts:["115.com"],capabilities:["account.status","file.search","file.rename","offline.submit"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>Nu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"account.status":"none","file.search":"none","file.rename":"none","offline.submit":"none"},quality:"silver"});var Lu=Object.freeze({trustClass:"builtin-public",hosts:["123pan.com"]});function vd(o){let e=new Uint32Array(256);for(let s=0;s<256;s+=1){let a=s;for(let i=0;i<8;i+=1)a=a&1?3988292384^a>>>1:a>>>1;e[s]=a}let t=4294967295;for(let s=0;s<o.length;s+=1)t=e[(t^o.charCodeAt(s))&255]^t>>>8;return(t^4294967295)>>>0}d(vd,"crc32");function Bu(){let o=new Uint32Array(1);return crypto.getRandomValues(o),o[0]%1e7}d(Bu,"secureNonce");function Mu(o,e={}){let t=["a","d","e","f","g","h","l","m","y","i","j","n","o","p","k","q","r","s","t","u","b","c","v","w","s","z"],s=e.nonce??Bu(),a=e.now??new Date,i=new Date(a.getTime()+6e4*a.getTimezoneOffset()+288e5),n=[...`${i.getFullYear()}${String(i.getMonth()+1).padStart(2,"0")}${String(i.getDate()).padStart(2,"0")}${String(i.getHours()).padStart(2,"0")}${String(i.getMinutes()).padStart(2,"0")}`].map(p=>t[Number(p)]).join(""),l=vd(n),c=Math.floor(i.getTime()/1e3),h=new URL(o),u=vd(`${c}|${s}|${h.pathname}|web|3|${l}`);return h.searchParams.set(String(l),`${c}-${s}-${u}`),h.href}d(Mu,"signPan123Url");function bd(o){if(typeof o!="string")return o;try{return JSON.parse(o)}catch(e){throw new D("PARSE_ERROR","123 云盘响应不是有效 JSON",{source:"pan123",cause:e})}}d(bd,"parsePayload");function wd(o,e){if(!o||typeof o!="object")throw new D("INVALID_RESPONSE",`123 云盘${e}响应无效`,{source:"pan123"});if(o.code===0)return o;let t=String(o.message||o.msg||`${e}失败`);throw/token is expired|unauthorized|登录|授权/i.test(t)?new D("AUTH_REQUIRED",t,{source:"pan123"}):new D("INVALID_RESPONSE",t,{source:"pan123"})}d(wd,"assertSuccess");function Ou(o,e={}){let t=d(async(s,a,i,r,n)=>{let l=Mu(`https://yun.123pan.com${s}`,{now:e.now?.(),nonce:e.nonce?.()});return o.request({providerId:"pan123",capability:n,method:"POST",url:l,body:JSON.stringify(a),responseType:"json",timeout:e.getTimeout?.()??5e3,headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`,"App-Version":"3",platform:"web",Origin:"https://yun.123pan.com",Referer:"https://yun.123pan.com/"},urlPolicy:Lu},r)},"request");return Object.freeze({contracts:["OfflineResolvedResource","OfflineSubmission"],homeUrl:"https://yun.123pan.com",async resolve(s,a={}){let{token:i,scope:r}=a;if(!i)throw new D("AUTH_REQUIRED","尚未同步 123 授权",{source:"pan123"});let n=await t("/b/api/v2/offline_download/task/resolve",{urls:s},i,r,"offline.resolve"),l=wd(bd(n.data),"解析"),c=l.data?.list?.[0];if(!c?.id||!Array.isArray(c.files))throw new D("INVALID_RESPONSE","123 云盘解析结果缺少资源文件",{source:"pan123"});return Object.freeze({id:c.id,files:Object.freeze(c.files.map(h=>Object.freeze({id:h.id,size:Number(h.size||0)})))})},async submitResolved(s,a={}){let{token:i,scope:r}=a;if(!i)throw new D("AUTH_REQUIRED","尚未同步 123 授权",{source:"pan123"});if(!s?.id||!Array.isArray(s.files)||s.files.length===0)throw new D("INVALID_RESPONSE","没有可建立离线的文件",{source:"pan123"});let n=s.files.map(h=>h.id),l=s.files.reduce((h,u)=>h+Number(u.size||0),0),c=await t("/b/api/v2/offline_download/task/submit",{resource_list:[{resource_id:s.id,select_file_id:n}]},i,r,"offline.submit");return wd(bd(c.data),"提交"),Object.freeze({fileCount:n.length,totalSize:l})},async submit(s,a={}){let i=await this.resolve(s,a);return this.submitResolved(i,a)}})}d(Ou,"createPan123Adapter");var yd=W({id:"pan123",trustClass:"builtin-public",hosts:["123pan.com"],capabilities:["offline.resolve","offline.submit"],requires:[y.http,y.settings],createClient:d(o=>Object.freeze({http:o[y.http],settings:o[y.settings]}),"createClient"),createAdapter:d(o=>Ou(o.http,{getTimeout:d(()=>Number(o.settings.snapshot().httpTimeout??5e3),"getTimeout")}),"createAdapter"),createHostAdapter:null,cachePolicy:{"offline.resolve":"none","offline.submit":"none"},quality:"silver"});function zu(){return Object.freeze({contracts:["Subtitle"],detailUrl(o){let e=String(o?.carNum||"").trim();if(!e)return null;let t=new URL("/index.php","https://subtitlecat.com");return t.searchParams.set("search",e),t.href}})}d(zu,"createSubtitleCatAdapter");var jd=W({id:"subtitlecat",trustClass:"builtin-public",hosts:["subtitlecat.com"],capabilities:["subtitle.search"],requires:[],createClient:d(()=>Object.freeze({id:"subtitlecat"}),"createClient"),createAdapter:d(()=>zu(),"createAdapter"),createHostAdapter:null,cachePolicy:"none",quality:"bronze"});var Sd=Object.freeze([Object.freeze({id:"u9a9",name:"U9A9",type:"网页来源",domain:"u9a9.com",baseUrl:"https://u9a9.com",priority:20,enabled:!0,searchPath:d(o=>`/?type=2&search=${encodeURIComponent(o)}`,"searchPath")}),Object.freeze({id:"u3c3",name:"U3C3",type:"网页来源",domain:"u3c3.com",baseUrl:"https://u3c3.com",priority:30,enabled:!0,searchPath:d(o=>`/?search2=a8lr16lo&search=${encodeURIComponent(o)}`,"searchPath")}),Object.freeze({id:"sukebei",name:"Sukebei",type:"网页来源",domain:"sukebei.nyaa.si",baseUrl:"https://sukebei.nyaa.si",priority:40,enabled:!0,searchPath:d(o=>`/?f=0&c=0_0&q=${encodeURIComponent(o)}`,"searchPath")}),Object.freeze({id:"btsow",name:"BTSOW",type:"API 来源",domain:"btsow.lol",baseUrl:"https://btsow.lol",priority:50,enabled:!0,searchPath:d(o=>`/search/${encodeURIComponent(o)}`,"searchPath")})]);function xd(o,e){let t=o,s=String(t?.magnet||"");return s.startsWith("magnet:")?Object.freeze({title:String(t.title||""),magnet:s,size:String(t.size||""),date:String(t.date||""),seeders:Number(t.seeders)||0,leechers:Number(t.leechers)||0,source:e,files:Object.freeze([])}):null}d(xd,"normalizeMagnet");function Uu(o,e,t){if(typeof o!="string")throw new D("INVALID_RESPONSE","磁力来源响应不是 HTML",{source:t});let s=new DOMParser().parseFromString(o,"text/html"),a=`${s.title} ${s.body?.textContent||""}`;if(/Just a moment|cf-chl-|Cloudflare/i.test(a))throw new D("CF_BLOCKED","磁力来源被 Cloudflare 拦截",{source:t});return Object.freeze([...s.querySelectorAll(".torrent-list tbody tr")].flatMap(i=>{if(i.textContent?.includes("置顶"))return[];let r=i.querySelector("td:nth-child(2) a"),n=r?.getAttribute("title")||r?.textContent?.trim()||"";if(!n.toLowerCase().includes(e.toLowerCase()))return[];let l=xd({title:n,magnet:i.querySelector('td:nth-child(3) a[href^="magnet:"]')?.getAttribute("href"),size:i.querySelector("td:nth-child(4)")?.textContent?.trim(),date:i.querySelector("td:nth-child(5)")?.textContent?.trim(),seeders:i.querySelector("td:nth-child(6)")?.textContent?.trim(),leechers:i.querySelector("td:nth-child(7)")?.textContent?.trim()},t);return l?[l]:[]}))}d(Uu,"parseTorrentSource");function Fu(o){let e=o;if(typeof e=="string")try{e=JSON.parse(e)}catch(s){throw new D("INVALID_RESPONSE","BTSOW 返回了无效 JSON",{source:"btsow",cause:s})}let t=e?.data;if(!Array.isArray(t))throw new D("INVALID_RESPONSE","BTSOW 响应缺少结果数组",{source:"btsow"});return Object.freeze(t.flatMap(s=>{let a=Number(s.lastUpdateTime),i=Number.isFinite(a)?new Date(1e3*a).toISOString().slice(0,10):"",r=xd({title:s.name,magnet:`magnet:?xt=urn:btih:${s.hash}`,size:`${(Number(s.size)/1073741824).toFixed(2)} GB`,date:i},"btsow");return r?[r]:[]}))}d(Fu,"parseBtsowSource");function Vu(o){let e=d(t=>Sd.find(s=>s.id===t),"find");return Object.freeze({contracts:["Magnet","MagnetSource"],getSources:d(()=>Object.freeze(Sd.map(t=>Object.freeze({id:t.id,name:t.name,type:t.type,domain:t.domain,baseUrl:t.baseUrl,priority:t.priority,enabled:t.enabled}))),"getSources"),targetUrl(t,s,a={}){let i=e(t);if(!i)throw new D("UNSUPPORTED",`未知磁力来源:${t}`,{source:"torrent-sources"});return`${new URL(a.baseUrl||i.baseUrl).origin}${i.searchPath(s)}`},async search(t,s,a={}){let i=e(t);if(!i)throw new D("UNSUPPORTED",`未知磁力来源:${t}`,{source:"torrent-sources"});let r=new URL(a.baseUrl||i.baseUrl).origin,l=new URL(r).hostname!==i.domain?{trustClass:"custom-public",expectedOrigin:r}:{trustClass:"builtin-public",hosts:[i.domain],expectedOrigin:r};if(i.id==="btsow"){let u=await o.request({capability:"magnet.search",providerId:"magnet:btsow",method:"POST",url:`${r}/search`,body:JSON.stringify([{search:s},50,1]),headers:{"Content-Type":"application/json"},responseType:"json",urlPolicy:l},a.scope);return Fu(u.data)}let c=`${r}${i.searchPath(s)}`,h=await o.request({capability:"magnet.search",providerId:`magnet:${i.id}`,method:"GET",url:c,responseType:"text",urlPolicy:l},a.scope);return Uu(h.data,s,i.id)}})}d(Vu,"createTorrentSourcesAdapter");var kd=W({id:"torrent-sources",trustClass:"builtin-public",hosts:["u9a9.com","u3c3.com","sukebei.nyaa.si","btsow.lol"],capabilities:["magnet.search"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>Vu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"magnet.search":"source-configured"},quality:"silver"});function St(o){return o.replace(/\s+/g," ").trim()}d(St,"compact");function Cd(o,e){let t=new DOMParser().parseFromString(o,"text/html"),s=St(t.querySelector('a[title="誕生日"]')?.closest("tr")?.querySelector("td")?.textContent??""),a=[...t.querySelectorAll("th")].find(g=>g.textContent?.includes("現年齢"))?.parentElement?.querySelector("td"),i=t.querySelector('a[title="身長"]')?.closest("tr")?.querySelector("td"),r=t.querySelector('a[title="体重"]')?.closest("tr")?.querySelector("td"),n=t.querySelector('a[title="スリーサイズ"]')?.closest("tr")?.querySelector("td"),l=[...t.querySelectorAll("th")].find(g=>g.textContent?.includes("ブラサイズ"))?.nextElementSibling;if(!s&&!i&&!n)throw new TypeError("Wikipedia actress information is missing");let c=Number.parseInt(St(a?.textContent??""),10),h=St(i?.textContent??"").split(" ")[0],u=St(r?.textContent??"").split("/"),p=St(u.at(-1)??"").replace(/^―\s*kg$/,"");return Object.freeze({birthday:s,age:Number.isFinite(c)?`${c}岁`:"",height:h&&!h.endsWith("cm")?`${h}cm`:h,weight:p,threeSizeText:St(n?.textContent??"").replace("cm","").trim(),braSize:St(l?.textContent??""),url:new URL(e).href})}d(Cd,"parseWikipediaActressInfo");function Hu(o){return Object.freeze({contracts:["ActressInfo"],profileUrl(e){return new URL(`/wiki/${encodeURIComponent(String(e))}`,"https://ja.wikipedia.org").href},async lookup(e,t={}){let s=this.profileUrl(e),a=await o.request({providerId:"wikipedia",capability:"person.actress-info",method:"GET",url:s,responseType:"text",timeout:15e3,urlPolicy:{trustClass:"builtin-public",hosts:["ja.wikipedia.org"]}},t.scope);try{return Cd(a.data,a.finalUrl||s)}catch(i){if(i instanceof TypeError&&/actress information is missing/.test(i.message))return null;throw i}}})}d(Hu,"createWikipediaAdapter");var _d=W({id:"wikipedia",trustClass:"builtin-public",hosts:["ja.wikipedia.org"],capabilities:["person.actress-info"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>Hu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"person.actress-info":xe.externalDetail},quality:"silver"});function $d(o){if(!o||typeof o!="object"||!Array.isArray(o.data))throw new D("INVALID_RESPONSE","迅雷字幕响应结构无效",{source:"xunlei"});return Object.freeze(o.data.flatMap(e=>{try{let t=new URL(String(e?.url??""));if(t.protocol!=="https:")return[];let s=String(e?.ext??"").toLowerCase().replace(/^\./,"");return s?[Object.freeze({name:String(e?.name??""),extension:s,url:t.href,providerId:"xunlei"})]:[]}catch{return[]}}))}d($d,"parseXunleiSubtitles");var Td=["xunlei.com"];function qu(o){return Object.freeze({contracts:["Subtitle"],async search(e,t={}){let s=String(e.carNum??"").trim();if(!s)return[];let a=new URL("https://api-shoulei-ssl.xunlei.com/oracle/subtitle");a.searchParams.set("gcid",""),a.searchParams.set("cid",""),a.searchParams.set("name",s);let i=await o.request({providerId:"xunlei",capability:"subtitle.search",method:"GET",url:a.href,responseType:"json",urlPolicy:{trustClass:"builtin-public",hosts:Td}},t.scope);return $d(i.data)},async download(e,t={}){let s=new URL(String(e.url??"")),a=await o.request({providerId:"xunlei",capability:"subtitle.download",method:"GET",url:s.href,responseType:"text",urlPolicy:{trustClass:"custom-public"}},t.scope);if(typeof a.data!="string")throw new TypeError("迅雷字幕正文不是文本");return a.data}})}d(qu,"createXunleiAdapter");var Ad=W({id:"xunlei",trustClass:"builtin-public",hosts:Td,capabilities:["subtitle.search","subtitle.download"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>qu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"subtitle.search":"public-1d","subtitle.download":"public-1d"},quality:"silver"});var Pd=Object.freeze([Vc,Jc,Qc,ed,sd,rd,id,nd,od,dd,pd,gd,md,fd,yd,jd,kd,_d,Ad]);function Wu(o,e){let t=o.close;o.close=function(a){let i=t.call(this,a);return e?.releaseEscClose?.(a),setTimeout(()=>{let r=document.querySelectorAll(".layui-layer-shade").length;document.documentElement.style.overflow=r>0?"hidden":""},10),i};let s=o.open;o.open=function(a={}){a=kt(a,e);let i=a.success;return s.call(this,{...a,success(r,n){typeof i=="function"&&i.call(this,r,n),e.setupEscClose(n)}})}}d(Wu,"patchLayerRuntime");function Ju(o){for(let e of["https://cdn.jsdelivr.net/npm/[email protected]/layer.min.css","https://cdn.jsdelivr.net/npm/[email protected]/src/toastify.min.css","https://cdn.jsdelivr.net/npm/[email protected]/dist/viewer.min.css","https://cdn.jsdelivr.net/npm/[email protected]/dist/css/tabulator_semanticui.min.css"])o.importResource(e)}d(Ju,"importVendorStyles");async function Ku(o){let e=await o.getSetting("disabledPlugins","[]"),t=Ge(e),s=_t(t);return{migrated:s,needsMigration:JSON.stringify(t)!==JSON.stringify(s)}}d(Ku,"readDisabledPluginSettings");async function Gu(o,e,t,s,a,i,r=null){await o.update(n=>{let l=Ge(typeof n.disabledPlugins=="string"?n.disabledPlugins:"[]"),c=_t(l);if(JSON.stringify(l)!==JSON.stringify(c)&&(n.disabledPlugins=JSON.stringify(c)),t.needsOrigin){let h=new Set(Array.isArray(n.trustedLocalOrigins)?n.trustedLocalOrigins:[]);for(let u of t.origins)h.add(u);n.trustedLocalOrigins=[...h]}t.needsNotice&&(n.localOriginTrustNoticeV1=!0),Object.prototype.hasOwnProperty.call(n,"enableLoadScreenShot")||(n.enableLoadScreenShot="yes"),Object.prototype.hasOwnProperty.call(n,"enableScreenSvg")||(n.enableScreenSvg=n.enableLoadScreenShot??"yes"),n.sortMethod==null&&["default","rateCount","date"].includes(s||"")&&(n.sortMethod=s),n.foldCategoryCollapsed==null&&["yes","no"].includes(a||"")&&(n.foldCategoryCollapsed=a==="yes"),n.videoMuted==null&&["yes","no"].includes(i||"")&&(n.videoMuted=i==="yes");for(let h of r?.cleanup?.settingKeys||[])n[h]===r.cleanup.settingValues?.[h]&&delete n[h]})}d(Gu,"persistBootstrapMigration");async function Qu(o){let e=await o.getSetting(),t=new Set(Array.isArray(e.trustedLocalOrigins)?e.trustedLocalOrigins:[]),s=null;try{e.webDavUrl&&(s=new URL(e.webDavUrl).origin)}catch{}return s&&!t.has(s)?(t.add(s),{origins:[...t],notice:`已按现有 WebDAV 配置授权本地来源:${s}`,needsOrigin:!0}):s&&!e.localOriginTrustNoticeV1?{origins:[...t],notice:`WebDAV 仅信任精确来源:${s}`,needsNotice:!0}:{origins:[...t],notice:null}}d(Qu,"resolveLocalOrigins");async function Id(){try{let o=performance.now(),e=globalThis.__jhsBrowserDiagnostics,t=d(E=>e&&((e.bootstrapPhases||(e.bootstrapPhases={}))[E]=performance.now()-o),"markPhase"),s=Eo(window.location),a=cl(),i=ol(),{utils:r,gmHttp:n,storageManager:l,stateService:c}=nl(i);t("legacy-runtime"),Object.assign(globalThis,{utils:r,gmHttp:n,storageManager:l,stateService:c,jhsEventBus:i}),["blacklist-rules-changed","filter-rules-changed","legacy-refresh"].forEach((E=>i.on(E,(()=>l._invalidateCache())))),i.on("car-state-changed",()=>l._invalidateCache(l.car_list_key)),Wu(a.layer,r),await Promise.resolve(),Ju(r),t("pre-settings");let h=await Ku(l),u=h.migrated,p=await Qu(l),g=new $s,m=new _s,f=N?g:B?m:null,v=f?.detectRoute()??"other",b=Oc({gmRequest:globalThis.GM_xmlhttpRequest,gmGetValue:globalThis.GM_getValue,gmSetValue:globalThis.GM_setValue,gmDeleteValue:globalThis.GM_deleteValue,legacyHttp:n,legacyStorage:l,eventBus:i,storageForage:l.forage,localStorage:globalThis.localStorage,layer:a.layer,stateService:c,hostAdapter:f,hostAdapters:{javdb:g,javbus:m},site:s.site,route:v,disabled:u,localOrigins:p.origins});t("context"),Ho(b.services.styles,qo()),Object.assign(globalThis,{settingsService:b.services.settings,credentialService:b.services.credential}),await b.services.settings.load(),t("settings-load");let w=await b.services.credential.migrateLegacy(b.services.settings,{deferCleanup:!0});b.services.profile.start();let S=localStorage.getItem("jhs_sortMethod"),j=localStorage.getItem("jhs_foldCategory"),k=localStorage.getItem("jhs_videoMuted");w.cleanup=await b.services.credential.validateLegacyCleanup(w.cleanup),await Gu(b.services.settings,h,p,S,j,k,w),await b.services.credential.cleanupLegacyPageStorage(w.cleanup?.pageKeys,b.services.settings),t("settings-migration");let x=ll(b.rootScope,{clogMsgCount:b.services.settings.snapshot().clogMsgCount});t("logger"),zo(b.rootScope),Fo(b.rootScope),t("theme-ui"),b.services.diagnostics.setBrowserMetadata({userAgent:navigator.userAgent,platform:navigator.platform,...globalThis.__jhsBrowserTestMetadata??{}}),Object.assign(globalThis,x),w.issues?.length&&x.show.info("部分旧凭证未能安全迁移,已保留原数据,请重新保存对应凭证"),p.notice&&x.show.info(p.notice);let _=new ys({diagnostics:b.services.diagnostics});for(let E of Pd)b.registries.integrations.register(E);for(let E of bl)b.registries.features.register(E);return Rc(_,b.registries.features,s.site),t("registry"),Ec({pluginManager:_,utils:r,gmHttp:n,storageManager:l,stateService:c,jhsEventBus:i,clog:x.clog,show:x.show,loading:x.loading},globalThis.unsafeWindow),window.isDetailPage=v==="detail",window.isListPage=v==="list",await b.registries.features.start(),t("feature-runtime"),await ws(l),await l.getReviewFilterKeywordList(),await c.recoverPendingTransaction(),t("data-prepare"),await Promise.all([_.processCss(),Promise.resolve(Vt(b.services.settings.snapshot().themeMode))]),t("plugin-css"),N&&/(^|;)\s*locale\s*=\s*en\s*($|;)/i.test(document.cookie)&&x.show.error("请切换到中文语言下才可正常使用本脚本",{duration:-1}),await _.processPlugins(),t("plugin-runtime"),t("first-ready"),t("total"),b}catch(o){throw o instanceof D?o:new D("BOOTSTRAP_FAILED",o instanceof Error?o.message:"JHS 启动失败",{source:"bootstrap",cause:o})}}d(Id,"bootstrapJhs");function Rd(o){if(console.error("[JHS] bootstrap failed:",o),globalThis.show?.error)return globalThis.show.error(o?.message||"JHS 启动失败",{duration:-1});let e=document.createElement("div");e.id="jhs-bootstrap-error",e.setAttribute("role","alert"),e.textContent=`JHS 启动失败:${o?.message||"未知错误"}`,Object.assign(e.style,{position:"fixed",inset:"12px 12px auto",zIndex:"2147483647",padding:"12px",background:"#7f1d1d",color:"white"}),document.documentElement.append(e)}d(Rd,"mountBootstrapError");Id().catch(Rd);})();