JAV Helper Suite:为 JavDB / JavBus 提供浏览、收藏、筛选、资源检索、数据备份与统计增强。
// ==UserScript== // @name JHS // @namespace https://sleazyfork.org/zh-CN/scripts/578503-jhs-ya // @version 6.5.1 // @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 Po=Object.defineProperty;var Ud=(o,e,t)=>e in o?Po(o,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[e]=t;var d=(o,e)=>Po(o,"name",{value:e,configurable:!0});var ct=(o,e,t)=>Ud(o,typeof e!="symbol"?e+"":e,t);var Dr=class Dr{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(Dr,"LifecycleScope");var te=Dr;var gs=new WeakSet;function kt(o={},e={}){if(gs.has(o)||gs.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 r,i=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,r=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","关闭弹窗"),r.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");r.listen(window,"resize",p),p()}try{return i?.call(this,l,c)}catch(u){throw r?.dispose(),u}},s.end=function(...l){return r?.dispose(),n?.apply(this,l)},gs.add(s),gs.add(s.success),s}d(kt,"prepareDialogOptions");var zd=/^(?:[a-z0-9-]+\.)?javdb(?:[a-z0-9-]*)\.com$/i,Fd=["javbus","javsee","seejav"];function Nr(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(Nr,"normalizeLocation");function Ct(o=window.location){let t=Nr(o).hostname.toLowerCase().replace(/\.$/,""),s=zd.test(t),a=Fd.some((c=>t.includes(c))),r=t==="123pan.com"||t.endsWith(".123pan.com"),i=t==="javtrailers.com"||t.endsWith(".javtrailers.com"),n=t==="subtitlecat.com"||t.endsWith(".subtitlecat.com");return{site:s?"javdb":a?"javbus":r?"123pan":i?"javtrailers":n?"subtitlecat":"unknown",hostname:t,isJavDB:s,isJavBus:a,is123Pan:r,isJavTrailers:i,isSubtitleCat:n}}d(Ct,"detectSite");function je(o=window.location){let e=Nr(o),t=e.pathname,s=e.searchParams;return t==="/rankings/movies"?{kind:"movie-ranking",period:s.get("p")||"daily",category:s.get("t")||"censored"}:t==="/rankings/playback"?{kind:"playback-ranking",period:s.get("p")||"daily",filter:s.get("t")||"high_score"}:t==="/rankings/top"?{kind:"top250-ranking",selection:s.get("t")||"all",page:Math.max(1,Number(s.get("page"))||1)}:t==="/rankings/actors"?{kind:"actor-ranking"}:t==="/rankings/fanza_award"?{kind:"award-ranking"}:t==="/tags/fc2"?{kind:s.get("jhs_source")==="123av"?"external-fc2-catalog":"fc2-catalog"}:t==="/search_advanced"?{kind:"advanced-search"}:{kind:"other"}}d(je,"classifyJavDbPage");function Io(o){let e=Nr(o);if(e.pathname!=="/advanced_search")return null;let t=e.searchParams,s=new URL(e.href);if(t.get("handlePlayback")==="1"){s.pathname="/rankings/playback",s.search="";let a=t.get("period")||"daily";s.searchParams.set("p",["daily","weekly","monthly"].includes(a)?a:"daily"),s.searchParams.set("t","high_score")}else if(t.get("handleTop")==="1"){s.pathname="/rankings/top",s.search="";let a=t.get("handleType"),r=t.get("type_value")||"";a==="year"&&/^\d{4}$/.test(r)&&s.searchParams.set("t",`y${r}`),a==="video_type"&&/^[0-3]$/.test(r)&&s.searchParams.set("t",r);let i=Math.max(1,Number.parseInt(t.get("page")||"1",10)||1),n=Math.floor((i-1)*50/40)+1;n>1&&s.searchParams.set("page",String(n)),["0","1"].includes(t.get("has_cnsub")||"")&&s.searchParams.set("jhs_subtitle",t.get("has_cnsub")==="1"?"with":"without")}else if(t.get("type")==="100"&&t.get("released_start")==="2099-09"){s.pathname="/tags/fc2",s.search="",s.searchParams.set("c10","1"),s.searchParams.set("jhs_source","123av");for(let a of["keyword","page"])t.has(a)&&s.searchParams.set(a,t.get(a)||"")}else s.pathname="/search_advanced";return s.href}d(Io,"resolveLegacyJavDbUrl");var Vd=Object.defineProperty,Lr=d(o=>{throw TypeError(o)},"a"),P=d((o,e,t)=>((s,a,r)=>a in s?Vd(s,a,{enumerable:!0,configurable:!0,writable:!0,value:r}):s[a]=r)(o,typeof e!="symbol"?e+"":e,t),"i"),Mr=d((o,e,t)=>(((s,a,r)=>{a.has(s)||Lr("Cannot "+r)})(o,e,"access private method"),t),"s"),X="",Br={site:"unknown",hostname:"",isJavDB:!1,isJavBus:!1,is123Pan:!1,isJavTrailers:!1,isSubtitleCat:!1},M=!1,B=!1,ms=!1,ce="filter",ue="favorite",pe="hasDown",me="hasWatch",Le="屏蔽",tt="已屏蔽";var Me="收藏",st="已收藏";var fe="已下载";var ve="已观看";var ne="no",R="yes",Be="javdb",Se="javbus",Oe="actor",at="actress",We="censored",Ke="uncensored",rt=[{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 Ro(o=window.location){let e=Ct(o);return X=o.href,Br=e,M=e.isJavDB,B=e.isJavBus,ms=X.includes("/search?q")||X.includes("/search/")||X.includes("/users/"),e}d(Ro,"initializeRuntimeConstants");function C(o){let e=document.createElement("span");return e.textContent=o,e.innerHTML.replaceAll('"',""").replaceAll("'","'")}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?qd(e):null)}d(T,"normalizeCarNum");var Hd=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 qd(o){let e=String(o||"").match(/^([A-Z]{2,8})(\d{2,7})$/);return e&&Hd.has(e[1])?`${e[1]}-${e[2]}`:o}d(qd,"tryCanonicalizeSimpleCarNum");function Eo(...o){for(let e of o){let t=T(e);if(t)return t}return null}d(Eo,"firstValidCarNum");function Do(o){if(!o||typeof o!="object"||Array.isArray(o))throw new TypeError("getPageInfo() contract broken: expected object");return o}d(Do,"assertPageInfoContract");function No(){return window.location.href.includes("hideNav=1")?` .navbar-default { display: none !important; } body { padding-top:0px!important; } `:""}d(No,"getJavBusHiddenNavCss");function Lo(){return window.location.href.includes("hideNav=1")?` .main-nav,#search-bar-container { display: none !important; } html { padding-top:0px!important; } `:""}d(Lo,"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 W=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 Bo(){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: ${W.content}; --jhs-z-elevated: ${W.elevated}; --jhs-z-local-popover: ${W.localPopover}; --jhs-z-popover: ${W.popover}; --jhs-z-dropdown: ${W.dropdown}; --jhs-z-fab-backdrop: ${W.fabBackdrop}; --jhs-z-fab-menu: ${W.fabMenu}; --jhs-z-fab: ${W.fab}; --jhs-z-debug-low: ${W.debugLow}; --jhs-z-host-nav: ${W.hostNav}; --jhs-z-host-topbar: ${W.hostTopbar}; --jhs-z-hover-preview: ${W.hoverPreview}; --jhs-z-modal: ${W.modal}; --jhs-z-sheet-backdrop: ${W.sheetBackdrop}; --jhs-z-sheet: ${W.sheet}; --jhs-z-layer: ${W.layer}; --jhs-z-dialog-hover-preview: ${W.dialogHoverPreview}; --jhs-z-viewer: ${W.viewer}; --jhs-z-loading: ${W.loading}; --jhs-z-debug: ${W.debug}; --jhs-z-tooltip: ${W.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(Bo,"buildThemeCss");function Ht(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(Ht,"applyThemeMode");function Oo(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"&&Ht(t)})}d(Oo,"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 Ue(o,{type:e="empty",title:t="",description:s="",actionLabel:a="",onAction:r=null}={}){let i=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 r=="function"&&l.append($('<button type="button" class="jhs-btn jhs-btn--secondary"></button>').text(a).on("click",r)),n.append(l),i.empty().append(n),n}d(Ue,"renderStateView");function zo(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(i=>{let n=i.nodeType===Node.ELEMENT_NODE&&i.matches?.(e)?[i]:[],l=i.querySelectorAll?[...i.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,r=d(()=>{a=!1;let i=[...s],n=i.filter((l=>!i.some((c=>c!==l&&c.contains?.(l)))));s.clear(),n.forEach(t)},"flush");return o.observe(document.documentElement,(i=>{i.forEach((n=>n.addedNodes.forEach((l=>{l.nodeType===Node.ELEMENT_NODE&&s.add(l)})))),s.size&&!a&&(a=!0,queueMicrotask(r))}),{childList:!0,subtree:!0})}d(zo,"initializeUiAccessibility");var ie=class ie{static _ensureGlobalClickHandler(){ie._globalClickBound||(ie._globalClickBound=!0,$(document).on("click.jhsSelect",(e=>{$(e.target).closest(".jhs-select-control").length||ie.closeAll()})))}constructor(e){if(this.source=$(e),!this.source.length)return;let t=ie.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"),ie.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,r)=>new ie(r))),s}static get(e){let t=$(e)[0];return t?ie.instances.get(t)||new ie(t):null}static setValue(e,t,s=!1){let a=ie.get(e);a&&(a.source.val(t),s?a.emitChange():a.refresh())}static refresh(e){ie.get(e)?.refresh()}static refreshAll(e=document){ie.enhance(e),$(e).find("select.jhs-select-source").each(((t,s)=>ie.refresh(s)))}static setVisible(e,t){ie.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],r=a&&ie.instances.get(a);r&&r!==e&&r.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),r=$('<div class="jhs-select-group__label"></div>').text(s.label);a.append(r),$(s).children("option").each(((i,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())),ie._ensureGlobalClickHandler()}options(){return this.menu.find(".jhs-select-option:not(:disabled)")}open(e="selected"){ie.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(ie,"JhsSelect"),ct(ie,"instances",new WeakMap),ct(ie,"_globalClickBound",!1);var K=ie;function Jd(){return` <style> .top-bar { z-index:var(--jhs-z-host-topbar)!important; } ${No()} .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(Jd,"buildJavBusCss");function Wd(){return` <style> ${Lo()} .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(Wd,"buildJavDbCss");var Kd=` <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>`,Fo=!1;function Vo(o,e=""){if(Fo)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",Bo()),B&&t("jhs-host-javbus",Jd()),M&&t("jhs-host-javdb",Wd()),t("jhs-core-layout",Kd),t("jhs-ui-primitives",Uo()),e&&t("jhs-detail-panels",e),Fo=!0}d(Vo,"injectCoreCss");function Ho(){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(Ho,"buildDetailPanelCss");var Gd=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"]),_t=class _t extends Error{constructor(e,t,s={}){if(super(t,{cause:s.cause}),!Gd.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 _t)return e;if(e instanceof DOMException&&e.name==="AbortError")return new _t("ABORTED","请求已取消",{source:t,cause:e});let s=e instanceof Error?e.message:String(e??"未知错误");return new _t("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(_t,"JhsError");var D=_t;var dt=Object.freeze(["favorite","downloaded","watched","blocked"]),Or=Object.freeze({[ue]:"favorite",[pe]:"downloaded",[me]:"watched",[ce]:"blocked"});function qt(){return{favorite:!1,downloaded:!1,watched:!1,blocked:!1}}d(qt,"createEmptyStateFlags");function Qd(o){let e=qt(),t=typeof o=="string"?Or[o]:void 0;return t&&(e[t]=!0),e}d(Qd,"stateFlagsFromLegacyStatus");function q(o){let e=qt();return dt.forEach((t=>e[t]=o?.[t]===!0)),e}d(q,"normalizeStateFlags");function Yd(o){let e=q(o);return e.blocked?ce:e.watched?me:e.downloaded?pe:e.favorite?ue:""}d(Yd,"projectLegacyStatus");function vs(o){return o.stateFlags=q(o.stateFlags),o.status=Yd(o.stateFlags),o}d(vs,"syncLegacyStatus");function oe(o){let e=q(o);return dt.some((t=>e[t]))}d(oe,"hasAnyState");function Ce(o){return typeof o=="string"&&Or[o]||null}d(Ce,"legacyActionToFlag");function qo(o){let e=new Map,t=[],s=[];o.filter(Boolean).forEach((r=>{let i=r.carNum,n=T(i);if(!n)return;let l={...r,carNum:n,stateFlags:r.stateFlags?q(r.stateFlags):Qd(r.status)};r.stateFlags||!r.status||Or[r.status]||s.push({carNum:n,status:r.status});let c=e.get(n)||[];c.push({original:i,item:l}),e.set(n,c)}));let a=[];for(let[r,i]of e){let n=i.map((g=>g.item)).sort(((g,m)=>String(g.updateDate||"").localeCompare(String(m.updateDate||"")))),l={},c=qt();n.forEach((g=>{Object.entries(g).forEach((([m,f])=>f!=null&&f!==""&&m!=="stateFlags"&&m!=="status"&&(l[m]=f))),dt.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=r,l.stateFlags=c,vs(l),a.push(l);let p=[...new Set(i.map((g=>g.original)).filter(Boolean))];p.length>1&&t.push({carNum:r,originals:p,count:i.length})}return{list:a,collisions:t,unknownStatuses:s}}d(qo,"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"]),Wo=Object.freeze(["trustedLocalOrigins","webDavUrl","webDavUsername","webDavPassword"]),Ko=Object.freeze(["webDavPassword"]),Zd=new Set(["car_list","filter_keyword_title","filter_keyword_review","blacklist","blacklist_car_list","favorite_actresses","highlighted_tags","offline_history"]),Xd=new Set(["setting","third_party_ttl_cache","activity_log","new_video_decisions"]);function Ur(o){let e=o&&typeof o=="object"&&!Array.isArray(o)?{...o}:{};for(let t of[...Wo,...Ko])delete e[t];return e}d(Ur,"selectPortableSettings");function Go(o,e){let t=Ur(e);for(let s of[...Wo,...Ko])Object.prototype.hasOwnProperty.call(o||{},s)&&(t[s]=o[s]);return t}d(Go,"mergePortableSettings");function Qo(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 Zd)if(o[t]!=null&&!Array.isArray(o[t]))throw new TypeError(`备份字段 ${t} 必须为数组`);for(let t of Xd)if(o[t]!=null&&(typeof o[t]!="object"||Array.isArray(o[t])))throw new TypeError(`备份字段 ${t} 必须为对象`);return e}d(Qo,"validatePortableData");async function zr(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(zr,"hasPortableUserData");async function eh(o){if(!await zr(o))return null;let e=await o._getSnapshots(),t=e.find(i=>i.kind==="migration-snapshot"&&i.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(((i,n)=>i+(Array.isArray(n)?n.length:n&&typeof n=="object"?1:0)),0),data:s},r=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",r):await r()}d(eh,"ensureV2MigrationSnapshot");async function th(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(th,"migrateLegacyStorage");async function sh(o){await eh(o);let e=await o.forage.getItem(o.car_list_key)||[],t=qo(e);await o._setItemAndInvalidate(o.car_list_key,t.list);let a=(await o.forage.getItem(o.favorite_actresses_key)||[]).map(i=>{if(!Array.isArray(i.newVideoList))return i;let n=i.newVideoList.map(l=>typeof l=="string"?T(l):{...l,carNum:T(l.carNum)}).filter((l=>typeof l=="string"?l:l.carNum));return{...i,newVideoList:n}});await o._setItemAndInvalidate(o.favorite_actresses_key,a);let r=await o.forage.getItem("data_health_warnings")||[];t.collisions.length&&r.push({type:"canonical-collision",createdAt:new Date().toISOString(),items:t.collisions}),t.unknownStatuses.length&&r.push({type:"unknown-legacy-status",createdAt:new Date().toISOString(),items:t.unknownStatuses}),r.length&&await o.forage.setItem("data_health_warnings",r)}d(sh,"migrateStateFlags");async function ah(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:[],r={...t||{}},i=Array.isArray(s?.entries)?s.entries:[],n=new Map;i.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=r[u];r[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",r),await o._setItemAndInvalidate(o.car_list_key,c),l):[]}d(ah,"repairNewVideoTombstones");async function rh(o){await ah(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(rh,"migrateV3");var ih=Object.freeze({1:th,2:sh,3:rh});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 r=ih[a];if(!r)throw new Error(`缺少数据迁移: ${a-1} → ${a}`);await r(o),await o.setDataVersion(a),s=a}return s},"run");return e?.request?e.request("jhs_data_migration",t):t()}d(ws,"runDataMigrations");var Fr=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"}),nh=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=Fr,s=nh;return[...new Set(e.filter(a=>typeof a=="string").flatMap(a=>s[a]??[t[a]??a]))]}d($t,"migrateDisabledPlugins");function Tt(o){return Fr[o]??o}d(Tt,"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 Vr=class Vr{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(),r=new e;r.pluginManager=this;let i=r.getName();if(this.plugins.has(i))throw new Error(`插件"${i}"已注册`);r.declaredDependencies=new Set(this._dependencyDeclarations[i]||[]),r.runtimeServices=Object.freeze({...t}),r.disableable=s.disableable??!0,this.plugins.set(i,r),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(Tt(s)))).map((([s])=>s)))}catch{return new Set}})())}async processCss(){let e=performance.now(),t=await this._getDisabledPlugins(),s=utils.isMobileMode(),r=(await Promise.all(Array.from(this.plugins).map((async([i,n])=>{try{if(t.has(i))return{name:i,status:"disabled"};if(s&&typeof n.shouldSkipOnMobile=="function"&&n.shouldSkipOnMobile())return{name:i,status:"skipped"};if(typeof n.initCss=="function"){let l=await n.initCss();return{name:i,status:"fulfilled",css:l}}return{name:i,status:"skipped"}}catch(l){return clog.error(`插件 ${i} 加载 CSS 失败`,l),this._addError(i,"initCss",l),{name:i,status:"rejected",error:l}}})))).map((i=>i.css)).filter(Boolean);r.length>0&&utils.insertStyle(r),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=[],r=[];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",r.push(h);else if(t&&typeof l.shouldSkipOnMobile=="function"&&l.shouldSkipOnMobile())h.status="skipped-mobile",r.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),r.push(h)}}this._lastTimings=r;let i=performance.now();await Promise.all(s.map((n=>(n.startedAt=performance.now(),this._runPlugin(n))))),this._immediateMs=performance.now()-i;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(Vr,"PluginManager");var ys=Vr,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="",P(this,"pluginManager",null),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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>'),P(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,r,i=window.location.href;if(M){let n=new URL(i).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=Eo(l,c,h,u),t=i.split("?")[0].split("#")[0],s=$(".female").prev().map(((p,g)=>$(g).text())).get().join(" "),a=$(".male").prev().map(((p,g)=>$(g).text())).get().join(" "),r=$('strong:contains("日期:")').parent(".panel-block").find(".value").text().trim()}return B&&(t=i.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="",r=$('span.header:contains("發行日期:")').parent("p").text().trim().replace("發行日期:","").trim()),Do({carNum:e,url:t,actress:s,actors:a,publishTime:r})}getActressId(){let e=X.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=M?$(".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 r=$(".section-meta:contains('男優')").length>0?Oe:at,i=We;t.some(h=>h.includes("無碼"))&&(i=Ke),e.includes("uncensored")&&(i=Ke);let n=null,l=null,c=new URL(e);if(M){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:r,movieType:i,blacklistUrl:n}}getSelector(e){let t=e||(M?Be:B?Se: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 r=e.find("a"),i=r.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=r.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:i||"",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,r)=>{let i=$(r);try{let n=this.getBoxCarInfo(i);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((r=>r.carNum)).filter((r=>r)));if(s.size===0)return!1;let a=0;for(let r=0;r<t.length;r++){let i=t[r]?t[r].carNum:null;if(i&&s.has(i)){if(a++,a>=2)return clog.warn("警告: 检测到连续番号信息重复, 该类别可能已被限制页码。"),!0}else a=0}return!1}};d(it,"BasePlugin"),ct(it,"_sharedIcons",null);var I=it;var Hr=class Hr{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),r=/id=["']challenge-form["']/i.test(e),i=s.includes("cf-chl-")||s.includes("cf_chl_opt"),n=s.includes("/cdn-cgi/challenge-platform/")||s.includes("challenge-platform");return a||r&&(i||n)||(t===403||t===429||t===503)&&i&&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,r={}){return this.gmRequest("GET",e,null,t,s,a,r)}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={},r={},i=!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:r,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 x=new Error(`Cloudflare challenge blocked: ${t}`);return x._cfBlocked=!0,x.status=j.status,x.requestUrl=t,x.finalUrl=j.finalUrl,x.cfDiagnostics={status:j.status,requestUrl:t,finalUrl:j.finalUrl,contentLength:j.responseText?.length||0},void S(x)}if(i&&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 x=JSON.parse(j.responseText);x.status=j.status,S(x)}catch{let x=new Error(j.responseText||`请求发生错误 ${j.status}`);x.status=j.status,S(x)}else{let x=new Error(`请求发生错误 ${j.status}`);x.status=j.status,S(x)}}catch(x){v(!0),S(x)}},"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(Hr,"GmHttp");var js=Hr;var oh=1e3,Yo=1e4,lh=30*864e5;function le(o){return o==null?o:JSON.parse(JSON.stringify(o))}d(le,"cloneStateValue");function xe(o){return o===null||typeof o!="object"?JSON.stringify(o):Array.isArray(o)?`[${o.map(xe).join(",")}]`:`{${Object.keys(o).sort().map((e=>`${JSON.stringify(e)}:${xe(o[e])}`)).join(",")}}`}d(xe,"stableStateValue");async function ch(o){let e=globalThis.crypto?.subtle;if(!e)throw new Error("当前环境不支持状态冲突归档哈希");let t=new TextEncoder().encode(xe(o)),s=await e.digest("SHA-256",t);return Array.from(new Uint8Array(s),(a=>a.toString(16).padStart(2,"0"))).join("")}d(ch,"hashState");function qr(o,e){return e.split(".").reduce(((t,s)=>t?.[s]),o)}d(qr,"getStatePath");function dh(o,e,t){let s=e.split("."),a=s.pop(),r=s.reduce(((i,n)=>i[n]||(i[n]={})),o);a&&(t===void 0?delete r[a]:r[a]=le(t))}d(dh,"setStatePath");function Jt(o){return[...new Set(o.filter((e=>typeof e=="string"&&!!e)))]}d(Jt,"uniqueStateKeys");function Jr(o,e,t){let s=T(t),a=[];return o.forEach(((r,i)=>(r.newVideoList||[]).forEach(((n,l)=>{T(typeof n=="string"?n:n.carNum)===s&&a.push({actressIndex:i,itemIndex:l,item:le(n)})})))),{actressItems:a,decision:le(e[s]||null)}}d(Jr,"captureNewVideoEffect");function hh(o,e,t,s,a=null){let r=T(t);return xe(e[r]||null)!==xe(a)?!1:s.actressItems.every((i=>!(o[i.actressIndex]?.newVideoList||[]).some(n=>T(typeof n=="string"?n:n.carNum)===r)))}d(hh,"canRestoreNewVideoEffect");function Zo(o,e,t,s){s.actressItems.forEach((r=>{let i=o[r.actressIndex];if(!i)return;let n=[...i.newVideoList||[]],l=Math.min(r.itemIndex,n.length);n.splice(l,0,le(r.item)),i.newVideoList=n}));let a=T(t);s.decision?e[a]=le(s.decision):delete e[a]}d(Zo,"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-lh,a=[],r=[];t.entries.forEach((n=>(Date.parse(n.createdAt)>=s||n.commitState==="pending"?a:r).push(n))),r.sort(((n,l)=>String(n.createdAt).localeCompare(String(l.createdAt)))),a.sort(((n,l)=>String(n.createdAt).localeCompare(String(l.createdAt))));let i=Math.max(0,oh-a.length);if(t.entries=[...r.slice(-i),...a].sort(((n,l)=>String(n.createdAt).localeCompare(String(l.createdAt)))),t.entries.length>Yo){let n=t.entries.filter((h=>h.commitState==="pending")),l=t.entries.filter((h=>h.commitState!=="pending")),c=Math.max(0,Yo-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 Wr=class Wr{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((r=>!t.has(r.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,r,i,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:r||[],decisions:i||{},activity:Ss(n)}}_removeHandledNewVideos(e,t,s){let a=new Set(Jt(s.map(T))),r={...t};return a.forEach((n=>delete r[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:r}}async _writeActivity(e){await this.storage.forage.setItem("activity_log",Ss(e))}async _commit(e,t,s,a=["carList","activity"]){let r=le(s),i={...e.activity,entries:[...e.activity.entries,r]},n=[...new Set([...a,"activity"])],l=d((h,u=!1)=>Object.fromEntries(n.map(p=>[p,le(p==="activity"&&u?i: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(i),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",i.entries=i.entries.map((h=>h.id===s.id?s:h)),await this._writeActivity(i),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((r=>r.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 r=await this._readDomains(a),i=a.filter(l=>l!=="activity");if(i.some((l=>{let c=xe(r[l]);return c!==xe(e.before[l])&&c!==xe(e.after[l])}))){let l={journal:le(e),detectedAt:new Date().toISOString(),currentStateHash:await ch(Object.fromEntries(i.map(c=>[c,r[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=Jt((Array.isArray(e)?e:[e]).map(T));if(!a.length)throw new Error("番号为空");let r=Object.keys(t).find((i=>!dt.includes(i)||typeof t[i]!="boolean"));if(r)throw new TypeError(`无效状态字段: ${r}`);return this._withLock((()=>this._patchWithoutLock(a,t,s)))}async _patchWithoutLock(e,t,s){await this._recoverWithoutLock();let a=await this._readDomains(),r=new Map(a.carList.map((u=>[T(u.carNum),u]))),i=[],n=[],l=Array.isArray(s.records)?new Map(s.records.map((u=>[T(u.carNum),u]))):new Map;if(e.forEach((u=>{let p=r.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:qt()},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))})),dt.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),r.set(u,v),i.push({carNum:u,operation:p?"patch":"create",fields:b,before:f,after:le(v),undoState:"pending"}))})),!i.length)return{changed:[],transactionId:null};i.forEach((u=>n.includes(u.carNum)&&(u.newVideoEffect=Jr(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:i,createdAt:new Date().toISOString(),undoAttemptedAt:null};return await this._commit(a,{carList:[...r.values()],...c},h,n.length?["carList","actresses","decisions","activity"]:["carList","activity"]),await this.eventBus.emit("car-state-changed",{carNums:i.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:i.map((u=>u.carNum)),transactionId:h.id}}async toggle(e,t,s={}){if(!dt.includes(t))throw new TypeError(`无效状态字段: ${t}`);let a=T(e);if(!a)throw new Error("番号为空");return this._withLock(async()=>{await this._recoverWithoutLock();let r=await this.storage.getCar(a),i=q(r?.stateFlags);return this._patchWithoutLock([a],{[t]:!i[t]},s)})}async remove(e){let t=new Set(Jt((Array.isArray(e)?e:[e]).map(T)));return this._withLock(async()=>{await this._recoverWithoutLock();let s=await this._readDomains(),a=s.carList.filter(i=>t.has(T(i.carNum))).map(i=>({carNum:T(i.carNum),operation:"delete",fields:["record"],before:le(i),after:null,undoState:"pending"}));if(!a.length)return{changed:[],transactionId:null};let r={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(i=>!t.has(T(i.carNum))),actresses:s.actresses,decisions:s.decisions},r,["carList","activity"]),await this.eventBus.emit("car-records-removed",{carNums:a.map(i=>i.carNum),transactionId:r.id}),await this.eventBus.emit("activity-log-changed",{transactionId:r.id}),{changed:a.map(i=>i.carNum),transactionId:r.id}})}async setNewVideoDecision(e,t,s=null){if(!["ignored","snoozed","dismissed",null].includes(t))throw new TypeError("无效新作决策");let a=Jt((Array.isArray(e)?e:[e]).map(T));return this._withLock(async()=>{await this._recoverWithoutLock();let r=await this._readDomains(),i={...r.decisions},n=new Date().toISOString(),l=[];if(a.forEach((u=>{let p=le(i[u]||null),g=t?{action:t,until:t==="snoozed"?s:null,createdAt:p?.createdAt||n,updatedAt:n}:null;xe(p)===xe(g)||(g?i[u]=g:delete i[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(r,{carList:r.carList,actresses:r.actresses,decisions:i},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=Jt((Array.isArray(e)?e:[e]).map(T));return this._withLock(async()=>{await this._recoverWithoutLock();let a=await this._readDomains(),r=s.filter((u=>{let p=Jr(a.actresses,a.decisions,u);return p.actressItems.length>0||!!p.decision&&p.decision.action!=="dismissed"}));if(!r.length)return{changed:[],transactionId:null};let i=new Date().toISOString(),n={...a.decisions},l=r.map((u=>{let p=Jr(a.actresses,a.decisions,u),g={action:"dismissed",until:null,createdAt:p.decision?.createdAt||i,updatedAt:i};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,r),h={id:globalThis.crypto?.randomUUID?.()||`activity_${Date.now()}`,type:"new-video-remove",commitState:"pending",changes:l,createdAt:i,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:r,reason:t}),await this.eventBus.emit("activity-log-changed",{transactionId:h.id}),{changed:r,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 r=new Map(s.carList.map((v=>[T(v.carNum),le(v)]))),i={...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=r.get(v.carNum);if(v.newVideoEffect&&!hh(n,i,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)):(r.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=i[v.carNum]||null;xe(w)!==xe(v.after)?(v.undoState="conflict",c.push(v.carNum)):(v.before?i[v.carNum]=le(v.before):delete i[v.carNum],v.undoState="reverted",l.push(v.carNum),h.add("decisions"));continue}if(v.operation==="new-video-remove"){Zo(n,i,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=>xe(qr(b,w))!==xe(qr(v.after,w))))){v.undoState="conflict",c.push(v.carNum);continue}v.operation==="create"&&!v.before?r.delete(v.carNum):(v.fields.forEach((w=>dh(b,w,qr(v.before,w)))),vs(b),r.set(v.carNum,b)),h.add("carList"),v.newVideoEffect&&(Zo(n,i,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=[...r.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:i,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",i),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(Wr,"StateService");var xs=Wr;function Xo(o,e){e.stateService=o}d(Xo,"attachStateServiceCompatibility");function Kr(o,e){return new Map(o.filter((t=>t&&t[e])).map((t=>[t[e],t])))}d(Kr,"createIndexedMap");function el(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(el,"createStatusMap");function tl(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(tl,"groupDuplicateItems");function sl(o,e){let t=new Map,s=[],a=!1;for(let r of o){let i=r&&r[e];if(!i){s.push(r);continue}let n=t.get(i);n?(Object.assign(n,r),a=!0):(t.set(i,r),s.push(r))}return{list:s,changed:a}}d(sl,"dedupeByKey");var Gr="filter_keyword_review",Qr="review_filter_keyword",al=Promise.resolve();function Wt(o,e){let t=d(async()=>{let a=await o.get(Gr),r=await o.get(Qr),i=[...new Set([...Array.isArray(a)?a.map(String):[],...Array.isArray(r)?r.map(String):[],...e==null?[]:[e]])];if(JSON.stringify(a??[])!==JSON.stringify(i)&&(await o.set(Gr,i),JSON.stringify(await o.get(Gr))!==JSON.stringify(i)))throw new Error("评论关键词回读失败");return Array.isArray(r)&&JSON.stringify(await o.get(Qr))===JSON.stringify(r)&&await o.remove?.(Qr),i},"write"),s=al.then(async()=>{let a=globalThis.navigator?.locks;return a?.request?await a.request("jhs_keyword_lock",t):await t()});return al=s.then(()=>{},()=>{}),s}d(Wt,"readReviewKeywords");var Yr=new WeakSet,rl=d(async function(o,e,t){let s,a=globalThis.navigator?.locks,r=d(async()=>{if(Array.isArray(o))s=[...o];else{let i=await this.forage.getItem(e)||[];if(i.includes(o)){let n=`${o} ${t}已存在`;throw show.error(n),new Error(n)}i.push(o),s=i}return await this._setItemAndInvalidate(e,s),s},"write");return a?.request?a.request("jhs_keyword_lock",r):r()},"t"),Kt=class Kt{constructor(){this.stateService=globalThis.stateService??null;var e,t,s;if(e=this,(t=Yr).has(e)?Lr("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,s),P(this,"car_list_key","car_list"),P(this,"filter_keyword_title_key","filter_keyword_title"),P(this,"filter_keyword_review_key","filter_keyword_review"),P(this,"setting_key","setting"),P(this,"blacklist_key","blacklist"),P(this,"blacklist_car_list_key","blacklist_car_list"),P(this,"third_party_cache_key","third_party_ttl_cache"),P(this,"favorite_actresses_key","favorite_actresses"),P(this,"highlighted_tags_key","highlighted_tags"),P(this,"_actressLock",Promise.resolve()),P(this,"forage",localforage.createInstance({driver:localforage.INDEXEDDB,name:"JAV-JHS",version:1,storeName:"appData"})),P(this,"cacheCarList",null),P(this,"cacheBlacklist",null),P(this,"cacheTitleFilterKeyword",null),P(this,"cacheFavoriteActresses",null),P(this,"cache_filter_actor_actress_car_list",null),P(this,"cacheSettingObj",null),P(this,"cacheCarMap",null),P(this,"cacheStatusMap",null),P(this,"cacheBlacklistMap",null),P(this,"_pendingReads",new Map),P(this,"_cacheGenerations",new Map),P(this,"_cacheStats",{hits:0,misses:0}),Kt.instance)throw new Error("StorageManager已被实例化过了!");Kt.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 r=this._getCacheGeneration(t),i=this.forage.getItem(t).then(n=>{let l=n||s;return r===this._getCacheGeneration(t)&&this[e]===null&&(this[e]=l),l}).finally(()=>{this._pendingReads.get(t)===i&&this._pendingReads.delete(t)});return this._pendingReads.set(t,i),i}_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(r=>t=r),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:r,avatar:i,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),r&&(p.allName=r),i&&(p.avatar=i),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=Kr(e,"carNum")}return this.cacheCarMap}async getStatusMap(){if(this.cacheStatusMap===null){let e=await this.getCarList();this.cacheStatusMap=el(e)}return this.cacheStatusMap}async getCar(e){return(await this.getCarMap()).get(T(e))}_saveSingleCar(e,t){let{carNum:s,url:a,names:r,actionType:i,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),r&&(r=r.trim());let c=t.find((h=>h.carNum===s));if(c)r&&(c.names=r),a&&(c.url=a),n&&(c.publishTime=n),c.updateDate=utils.getNowStr();else{let h=utils.getNowStr();c={carNum:s,url:a,names:r,status:"",createDate:h,updateDate:h,publishTime:n},l&&(c.starId=l),t.push(c)}switch(i){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错误, 请联系作者更正: "+i;throw show.error(h),new Error(h)}}async saveCar(e){let t=T(e.carNum),s=Ce(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 r={blocked:"已在屏蔽列表中",favorite:"已在收藏列表中",downloaded:"已标记为已下载",watched:"已标记为已观看"},i=`${t} ${r[s]}`;throw show.error(i),new Error(i)}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:r,publishTime:i,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=Ce(r);if(!c){let h="actionType错误, 请联系作者更正: "+r;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:i}})}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 r of e){let i=T(r.carNum),n=Ce(r.actionType);if(!i)throw show.error("番号为空!"),new Error("番号为空!");if(!r.url)throw show.error("url为空!"),new Error("url为空!");if(!n)throw new Error("actionType错误, 请联系作者更正: "+r.actionType);let l=`${i}:${n}`;if(s.has(l)||q(t.get(i)?.stateFlags)[n])throw new Error(`${i} 状态已存在`);s.add(l);let c=a.get(n)||[];c.push({...r,carNum:i}),a.set(n,c)}for(let[r,i]of a)await this.stateService.patch(i.map((n=>n.carNum)),{[r]:!0},{type:"legacy-batch-save",records:i})}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,r=s.map((i=>{if(!i.newVideoList||!Array.isArray(i.newVideoList))return i;let n=i.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{...i,newVideoList:n}}));return a.size&&await this._setItemAndInvalidate(this.favorite_actresses_key,r),{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=Kr(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:r,movieType:i,url:n}=e;if(!t)throw new Error("缺失starId");if(!s)throw new Error("缺失name");if(!r)throw new Error("缺失role");let l=await this.getBlacklist(),c=l.find((h=>h.starId===t));if(c)c.url=n,c.role=r,c.movieType=i,clog.log("更新黑名单演员信息",c);else{let h={starId:t,name:s,allName:a||[s],createTime:utils.getNowStr(),role:r,movieType:i,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,r=[];for(let i of e)s.find((n=>n.carNum===i.carNum))||(this._saveSingleCar(i,s),clog.html(`屏蔽演员番号: <span class="jhs-layout-eeefd8c8">${C(i.names)} ${C(i.carNum)}</span>`),a=!0,r.push(i.carNum));if(a){await this._setItemAndInvalidate(this.blacklist_car_list_key,s);let i=await this.removeNewVideoList(r);i.changed.length&&await window.jhsEventBus?.emit?.("new-video-changed",{reason:"blacklist-car-removed",carNums:i.changed}),await window.cleanCache_filter_actor_actress_car_list()}return{changed:r.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:r,name:i,allName:n,avatar:l,lastCheckTime:c,lastPublishTime:h,actressType:u}=a;if(!r)throw new Error("缺失starId");if(!i)throw new Error("缺失name");n||(n=[i]);let p="(無碼)";u||(u=i.includes(p)||n.some((f=>f.includes(p)))?Ke:We),i=i.replace(p,""),n=n.map((f=>f.replace(p,"")));let g=t.find((f=>f.starId===r));if(g){g.avatar&&g.avatar.includes("https")||l&&(clog.log(l),g.avatar=l,clog.html(`<span class="jhs-layout-eeefd8c8">补全女优头像: ${C(i)}</span>`),s++),!g.actressType&&u&&(g.actressType=u,clog.html(`<span class="jhs-layout-eeefd8c8">补全女优类别: ${C(i)} ${C(u)}</span>`),s++),g.name.includes(p)&&(g.name=i,g.allName=n,clog.html(`<span class="jhs-layout-eeefd8c8">更正女优名字: ${C(i)} ${C(n)}</span>`),s++);continue}let m=utils.getNowStr();t.push({starId:r,name:i,allName:n,avatar:l,lastCheckTime:c,lastPublishTime:h,createDate:m,updateDate:m,actressType:u}),clog.html(`<span class="jhs-layout-eeefd8c8">同步JavDB已收藏的演员: ${C(i)}</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((r=>r.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 Mr(this,Yr,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((r=>{if(!r.newVideoList||!Array.isArray(r.newVideoList))return r;let i=r.newVideoList.filter((n=>{let l=typeof n=="string"?n:n.carNum,c=l.startsWith(e);return c&&(clog.log("移除关联女优新作品",r.name,l),s=!0),!c}));return{...r,newVideoList:i}}));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 Mr(this,Yr,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 r=await this.getSetting();r[e]=t,await this.saveSetting(r)},"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){Qo(e),await zr(this)&&await this.createSnapshot("导入前自动备份","auto-import");let t={...e};t.setting&&typeof t.setting=="object"&&!Array.isArray(t.setting)&&(t.setting=Go(await this.getSetting(),t.setting));let s=new Set([...Jo,"data_version"]);await this._withCrossTabLock("jhs_state_mutation",async()=>{let a=[];for(let r in t){if(!s.has(r)){clog.warn(`[导入] 跳过未知数据键: ${r}`);continue}r!=="third_party_ttl_cache"&&a.push(r==="data_version"?this.setDataVersion(t[r]):this._setItemAndInvalidate(r,t[r]))}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?Ur(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(),r=await this.getThirdPartyCache(),i=r[e];if(i&&i.time&&a-i.time<(i.ttl||t))return this._cacheStats.hits++,i.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:(r[e]={time:a,ttl:l,data:c},this._pruneThirdPartyCache(r,a),await this._withCrossTabLock("jhs_ttl_cache_lock",async()=>{let h=await this.getThirdPartyCache();h[e]=r[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 r=await this.getThirdPartyCache();r[e]={time:a,ttl:s,data:t},this._pruneThirdPartyCache(r,a),await this.setThirdPartyCache(r)})}_pruneThirdPartyCache(e,t){for(let i of Object.keys(e)){let n=e[i];(!n||n.time&&t-n.time>Math.max(n.ttl||0,2592e6))&&delete e[i]}let r=Object.keys(e);if(r.length>500){r.sort(((i,n)=>(e[i].time||0)-(e[n].time||0)));for(let i of r.slice(0,r.length-500))delete e[i]}}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 tl(e,t)}_dedupeByKey(e,t){return sl(e,t)}async inspectDataHealth(){let[e,t,s,a]=await Promise.all([this.getCarList(),this.getFavoriteActressList(),this.getBlacklist(),this.getBlacklistCarList()]),r=await this.getCarMap(),i={checkedAt:utils.getNowStr(),totals:{carList:e.length,favoriteActresses:t.length,blacklist:s.length,blacklistCarList:a.length},fixable:[],readonly:[]},n=d((k,_,E)=>i.fixable.push({type:k,message:_,count:E}),"o"),l=d((k,_,E)=>i.readonly.push({type:k,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((k=>k&&k.actress)).length,g=a.filter((k=>k&&k.actress)).length,m=t.filter((k=>k&&Object.prototype.hasOwnProperty.call(k,"dbId"))).length,f=s.filter((k=>k&&("key"in k||"recordTime"in k||"isActor"in k))).length;p+g+m+f>0&&n("legacy-fields","旧字段残留",p+g+m+f);let v=t.filter((k=>k&&k.name&&!Array.isArray(k.allName))).length+s.filter((k=>k&&k.name&&!Array.isArray(k.allName))).length;v&&n("invalid-all-name","演员别名不是数组",v);let b=0;t.forEach((k=>{Array.isArray(k?.newVideoList)&&(b+=k.newVideoList.filter((_=>{let E=typeof _=="string"?_:_.carNum;return r.has(E)})).length)})),b&&n("stored-new-video","新作品列表中已有鉴定记录",b);let w=e.filter((k=>k&&k.carNum&&!k.url)).length;w&&l("missing-url","番号记录缺失 url,需要人工确认来源",w);let S=t.filter((k=>k&&!k.starId)).length+s.filter((k=>k&&!k.starId)).length;S&&l("missing-star-id","演员缺失 starId,需要人工确认身份",S);let j=new Set(s.map((k=>k&&k.starId)).filter(Boolean)),x=a.filter((k=>k&&k.starId&&!j.has(k.starId))).length;return x&&l("orphan-blacklist-car","黑名单作品找不到关联演员",x),i}async repairDataHealth(){let e=0,t=await this.getCarList(),s=await this.getFavoriteActressList(),a=await this.getBlacklist(),r=await this.getBlacklistCarList(),i=this._dedupeByKey(t,"carNum");i.changed&&(t=i.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})),r=r.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?Oe:at),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,r),{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 r=new Set(a.map((n=>n.actress))),i=t.filter((n=>r.has(n.name)));i=i.map((n=>{let{key:l,recordTime:c,...h}=n,u=h;return c!==void 0&&(u.createTime=c),u})),(t.length!==i.length||t.some((n=>"key"in n||"recordTime"in n)))&&(clog.debug("清理 Blacklist 前",t.length),clog.debug("清理 Blacklist 后",i.length),await this._setItemAndInvalidate(this.blacklist_key,i))}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 r=t[a];Object.prototype.hasOwnProperty.call(s,a)&&(s[r]=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((i=>{let n=!1;if(Object.prototype.hasOwnProperty.call(i,"isActor")&&!i.role&&(i.role=i.isActor?Oe:at,delete i.isActor,n=!0),!i.starId&&i.url)try{let l=new URL(i.url).pathname,c=l.split("/").filter((h=>h.trim()!=="")).pop();i.starId!==c&&(i.starId=c,n=!0)}catch(l){clog.error("提取url-starId发生错误",i.url,l)}if(i.allName||(i.allName=i.name?[i.name]:[],n=!0),i.movieType||(i.movieType=We,n=!0),i.url&&i.url.includes("sort_type")){let l=new URL(i.url);l.searchParams.delete("sort_type"),i.url=l.toString(),clog.debug("去除黑名单地址sort_type参数")}return n&&(t=!0),i}));t&&(clog.debug("更正 Blacklist 数据结构"),await this._setItemAndInvalidate(this.blacklist_key,s));let a=await this.getBlacklistCarList();t=!1;let r=a.map((i=>{if(!i.starId){let n=e.find((l=>l.name===i.actress));n&&(i.starId=n.starId),t=!0}return i.type&&(delete i.type,t=!0),i}));t&&(clog.debug("更正 blacklistCarList 数据结构"),await this._setItemAndInvalidate(this.blacklist_car_list_key,r))}async merge_favoriteActress(){let e=await this.getFavoriteActressList();if(!e||e.length===0)return;let t=!1,s=e.map((a=>{let r=!1;return a.dbId&&(a.starId=a.dbId,delete a.dbId,r=!0),r&&(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((i=>{let n=!1;return i.actress!==void 0&&(i.names=i.actress,delete i.actress,n=!0),n&&(s=!0),i}));s&&(clog.debug("更正 blacklistCarList 数据结构 actress->names"),await this._setItemAndInvalidate(this.blacklist_car_list_key,a)),s=!1;let r=t.map((i=>{let n=!1;return i.actress!==void 0&&(i.names=i.actress,delete i.actress,n=!0),n&&(s=!0),i}));s&&(clog.debug("更正 carList 数据结构 actress->names"),await this._setItemAndInvalidate(this.car_list_key,r))}_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 r=0;for(let n of Object.values(a))Array.isArray(n)?r+=n.length:typeof n=="object"&&n&&r++;let i={id:"snap_"+Date.now()+"_"+Math.random().toString(36).slice(2,8),name:e||utils.getNowStr(),source:t,time:utils.getNowStr(),itemCount:r,data:a,kind:"snapshot"};return s.push(i),s.length>10&&s.splice(0,s.length-10),await this._saveSnapshots(s),clog.log(`创建快照: ${i.name} (${t})`),i})}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={},r={added:0,removed:0,modified:0,unchanged:0};for(let i of s){let n=e[i],l=t[i];if(!(n===void 0&&l===void 0))if(n===void 0){let c=Array.isArray(l)?l.length:1;a[i]={status:"added",oldCount:0,newCount:c,added:Array.isArray(l)?l:[],removed:[],modified:[]},r.added++}else if(l===void 0){let c=Array.isArray(n)?n.length:1;a[i]={status:"removed",oldCount:c,newCount:0,added:[],removed:Array.isArray(n)?n:[],modified:[]},r.removed++}else if(Array.isArray(n)&&Array.isArray(l)){let c=this._diffArrays(n,l,i);a[i]={status:c.status,oldCount:n.length,newCount:l.length,...c},r[c.status]++}else if(typeof n=="object"&&typeof l=="object"&&!Array.isArray(n)&&!Array.isArray(l)){let c=this._diffObjects(n,l);a[i]={status:c.status,oldCount:Object.keys(n).length,newCount:Object.keys(l).length,added:[],removed:[],modified:c.changes},r[c.status]++}else n===l?(a[i]={status:"unchanged",oldCount:1,newCount:1,added:[],removed:[],modified:[]},r.unchanged++):(a[i]={status:"modified",oldCount:1,newCount:1,added:[],removed:[],modified:[{key:i,changes:{_value:[n,l]}}]},r.modified++)}return{summary:r,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 r=new Map(e.map((u=>[u[a],u]))),i=new Map(t.map((u=>[u[a],u]))),n=[],l=[],c=[];for(let[u,p]of i){let g=r.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 r)i.has(u)||l.push(r.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={},r=0;for(let i of s){let n=e[i],l=t[i];this._stableStringify(n)!==this._stableStringify(l)&&(a[i]=[n,l],r++)}return{status:r===0?"unchanged":"modified",changes:a}}};d(Kt,"StorageManager");var ks=Kt;var At=class At{constructor(){return P(this,"intervalContainer",{}),P(this,"waitSequence",0),P(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"}),P(this,"timers",new Map),P(this,"insertStyle",(e=>{let t=(Array.isArray(e)?e:[e]).filter(Boolean);if(t.length===0)return;let s=t.map((r=>r.replace(/^\s*<style[^>]*>/i,"").replace(/<\/style>?\s*$/i,""))).filter(Boolean).join(` `),a=document.createElement("style");s&&(a.textContent=s,document.head.append(a))})),P(this,"layerIndexStack",[]),At.instance||(At.instance=this),At.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 r=a&&(Object.prototype.hasOwnProperty.call(a,"event")||Object.prototype.hasOwnProperty.call(a,"newTab"))?a:{event:a},i=r.event,n=new URL(e,window.location.origin),l=T(t);if(/^\/v\/[^/]+/.test(n.pathname)&&l&&n.searchParams.set("jhsCarNum",l),r.newTab||i&&(i.ctrlKey||i.metaKey||i.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:W.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,r=d(i=>$(i).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(r(document))a=!0;else{let i=s.find(`#layui-layer-iframe${t}`)[0];if(i)try{i.contentDocument&&r(i.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 r=(t=s[0])==null?void 0:t.contentDocument;if(r){if(s.attr("data-esc-bound")==="yes")return;$(r).off(a),$(r).on(a,this._boundHandler),s.attr("data-esc-bound","yes")}}catch(r){clog.error("iframe监听失败 (跨域或未加载完毕):",r)}}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((i=>!i.hidden&&i.getAttribute("aria-hidden")!=="true"&&i.offsetParent!==null)),"visible"),r=d(i=>{if(i.key!=="Tab")return;let n=a();if(!n.length)return void i.preventDefault();let l=n[0],c=n[n.length-1];i.shiftKey&&document.activeElement===l?(i.preventDefault(),c.focus()):!i.shiftKey&&document.activeElement===c&&(i.preventDefault(),l.focus())},"handleKeydown");return e.addEventListener("keydown",r),queueMicrotask((()=>a()[0]?.focus())),()=>{e.removeEventListener("keydown",r),t?.isConnected&&typeof t.focus=="function"&&t.focus()}}getOwningLayerIndex(e={}){let t=d(r=>{let i=r?.id||"",n=/^layui-layer(\d+)$/.exec(i);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 r=a.jquery?a[0]:a.nodeType?a:null,i=r?.matches?.(".layui-layer")?r:r?.closest?.(".layui-layer");s=t(i)}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 r=window.parent&&window.parent!==window?window.parent:window,i=r.layer||globalThis.layer;return a!==null&&typeof i?.close=="function"?(i.close(a),!0):(window.close(),!0)}loopDetector(e,t,s=20,a=1e4,r=!0,i=null){let n=++this.waitSequence,l=null,c=null,h=null,u=!1,p=d(()=>{l&&(i?.releaseObserver?i.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):(i?.observe&&document.documentElement?l=i.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||r)}),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",(r=>{let i=r.target.closest(t);i&&s(r,i)})):clog.error("rightClick(), 必须提供有效的 targetSelector。")}q(e,t,s,a){let r;if(this.isMobileMode())r=layer.confirm(t,{title:"提示",btn:["确定","取消"],shade:0,zIndex:W.layer},(function(){s&&s(),layer.close(r)}),(function(){a&&a()}));else{let i,n;e?(i=e.clientX-130,n=e.clientY-120):(i=window.innerWidth/2-120,n=window.innerHeight/2-120),r=layer.confirm(t,{offset:[n,i],title:"提示",btn:["确定","取消"],shade:0,zIndex:W.layer},(function(){s&&s(),layer.close(r)}),(function(){a&&a()}))}}getNowStr(e="-",t=":",s=null){let a;if(a=s?new Date(s):new Date,isNaN(a.getTime()))return"";let r=a.getFullYear(),i=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`${[r,i,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 r=a.getFullYear(),i=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`${[r,i,n].join(t)} ${[l,c,h].join(s)}`}getHourDifference(e,t){let s=e.getTime(),a=t.getTime(),r=Math.abs(a-s)/36e5;return Math.floor(r)}download(e,t){show.info("开始请求下载...");let s=t.split(".").pop().toLowerCase(),a,r=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:r});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:r})}else a=new Blob([e],{type:r});let i=URL.createObjectURL(a),n=document.createElement("a");n.href=i,n.download=t,document.body.appendChild(n),n.click(),setTimeout((()=>{document.body.removeChild(n),URL.revokeObjectURL(i)}),100)}smoothScrollToTop(e=500){return new Promise((t=>{let s=performance.now(),a=window.pageYOffset;window.requestAnimationFrame(d((function r(i){let n=i-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(r):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}=([^&]*)`),r=s.match(a),i="";return r&&r[1]&&(i=decodeURIComponent(r[1].replace(/\+/g," "))),i&&(i==="true"||i==="false"?i.toLowerCase()==="true":typeof i!="string"||i.trim()===""||isNaN(Number(i))?i:Number(i))}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,r=Math.max(320,Math.min(s[0],window.innerWidth-a)),i=Math.max(320,Math.min(s[1],window.innerHeight-a));return[`${r}px`,`${i}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(r){let i=document.createElement("textarea"),n=document.activeElement;i.value=s,i.setAttribute("readonly",""),i.style.position="fixed",i.style.opacity="0",document.body.appendChild(i),i.select();try{if(a=document.execCommand("copy")===!0,!a)throw r}catch(l){clog.error("复制失败:",l),show.error("复制失败,请手动复制")}finally{i.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),r=performance.now()-a.startTime,i,n;return a.unit==="s"?(i=(r/1e3).toFixed(a.precision),n="秒"):(i=r.toFixed(a.precision),n="毫秒"),this.timers.delete(e),`${e}: ${i}${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(...r){let i=this;clearTimeout(s),s=setTimeout((()=>{s=null,e.apply(i,r)}),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"),r=d((l,c)=>c!=null?typeof c=="function"?c(l):l&&typeof l=="object"?l[c]:void 0:l,"getVal"),i=[],n=[];for(let l of e){let c=!1;for(let h of t){let u=r(l,h.key);if(u==null||u===void 0){c=!0;break}}c?i.push(l):n.push(l)}return n.sort(((l,c)=>{for(let h of t){let{key:u,order:p="asc"}=h,g=r(l,u),m=r(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,...i]:[...i,...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 r=a instanceof Error?a.message:typeof a=="object"?JSON.stringify(a):String(a);if(a?._cfBlocked||a?._circuitBroken||r.includes("Just a moment")||r.includes("重定向")||r.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} 次重试, 错误信息: ${r}`)}}};d(At,"Utils");var Cs=At;function il(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 Xo(a,t),Object.freeze({utils:e,gmHttp:s,storageManager:t,stateService:a})}d(il,"createLegacyRuntime");var Xr=class Xr{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(Xr,"JhsEventBus");var Zr=Xr,V;function nl(){if(V)return V;V=new Zr;let o=window;return o.refresh=()=>V?.emit("legacy-refresh"),o.cleanCache_filter_actor_actress_car_list=()=>V?.emit("blacklist-rules-changed"),o.clean_cacheSettingObj=()=>V?.emit("settings-changed",{source:"legacy"}),V}d(nl,"initializeEventBus");var ht;function ol(o,{clogMsgCount:e=2e3}={}){if(ht)return ht;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 i=document.createElement("div");i.className="loading-container",i.setAttribute("role","status"),i.setAttribute("aria-live","polite"),i.setAttribute("aria-label","处理中"),i.setAttribute("aria-busy","true");let n=document.createElement("div");return n.className="loading-animation",i.appendChild(n),document.body.appendChild(i),{close:d(()=>{i&&i.parentNode&&i.parentNode.removeChild(i)},"close")}},(function(){let i=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:W.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 x=Toastify(j);return x.showToast(),x.closeShow=()=>{x.toastElement.remove()},x},"e");window.show={ok:d((n,l="center",c,h)=>i(n,"success",l,c,h),"ok"),error:d((n,l="center",c,h)=>i(n,"error",l,c,h),"error"),info:d((n,l="center",c,h)=>i(n,"info",l,c,h),"info")}})(),(function(){let i=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 z=document.createElement("div"),Z=document.createElement("img");z.className="temporary-container jhs-layout-c8be1ccb",Z.src=String(n),Z.alt=String(l),z.appendChild(Z),document.body.appendChild(z),h=$(z),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());i?.close(!1);let j=p.closest(".layui-layer"),x=p.closest("button,a,[tabindex]")||document.activeElement,k=g&&j?.querySelector(".layui-layer-content"),_=new te("ui:image-viewer"),E=document.documentElement.style.overflow,L=document.body.style.overflow,N,A,O,U,H=g?.inert,Q=k?.classList.contains("jhs-image-viewer-owner"),se={close(z=!0){if(!_.disposed){_.dispose(),A?.();try{N?.destroy()}finally{O?.remove(),k&&(k.classList.toggle("jhs-image-viewer-owner",Q),g.inert=H),u&&h.remove(),i===se&&(i=null,document.documentElement.style.overflow=document.querySelector(".layui-layer-shade")?"hidden":j?"":E,document.body.style.overflow=L,z&&x?.isConnected&&x.focus?.({preventScroll:!0}))}}}};i=se,A=o.addCleanup(()=>se.close(!1));let ge=[...document.querySelectorAll(".layui-layer")].reduce((z,Z)=>{let re=window.getComputedStyle(Z),xt=Number(re.zIndex);return re.display!=="none"&&Number.isFinite(xt)?Math.max(z,xt+1):z},W.viewer);if(k){O=document.createElement("div"),O.className="jhs-image-viewer-host",O.style.zIndex=String(ge);let z=document.createElement("div");z.hidden=!0,b.forEach(Z=>{let re=document.createElement("img");re.src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1' height='1'/%3E",re.setAttribute("data-jhs-viewer-source",Z.currentSrc||Z.src),re.alt=Z.alt,z.appendChild(re)}),O.appendChild(z),k.classList.add("jhs-image-viewer-owner"),k.appendChild(O),g.inert=!0,v=$(z)}let De=d(z=>z<0?N?.prev(!!g):N?.next(!!g),"navigate"),Ne={zIndex:ge,...g?{className:`jhs-fc2-image-viewer jhs-ui${k?" viewer-in":""}`,inline:!!k,zIndexInline:ge,minWidth:0,minHeight:0,button:!1,transition:!1,initialCoverage:.9,ready:d(()=>{if(_.disposed||!N?.viewer)return;let z=N.viewer,Z=document.createElement("div");Z.className="jhs-image-viewer-toolbar",z.setAttribute("role","dialog"),z.setAttribute("aria-label","图片预览");let re=d((ye,Ld,Md,Bd,Od=z)=>{let lt=document.createElement("button");return lt.type="button",lt.className=`jhs-btn jhs-btn--secondary ${Md}`,lt.setAttribute("aria-label",ye),lt.textContent=Ld,_.listen(lt,"click",Ao=>{Ao.preventDefault(),Ao.stopPropagation(),Bd()}),Od.appendChild(lt),lt},"button"),xt=re("关闭图片","×","jhs-image-viewer-close",()=>se.close());S&&(re("上一张","‹","jhs-image-viewer-nav jhs-image-viewer-prev",()=>De(-1)),re("下一张","›","jhs-image-viewer-nav jhs-image-viewer-next",()=>De(1))),re("放大图片","放大","",()=>N.zoom(.1),Z),re("缩小图片","缩小","",()=>N.zoom(-.1),Z),re("适应窗口","适应","",()=>N.reset(),Z),U=document.createElement("span"),U.className="jhs-image-viewer-count",U.setAttribute("aria-live","polite"),Z.appendChild(U),N.footer.appendChild(Z);let ps=-1/0;if(_.listen(z,"wheel",ye=>{!S||ye.ctrlKey||!ye.deltaY||(ye.preventDefault(),ye.stopPropagation(),!(ye.timeStamp-ps<180)&&(ps=ye.timeStamp,De(Math.sign(ye.deltaY))))},{passive:!1}),k&&typeof ResizeObserver<"u"){let ye=new ResizeObserver(()=>{N?.ready&&!_.disposed&&N.resize()});ye.observe(O),_.ownObserver(ye)}xt.focus({preventScroll:!0})},"bindFc2Controls")}:{},...k?{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){N.resize(),U&&(U.textContent=`${N.index+1} / ${b.length}`);return}N.zoomTo(1.4);let z=(N.viewerData.width-N.imageData.width)/2,Z=(N.viewerData.height-N.imageData.height)/2;N.moveTo(z,Z)},shown(){_.disposed||(document.documentElement.style.overflow="hidden",document.body.style.overflow="hidden")},hidden(){se.close()}};try{_.listen(document,"keydown",z=>{if(S&&z.key==="ArrowLeft")return z.preventDefault(),z.stopPropagation(),void De(-1);if(S&&z.key==="ArrowRight")return z.preventDefault(),z.stopPropagation(),void De(1);if(g&&z.key==="Tab"&&N?.viewer){let Z=[...N.viewer.querySelectorAll("button")],re=Z.indexOf(document.activeElement);z.preventDefault(),Z[(re+(z.shiftKey?-1:1)+Z.length)%Z.length]?.focus();return}(z.key==="Escape"||!g&&z.key===" ")&&(z.preventDefault(),z.stopPropagation(),se.close())},!0),_.observe(document.body,()=>{(!p.isConnected||j&&!j.isConnected)&&se.close(!1)},{childList:!0,subtree:!0}),N=new Viewer(v[0],Ne),N.show()}catch(z){throw se.close(!1),z}}})(),window.ImageHoverPreview=class{constructor(i={}){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:W.hoverPreview,owner:null,resolveOwner:null,zIndexStrategy:"fixed",transition:.2,hideDelay:100,loadedUrlLimit:128,autoAdjustPosition:!0,...i},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 i=document.createElement("style");i.id="jhs-image-hover-preview-style",i.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(i)}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 i=typeof this.config.resolveOwner=="function"?this.config.resolveOwner():this.config.owner;return i?.jquery?i[0]:i}resolvePreviewZIndex(){let i=Number(this.config.zIndex)||W.hoverPreview;if(this.config.zIndexStrategy!=="owner"&&!this.resolveOwnerElement())return i;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){i=c+1;break}n=n.parentElement}return i}refreshOwnerZIndex(){if(this.preview&&(this.config.zIndexStrategy==="owner"||this.resolveOwnerElement())){let i=String(this.resolvePreviewZIndex());this.preview.style.zIndex!==i&&(this.preview.style.zIndex=i)}}isOwnerUncovered(){let i=this.resolveOwnerElement();if(!i)return this.config.zIndexStrategy!=="owner";if(!i.isConnected||!this.currentTarget?.isConnected||!i.contains(this.currentTarget))return!1;let n=i.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(i))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(i){let n=i.target;return n?.closest?n.closest(this.config.selector):null}handleDocumentOver(i){if(this.suppressUntilMouseMove)return;let n=this.findTarget(i);n&&(!i.relatedTarget||!n.contains(i.relatedTarget))&&this.handleMouseEnter(i,n)}handleDocumentOut(i){let n=this.findTarget(i);n&&(!i.relatedTarget||!n.contains(i.relatedTarget))&&this.handleMouseLeave()}handleDocumentMove(i){this.suppressUntilMouseMove=!1,this.currentTarget&&(i.target===this.currentTarget||this.currentTarget.contains(i.target))&&this.handleMouseMove(i)}handleMouseEnter(i,n=i.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:i.clientX,y:i.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(i,n){if(!this.preview)return;let l=document.createElement("img");l.src=i,l.alt="预览图",this.preview.replaceChildren(l),this.imgElement=l,this.currentUrl=i,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 i=this.preview.offsetWidth,n=this.preview.offsetHeight;this.placement=this.choosePlacement(this.pointer.x,this.pointer.y,i,n),this.preview.classList.add("active"),this.schedulePosition()}calculateImageSize(i){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/i.naturalWidth,u/i.naturalHeight);return{width:Math.max(1,Math.round(i.naturalWidth*p)),height:Math.max(1,Math.round(i.naturalHeight*p))}}choosePlacement(i,n,l,c){if(!this.config.autoAdjustPosition)return{horizontal:"right",vertical:"bottom"};let h=window.innerWidth-i-this.config.offsetX,u=i-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(i){!this.currentTarget||!this.preview?.classList.contains("active")||(this.pointer={x:i.clientX,y:i.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 i=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(i,c),Math.max(i,window.innerWidth-n-i)),h=Math.min(Math.max(i,h),Math.max(i,window.innerHeight-l-i)),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 i={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&&i[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(i).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=i[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,x=[];i[b]?(j=b,x=w):(j="base",x=[b,...w]),j=i[j]?j:"base";let k=[v,...x],_="msg",E=[];k.forEach((A=>{if(Object.prototype.toString.call(A)==="[object Error]")E.push(String(A));else if(typeof A=="object"&&A!==null)try{E.push("<br/>"+JSON.stringify(A,null,2)),_="json"}catch{E.push(String(A)),_="msg"}else E.push(String(A))}));let L=E.join(" ");f&&(L=L.replace(/(?:(?:https?|ftp):\/\/|www\.|(?:\/\/))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]/gi,(A=>{let O=A.startsWith("http")||A.startsWith("ftp"),U=A.startsWith("//"),H=A.startsWith("www."),Q=A;return U?Q=`http:${A}`:!O&&H&&(Q=`http://${A}`),`<a href="${C(Q)}" target="_blank">${C(A)}</a>`})));let N={message:L,messageType:_,type:j,html:f,timestamp:new Date,id:Date.now()+Math.random()};if(this.logs.push(N),this.logs.length>l){this.logs.shift();let A=this.content.querySelector(".console-logger-entry");A&&A.remove()}S&&this.renderLog(N)}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=i[f.type]||i.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 x=f.message.replace(/<br\s*\/?>/gi,` `),k=/(?:(?:https?|ftp):\/\/|www\.|(?:\/\/))[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|]/gi,_=0,E;for(;E=k.exec(x);){E.index>_&&j.appendChild(document.createTextNode(x.slice(_,E.index)));let L=E[0],N=L;L.startsWith("//")?N=`http:${L}`:L.startsWith("www.")&&(N=`http://${L}`);let A=document.createElement("a");A.href=N,A.target="_blank",A.textContent=L,j.appendChild(A),_=E.index+E[0].length}_<x.length&&j.appendChild(document.createTextNode(x.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(W.debugLow))}highZIndex(){this.isInitialized&&this.container&&(this.container.style.zIndex=String(W.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 i(l,c,h){let u=(function(E){let L=document.createElement("div");L.classList.add("js-tooltip");let N=document.createElement("div");return N.innerHTML=C(E),L.appendChild(N),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"),x=p.left+p.width/2-g.width/2,k=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=x,v<8?v=8:v+g.width>m-8&&(v=m-g.width-8)):(w==="left"||w==="right")&&(b=k,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(i,"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&&i(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,r=window.show;return ht=Object.freeze({loading:a,show:r,clog:s}),window.loading=ht.loading,window.show=ht.show,window.clog=ht.clog,ht}d(ol,"initializeLoggerRuntime");function ll(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(ll,"getVendorRuntime");var uh=new Set(["star","genre","maker","actress","series","tag","search","director","studio","label"]),ei=class ei{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],r=s[s.length-2];if(s.length>=2&&/^\d+$/.test(a)&&(r==="page"||s.length>=3&&uh.has(s[s.length-3]))){let n=r==="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(ei,"JavBusHostAdapter");var _s=ei;var ph=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&&ph.has(t[1])?`${t[1]}-${t[2]}`:e||null}d(ee,"normalizeMovieCarNum");function cl(o,e="https://javdb.com"){try{return new URL(String(o||""),e).pathname.match(/^\/v\/([^/]+)\/?$/)?.[1]||null}catch{return null}}d(cl,"extractJavDbMovieId");var ti=class ti{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":["actor-ranking","award-ranking"].includes(this.getPageContext().kind)?"other":this.locateListRoot()?"list":"other"}getPageContext(){return je(this.location)}getTop250FilterContainer(){return this.document.querySelector("section .container")??this.getListContainer()}locateTop250SubtitleCards(){return this.locateListItems()}mountTop250SubtitleControls(e){let t=this.locateListRoot();t?.parentElement?.insertBefore(e,t)}mountExternalFc2Catalog(e){let t=this.getListContainer();if(!t)throw new Error("JavDB 列表容器不可用");t.querySelector(":scope > .box")?.remove(),t.querySelector(":scope > .tool-box")?.remove(),this.mountOwnedListRoot(t,e)}syncTop250SubtitleLinks(e){let t=this.getTop250FilterContainer();if(t)for(let s of t.querySelectorAll('a[href^="/rankings/top"],select[data-url^="/rankings/top"]')){let a=s.matches("select")?"data-url":"href",r=s.getAttribute(a);if(!r)continue;let i=new URL(r,this.location.origin);e==="all"?i.searchParams.delete("jhs_subtitle"):i.searchParams.set("jhs_subtitle",e),s.setAttribute(a,`${i.pathname}${i.search}`)}}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(r=>r===t||r.contains(t))||t;return Object.freeze({site:"javdb",hostRoot:s,controller:t,observeRoot:t,resourceRoot:e,resourceRegion:a,rows:d(()=>[...e.children].filter(r=>r.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 r=e.closest(".message.video-panel, .video-panel")||t;r.setAttribute("data-jhs-resource-surface","true");let i=e.closest(".message-body");i&&r.contains(i)&&i.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(r){return r.querySelector('.copy-to-clipboard[data-clipboard-text^="magnet:"]')?.getAttribute("data-clipboard-text")||r.querySelector('.magnet-name a[href^="magnet:"]')?.getAttribute("href")||""},getActionTarget:d(r=>r.querySelector(":scope > .buttons"),"getActionTarget"),actionTargetRequiresWrapper:d(()=>!1,"actionTargetRequiresWrapper"),getTitleTarget:d(r=>r.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 r=[...s.querySelectorAll(".movie-list .item")];return Object.freeze(r.flatMap(i=>{let n=i.querySelector(".video-title"),l=n?.querySelector("strong")?.textContent?.trim()??"",c=ee(l);if(!c)return[];let h=i.querySelector("img")?.getAttribute("src")??"",u=i.querySelector("a[href]")?.getAttribute("href")??"",p=i.querySelector(".score .value, .score")?.textContent?.trim()??"",g=i.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:i.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 r=s.querySelector("#actors");if(!r)return Object.freeze({state:"invalid",isEmpty:!1,actors:Object.freeze([]),nextUrl:null});try{let i=[...r.querySelectorAll(".actor-box")],n=i.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:i.length===0,actors:Object.freeze(n),nextUrl:c})}catch{return Object.freeze({state:"invalid",isEmpty:!1,actors:Object.freeze([]),nextUrl:null})}}};d(ti,"JavDbHostAdapter");var $s=ti;var gh=new Set(["system","feature"]),mh=new Set(["eager","idle","on-command","on-demand"]),fh=new Set(["builtin-public","custom-public","user-local"]),vh=new Set(["bronze","silver"]);function ut(o,e){if(typeof o!="string"||o.trim()==="")throw new TypeError(`${e} must be a non-empty string`)}d(ut,"requireNonEmptyString");function dl(o,e){if(!Array.isArray(o))throw new TypeError(`${e} must be an array`)}d(dl,"requireArray");function Pt(o,e){dl(o,e);let t=o;for(let s of t)ut(s,`${e} item`);if(new Set(t).size!==t.length)throw new TypeError(`${e} cannot contain duplicates`)}d(Pt,"requireUniqueStrings");function si(o,e){dl(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(si,"requireUniqueTokens");function Re(o){if(ut(o.id,"Feature id"),!gh.has(String(o.kind)))throw new TypeError("Feature kind must be system or feature");if(!mh.has(String(o.startup)))throw new TypeError("Feature startup mode is invalid");for(let e of["sites","routes","contributes","providesCommands"])Pt(o[e],e);if(si(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(Re,"defineFeature");function hl(o){if(ut(o.id,"Contribution id"),ut(o.featureId,"Contribution featureId"),ut(o.legacyPluginId,"Contribution legacyPluginId"),Pt(o.sites,"sites"),Pt(o.routes,"routes"),Pt(o.surfaces,"surfaces"),si(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(hl,"defineContribution");function J(o){if(ut(o.id,"Integration id"),!fh.has(String(o.trustClass)))throw new TypeError("Integration trustClass is invalid");if(!vh.has(String(o.quality)))throw new TypeError("Integration quality is invalid");Pt(o.hosts,"hosts"),Pt(o.capabilities,"capabilities"),si(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(i=>!Object.hasOwn(s,String(i))),r=Object.keys(s).filter(i=>!t.includes(i));if(a.length||r.length)throw new TypeError(`Integration cachePolicy mismatch (missing: ${a.join(", ")||"none"}; extra: ${r.join(", ")||"none"})`);for(let[i,n]of Object.entries(s))ut(n,`cachePolicy.${i}`)}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(J,"defineIntegration");function G(o,e){return Symbol.for(`jhs.${o}.${e}`)}d(G,"createToken");var Y=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")}),ke=Object.freeze({externalDetail:"external-detail-v1"});var ai=class ai{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 r=e.createElement("section");r.className=`jhs-detail-owned-slot jhs-detail-owned-slot--${a}`,r.setAttribute("data-jhs-slot",a),s.append(r),this.created.add(r)}}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(ai,"HostedDetailSurface");var Ts=ai;var ri=class ri{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(ri,"DetailController");var As=ri;var ul=Re({id:"detail",kind:"feature",disableable:!0,sites:["javdb","javbus"],routes:["detail","owned-detail"],startup:"eager",requires:[Y.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[Y.host],scope:e.scope,enabledContributions:e.enabledContributions});return t.start(),{dispose:d(()=>t.dispose(),"dispose")}},"activate")});var It=d((o,e,t)=>Re({id:o,kind:"feature",disableable:!0,sites:e,routes:[],startup:"eager",requires:[],contributes:t,providesCommands:[],activate:d(()=>({}),"activate")}),"feature"),pl=Object.freeze([It("list",["javdb","javbus"],["list.core","list.auto-page","list.fold-category","list.actions"]),It("library",["javdb","javbus"],["library.history","library.keyword-filter","library.state-actions","library.blacklist","library.favorite-actresses"]),It("discovery",["javdb","javbus"],["discovery.hit-show","discovery.top250","discovery.new-video","discovery.scheduler"]),It("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"]),It("identity",["javdb","javbus"],["identity.javdb-navigation","identity.javbus-navigation","identity.image-search","identity.actress-info"]),It("compatibility",["javdb","javbus"],["compatibility.enhancements"])]);var pt=null;function gl(o){if(typeof o!="function")throw new TypeError("Settings UI owner must be a function");if(pt&&pt!==o)throw new Error("Settings UI owner is already registered");return pt=o,()=>{pt===o&&(pt=null)}}d(gl,"registerSettingsUiOwner");function ml(o){if(!pt)throw new Error("Settings UI owner is not ready");return pt(o)}d(ml,"openSettingsUi");var fl=Object.freeze([Re({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(()=>ml(),"settings.open")}}),"activate")}),Re({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")}),Re({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")}),Re({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 vl=Object.freeze([...fl,ul,...pl]);var bl=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","ScreenShotPlugin"],Fc2By123AvPlugin:["ListPagePlugin"],HistoryPlugin:["UnifiedOfflinePlugin","ListPagePlugin","Fc2Plugin"],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"],UnifiedOfflinePlugin:["OneTwoThreeOfflinePlugin"]});var ii=class ii 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((i=>clog.error("演员信息重新挂载失败",i))))},"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 r=$("strong").filter(((n,l)=>/^(?:演員|演员)\s*:?$/.test($(l).text().trim()))).first().parent(),i=t.first().closest(".panel-block");r.length?r.after(...a):i.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 r=null;for(let l of t){try{r=await this.searchInfo(l)}catch(c){clog.error("演员资料查询失败",l,c)}if(!this.isStillActive(e))return;if(r)break}let i=$('<div class="jhs-layout-c0d4a511"></div>');if(!r)i.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(`出生日期: ${r.birthday}`),$("<span></span>").addClass("jhs-layout-d4a09a0d").text(`年龄: ${r.age}`),$("<span></span>").addClass("jhs-layout-d4a09a0d").text(`身高: ${r.height}`)),c.append($("<span></span>").addClass("jhs-layout-dd5a75f6").text(`体重: ${r.weight}`),$("<span></span>").addClass("jhs-layout-d4a09a0d").text(`三围: ${r.threeSizeText}`),$("<span></span>").addClass("jhs-layout-d4a09a0d").text(`罩杯: ${r.braSize}`)),i.append(l,c)}if(!this.isStillActive(e))return;let n=r?$("<a></a>").addClass("actress-info").attr({href:r.url,target:"_blank",rel:"noopener noreferrer"}).append(i):i.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(ii,"ActressInfoPlugin");var Ps=ii;var ni=class ni extends I{constructor(){super(...arguments),P(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"),r=$("#preview-image"),i=$("#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),r.attr("src",f),a.show(),this.resetSearchUI())})),n.on("click",(async()=>{let g=r.attr("src");if(g){if(!this.isUploading){this.isUploading=!0;try{let m=await this.searchByImage(g);if(!m)return;i.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}),x=$('<input type="checkbox" class="site-checkbox jhs-layout-8896c95d">').attr("data-site-name",w.name).prop("checked",S);j.append(x,$("<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())&&(r.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 r=new FileReader;r.onload=i=>{t.src=String(i.target?.result||""),s.style.display="block",a.style.display="none",$("#handle-btn")[0]?.click()},r.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(ni,"SearchByImagePlugin");var Is=ni;async function Te(o,e=4,t){let s=new Array(o.length),a=0,r=d(async()=>{for(;a<o.length;){let i=a++;s[i]=await t(o[i],i)}},"worker");return await Promise.all(Array.from({length:Math.min(Math.max(1,e),o.length)},r)),s}d(Te,"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),r=new Date(a[0],a[1]-1,a[2],a[3],a[4],a[5]);return r.getFullYear()===a[0]&&r.getMonth()===a[1]-1&&r.getDate()===a[2]&&r.getHours()===a[3]&&r.getMinutes()===a[4]&&r.getSeconds()===a[5]?r.getTime():null}let s=new Date(e).getTime();return Number.isFinite(s)?s:null}d($e,"parseTaskTimestamp");function gt(o,e,t=Date.now()){let s=ae(e,0,{min:0}),a=$e(o),r=$e(t);return s>0&&a!=null&&r!=null&&r>=a&&r-a>=36e5*s}d(gt,"shouldSkipStopped");function Gt(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(Gt,"selectLatestPublishTime");function Ye(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(Ye,"normalizeHttpUrl");function wl(o){let e=String(o||"").trim();return/^(?:[a-f\d]{40}|[a-z2-7]{32})$/i.test(e)?e.toUpperCase():null}d(wl,"normalizeBtihHash");function yl(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(yl,"parseCarNumberText");function jl(o,e="https://javdb.com"){return`${e}/search?q=${encodeURIComponent(String(o??""))}`}d(jl,"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 r=a&&typeof a=="object"&&"name"in a?String(a.name):"";return t&&!["NotAllowedError","AbortError"].includes(r)&&show.error(s),!1}}d(de,"safePlay");var Ee=Object.freeze({all:"全部",waitCheck:"待鉴定",favorite:"收藏",hasDown:"下载",hasWatch:"已看",blockedItems:"屏蔽项",favoriteUndownloaded:"收藏未下载",favoriteUnwatched:"收藏未观看",downloadedUnwatched:"下载未观看",recent7d:"最近 7 天"}),mt=Object.freeze(["all","waitCheck","favorite","hasDown","hasWatch"]),Qt=Object.freeze(["blockedItems","favoriteUndownloaded","favoriteUnwatched","downloadedUnwatched","recent7d"]),bh=new Set([...mt,...Qt]);function Ae(o){return o==="filter"?"blockedItems":typeof o=="string"&&bh.has(o)?o:"waitCheck"}d(Ae,"normalizeQuickFilterKey");function ft(o,e={}){return!!(o.blocked||e.keyword||e.actorBlacklist||e.actressBlacklist)}d(ft,"isHardHidden");function oi(o,e,{visibilityReasons:t={},recent:s=!1}={}){let a=Ae(o),r=ft(e,t);return a==="all"?!0:a==="blockedItems"?r:r?!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(oi,"matchesQuickFilter");function Sl({filter:o,flags:e,visibilityReasons:t,recent:s}){return oi(o,e,{visibilityReasons:t,recent:s})}d(Sl,"shouldShowItem");var xl=Object.freeze(["native-javdb","native-javbus","u9a9","u3c3","sukebei","btsow"]);function li(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(li,"normalizeMagnetResult");function kl(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(kl,"extractInfoHash");function Es(o){let e=new Map;return o.forEach((t=>{let s=kl(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 hi=class hi{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(hi,"MagnetSourceRegistry");var Yt=hi;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 Cl(o,e=[],t=[],s=[]){let a=`${o.title||""} ${(o.files||[]).join(" ")}`,r=d((u,p)=>u.type==="regex"?new RegExp(u.pattern,"i").test(p):p.toLowerCase().includes(u.pattern.toLowerCase()),"matches"),i=e.filter((u=>u.enabled&&r(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=>{r(u,u.value)&&(c.push(u.id||u.pattern),u.action==="hide"?n=!0:l+=Number(u.penalty)||0)})),{...o,tags:i.map((u=>u.name)),customTagWeight:i.reduce(((u,p)=>u+(Number(p.weight)||0)),0),hidden:n,filterPenalty:l,filteredReasons:c}}d(Cl,"applyMagnetRules");function ci(o,e){let t=new Map;return $(o).find('a[href^="magnet:"],[data-clipboard-text^="magnet:"]').each(((s,a)=>{let r=$(a),i=r.attr("href")||r.attr("data-clipboard-text");if(!i)return;let n=r.closest(".item, .magnet-name, tr, .panel-block"),l=n.find(".name, .magnet-name, .title").first().text().trim()||r.text().trim()||"本站磁力",c=li({title:l,magnet:i,size:n.find(".meta, .size").first().text().trim()},e);c&&t.set(kl(i)||i,c)})),[...t.values()]}d(ci,"parseNativeMagnets");function vt(o,e){return String(e||"").split(".").filter(Boolean).reduce(((t,s)=>t?.[s]),o)}d(vt,"readJsonPath");function di(o,e,t){if(o=bt(o),o.parserType==="json")return(vt(e,o.resultsPath)||[]).map((r=>li({title:vt(r,o.titlePath),magnet:o.magnetPath?vt(r,o.magnetPath):`magnet:?xt=urn:btih:${vt(r,o.hashPath)}`,size:vt(r,o.sizePath),date:vt(r,o.datePath),seeders:vt(r,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(((r,i)=>{let n=$(i),l=o.parserType==="magnet-links"?n:n.find(o.magnetSelector).first();return li({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(di,"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 Rt(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(Rt,"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 Zt(o,e=!1){return be(o,e)}d(Zt,"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 Ze(o,e){if(["enable123Offline","enable115Offline","enable115Match","enable115LoginRedirect"].includes(o))return Zt(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(Ze,"normalizeCloudSetting");var ui=class ui{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 r;return await this.storage.updateSetting(i=>{let n=i[e],l;if(Array.isArray(n))l=n;else try{let c=JSON.parse(n||"[]");l=Array.isArray(c)?c:[]}catch{l=[]}if(r=t(l),!Array.isArray(r))throw new TypeError("配置必须是数组");i[e]=JSON.stringify(r)}),r}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(Rt),this.saveArray("magnetTagRules",e)}getMagnetFilterRules(){return this.getArray("magnetFilterRules")}saveMagnetFilterRules(e){return e.forEach(Rt),this.saveArray("magnetFilterRules",e)}async getBuiltInSources(){return await this.getArray("magnetBuiltInSources")}saveBuiltInSources(e){return e.forEach((t=>{if(!xl.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:Zt(await this.storage.getSetting("enable123Offline",!0),!0),enable115Offline:Zt(await this.storage.getSetting("enable115Offline",!1),!1),enable115Match:Zt(await this.storage.getSetting("enable115Match",!1),!1),enable115LoginRedirect:Zt(await this.storage.getSetting("enable115LoginRedirect",!1),!1),providerMode:Ze("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 r=Ze(e,t);return await this.storage.saveSettingItem(a,r),r}async saveCloudSettings(e){let t={enable123Offline:Ze("enable123Offline",e.enable123Offline),enable115Offline:Ze("enable115Offline",e.enable115Offline),enable115Match:Ze("enable115Match",e.enable115Match),enable115LoginRedirect:Ze("enable115LoginRedirect",e.enable115LoginRedirect),offlineProviderMode:Ze("offlineProviderMode",e.providerMode||"ask"),oneOneFiveConcurrency:Ze("oneOneFiveConcurrency",e.concurrency),oneOneFiveCacheMinutes:Ze("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(Rt),s.push(()=>this.saveMagnetTagRules(t.magnetTagRules))}if(Object.hasOwn(t,"magnetFilterRules")){if(!Array.isArray(t.magnetFilterRules))throw new TypeError("过滤规则必须是数组");t.magnetFilterRules.forEach(Rt),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(ui,"ResourceSettingsService");var nt=ui;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 pi="x7k9p3",$l="jhs_credential_install_secret",Tl="AES:",Al="";function gi(){let o=globalThis.localStorage?.getItem?.($l)||Al;if(o)return o;let e=crypto.getRandomValues(new Uint8Array(32));return o=Il(e.buffer),Al=o,globalThis.localStorage?.setItem?.($l,o),o}d(gi,"getInstallationSecret");async function Pl(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(Pl,"getEncryptionKey");function Il(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(Il,"arrayBufferToBase64");function wh(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(wh,"base64ToArrayBuffer");async function Xt(o,e=gi()){let t=await Pl(e),s=crypto.getRandomValues(new Uint8Array(12)),a=await crypto.subtle.encrypt({name:"AES-GCM",iv:s},t,new TextEncoder().encode(o)),r=new Uint8Array(s.length+a.byteLength);return r.set(s),r.set(new Uint8Array(a),s.length),Il(r.buffer)}d(Xt,"encryptData");async function Rl(o){return Xt(o,pi)}d(Rl,"encryptPortableBackup");async function Xe(o,e=gi(),t=!0){let s=wh(o),a=s.slice(0,12),r=s.slice(12),i=d(async n=>new TextDecoder().decode(await crypto.subtle.decrypt({name:"AES-GCM",iv:a},await Pl(n),r)),"decrypt");try{return await i(e)}catch(n){if(!t||e===pi)throw n;return i(pi)}}d(Xe,"decryptData");async function es(o){return Xe(o)}d(es,"decryptPortableBackup");async function El(o,e=gi()){if(!o||!o.startsWith(Tl))return o;try{return await Xe(o.slice(Tl.length),e)}catch{return console?.warn?.("[凭证] 凭证解密失败,按原文返回"),o}}d(El,"decryptCredential");var yh="zh-cn",jh=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(r=>Number.isInteger(r)&&r>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??yh,langs:t.langs??jh})}d(ze,"createJhsTable");var Fe=d(o=>o instanceof Error?o.message:String(o),"errorMessage");function Dl(o){let e=o,t=typeof e?.code=="string"&&/^[A-Z_]{2,32}$/.test(e.code)?e.code:"UNKNOWN",s=Number(e?.details?.status);return{code:t,...Number.isInteger(s)&&s>=100&&s<=599?{status:s}:{}}}d(Dl,"backupErrorDetails");function Ms(o){let e=typeof o.code=="string"&&/^[A-Z_]{2,32}$/.test(o.code)?o.code:void 0,t={stage:o.stage,result:o.result,durationMs:Math.max(0,Math.round(o.durationMs)),...o.bytes==null?{}:{bytes:o.bytes},...o.timeoutMs==null?{}:{timeoutMs:o.timeoutMs},...e?{code:e}:{},...o.status==null?{}:{status:o.status}};try{o.result==="error"?clog.warn?.("[WebDAV备份]",t):clog.log?.("[WebDAV备份]",t)}catch{}}d(Ms,"logBackupStage");async function mi(o,e){let t=performance.now();try{let s=await e();return Ms({stage:o,result:"success",durationMs:performance.now()-t}),s}catch(s){throw Ms({stage:o,result:"error",durationMs:performance.now()-t,...Dl(s)}),s}}d(mi,"measureBackupStage");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 El(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 r=new FileReader;r.onload=async i=>{t();try{let n=String(i.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("差异分析失败: "+Fe(h))}}catch(n){clog.error(n),show.error("导入失败:文件内容不是有效的JSON格式 "+Fe(n))}},r.onerror=()=>{t(),show.error("读取文件时出错")},r.readAsText(a)},document.body.appendChild(e),e.click(),setTimeout(t,3e5)}catch(e){clog.error(e),show.error("导入数据时出错: "+Fe(e))}}d(Ll,"importSettingData");async function Ml(o,e){let t=loading(),s=performance.now(),a="error",r;try{let i=await mi("读取凭据",()=>Nl(e)),n=i.url;if(!n)return void show.error("请填写webDav服务地址并保存后, 再试此功能");let l=i.username;if(!l)return void show.error("请填写webDav用户名并保存后, 再试此功能");if(!i.password)return void show.error("请填写webDav密码并保存后, 再试此功能");let c=utils.getNowStr("_","_")+".json",h=await mi("导出数据",async()=>JSON.stringify(await storageManager.exportData())),u=await mi("加密",()=>Rl(h));r=u.length,await e.createClient({url:n,username:l,password:i.password}).backup(o,c,u,Ms),a="success",show.ok("备份完成")}catch(i){clog.error("[WebDAV备份失败]",Dl(i)),show.error(Fe(i))}finally{Ms({stage:"合计",result:a,durationMs:performance.now()-s,...r==null?{}:{bytes:r}}),t.close()}}d(Ml,"backupDataByWebDav");async function Bl(o,e,t){let s=await Nl(t),a=s.url;if(!a)return void show.error("请填写webDav服务地址并保存后, 再试此功能");let r=s.username;if(!r)return void show.error("请填写webDav用户名并保存后, 再试此功能");if(!s.password)return void show.error("请填写webDav密码并保存后, 再试此功能");let i=loading();try{let n=s.password,l=t.createClient({url:a,username:r,password:n}),c=await l.getBackupList(o);e(c,l,"WebDav")}catch(n){clog.error(n),show.error(`发生错误: ${Fe(n)}`)}finally{i.close()}}d(Bl,"backupListBtnByWebDav");function Sh(o,e,t,s,a,r){let i=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">${i(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";r.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")r.confirm(`是否删除 ${f.name} ?`,{icon:3,title:"提示",btn:["确定","取消"]},async v=>{r.close(v);let b=loading();try{await e.deleteFile(f.fileId),o=await e.getBackupList(s),h.html(n(o)),r.alert("删除成功")}catch(w){clog.error(w),show.error(`发生错误: ${Fe(w)}`)}finally{b.close()}});else if(g==="download"){let v=loading();try{let b=await es(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 es(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("预览失败: "+Fe(b))}}}})},"success")})}d(Sh,"openFileListDialogMobile");function Ol(o,e,t,s,a,r){if(utils.isMobileMode()){Sh(o,e,t,s,a,r);return}r.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(i=>{let n=$(i).find(".jhs-table-dialog__content").get(0)||$(i).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=>{r.confirm(`是否删除 ${p.name} ?`,{icon:3,title:"提示",btn:["确定","取消"]},(async b=>{r.close(b);let w=loading();try{await e.deleteFile(p.fileId);let S=await e.getBackupList(s);l.replaceData(S),r.alert("删除成功")}catch(S){clog.error(S),show.error(`发生错误: ${Fe(S)}`)}finally{w.close()}}))})),m&&m.addEventListener("click",(async v=>{let b=loading();try{let w=await es(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 es(w);let S=JSON.parse(w),j=await storageManager.exportData(),x=await storageManager.diffData(j,S);b.close(),a(x,null,S)}catch(w){b.close(),clog.error(w),show.error("预览失败: "+Fe(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 Ul(){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("导出数据时出错: "+Fe(o))}}d(Ul,"exportSettingData");function zl(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(zl,"buildSettingCss");async function xh(o=null,e){if($("#verticalImgStyle").remove(),(e===void 0?await storageManager.getSetting("enableVerticalModel",ne):e)===R){let s="100% 50% !important";window.location.pathname==="/tags/fc2"&&new URLSearchParams(window.location.search).get("jhs_source")==="123av"&&(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(xh,"applyImageMode");async function fi(o={},{busImgPlugin:e=null,hostAdapter:t=null}={}){let s=o.enableVerticalModel===void 0?ne:o.enableVerticalModel;await xh(e,s);let a=globalThis.utils?.isMobileMode?.()??!1,r=a?1:Number(o.containerColumns??5)||5,i=a?100:Number(o.containerWidth??100)||100;if(B&&e?.logImageHeightsByRow&&await e.logImageHeightsByRow({vertical:s,columns:r}),t){let n=t.locateListRoot?.();n&&(n.style.gridTemplateColumns=`repeat(${r}, minmax(0, 1fr))`);let l=t.getListLayoutContainer?.();l&&(l.style.minWidth=`${i}%`)}}d(fi,"applyLayoutFromSettings");var vi=new WeakMap;function wi(o){let e=vi.get(o);return e||(e=new bi(o),vi.set(o,e)),e}d(wi,"getSettingBindingHub");function Fl({root:o,selector:e,key:t,getValue:s,setValue:a,fallback:r=void 0,label:i=t,settings:n,onChange:l=null}){let c=wi(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,r,i)}),u.setValue(t,c.desiredValue(t,n.snapshot()[t]??r)),{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 Ve({settings:o,key:e,fallback:t=void 0,apply:s,onError:a=d(()=>{},"onError")}){let r=0;return async i=>{let n=++r;s(i);try{await o.set(e,i)}catch(l){n===r&&(s(o.snapshot()[e]??t),a(l))}}}d(Ve,"createLatestSettingWriter");var yi=class yi{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 r of a){let i=this.pending.get(r);this.syncAll(r,i?i.value:s[r])}}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 i={token:++this.revision,value:t,promise:Promise.resolve()},n=this.settings.set(e,t).then(()=>{this.pending.get(e)===i&&(this.pending.delete(e),this._maybeDispose())},l=>{if(this.pending.get(e)===i){this.pending.delete(e),i.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 i.promise=n,this.pending.set(e,i),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),vi.delete(this.settings))}};d(yi,"SettingBindingHub");var bi=yi;function ji(o,e){return be(e,!1)}d(ji,"normalizeBooleanValue");function Vl(o,e={}){let t=globalThis.$,s=e.value??o.defaultValue,a=e.onChange??null,r;if(o.type==="boolean")return r=t('<input type="checkbox" class="mini-switch">').prop("checked",ji(o.key,s)),r.on("change",()=>{a?.(r.is(":checked")?"yes":"no")}),{root:r,getValue:d(()=>r.is(":checked")?"yes":"no","getValue"),setValue:d(i=>r.prop("checked",ji(o.key,i)),"setValue")};if(o.type==="select"){let i=Array.isArray(o.options)?o.options:[];return r=t('<select class="jhs-select-source"></select>'),i.forEach(n=>{let l=n&&typeof n=="object"?n:{value:n,label:String(n)};r.append(t("<option></option>").attr("value",l.value).text(l.label??String(l.value)))}),r.val(String(s??"")),r.on("change",()=>a?.(r.val())),{root:r,getValue:d(()=>r.val(),"getValue"),setValue:d(n=>r.val(String(n??"")),"setValue")}}return o.type==="number"?(r=t('<input type="number" class="jhs-field">').val(s==null?"":String(s)),r.on("change",()=>a?.(Number(r.val())||0)),{root:r,getValue:d(()=>Number(r.val())||0,"getValue"),setValue:d(i=>r.val(i==null?"":String(i)),"setValue")}):(r=t('<input type="text" class="jhs-field">').val(s==null?"":String(s)),r.on("change",()=>a?.(r.val())),{root:r,getValue:d(()=>r.val(),"getValue"),setValue:d(i=>r.val(i==null?"":String(i)),"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||"")),r=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,r),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:r}=Bs(a);s.append(r)}return s}d(Hl,"buildQuickSettingsHtml");function ts(o,e,{settings:t,onChanged:s=null}){let a=wi(t),r=new Si(o,e,{settings:t,hub:a,onChanged:s});return{sync:d(i=>r.sync(i),"sync"),flush:d(i=>a.flush(i),"flush"),dispose:d(()=>r.dispose(),"dispose"),setters:r.setters}}d(ts,"bindSettingRows");var xi=class xi{constructor(e,t,{settings:s,hub:a,onChanged:r=null}){this.root=e,this.settings=s,this.hub=a,this.onChanged=r,this.setters={},this.controls=new Map,a.bindings.add(this);for(let i of t)this._bindDescriptor(i)}_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"),r=a.children().first();if(!r.length){let h=Vl(e);a.append(h.root),r=h.root}let i=e.type||(r.is("select")?"select":r.is('input[type="checkbox"]')?"boolean":r.is('input[type="number"]')?"number":"text"),n=kh(i,r),l=Ch(i,r),c=e.defaultValue;r.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:r,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(xi,"RowBinding");var Si=xi;function kh(o,e){return o==="boolean"?t=>e.prop("checked",ji("",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(kh,"makeSetValue");function Ch(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(Ch,"makeGetValue");var ki=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"]),_h=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 $h(o){let e=new Set;o.data("jhsDirtyManualKeys",e);for(let t of ki){let s=_h[t];s&&o.find(s).off(".jhsDirty").on("change.jhsDirty",()=>e.add(t))}}d($h,"bindManualDirtyTracking");function Jl(o){return o?globalThis.$(o):globalThis.$(document)}d(Jl,"formRoot");async function Wl(o,e=null){let t=Jl(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,r=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 ${r}`),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 i=o.webdav,n=i?.getProfile?await i.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=>{Ci("#reviewKeywordContainer",u,t)}),h&&h.forEach(u=>{Ci("#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)}))}),$h(t),Ah(t),Th(t,o.busImg,o.host,o.settings)}d(Wl,"loadSettingForm");function Th(o,e,t,s){o.find("#containerColumns").off(".jhsSetting").on("input.jhsSetting",(()=>{ss(o,t,"containerColumns",o.find("#containerColumns").val())})),o.find("#containerWidth").off(".jhsSetting").on("input.jhsSetting",(a=>{ss(o,t,"containerWidth",parseInt($(a.target).val())+70)}))}d(Th,"bindLayoutRangeEvents");function ss(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))),r=`${a}%`;o.find("#containerWidth").val(String(a-70)),o.find("#showContainerWidth").text(r);let i=e?.getListLayoutContainer?.();i&&(i.style.minWidth=r)}d(ss,"applyLayoutRangeValue");function et(o){let e=$(o);e.data("jhsQuickSettingBinding")?.dispose?.(),e.removeData("jhsQuickSettingBinding"),e.empty().hide()}d(et,"disposeQuickSettingHost");async function Os(o,e,t,s){let a=$(s);if(!a.length)throw new Error("Quick setting root is required");let r=o.settingsRegistry;if(!r)return;let i=r.list({surfaces:["quick"]}),n=ts(a,i,{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?.(),et(a),await t("base-panel")}))}d(Os,"initQuickSettingForm");async function Kl(o,e=null){let t=Jl(e),s=t.data("jhsDirtyManualKeys")||null,a=null,r=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");r=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(r&&!p.has(r)&&!await new Promise(m=>utils.q(null,`仅授权 WebDAV 精确来源:${r},是否继续?`,()=>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 Ph(t,s);await o.settings.update(p=>{if(Object.assign(p,n),r){let g=new Set(Array.isArray(p.trustedLocalOrigins)?p.trustedLocalOrigins:[]);g.add(r),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(!V)throw new Error("EventBus 尚未初始化");await V.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 Ah(o){o.data("jhsDirtyReviewKeywords",!1),o.data("jhsDirtyTitleKeywords",!1)}d(Ah,"bindKeywordDirtyTracking");async function Ph(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")},r=e instanceof Set?ki.filter(n=>e.has(n)).filter(n=>!["webDavUrl","webDavUsername","webDavPassword"].includes(n)):ki.filter(n=>!["webDavUrl","webDavUsername","webDavPassword"].includes(n)),i={};for(let n of r){let l=a[n];l&&(i[n]=await l())}return i}d(Ph,"collectManualSettingPatch");function Ci(o,e,t){let s=t.find(`${o} .tag-box`),a=String(e),r;/^[a-z]{2,}-/i.test(a)&&M?r=$("<a>").addClass("keyword-label keyword-label--link").attr("data-keyword",a).attr("href",`/video_codes/${a.replace("-","")}`).attr("target","_blank"):r=$("<div>").addClass("keyword-label").attr("data-keyword",a),r.append(document.createTextNode(a)),r.append($("<span>").addClass("keyword-remove").text("×"));let i=o==="#reviewKeywordContainer"?"jhsDirtyReviewKeywords":"jhsDirtyTitleKeywords";r.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(i,!0)}))})),s.append(r)}d(Ci,"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((i=>$(i).text().replaceAll("×","").trim()===a))||Ci(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 Ih(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(Ih,"buildCacheItemsHtml");function Rh(){let o="";return rt.forEach(e=>{e.canSelect&&(o+=`<option value="${e.quality}">${e.text}</option>`)}),o}d(Rh,"buildVideoQualityOptions");function Ql(o,e){let t=Ih(e),s=Rh();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 ${M?"":"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 ${M?"":"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 ${M?"":"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 ${M?"":"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 ABC-002 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 Us(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(Us,"buildQuickSettingHtml");async function Et(o){let e=o.getNetworkDiagnostics(),t=e.circuitBreakers,s=e.domainStats,a=await storageManager.getSetting("circuitBreakerThreshold",3),r=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(r/1e3)),c.dataset.jhsHydrated="1")}));let i=Object.entries(t);if(i.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 i){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} 的熔断状态`),Et(o)})),$("#resetAllBreakersBtn").off("click").on("click",(()=>{o.resetAllCircuitBreakers(),show.ok("已重置全部熔断状态"),Et(o)})),$("#clearDomainStatsBtn").off("click").on("click",(()=>{o.clearDomainStats(),show.ok("已清空域名统计"),Et(o)}))}d(Et,"renderNetworkPanel");async function as(){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,r)=>{let i=s.getData();return r((()=>{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(i.name)}」? 当前数据会自动备份。`,(async()=>{let u=loading();try{await storageManager.restoreSnapshot(i.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(i.id);if(!p)throw new Error("快照不存在");utils.download(JSON.stringify(p.data),`snapshot_${String(i.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(i.name)}」?`,(async()=>{try{await storageManager.deleteSnapshot(i.id),show.ok("已删除"),as()}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(as,"renderSnapshotPanel");function sc(o,e,t=null,s){let a=o.summary,r=[];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};r.push(u)}let i='<div class="jhs-dialog-content">';if(i+='<div class="jhs-summary-grid">',i+=`<div class="jhs-summary-card jhs-summary-card--success"><strong>${a.added}</strong><span>新增数据源</span></div>`,i+=`<div class="jhs-summary-card jhs-summary-card--danger"><strong>${a.removed}</strong><span>缺失数据源</span></div>`,i+=`<div class="jhs-summary-card jhs-summary-card--warning"><strong>${a.modified}</strong><span>有变更</span></div>`,i+=`<div class="jhs-summary-card"><strong>${a.unchanged}</strong><span>无变化</span></div>`,i+="</div>",r.length>0){i+='<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 r)i+=`<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>`;i+="</tbody></table></div>"}else i+='<div class="jhs-empty-note">数据完全一致,无需导入</div>';i+='<div class="jhs-warning-note">导入将覆盖当前数据,建议先创建快照备份</div>',i+="</div>";let n=r.length>0,l=s.open({type:1,title:"数据差异预览",content:i,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 _i(o,e=null){let t=o.exportSnapshot(),s=Ge(await storageManager.getSetting("disabledPlugins","[]")),a=t.legacyPlugins,r=d(S=>{let j=new Set(S);return a.filter((x=>j.has(x)||j.has(Tt(x))))},"effectiveDisabledNames"),{categories:i,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(i)){let x=j.plugins.filter(k=>c.has(k));if(x.length){h+='<section class="jhs-plugin-group">',h+=`<h4 class="jhs-plugin-group__title">${C(j.label)}</h4>`;for(let k of x){let _=l.get(k)?.disableable===!1,E=s.includes(Tt(k)),L=n[k]?.[0]||k;h+='<div class="jhs-plugin-row">',h+=`<span class="jhs-plugin-copy" title="内部插件名:${C(k)}"><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(k)}" ${E?"":"checked"}>`,h+="</div>"}h+="</section>"}}$("#plugin-mgmt-list").html(h);let u=r(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),x=j.data("plugin"),k=j.is(":checked"),_=!k,E=Ge(await storageManager.getSetting("disabledPlugins","[]")),L=Tt(x);if(k?E=E.filter(A=>A!==x&&A!==L):E.includes(L)||E.push(L),!e)throw new Error("SettingsService is unavailable");let N=d(A=>{let O=t.legacyPlugins,U=r(A);$("#pm-total").text(O.length),$("#pm-enabled").text(O.length-U.length),$("#pm-disabled").text(U.length)},"renderState");N(E);try{await e.set("disabledPlugins",JSON.stringify(E)),show.ok(`插件 "${x}" 已${k?"启用":"禁用"},刷新后生效`)}catch(A){j.prop("checked",_);let O=Ge(await storageManager.getSetting("disabledPlugins","[]"));N(O),clog.error("插件状态保存失败,已恢复",A),show.error(`插件 "${x}" 状态保存失败,已恢复`)}});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(((x,k)=>k.elapsed-x.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 x of S){let k=x.status==="disabled"?"is-muted":x.elapsed>500?"is-slow":x.elapsed>200?"is-warning":"",_=x.status==="disabled"?"已禁用":x.status==="error"?"错误":x.status==="pending-idle"?"等待空闲":x.status==="skipped-mobile"?"移动端跳过":"正常";j+=`<tr><td class="${k}">${C(x.name)}</td><td class="is-center">${x.startupMode==="idle"?"空闲":"即时"}</td><td class="is-right ${k}">${x.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(_i,"renderPluginMgmtPanel");async function rs(){let o=$("#health-data-display");if(o.length){o.text("体检中...");try{let e=await storageManager.inspectDataHealth(),t=e.fixable.reduce(((r,i)=>r+i.count),0),s=e.readonly.reduce(((r,i)=>r+i.count),0),a=d(r=>r.length?r.map((i=>`<li><strong>${C(i.message)}</strong>:${i.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(rs,"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 rs()}d(ac,"repairDataHealthWithBackup");var $i=class $i extends I{constructor(){super(...arguments),P(this,"folderName","JHS-数据备份"),P(this,"resourceSettings",new nt),P(this,"pendingCarImport",null),P(this,"taskStatusUnsubscribe",null),P(this,"_desktopSettingNavMounted",!1),P(this,"_settingScope",null),P(this,"_settingNavResizeCleanup",null),P(this,"_desktopNavGeneration",0),P(this,"_settingsDialogGeneration",0),P(this,"_fullSettingBinding",null),P(this,"_cloudSettingBinding",null),P(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 fi(e,{busImgPlugin:this.getOptionalDependency("BusImgPlugin"),hostAdapter:this.getRuntimeService("host")}).catch((a=>clog.error("[JHS] applyLayoutFromSettings failed:",a))),zl(t,s,B,M)}async handle(){let e=this.getRuntimeService("settings");this.resourceSettings=new nt({getSetting:d(async(i=null,n)=>i===null?e.snapshot():Object.prototype.hasOwnProperty.call(e.snapshot(),i)?e.snapshot()[i]:n,"getSetting"),saveSettingItem:d((i,n)=>e.set(i,n),"saveSettingItem"),updateSetting:d(i=>e.update(i),"updateSetting"),patch:d(i=>e.patch(i),"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(i=>{let n=i.detail?.names||[];n.length&&(n.includes("themeMode")&&Ht(s.snapshot().themeMode),n.includes("enableClog")&&(s.snapshot().enableClog==="yes"?clog.show():clog.hide()),n.some(l=>["mobileMode","enableVerticalModel","containerColumns","containerWidth"].includes(l))&&fi(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 r=d(async(i="backup-panel")=>{try{return await this.openSettingDialog(i)}catch(n){throw clog.error("设置中心打开失败",n),show.error("设置中心打开失败"),n}},"openSettings");t.addCleanup(gl(r)),t.listen(document,"click",(i=>{i.target instanceof Element&&i.target.closest("#setting-btn, #mini-setting-btn")&&(i.preventDefault(),$(".simple-setting, .mini-simple-setting").each((l,c)=>et(c)),clog.lowZIndex(),r().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(M){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");et(a),a.html(Us(this.getRuntimeService("settingsRegistry"))).show();try{await Os(this.getFormDependencies(),this.getSelector.bind(this),this.openSettingDialog.bind(this),a)}catch(r){clog.warn("桌面快捷设置初始化失败",r)}clog.lowZIndex()})).on("mouseleave.jhsSettingQuick",".setting-box",(s=>{et($(s.currentTarget).find(".simple-setting"))})).on("mouseenter.jhsSettingQuick",".mini-setting-box",(async s=>{let a=$(s.currentTarget).find(".mini-simple-setting");et(a),a.html(Us(this.getRuntimeService("settingsRegistry"))).show();try{await Os(this.getFormDependencies(),this.getSelector.bind(this),this.openSettingDialog.bind(this),a)}catch(r){clog.warn("迷你快捷设置初始化失败",r)}clog.lowZIndex()})).on("mouseleave.jhsSettingQuick",".mini-setting-box",(s=>{et($(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)=>et(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");et(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>'),r=$(`<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>`),i=r.find(".jhs-quick-setting");i.html(Us(this.getRuntimeService("settingsRegistry"))),$("body").append(a,r),clog.lowZIndex(),a.on("click.jhsQuickSetting",(()=>s())),r.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=r.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 Os(this.getFormDependencies(),this.getSelector.bind(this),(n=>{s(!1),this.openSettingDialog(n).catch((l=>clog.error("完整设置打开失败",l)))}),i),r.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,r)=>{let i=++this._settingsDialogGeneration,n=$(a);this._settingsFocusCleanup?.(),this._settingsFocusCleanup=utils.trapFocus(n[0]),n.data("jhsSettingsGeneration",i),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(r),t&&t(),this.renderTaskStatuses(n),this.taskStatusUnsubscribe?.(),this.taskStatusUnsubscribe=V.on("task-status-changed",(()=>this.renderTaskStatuses(n))),utils.isMobileMode()&&this.collapseAdvancedTabs(n);let c=await Promise.allSettled([this.hydrateSettingForm(a,i),this.loadResourceSettings(a,i)]),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"),r=this.getRuntimeService("settings"),i=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:r.snapshot()[p.key]??p.defaultValue});s.append(g)});let c=s.length?ts(s,l,{settings:r}):null,h=[],u=d(p=>{let g=Fl({settings:r,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=>ss(t,i,"containerColumns",p),"setValue"),fallback:5,label:"列表列数"}),u({selector:"#containerWidth",key:"containerWidth",getValue:d(()=>Number(t.find("#containerWidth").val())+70,"getValue"),setValue:d(p=>ss(t,i,"containerWidth",p),"setValue"),fallback:100,label:"列表宽度"}),u({selector:"#defaultQuickFilterTab",key:"defaultQuickFilterTab",getValue:d(()=>Ae(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 r=$(e);try{return await Wl(this.getFormDependencies(),r),!s[0]?.isConnected||t!==this._settingsDialogGeneration||r.data("jhsSettingsGeneration")!==t?!1:(K.refreshAll(e),s.attr("data-jhs-settings-ready","true").prop("disabled",!1).removeAttr("title"),a.empty().text("设置已加载"),!0)}catch(i){if(!s[0]?.isConnected||t!==this._settingsDialogGeneration||r.data("jhsSettingsGeneration")!==t)return!1;clog.error("settings-form 加载失败",i),this.getRuntimeService("diagnostics").recordError({source:"settings-form",message:i?.message||String(i)});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:"新作品"},r={idle:"正常",running:"运行中",pending:"等待下一次任务检查",due:"待运行"},i=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]}:${r[l.state]}`)),c.append($('<span class="form-content jhs-helper-text"></span>').text(`上次完成 ${i(l.completedAt)};下次检查 ${l.nextAt?i(l.nextAt):"立即"}`)),t.append(c)}))}collapseAdvancedTabs(e=null){let t=[{id:"health-panel",label:"数据体检",render:d(()=>rs(this.getRuntimeService("diagnostics")),"render")},{id:"plugin-mgmt-panel",label:"插件管理",render:d(()=>_i(this.getRuntimeService("diagnostics"),this.getRuntimeService("settings")),"render")},{id:"snapshot-panel",label:"恢复点",render:as},{id:"network-panel",label:"外部请求",render:d(()=>Et(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 r=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(""),i=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="更多工具">${r}</div> <div class="jhs-sub-panels">${i}</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"),r=this.getRuntimeService("diagnostics"),i=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"),rs()),m==="plugin-mgmt-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),_i(t.getRuntimeService("diagnostics"),t.getRuntimeService("settings"))),m==="snapshot-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),as()),m==="network-panel"&&(c.find("#saveBtn").hide(),c.find("#clean-all").addClass("jhs-is-hidden"),Et(r))})),c.find("#importBtn").on("click",(m=>Ll(l))),c.find("#exportBtn").on("click",(m=>Ul())),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=>Ml(this.folderName,s))),c.find("#webdavBackupListBtn").on("click",(m=>Bl(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",(()=>rs())),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("快照创建成功"),as()}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"?r.resetAllCircuitBreakers():f==="_domainStats"?r.clearDomainStats():f==="jhs_translate"?await n.clearCache():f==="jhs_actress_info"?(await this.getRuntimeService("cache").clearNamespace("actress-info"),await i.removeLocal(f)):f==="jhs_screenShot"?(await this.getRuntimeService("cache").clearNamespace("screenshot"),await i.removeLocal(f)):i.removeLocal(f),show.ok(`${v.text} 清理成功`),c.find("#cache-data-display").addClass("jhs-is-hidden"),f==="jhs_dmm_video"&&i.removeLocal("jhs_other_site_dmm")})),c.find("#clean-all").on("click",(async()=>{this.cacheItems.forEach((m=>m.key!=="jhs_translate"&&i.removeLocal(m.key))),await n.clearCache(),await this.getRuntimeService("cache").clearAll(),show.ok("全部缓存已清理"),c.find("#cache-data-display").addClass("jhs-is-hidden"),i.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(r.getNetworkDiagnostics().circuitBreakers):f==="_domainStats"?v=JSON.stringify(r.getNetworkDiagnostics().domainStats):f==="jhs_translate"?v=JSON.stringify(await n.inspectCache()):v=i.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,r,i,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:r,filters:i,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"),r=this.getRuntimeService("settings"),i=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");i.forEach(l=>{let c=Bs(l,{value:n(l.key)});c.root.attr("id",l.key),s.append(c.row)}),this._cloudSettingBinding=ts(s,i,{settings:r})}renderResourceSettings(e=$(document)){let t=d((s,a,r)=>{let i=$('<article class="jhs-card jhs-resource-card"></article>');i.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>'),i.append(n),i.on("change",".jhs-source-toggle",async l=>{let c=!l.currentTarget.checked;s.enabled=l.currentTarget.checked;try{r==="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("来源设置保存失败,已恢复原设置")}}),i.on("click",".jhs-source-test",l=>this.testSource(l.currentTarget,s.baseUrl||s.searchUrlTemplate?.replace("{keyword}","test"),{custom:a,source:s})),a&&i.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)}})))),i},"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((r=>{let i=$('<article class="jhs-card"></article>').append($("<strong></strong>").text(r.name),$("<p></p>").text(`${r.type==="regex"?"正则":"包含"}:${r.pattern}${e==="tag"?` · 权重 ${Number(r.weight)>=0?"+":""}${r.weight||0}`:` · ${r.action==="hide"?"隐藏":`降权 ${r.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>');i.on("click",".jhs-rule-edit",(()=>this.openRuleDialog(e,r,t))).on("click",".jhs-rule-delete",(n=>utils.q(n,`确认删除规则「${C(r.name)}」?`,(async()=>{try{await this.resourceSettings.updateArray(e==="tag"?"magnetTagRules":"magnetFilterRules",l=>l.filter((c=>c.id!==r.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(i)}))}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"],r=$('<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>'),i=d(()=>{let n=r.find('[name="parserType"]').val(),l=n==="torrent-table"?a.slice(0,7):n==="json"?a.slice(7):[];r.find(".jhs-parser-fields").html(l.map((c=>`<label>${c}<input name="${c}" class="jhs-field"></label>`)).join("")),l.forEach((c=>r.find(`[name="${c}"]`).val(e?.[c]||"")))},"renderFields");Object.entries(e||{enabled:!0,priority:100,parserType:"magnet-links"}).forEach(([n,l])=>{let c=r.find(`[name="${n}"]`);c.attr("type")==="checkbox"?c.prop("checked",l):c.val(l)}),r.on("change",'[name="parserType"]',i),i(),r.appendTo("body").hide(),s.open({type:1,title:e?"编辑自定义磁力源":"添加自定义磁力源",content:r,ui:{size:"md",body:"scroll"},area:utils.getDialogArea("md"),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());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"),r=e==="tag",i=$(`<div class="jhs-setting-section"><label>名称<input name="name" class="jhs-field"></label>${r?"":'<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>${r?'<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=i.find(`[name="${n}"]`);c.attr("type")==="checkbox"?c.prop("checked",l):c.val(l)}),i.appendTo("body").hide(),a.open({type:1,title:`${t?"编辑":"新建"}${r?"标签":"过滤"}规则`,content:i,ui:{size:"sm",body:"scroll"},area:utils.getDialogArea("sm"),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());l.id=t?.id||`rule-${Date.now()}`,l.weight=Number(l.weight),l.penalty=Number(l.penalty);try{Rt(l),await this.resourceSettings.updateArray(r?"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[r?"tags":"filters"]=await this.resourceSettings.getArray(r?"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),r=a.siblings(".jhs-source-test-state").length?a.siblings(".jhs-source-test-state"):$('<span class="jhs-badge jhs-source-test-state"></span>').insertAfter(a);r.text("检测中");try{let i=new URL(t),n=await this.getRuntimeService("scope")(),l=await this.getRuntimeService("http").request({providerId:`settings-source-${s.source?.id||"unknown"}`,method:"GET",url:i.href,responseType:"text",cacheScope:"none",urlPolicy:s.custom?{trustClass:"custom-public"}:{trustClass:"builtin-public",hosts:[s.source?.domain||i.hostname]}},n);r.text(l.data?"200 · 可解析":"空响应")}catch(i){r.text(i?.code==="NOT_FOUND"?"404":i?.code==="RATE_LIMITED"?"限流":i?.code==="AUTH_REQUIRED"?"需要授权":"请求失败")}finally{a.prop("disabled",!1).text("测试")}}previewCarNumbers(e=$(document)){let t=yl(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]))),r={added:0,updated:0,failed:0},i=Ce(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||jl(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),{[i]:!0},{type:"manual-car-number-import",records:u}),u.forEach(p=>a.has(p.carNum)?r.updated++:r.added++)}catch(p){r.failed+=u.length,clog.warn("番号批量导入块失败",p)}}this.pendingCarImport=null,t.find("#confirm-car-number-import").prop("disabled",!0),show.ok(`导入完成:新增 ${r.added},更新 ${r.updated},失败 ${r.failed}`)}))}};d($i,"SettingPlugin");var zs=$i;async function He(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(He,"requestHostPage");function rc(o){let e=globalThis.$,t=o?.jquery?o:e(o),s=[];return t.find('.tags a[href^="/actors/"]').each((a,r)=>{let i=e(r).text().trim();i&&s.push(i)}),t.find('span[onmouseover*="star_"] a').each((a,r)=>{let i=e(r).text().trim();i&&s.push(i)}),[...new Set(s)].join(" ")}d(rc,"readCardNames");function _e(o){let e=globalThis.$,t=o?.jquery?o:e(o),s=t.find("a"),a=t.attr("data-jhs-original-url")||s.attr("href"),r=t.find(".video-title"),i,n,l;if(r.length){let h=r.find("strong");h.length&&(i=h.text().trim()),n=s.attr("title")?s.attr("title").trim():i?r.text().replace(i,"").trim():r.text().trim(),l=t.find(".meta").text().trim()}if(!i){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)),i=u.find(p=>!/^\d{4}-\d{1,2}-\d{1,2}$/.test(p))}let c=ee(i);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(_e,"readListItem");function Ti(o,e,t){for(let s of o)if(e.includes(s)||t.startsWith(s))return s;return null}d(Ti,"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 ns(o,e,{filter:t="waitCheck"}={}){let s=o?.carNum,a=s?e.carMap.get(s):null,r=q(a?.stateFlags),n={keyword:!!(e.titleKeywords.length&&s?Ti(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(r,n);return{flags:r,visibilityReasons:n,recent:l,hardHidden:c,matchesCurrentFilter:oi(t,r,{visibilityReasons:n,recent:l})}}d(ns,"evaluateListItem");function ic(o){return o.replace(/\/+$/,"")}d(ic,"stripTrailingSlashes");function nc(o,e){try{let t=new URL(o),s=new URL(e);return t.origin===s.origin&&ic(t.pathname)===ic(s.pathname)&&t.search===s.search}catch{return o===e}}d(nc,"isSamePageUrl");async function Fs({startDom:o,itemSelector:e,nextPageSelector:t,fetchHtml:s,parseItem:a,evaluate:r,isCancelled:i=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(i())return p;let b=await s(u);if(i())return p;let w=new DOMParser().parseFromString(b,"text/html");m=$(w)}for(;m&&m.length&&!i();){n({page:f,scanned:v,matched:p.length});let b=m.find(e).toArray();for(let x of b){if(i())break;let k=null;try{k=a($(x))}catch{continue}if(!k?.carNum)continue;v++;let _=r(k);_?.matchesCurrentFilter&&!g.has(k.carNum)&&(g.add(k.carNum),p.push({...k,flags:_.flags,visibilityReasons:_.visibilityReasons,hardHidden:_.hardHidden}))}let w=m.find(t).attr("href");if(!w||i()||f>=c||(l&&await new Promise(x=>setTimeout(x,l)),i()))break;let S=await s(w),j=new DOMParser().parseFromString(S,"text/html");m=$(j),f++}return p}d(Fs,"scanAllPages");var Dt=null;function Vs(){if(Dt)return null;let o={id:Symbol("batch-run"),cancelRequested:!1};return Dt=o,o}d(Vs,"tryBeginBatchRun");function Nt(o){return Dt===o}d(Nt,"isActiveBatchRun");function oc(o){return!!o?.cancelRequested||!Nt(o)}d(oc,"isBatchRunCancelled");function lc(o){Dt===o&&o&&(o.cancelRequested=!0)}d(lc,"requestCancelBatchRun");function Hs(o){Dt===o&&(Dt=null)}d(Hs,"endBatchRun");function qs(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(qs,"parseDetailPage");function cc(){if(!V)throw new Error("Blacklist EventBus 未初始化");return V}d(cc,"getBlacklistEventBus");var Ai=class Ai 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,r;if(X.includes("/tags")){let p=new URL(X);p.searchParams.delete("page");let g=$("#jhs-check-tag").text().trim();a={starId:"no-"+g,name:"虚拟演员-"+g,allName:["虚拟演员"],role:"虚拟演员",movieType:g,blacklistUrl:p.toString()},r=`是否将分类 <span class="jhs-task-emphasis">${C(g)}</span> 加入到黑名单中?`,s&&(r=`分类 <span class="jhs-task-emphasis">${C(g)}</span> 已在黑名单中, 是否从当前页开始追加屏蔽?`)}else a=this.getActressPageInfo(),r=`是否将该演员 <span class="jhs-task-emphasis">${C(a.name)}</span> 加入到黑名单中?`,s&&(r=`演员 <span class="jhs-task-emphasis">${C(a.name)}</span> 已在黑名单中, 是否从当前页开始追加屏蔽?`);let{starId:i,name:n,allName:l,role:c,movieType:h,blacklistUrl:u}=a;if(X.includes("page")&&!X.includes("page=1")&&(r+="<br/> 注意: 当前页面非第一页, 屏蔽数据将从此页面开始"),B){let p=X.split("/star/")[1].split("/");p.length>1&&parseInt(p[1])>1&&(r+="<br/> 注意: 当前页面非第一页, 屏蔽数据将从此页面开始")}utils.q(t,r,(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:i,name:n,allName:l,role:c,movieType:h,url:u}),await this.filterActorVideo(n,i,null,B?Se: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${M?"":" 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 r=>{let i=$(r).find(".layui-layer-content > div").first().addClass("jhs-blacklist-layout").removeAttr("style");this.blacklistRoot=i;let n=i.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"),i.find("#table-container").removeAttr("style"),i.find("#table-container").before('<div id="blacklist-task-status" class="jhs-task-status jhs-blacklist-task-status" aria-live="polite"></div>'),K.enhance(r),e||i.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=$(r).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:"待运行"},r=d(n=>n?new Date(n).toLocaleString():"无","format"),i=s.state;e.empty().append($('<span class="jhs-task-status__name"></span>').text(`黑名单:${a[i]||a.idle}`),$('<span class="jhs-task-status__meta"></span>').text(`上次完成 ${r(s.completedAt)};下次检查 ${s.nextAt?r(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(),r=e.find("#statusType").val(),i=e.find("#dataType"),n=i.val(),l=e.find("#urlType").val(),c=t.length,h=0,u=0,p=t.map(f=>{f.role===Oe?h++:f.role===at&&u++;let v=!1;return v=gt(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=!r||r==="normal"&&!f.isUnCheck||r==="stop"&&f.isUnCheck,j=!n||f.role===n,x=f.url.includes("t=");return w&&S&&j&&(!l||l==="hasT"&&x||l==="noT"&&!x)});i.html(` <option value="">所有 (${c})</option> <option value="actor">男演员 (${h})</option> <option value="actress">女演员 (${u})</option> `),K.setValue(i,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");Ue(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,r,i,n,l)=>`演员: ${n} 番号总数: ${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,r,i)=>{let n=a.getData(),l=Ye(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,r,i)=>{let n=a.getData().role,l=n;return n===Oe?l="男演员":n===at&&(l="女演员"),l},"formatter")},{title:"影视类别",field:"movieType",sorter:"string",width:120,responsive:5,formatter:d((a,r,i)=>{let n=a.getData().movieType,l=n;return n===We?l="有码":n===Ke&&(l="无码"),l},"formatter")},{title:"屏蔽类型",field:"url",sorter:"string",minWidth:120,responsive:4,visible:M,formatter:d((a,r,i)=>{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,r,i)=>{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,r,i)=>{let n=a.getData();return i((()=>{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 r=Ae(t),i=Ee[r],n=r==="all"?"将处理当前搜索全部分页的所有作品(包括屏蔽项)并加入黑名单。":`将处理当前搜索全部分页中符合「${i}」筛选的作品并加入黑名单。`;if(s&&!await new Promise(u=>utils.q(null,n,()=>u(!0),()=>u(!1))))return{cancelled:!0};let l=Vs();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(()=>!Nt(l)||!!h?.disposed,"isCancelled"),m=await Fs({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=>He(this.getRuntimeService("http"),b,h),"fetchHtml"),parseItem:d(b=>_e(b),"parseItem"),evaluate:d(b=>ns({carNum:b.carNum,title:b.title||""},p,{filter:r}),"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{Nt(l)&&Hs(l),$("#favoriteAllVideo, #hasDownAllVideo, #filterAllVideo").removeAttr("aria-disabled").removeClass("jhs-batch-busy")}}async filterActorVideo(e,t,s,a=B?Se:Be,r=1,i=0,n=new Set){let{nextPageLink:l,recordCount:c}=await this.parseAndSaveFilterInfo(s,e,t,a);if(i+=c,(this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`正在处理第 ${r} 页 · 已屏蔽 ${i} 个番号`),this.nextPageLink=l,l&&r<200&&!n.has(l)){n.add(l);let h;this.lastPageLink=l,clog.log("正在请求下一页内容:",l);let u=await this.getRuntimeService("scope")(),p=await He(this.getRuntimeService("http"),l,u);h=utils.htmlTo$dom(p),await this.filterActorVideo(e,t,h,a,r+1,i,n)}else r>=200?((this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`已达到页数上限(200 页),已停止 · 已屏蔽 ${i} 个番号`),clog.warn("演员视频分页扫描已达上限,已停止")):(this.blacklistRoot||$()).find("#checkBlacklistMsg").text(`处理完成 · ${r} 页 · 新增 ${i} 个番号`)}async parseAndSaveFilterInfo(e,t,s,a){if(![Be,Se].includes(a))throw new Error(`未知黑名单来源站点: ${a}`);let r=e||$(document),i=this.getSelector(a);a===Se&&r.find(".avatar-box").length>0&&r.find(".avatar-box").parent().remove();let n=qs(r,{boxSelector:a===Se?`${i.boxSelector}, #waterfall`:i.boxSelector,requestDomItemSelector:e?i.requestDomItemSelector:i.itemSelector}),l=r.find(i.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}=_e(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:Gt(h),recordCount:c.length}}};d(Ai,"BlacklistPlugin");var Js=Ai;var Pi=class Pi 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=M?".title strong, .current-title":B?"h3":".current-title, .origin-title, .jhs-detail-title";s.off("contextmenu.jhsTitleFilter",a).on("contextmenu.jhsTitleFilter",a,(r=>{let i=window.getSelection()?.toString()||"";if(i){r.preventDefault();let n={clientX:r.clientX,clientY:r.clientY+80};utils.q(n,`是否屏蔽标题关键词 ${C(i)}?`,(async()=>{let l=i.replace(/\r?\n+/g," ").replace(/\s{2,}/g," ").trim().slice(0,120);l&&await storageManager.saveTitleFilterKeyword(l),await V?.emit("filter-rules-changed",{scope:"title-keyword"}),utils.closePage({root:s,layerIndex:t})}))}}))}};d(Pi,"FilterTitleKeywordPlugin");var Ws=Pi;function Ks(o,{retry:e=null,tone:t="neutral",extraClass:s=""}={}){let a=globalThis.$,r=a('<div class="jhs-panel-state"></div>').text(o);return s&&r.addClass(s),t==="error"&&r.addClass("is-error"),e&&r.append(" ",a('<button type="button" class="jhs-btn jhs-btn--secondary jhs-btn--sm">重试</button>').on("click",e)),r}d(Ks,"createPanelState");function dc(o="正在加载…"){return Ks(o)}d(dc,"createPanelLoading");function hc(o,e=null){return Ks(o,{retry:e,tone:"error"})}d(hc,"createPanelError");function Ii(o){try{let e=new URL(String(o||""));return["http:","https:"].includes(e.protocol)?e.href:null}catch{return null}}d(Ii,"normalizeUrl");function he(o,e,t=null){let s=globalThis.$,a=s(o).empty(),r=Ks(e,{retry:t,tone:t?"error":"neutral",extraClass:"jhs-fc2-state"});a.append(r)}d(he,"renderFc2State");function os(o,e,t=null){let s=globalThis.$,a=[...new Set((e||[]).map(Ii).filter(Boolean))],r=o.root.find('[data-jhs-role="gallery-grid"]').empty(),i=o.root.find('[data-jhs-role="main-preview"]').empty();o.galleryUrls=new Set(a);let n=Ii(t);if(n&&i.append(s("<img>").attr({src:n,alt:`${o.carNum} 概览`,loading:"eager"})),!a.length)return he(r,"暂无剧照");a.forEach((c,h)=>r.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(os,"renderFc2Gallery");function Gs(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 原页面",Ii(o.url)],...a.map(i=>[i.providerId==="fc2ppvdb"?"FC2PPVDB":"FC2 市场",i.url])].forEach(([i,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(i))),s}d(Gs,"createFc2SourceLinks");var Ri=class Ri 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(){let e=document.querySelector('#navbar-menu-hero a[href^="/tags/fc2"]');if(e&&!document.querySelector("#jhs-123av-nav")){let t=document.createElement("a");t.id="jhs-123av-nav",t.className="navbar-item",t.href="/tags/fc2?c10=1&jhs_source=123av",t.textContent="123AV · FC2片库",e.after(t)}je(window.location).kind==="external-fc2-catalog"&&(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=this.$contentBox.find("h2.section-title").first();a.length||(a=$("<h2></h2>").addClass("section-title").prependTo(this.$contentBox)),a.text("123AV · FC2片库"),a.css("marginBottom","0"),a.append(` <div class="jhs-layout-f5f47b30"> <input id="search-123av-keyword" type="text" placeholder="搜索123AV FC2内容" 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 r=String($("#search-123av-keyword").val()||"").trim();r&&(this.keyword=r,utils.setHrefParam("keyword",r),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(),e.mountExternalFc2Catalog(this.$listRoot[0]),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",(r=>{r.preventDefault(),this.currentPage=parseInt($(r.target).data("page")),utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery()})),$(".pagination-previous").on("click",(r=>{r.preventDefault(),this.currentPage>1&&(this.currentPage--,utils.setHrefParam("page",this.currentPage),this.renderPagination(),this.handleQuery())})),$(".pagination-next").on("click",(r=>{r.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 r=s;r<=a;r++){let i=r===this.currentPage?" is-current":"";e.append(`<li><button type="button" class="jhs-btn pagination-link${i}" data-page="${r}">${r}</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 r=a.items;this.maxPage=Math.max(1,Number(a.maxPage)||1),this.currentPage=Math.min(Math.max(1,this.currentPage),this.maxPage),this.renderPagination(),r.length===0&&(clog.log(r),show.error("无结果"),clog.error("123AV 获取数据失败"));let i=this.markDataListHtml(r);this.$listRoot?.html(i);let n=this.getOptionalDependency("ListPagePlugin");n&&this.$listRoot&&await n.processAddedItems?.(this.$listRoot.find(".item").toArray()),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),r=this.getActressInfo(e.carNum);a.then((i=>e.isAlive()&&os(e,i,null))).catch((i=>e.isAlive()&&he(e.root.find('[data-jhs-role="gallery-grid"]'),"剧照加载失败",(()=>{this.reloadImages(e)})))),r.then((async i=>{await s.catch((()=>null)),e.isAlive()&&this.render123AvActress(e,i)})).catch((i=>clog.error("FC2 演员信息加载失败",i))),await Promise.allSettled([s,a,r])}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>',Gs(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()&&os(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=Ye(s.url),r=Ye(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 ">${r?`<img loading="lazy" src="${C(r)}" 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(Ri,"Fc2By123AvPlugin");var Qs=Ri;var Eh=Object.freeze({blocked:{id:"filterBtn",tone:"filter",label:Le},favorite:{id:"favoriteBtn",tone:"fav",label:Me},downloaded:{id:"hasDownBtn",tone:"down",label:fe},watched:{id:"hasWatchBtn",tone:"watch",label:ve}});function Lt({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 r=Eh[a];if(!r)continue;let i=t('<button type="button" class="jhs-btn jhs-state-action" aria-pressed="false"><span></span></button>');i.attr("id",e[a]||r.id).addClass(`jhs-btn--${r.tone}`).find("span").text(r.label),s.children().append(i)}return s}d(Lt,"createStateActions");var pc={blocked:{selector:"#filterBtn",inactive:d(()=>Le,"inactive"),active:d(()=>tt,"active")},favorite:{selector:"#favoriteBtn",inactive:d(()=>Me,"inactive"),active:d(()=>st,"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 Ei=class Ei{constructor(e){this.stateService=e}bind({root:e=document,closeRoot:t=e,layerIndex:s=null,carNum:a,getRecord:r=null,activityType:i="detail-state",selectors:n={}}){let l={root:e,closeRoot:t,layerIndex:s,carNum:T(a),getRecord:r,activityType:i,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),r=q(a?.stateFlags);return t==="blocked"&&!r.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,r=s?.currentTarget?$(s.currentTarget):$(e.root).find(a);if(!r.prop("disabled")){r.prop("disabled",!0).attr("aria-busy","true");try{let i=typeof e.getRecord=="function"?await e.getRecord():e.getRecord||{carNum:e.carNum};await this.stateService.toggle(e.carNum,t,{type:e.activityType,record:i}),await this.render(e),await utils.closePage({layerIndex:e.layerIndex,root:e.closeRoot||e.root})}catch(i){clog.error("详情状态更新失败",i),show.error("操作失败")}finally{r[0]?.isConnected&&r.prop("disabled",!1).removeAttr("aria-busy")}}}async render({root:e=document,carNum:t,selectors:s={}}){let a=await storageManager.getCar(T(t)),r=q(a?.stateFlags);for(let[i,n]of uc()){let l=$(e).find(s[i]||n.selector),c=!!r[i];l.attr("aria-pressed",String(c)).each((h,u)=>$(u).find("span").first().text(c?n.active():n.inactive()))}return r}};d(Ei,"DetailStateController");var Mt=Ei;var mc="https://jdforrepam.com/api",gc=0,Ys="",ls=new Map;async function fc(){let o=globalThis;if(o.credentialService?.get)return o.credentialService.get("jhs_appAuthorization");let e=localStorage.getItem("jhs_appAuthorization");return e?Xe(e):""}d(fc,"readJavDbToken");function Dh(o){return o&&typeof o=="object"?o:{}}d(Dh,"asResponseRecord");function vc(){let o=Math.floor(Date.now()/1e3);return Ys&&o-gc<=20||(gc=o,Ys=`${o}.lpw6vgqzsp.${md5(`${o}71cf27bb3c0bcdf207b64abecddc970098c7421ee7203b9cdae54478478a199e7d5a6e1a57691123c1a931c057842fb73ba3b3c83bcd69c17ccf174081e3d8aa`)}`),Ys}d(vc,"O");async function bc(o){let e=String(o||"").trim(),t=await fc();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((([r,i])=>`--${s}\r Content-Disposition: form-data; name="${r}"\r \r ${i}\r `)).join("")+`--${s}--\r `;try{let r=await gmHttp.gmRequest("POST",`${mc}/v1/movies/${encodeURIComponent(e)}/reviews`,a,{},{"user-agent":"Dart/3.5 (dart:io)","accept-language":"zh-TW",authorization:`Bearer ${t}`,jdsignature:await vc(),"content-type":`multipart/form-data; boundary=${s}`});if(r?.success===0)throw r;return await storageManager.deleteCachedRequest(`movie-detail:${e}`),ls.set(e,!0),r}catch(r){let i=Dh(r);if(i.status===401||i.action==="JWTVerificationError"||/未登录|登录|unauthorized|jwt/i.test(i.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 r instanceof Error?r:new Error(i.message||"加入 JavDB 想看失败")}}d(bc,"markJavDbWantWatch");async function wc(o){let e=String(o||"").trim(),t=await fc();if(!t)return null;if(!e)throw new Error("JavDB 影片 ID 无效");if(ls.has(e))return ls.get(e);let s=48;for(let a=1;a<=100;a++){let r=`${mc}/v2/users/review_movies?status=want_watch&type=0&sort_by=create&order_by=desc&page=${a}&limit=${s}`,i=await gmHttp.gmRequest("GET",r,null,{},{"user-agent":"Dart/3.5 (dart:io)","accept-language":"zh-TW",authorization:`Bearer ${t}`,jdsignature:await vc()}),n=i?.data?.movies??i?.movies;if(!Array.isArray(n))throw new Error("JavDB 想看状态响应无效");if(n.some(l=>String(l.id)===e))return ls.set(e,!0),!0;if(n.length<s)return ls.set(e,!1),!1}return!1}d(wc,"getJavDbWantWatchState");var Zs=!1;function yc({dialog:o,account:e,credential:t,getScope:s,onSuccess:a}){if(Zs)return null;Zs=!0;try{return o.open({type:1,title:"JavDB",closeBtn:1,area:utils.getResponsiveArea(["360px","auto"]),shadeClose:!1,content:'<div class="jhs-layout-e32cff7f"><div class="jhs-layout-598afa5a"><input type="text" id="username" name="username" placeholder="用户名 | 邮箱" class="jhs-field"></div><div class="jhs-layout-da303dcf"><input type="password" id="password" name="password" placeholder="密码" class="jhs-field"></div><button id="loginBtn" class="jhs-btn jhs-layout-c4eb15bf" type="button">登录</button></div>',success:d((r,i)=>{$(r).find("#loginBtn").on("click",async()=>{let n=String($(r).find("#username").val()||""),l=String($(r).find("#password").val()||"");if(!n||!l)return void show.error("请输入用户名和密码");let c=loading();try{let h=await e.login("javdb",{username:n,password:l},{scope:await s()});if(!h.success)return void show.error(h.message);if(!t?.set)throw new Error("凭证服务不可用");await t.set("jhs_appAuthorization",h.token),show.ok("登录成功"),o.close(i),await a?.()}catch(h){clog.error("登录异常:",h),show.error(h instanceof Error?h.message:String(h))}finally{c.close()}})},"success"),end:d(()=>{Zs=!1},"end")})}catch(r){throw Zs=!1,r}}d(yc,"openJavDbLoginDialog");async function Xs(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 r=s.nextAll(".translated-title").first();r.length||(r=e('<div class="translated-title"></div>').insertAfter(s)),r.removeClass("is-error").text("翻译中...");try{let i=await o.translation.translate(a,{cacheAlias:o.carNum,scope:o.scope});if(o.isActive&&!o.isActive()||!s[0]?.isConnected||!r[0]?.isConnected)return;r.text(i)}catch(i){if(o.isActive&&!o.isActive()||!s[0]?.isConnected||!r[0]?.isConnected)return;let n=i instanceof Error?i.message:String(i);globalThis.clog?.error("翻译失败:",i),r.addClass("is-error").text(`翻译失败: ${n}`)}}d(Xs,"renderTranslatedTitle");function Nh(o){try{let e=new URL(String(o||""));return e.protocol==="https:"?e.href:null}catch{return null}}d(Nh,"normalizeImageUrl");function Lh(o,e,t){let s=globalThis.$,a=Nh(e);if(!a)return null;let r=s("<img>").attr({src:a,alt:t,loading:"lazy"}).addClass("jhs-fc2-gallery__image"),i=s('<button type="button" class="jhs-btn jhs-fc2-gallery-item jhs-fc2-screenshot-thumbnail"></button>').attr("aria-label",`查看${t}大图`).append(r);return o.empty().append(i).off("click.jhsScreenshot").on("click.jhsScreenshot",".jhs-fc2-screenshot-thumbnail",n=>{n.preventDefault(),n.stopPropagation(),globalThis.showImageViewer(r[0])}),a}d(Lh,"renderImage");async function ea(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:r}=o.screenshot.getScreenshotSettings(o.settings),i=o.screenshot.getEnabledProviders(o.settings);if(r!=="manual"&&!i.some(u=>u.id===a))return t.empty(),null;if(!i.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):Lh(u,m.url,"缩略图")}catch(g){return s()&&(u.empty().append(hc("缩略图加载失败 ",()=>{n(u,p)})),globalThis.clog?.error("缩略图加载失败",g)),null}},"load");if(r!=="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 i.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(ea,"renderScreenshotPanel");var Di=class Di{constructor(e){this.related=e.related,this.settings=e.settings,this.scope=e.scope}async show(e,t,s={}){let a=globalThis.$,r=s.isActive??(()=>!0);if(!t)throw new TypeError("未传入movieId");if(!r()||!e?.length)return a();let i=e.children('[data-jhs-panel="related"]').filter((b,w)=>a(w).attr("data-jhs-movie-id")===String(t)).first();if(i.length)return i;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(!r()||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&&r(),"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=Ve({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,r=new te(`related:${e.movieId}:page:1`),i=e.panelScope.addCleanup(()=>r.dispose());e.requestScope=r;try{let n=await this.related.list({movieId:e.movieId},{page:1,limit:20,scope:r});if(!e.isActive()||r.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()||r.signal.aborted||a!==e.generation||!e.enabled)return;globalThis.clog?.error("获取清单失败:",n),this.renderRetry(t,()=>{this.fetch(e)})}finally{i(),e.requestScope===r&&(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.$,r=a('<button type="button" class="jhs-btn jhs-btn--secondary jhs-related-load-more">加载更多清单</button>'),i=a('<div class="jhs-panel-end jhs-related-end">已加载全部清单</div>').hide();s.empty().append(r,i),r.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,r.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?(r.remove(),i.show()):r.text("加载更多清单").prop("disabled",!1)}catch(u){if(!e.isActive()||c.signal.aborted||l!==e.generation||!e.enabled)return;globalThis.clog?.error("加载更多清单失败:",u),r.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(r=>{let i=a("<a></a>").addClass("jhs-related-title").attr({href:`/lists/${encodeURIComponent(r.id)}`,target:"_blank",rel:"noopener noreferrer"}).text(r.name||"未命名清单"),n=a('<div class="jhs-related-heading"></div>').append(a("<span></span>").addClass("jhs-related-index").text(`#${e.floorIndex++}`),i),l=a('<div class="jhs-related-meta"></div>'),c=r.createdAt?globalThis.utils.formatDate(r.createdAt):"未知";l.append(a("<span></span>").text(`视频:${Number(r.movieCount)||0}`),a("<span></span>").text(`收藏:${Number(r.collectionCount)||0}`),a("<span></span>").text(`查看:${Number(r.viewCount)||0}`),a('<time class="jhs-related-time"></time>').text(`创建时间:${c}`)),s.append(a('<article class="jhs-related-item"></article>').append(n,l))})}};d(Di,"RelatedPanel");var Bt=Di;var Ni=class Ni{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.$,r=s.isActive??(()=>!0);if(!r()||!t?.length)return a();let i=t.children('[data-jhs-panel="reviews"]').filter((b,w)=>a(w).attr("data-jhs-movie-id")===String(e)).first();if(i.length)return i;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(!r()||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&&r(),"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=Ve({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 r=Number(this.settings.snapshot().reviewCount)||20,i=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:r,scope:n});if(!e.isActive()||n.signal.aborted||i!==e.generation||!e.enabled)return;let h=await this.getKeywords();if(!e.isActive()||n.signal.aborted||i!==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===r?this.bindLoadMore(e,r,h,s,a):a.append(t('<div class="jhs-panel-end"></div>').text("已加载全部评论"))}catch(c){if(i===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,r){let i=globalThis.$,n=i('<button type="button" class="jhs-btn jhs-btn--secondary jhs-review-load-more">加载更多评论</button>'),l=i('<div class="jhs-panel-end jhs-review-end">已加载全部评论</div>').hide();r.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 r=globalThis.$,i=a.length?new RegExp(a.map(n=>n.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")).join("|")):null;for(let n of t){let l=String(n.content||"");if(i?.test(l))continue;let c=r('<article class="jhs-review-item"></article>'),h=r('<div class="jhs-review-meta"></div>'),u=r('<div class="review-content jhs-review-content"></div>');h.append(r("<span></span>").addClass("jhs-review-author").text(n.author||"匿名用户"));let p=r('<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,r("<time></time>").text(m),r("<span></span>").text(`点赞:${Number(n.likes)||0}`),r("<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,r;for(;r=s.exec(t);)r.index>a&&e.append(document.createTextNode(t.slice(a,r.index))),this.appendLink(e,r[0]),a=r.index+r[0].length;a<t.length&&e.append(document.createTextNode(t.slice(a)))}appendLink(e,t){let s=globalThis.$,a=t.startsWith("ed2k://"),r=t.startsWith("magnet:"),i=a?"ED2K 链接":r?"Magnet 链接":"打开链接",n=a||r,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(i).on("click",()=>globalThis.utils.copyToClipboard(i,t)):s("<a></a>").addClass("jhs-review-link").attr({href:t,target:"_blank",rel:"noopener noreferrer"}).text(i),u=s('<button type="button" class="jhs-btn jhs-review-link jhs-review-link-copy">复制</button>').on("click",()=>globalThis.utils.copyToClipboard(i,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(Ni,"ReviewPanel");var Ot=Ni;function Mh(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(Mh,"normalizeWorkspaceMovieContext");function jc({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((([r,i])=>{let n=$('<section class="jhs-fc2-section"></section>').attr("data-jhs-section",r),l=$('<header class="jhs-fc2-section__header"></header>'),c=$("<h2></h2>").text(i),h=$('<div class="jhs-fc2-section__actions"></div>').attr("data-jhs-section-actions",r);n.append(l.append(c,h),$('<div class="jhs-fc2-section__content"></div>').attr("data-jhs-slot",r)),s.append(n)})),s}d(jc,"createFc2DetailShell");function Sc(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)}`,r=new Set,i=e.mode==="dialog"?"fc2-dialog":"native-detail",n=Mh({...e,carNum:e.carNum||t.attr("data-jhs-car-num"),detailUrl:e.url,surface:i},i),l={...e,movieContext:n,root:t,workspace:t,namespace:a,observers:r,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&&r.add(c),c},destroy(){s||(s=!0,t.off(a).find("*").off(a),r.forEach((c=>c.disconnect?.())),r.clear(),t.removeData("jhsFc2Context"))}};return t.data("jhsFc2Context",l).attr("data-jhs-surface",i),n&&t.data("jhsMovieContext",n),l}d(Sc,"createFc2DetailContext");function Bh(o){return cl(o,window.location.origin)}d(Bh,"parseExplicitJavDbMovieId");var Li=class Li extends I{constructor(){super(...arguments),this.detailStateController=null,this.translationGeneration=0}getName(){return"Fc2Plugin"}getDetailStateController(){return this.detailStateController||(this.detailStateController=new Mt(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 Bh(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(){if(!X.includes("collection_codes?movieId"))return;let e=new URLSearchParams(window.location.search),t=e.get("movieId"),s=e.get("carNum"),a=e.get("url"),r=e.get("source"),i=$("section").first().empty();if(!s||!a)return void i.append($('<div class="jhs-fc2-state is-error"></div>').text("FC2 详情参数不完整"));let n=t&&t!=="search"?t:await this.resolveMovieIdForRecord(s,a),l=["fc2","123av"].includes(r||"")?r:await this.resolveFc2Source({url:a}),c=this.mountFc2Detail(i,{movieId:n,carNum:s,url:a,source:l,mode:"page"});$(window).off("pagehide.jhsFc2Detail").one("pagehide.jhsFc2Detail",(()=>c.destroy()))}openFc2Dialog(e,t,s,{source:a=""}={}){a=["fc2","123av"].includes(a)?a:"";let r=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((i,n)=>{r=this.mountFc2Detail($(i).find(".jhs-fc2-dialog-host"),{movieId:e,carNum:t,url:s,source:a,layerIndex:n,mode:"dialog"}),utils.setupEscClose(n)},"success"),end:d(()=>r?.destroy(),"end")})}mountFc2Detail(e,t){let s=$(e);s.data("jhsFc2Context")?.destroy?.(),s.empty();let r=jc(t).appendTo(s),i=Sc(r,t);return s.data("jhsFc2Context",i),i.translationGeneration=0,i.screenshotGeneration=0,i.otherSiteGeneration=0,this.initializeWorkspace(i),this.bindFc2FeatureLifecycle(i),i}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(Lt()),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>'),r=$('<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,r);let i=$('<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>'),i.append(n,l,c),e.getSlot("resources").append(i),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 r=a.detail?.names;if(r?.length&&(r.includes("enableLoadScreenShot")&&(t.snapshot().enableLoadScreenShot==="no"?(e.screenshotGeneration=(e.screenshotGeneration||0)+1,this.unmountFc2Screenshot(e)):this.loadFc2Screenshot(e)),r.includes("translateTitle")&&((t.snapshot().translateTitle??R)===R?this.applyFc2Translation(e):(e.translationGeneration=(e.translationGeneration||0)+1,this.revertFc2Translation(e))),r.includes("enableMagnetsFilter")&&e.magnetFilterApply?.((t.snapshot().enableMagnetsFilter??R)===R),r.includes("enableLoadOtherSite"))){let i=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,i)):this.mountFc2OtherSites(e,i,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 r=(e.screenshotGeneration||0)+1;e.screenshotGeneration=r,Promise.resolve().then((()=>this.getRuntimeService("scope")())).then(i=>ea({target:a,carNum:e.carNum.replace("FC2-",""),screenshot:t,settings:s.snapshot(),scope:i,isActive:d(()=>e.isAlive()&&s.snapshot().enableLoadScreenShot!=="no"&&r===e.screenshotGeneration,"isActive"),isDuplicate:d(n=>!!e.galleryUrls?.has(n),"isDuplicate")})).then(i=>{if(!(!e.isAlive()||r!==e.screenshotGeneration)&&s.snapshot().enableLoadScreenShot==="no")return void a.empty()}).catch(i=>{!e.isAlive()||r!==e.screenshotGeneration||(a.empty(),clog.error("FC2 剧照初始化失败",i))})}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=>Xs({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"),r=(e.otherSiteGeneration||0)+1;e.otherSiteGeneration=r,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"&&r===e.otherSiteGeneration,"isActive")}))).then(i=>{!e.isAlive()||r!==e.otherSiteGeneration||(i?t.show():t.hide())}).catch(i=>{!e.isAlive()||r!==e.otherSiteGeneration||(t.show(),he(e.root.find('[data-jhs-role="other-sites"]'),"外部站点加载失败"),clog.error("FC2 外部站点加载失败",i))})}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 r=await wc(a);if(!e.isAlive())return;if(r)return void s.prop("disabled",!0).attr("aria-pressed","true").text("已在 JavDB 想看")}catch(r){clog.warn("读取 JavDB 想看状态失败,保留手动操作",r)}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 bc(t),!e.isAlive())return;s.attr({"aria-pressed":"true","aria-disabled":"false"}).text("已加入 JavDB 想看"),show.ok("已加入 JavDB 想看")}catch(a){if(!e.isAlive())return;let r=a;if(r?.code==="LOGIN_REQUIRED")return s.attr("aria-disabled","false").text("JavDB 想看"),yc({dialog:this.getRuntimeService("dialog"),account:this.getRuntimeService("account"),credential:this.getRuntimeService("credential"),getScope:this.getRuntimeService("scope"),onSuccess:d(()=>this.submitJavDbWant(e,t,s),"onSuccess")});s.attr("aria-disabled","false").text("JavDB 想看"),show.error(r?.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),os(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 r=$('<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=>r.append($("<span></span>").text(l)))),s.append(r);let i=[],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&&i.push(l.name)})),t.actors?.length||n.append($("<span></span>").text("暂无演员信息")),s.append(n,Gs(e,this.getRuntimeService("movie")),$('<span class="jhs-is-hidden" data-jhs-role="actress-data"></span>').text(i.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")(),r=await this.getRuntimeService("magnet").listNative({movieId:t,providerId:"javdb"},{scope:a});if(!e.isAlive())return;if(s.empty(),!r.length)return he(s,"暂无站内磁力");let i=[],n=this.getRuntimeService("magnet");r.forEach((l=>{let c=wl(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>');i.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,i.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"),r=a.find(".jhs-fc2-section__actions");r.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=Ve({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,r.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"),r=new Bt({related:this.getRuntimeService("related"),settings:this.getRuntimeService("settings"),scope:a}),i=new Ot({review:this.getRuntimeService("review"),settings:this.getRuntimeService("settings"),storage:this.getRuntimeService("storage"),scope:a});await Promise.allSettled([i.show(s,e.getSlot("reviews"),{ownedSection:e.getSection("reviews"),isActive:e.isAlive,ownCleanup:d(n=>e.addObserver({disconnect:n}),"ownCleanup")}),r.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 r=new URL("/users/collection_codes",window.location.origin);return r.searchParams.set("movieId",String(e).trim()),r.searchParams.set("carNum",t),r.searchParams.set("url",s),r.searchParams.set("source",a),r.href}async openFc2Page(e,t,s,a={newTab:!0},{source:r=""}={}){r=["fc2","123av"].includes(r)?r:"";let i=String(e||"").trim();if(!i)return void utils.openPage(s,t,!0,a);utils.openPage(this.createFc2PageUrl(i,t,s,{source:r}),t,!0,a)}};d(Li,"Fc2Plugin");var ta=Li;var Mi=class Mi extends I{getName(){return"HitShowPlugin"}async handle(){let e=je(window.location);if(e.kind!=="playback-ranking")return;let t=this.getRuntimeService("host").locateListRoot?.();t&&(t.setAttribute("data-jhs-ranking","playback"),t.setAttribute("data-jhs-ranking-period",e.period),t.setAttribute("data-jhs-ranking-filter",e.filter))}};d(Mi,"HitShowPlugin");var sa=Mi;var Bi=class Bi 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(),r=t.find((i=>$(i).find(".vid-title").text().toLowerCase().includes(a)));if(r)return void(window.location.href=$(r).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(W.debug)}),$(".vjs-control-bar").css({position:"fixed",bottom:"20px",zIndex:String(W.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(W.debug-1)})}),20,1e4,!0,e);e.addCleanup(t),e.addCleanup(s)}};d(Bi,"JavTrailersPlugin");var aa=Bi;var ra=Object.freeze({magnet:216e5,screenshot:6048e5,screenshotNegative:432e5,match115:36e5,externalDetail:864e5}),Oi=class Oi 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(Oi,"ProviderError");var we=Oi;function cs(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(),r=String(o.resolution||"").toLowerCase(),i=/4k|2160p/.test(r)||/4k|2160p/.test(a)?25:/1080p/.test(r)||/1080p/.test(a)?20:/720p/.test(r)||/720p/.test(a)?15:5;e+=i;let n=o.hasSubtitle||/-c\b|-uc\b|chinese|中字|字幕/.test(a)?20:0;e+=n;let l=Oh(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:i,subtitle:n,freshness:c,completeness:h}}d(cs,"calcMagnetScore");function Oh(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(Oh,"daysSince");function Ui(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(Ui,"getMagnetQualitySignals");function xc({title:o="",hasHdTag:e=!1,hasSubtitleTag:t=!1,date:s=null,seeders:a=0}={}){let r=Ui(o,t),i=e||r.highQuality,n=cs({title:o,date:s,seeders:a,resolution:e&&!r.resolution?"1080p":r.resolution,hasSubtitle:r.subtitle});return{...r,highQuality:i,score:n,grade:n.total>=70?"高":n.total>=40?"中":"低"}}d(xc,"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 kc(o,e="other"){let t=wt(o,e);if(!t)throw new TypeError("Movie context requires a valid carNum");return t}d(kc,"createMovieContext");function ia(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(ia,"readOwnedMovieContext");function zi(o={}){let e=wt(o.explicitContext);if(e)return{context:e,source:"explicit"};let t=wt(o.ownedResolver?.()??ia(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 r=wt(o.legacyResolver?.(),"other");return r?(o.logger?.("movie-context source=legacy-fallback",r),{context:r,source:"legacy-fallback"}):{context:null,source:"missing"}}d(zi,"resolveMovieContext");var Fi=class Fi extends I{constructor(){super(...arguments),this.sourceRegistry=new Yt,this.searchEngines=[]}async initializeSources(){let e=new nt,t=this.getRuntimeService("magnet"),s=await e.getBuiltInSources(),a=await e.getMagnetSources(),r=t.getBuiltInSources(),i=[...Ns,...r],n=d(h=>({...i.find(u=>u.id===h)||{},...s.find(u=>u.id===h)||{}}),"configured"),l=r.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 Yt([{name:"JavDB 本站",id:"native-javdb",applicable:M,enabled:M,priority:1,search:d(async(h,u=document)=>ci(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)=>ci(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"?kc({carNum:e}):s?.movieContext;if(!a?.carNum)return $('<div class="magnet-container jhs-ui"></div>').append($('<div class="magnet-error"></div>').text("无法确定影片身份,未加载磁力"));let r=a.carNum.replace("FC2-",""),i=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(r))).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(r))).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,r,i))})),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),x=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(x).trigger("click").trigger("focus")})),this.searchEngine(b,f,r,i),c}async searchEngine(e,t,s,a=$(document)){e.html(`<div class="magnet-loading">正在从 ${C(t.name)} 搜索 "${C(s)}"...</div>`);let r=`${t.name}_${s}`;if(t.search)try{return void this.displayResults(e,await this.applyRuntimeRules(Es(await t.search(s,a))),t.name)}catch(i){return clog.error(`磁力源 ${t.name} 请求失败`,i),void e.html(`<div class="magnet-error">${C(t.name)} 请求失败</div>`)}if(t.parseHtml)try{let i=t.url.replace("{keyword}",encodeURIComponent(s)),n=await this.requestSource(t.id,i,{ttlMs:216e5}),l=t.parseHtml.call(this,n,s);return void this.displayResults(e,l,t.name)}catch(i){return void e.html(`<div class="magnet-error">解析 ${C(t.name)} 结果失败: ${C(i instanceof Error?i.message:String(i))}</div>`)}t.parseJson&&await t.parseJson.call(this,e,t,s,r)}async searchCustomSources(e){let s=JSON.parse(await storageManager.getSetting("customMagnetSources","[]")).filter(r=>r.enabled).map(bt),a=await Te(s,4,(async r=>{let i=r.searchUrlTemplate.replaceAll("{keyword}",encodeURIComponent(e));try{let n=await this.requestSource(r.id,i,{ttlMs:ra.magnet,custom:!0,responseType:r.parserType==="json"?"json":"text"}),l=r.parserType==="json"&&typeof n=="string"?JSON.parse(n):n;return di(r,l,r.id)}catch(n){let l=n;return clog.error(`自定义磁力源 ${r.name} 失败`,new we(r.id,l.code||"HTTP_ERROR",l.message||String(n),{cause:n,url:i,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:ra.magnet,custom:!0,responseType:e.parserType==="json"?"json":"text"});return di(e,e.parserType==="json"&&typeof a=="string"?JSON.parse(a):a,e.id)}async searchAllSources(e,t){let s=await Te(e,3,(async a=>{try{return await a.search(t)}catch(r){return clog.warn(`磁力源 ${a.name} 聚合失败`,r),[]}}));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??ra.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 nt,[s,a]=await Promise.all([t.getMagnetTagRules(),t.getMagnetFilterRules()]);return e.map((r=>Cl(r,s,a.filter((i=>(i.target||"title")==="title")),a.filter((i=>i.target==="file"))))).filter((r=>!r.hidden))}async displayResults(e,t,s){function a(r){let i=r.text();r.addClass("copied").text("已复制"),setTimeout((()=>{r.removeClass("copied").text(i)}),2e3)}d(a,"a"),e.empty(),t.length!==0?(t.forEach((r=>{let i=this.calcMagnetScore(r);r._score={...i,total:Math.max(0,Math.min(100,i.total+(r.customTagWeight||0)+(r.filterPenalty||0)))}})),t.sort(((r,i)=>i._score.total-r._score.total)),t.forEach((r=>{let i=r._score?r._score.total:0,n=i>=80?"高":i>=60?"中":"低",l=r._score?`做种:${r._score.seeders}/35 分辨率:${r._score.resolution}/25 字幕:${r._score.subtitle}/20 新鲜度:${r._score.freshness}/15 完整性:${r._score.completeness}/5`:"",c=C(r.title),h=C(r.magnet),u=C(String(r.size||"未知")),p=C(String(r.date||"未知")),g=$(` <div class="magnet-result"> <div class="magnet-title"> <span class="magnet-score" title="${l}">${n} ${i}</span> <a href="${h}">${c}</a> </div> <div class="magnet-info"> <span>大小: ${u}</span> <span>做种: ${r.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> `);r.tags?.length&&g.find(".magnet-info").after($("<div></div>").addClass("magnet-tags").append(r.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 r=>{let i=$(r.currentTarget),n=i.data("magnet");await utils.copyToClipboard("磁力链接",n)&&a(i)}))):e.append('<div class="magnet-error">没有找到相关结果</div>')}calcMagnetScore(e){return cs(e)}};d(Fi,"MagnetHubPlugin");var na=Fi;var Vi=class Vi 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=>!!(M&&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((i=>clog.error("外部站点重新挂载失败",i))))},"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 r=s.root?.[0]||null,i=r?(this._mountGenerations.get(r)||0)+1:++this.mountGeneration;r&&this._mountGenerations.set(r,i);let n=d(()=>(r?i===this._mountGenerations.get(r):i===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 Te(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 r=this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e});return void(r?(a.attr("href",r),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 Te(t.configs,4,(async r=>{r.condition&&r.condition(r.sourceCarNum)===!1||await this.handleSite(e,r,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 r="jhs_other_site_dmm",i=this.getRuntimeService("storage").getLocal(r),n=null;try{let l=i?JSON.parse(i):{};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 r=await this.getRuntimeService("scope")(),i=await this.getRuntimeService("movie").resolve({carNum:e,providerId:t.providerId},{scope:r});if(s.isActive?.()===!1)return;let n=this.getRuntimeService("movie").searchUrl(t.providerId,{carNum:e});a.attr("href",i?.url||n||""),this.setSiteState(a,i?.url?"available":"unavailable"),i?.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 r="jhs_other_site",i=this.getRuntimeService("storage"),n=i.getLocal(r),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=i.getLocal(r),S=w?JSON.parse(w):{};S[c]=b,i.setLocal(r,JSON.stringify(S))}v&&a.append(v)}catch(r){let i=String(r),n=t.id.replace("Btn",""),l=r?.code;l==="CIRCUIT_OPEN"?(a.attr("title",i),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(r),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 r=$('<input type="checkbox">').attr("data-site-id",a.id).prop("checked",t.includes(a.id));s.append($('<label class="jhs-site-option"></label>').append(r,$("<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 r=e.carNum||this.getPageInfo().carNum,i=e.configs.find((n=>n.id===a));i&&await this.prepareSiteLink(r,i,e)}else e.root.find(`[data-jhs-site-id="${a}"],#${a}`).addClass("jhs-is-hidden");this.saveEnabledSites(t.find('input[type="checkbox"]:checked').map(((r,i)=>$(i).attr("data-site-id"))).get())}catch(r){clog.warn(`外部站点 ${a||"unknown"} 状态更新失败`,r)}}))}};d(Vi,"OtherSitePlugin");var oa=Vi;var Hi=class Hi extends I{getName(){return"RelatedPlugin"}async handle(){if(!window.isDetailPage||!M)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(Hi,"RelatedPlugin");var la=Hi;var qi=class qi extends I{getName(){return"ReviewPlugin"}async handle(){if(window.isDetailPage){if(M){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,r=d(async()=>{if(!(a||t?.disposed||s.snapshot().enableLoadReview==="no")){a=!0;try{let i=await this.getRuntimeService("movie").resolve({carNum:e},{scope:t});i?.movieId&&!t?.disposed&&s.snapshot().enableLoadReview!=="no"&&await this.showReview(i.movieId,this.getHostedSlot("reviews"))}finally{a=!1}}},"mount");t?.listen?.(s,"settings.changed",i=>{i.detail?.names?.includes("enableLoadReview")&&r().catch(n=>clog.error("加载评论失败",n))}),await r()}}}getHostedSlot(e){let t=this.getRuntimeService("host").locateDetailSlots()[e];return t?$(t):$()}async showReview(e,t,s={}){return new Ot({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(qi,"ReviewPlugin");var ca=qi;function Uh(o){return[...o.querySelectorAll(".tags .tag")].some(e=>/中字磁[链鏈]/u.test(e.textContent||""))}d(Uh,"hasChineseSubtitleMagnet");var ha=class ha extends I{getName(){return"TOP250Plugin"}async initCss(){return"<style>.jhs-top250-subtitle{display:flex;gap:var(--jhs-space-2);max-width:100%;overflow-x:auto;margin:var(--jhs-space-3) 0}.jhs-top250-subtitle .jhs-btn{flex-shrink:0;white-space:nowrap}.jhs-top250-subtitle-hidden{display:none!important}</style>"}async handle(){if(je(window.location).kind!=="top250-ranking")return;let e=this.getRuntimeService("host"),t=e.locateListRoot?.(),s=e.getTop250FilterContainer?.();if(!t||!s||s.querySelector(".jhs-top250-subtitle"))return;let a=document.createElement("div");a.className="jhs-top250-subtitle",a.setAttribute("role","group"),a.setAttribute("aria-label","TOP250 已加载条目筛选");for(let[i,n]of[["all","已加载条目:全部"],["with","已加载条目:含中字磁链"],["without","已加载条目:无中字磁链"]]){let l=document.createElement("button");l.type="button",l.className="jhs-btn jhs-btn--secondary",l.dataset.jhsSubtitle=i,l.textContent=n,a.append(l)}e.mountTop250SubtitleControls(a);let r=new URLSearchParams(window.location.search).get("jhs_subtitle");this.applySubtitleFilter(["with","without"].includes(r||"")?r:"all",a),a.addEventListener("click",i=>{let l=i.target?.closest("button[data-jhs-subtitle]")?.getAttribute("data-jhs-subtitle");if(!["all","with","without"].includes(l||""))return;let c=new URL(window.location.href);l==="all"?c.searchParams.delete("jhs_subtitle"):c.searchParams.set("jhs_subtitle",l),window.history.replaceState(window.history.state,"",c.href),this.applySubtitleFilter(l,a)})}applySubtitleFilter(e,t){let s=this.getRuntimeService("host");for(let a of s.locateTop250SubtitleCards()){let r=Uh(a);a.classList.toggle("jhs-top250-subtitle-hidden",e==="with"?!r:e==="without"&&r)}t.querySelectorAll("button[data-jhs-subtitle]").forEach(a=>{let r=a.getAttribute("data-jhs-subtitle")===e;a.setAttribute("aria-pressed",String(r)),a.classList.toggle("active",r)}),s.syncTop250SubtitleLinks?.(e)}};d(ha,"Top250Plugin"),ct(ha,"legacyPluginId","TOP250Plugin");var da=ha;var Ji=class Ji 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 r=$(a),i=r.attr("href"),n=null;if(i){let c=(i.endsWith("/")?i.slice(0,-1):i).split("/"),h=c[c.length-1];h&&(n=h.trim())}let l=!1;n&&(l=t.has(n)),l&&(r.addClass("highlighted"),r.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),r=a?a[1]:null;r&&await this.removeActorFromStorage(r)})),$("#button-collect-actor").click((async t=>{let s=$("#button-collect-actor").attr("href").match(e),a=s?s[1]:null,r=[],i=$(".actor-section-name");i.length&&i.text().trim().split(",").forEach((u=>{r.push(u.trim())}));let n=$(".section-meta:not(:contains('影片'))");if(n.length&&n.text().trim().split(",").forEach((u=>{r.push(u.trim())})),!r.length)return void clog.error("获取演员名称失败");let l=r[0];if(!a)return void clog.error("无法获取演员ID进行收藏操作。");let c=($(".avatar").first().css("background-image")||"").replace(/^url\(["']?|["']?\)$/g,""),h={starId:a,name:l,allName:r,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(Ji,"FavoriteActressesPlugin");var ua=Ji;var Wi=class Wi extends I{getName(){return"BusImgPlugin"}handle(){}async getVisibleImageItems(e,t){let s=[],a=document.querySelectorAll(e);for(let r of a)if(!utils.isHidden(r)){let i=r.querySelector(t);if(!(i instanceof HTMLImageElement))continue;i.style.removeProperty("height");let n=i.offsetHeight;n>0&&s.push({element:r,imgElement:i,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,r=Number(s)||5,i=await this.getVisibleImageItems(a,"img");if(i.length===0)return;let n=[];for(let l=0;l<i.length;l++){let c=Math.floor(l/r);n[c]||(n[c]=[]),n[c].push(i[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(Wi,"BusImgPlugin");var pa=Wi;var Ut=d((o,e)=>{if(!o||o.length===0)return null;let t=new Set(o);if(e&&t.has(e))return e;let s=rt.map((a=>a.quality)).reverse();for(let a of s)if(t.has(a))return a;return o[0]||null},"Z"),Ki="jhs_dmm_video",zh=30*864e5,Cc=500;function Gi(o){if(!o)return{};try{let e=JSON.parse(o);return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}catch{return{}}}d(Gi,"parseJsonMap");function Qi(o){let e=Date.now();for(let s of Object.keys(o)){let a=o[s];(!a||a.time&&e-a.time>zh)&&delete o[s]}let t=Object.keys(o);if(t.length>Cc){t.sort(((s,a)=>(o[s].time||0)-(o[a].time||0)));for(let s of t.slice(0,t.length-Cc))delete o[s]}return o}d(Qi,"pruneDmmCache");function Pe(o){return o?.enablePreviewVideo!=="no"}d(Pe,"isPreviewEnabled");function ds(o){return o?.enableLoadPreviewVideo!=="no"}d(ds,"isDmmEnabled");function _c(o){return Pe(o)}d(_c,"canUsePreview");function zt(o){return Pe(o)&&ds(o)}d(zt,"canUseDmmPreview");function ga(o){return zt(o)}d(ga,"canUseCardPreview");var Xi=class Xi{constructor(e,t,s,a){this.carNum=e||"",this.storage=t,this.movie=s,this.scope=a,this.lastError=null}_checkCache(){let e=Qi(Gi(this.storage.getLocal(Ki)));return e[this.carNum]?(clog.debug("缓存中存在预览视频信息",e[this.carNum]),e[this.carNum]):null}_updateCache(e){let t=Qi(Gi(this.storage.getLocal(Ki)));t[this.carNum]={...e,time:Date.now()},clog.debug("成功解析出预览视频并已缓存:",e),this.storage.setLocal(Ki,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=Qi(Gi(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 r=$("#fanzaBtn");return r.attr("href",this.movie.searchUrl("dmm",{carNum:this.carNum})),r.attr("title","未查询到, 点击前往搜索页"),r.css("backgroundColor","var(--jhs-status-filter)"),null}}};d(Xi,"DmmPreviewParser");var Yi=Xi;async function Zi(o,e,t,s){let a=new Yi(o,e,t,s);return{sources:await a.fetchVideo(),error:a.lastError}}d(Zi,"fetchDmmPreview");async function ma(o,e,t,s,a){return ds(a)?Zi(o,e,t,s):{sources:null,error:null}}d(ma,"fetchDmmPreviewIfEnabled");var en=class en 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(r=>r==="enablePreviewVideo"||r==="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,r=$(".preview-video-container");r.on("click",(async i=>{if(i.preventDefault(),i.stopPropagation(),a)show.info("正在加载中, 勿重复点击");else{a=!0;try{await this.handleVideo()}finally{a=!1}}})),window.location.href.includes("autoPlay=1")&&r.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||!Pe(this.getRuntimeService("settings").snapshot()))return;if(a.length>0)return t.addClass("is-open"),void await de(a[0],{context:"JavBus 预览视频",notify:!0});let r=this.getPageInfo().carNum,i=await this.getRuntimeService("scope")(),{sources:n,error:l}=await ma(r,this.getRuntimeService("storage"),this.getRuntimeService("movie"),i,this.getRuntimeService("settings").snapshot());e!==this._busPreviewGeneration||!Pe(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=Ut(Object.keys(e),s);let a=e[s],r=$('<div class="video-player-wrapper"></div>'),i=$('<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>');i.append(n),r.append(i),t.empty().append(r,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)))})),rt.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(en,"BusPreviewVideoPlugin");var fa=en;var tn=class tn 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 r=a.detail?.names||[];r.some(i=>i==="enablePreviewVideo"||i==="enableLoadPreviewVideo")&&(this.previewGeneration++,ga(t.snapshot())?this.addSvgBtn().catch((i=>clog.error("卡片预览重新挂载失败",i))):($('[id$="_preview_video"]').each((i,n)=>{n.pause?.(),$(n).parent().remove()}),this.enableSvgBtn())),r.some(i=>["enableScreenSvg","enableVideoSvg","enableHandleSvg","enableSiteSvg","enableCopySvg"].includes(i))&&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>${Me}</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>${Le}</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=M?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:r=R,enableHandleSvg:i=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&&ga(t)?R:"no"},{selector:".handleSvg",enabled:i},{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=Ce(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(),r=this.getRuntimeService("movie"),i=r.externalSiteOrigin("missAvBtn",a),n=r.externalSiteOrigin("jableBtn",a),l=r.externalSiteOrigin("avgleBtn",a),c=r.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:`${i}/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=`${i}/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(!ga(a))return show.error("预览视频已关闭");let r=this.previewGeneration,i=`${s}_preview_video`,n=$(`#${i}`);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 ma(s,this.getRuntimeService("storage"),this.getRuntimeService("movie"),c,a);if(r!==this.previewGeneration||!Pe(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=Ut(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=i,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(tn,"CoverButtonPlugin");var va=tn;var sn=class sn 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(r=>r==="enablePreviewVideo"||r==="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(!_c(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&&Pe(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||!Pe(s.snapshot())||!ds(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(r=>{if(r?.disposed||t.disposed)throw new Error("预览请求已取消");return s=r?.addCleanup?.(()=>t.dispose()),Zi(this.getPageInfo().carNum,this.getRuntimeService("storage"),this.getRuntimeService("movie"),t)}).then((r=>(this.dmmPreviewPromise===a&&(r.error?.retryable||r.error?.code==="HTTP_ERROR")&&(this.dmmPreviewPromise=null),r)),(r=>{throw this.dmmPreviewPromise===a&&(this.dmmPreviewPromise=null),r})).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 r=d(()=>{l(),this.isSessionOpen(a)&&s()},"loaded"),i=d(()=>l(),"failed"),n=setTimeout(i,5e3),l=a.scope.addCleanup(()=>{clearTimeout(n),e.removeEventListener("loadedmetadata",r),e.removeEventListener("error",i),a.seekCleanups.delete(e)});e.addEventListener("loadedmetadata",r,{once:!0}),e.addEventListener("error",i,{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",r),e.removeEventListener("error",i),t?.removeEventListener("abort",i),s(l)},"finish"),r=d(()=>a(!0),"loaded"),i=d(()=>a(!1),"failed"),n=setTimeout(i,1e4);e.addEventListener("canplay",r,{once:!0}),e.addEventListener("error",i,{once:!0}),t?.addEventListener("abort",i,{once:!0})})}async restoreNativePlayer(e,t,s=!1,a=!0){if(!t||!this.isSessionOpen(this.previewSession))return!1;let r=e.parent().find("#jhs-preview-video"),i=r[0];return i&&(i.pause(),r.removeAttr("src"),i.load(),r.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||!Pe(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 r=this.previewSession;if(r.generation===this.previewGeneration)return;r.generation=this.previewGeneration;let i=d(()=>this.previewSession===r&&this.isSessionOpen(r)&&u===this.previewGeneration&&Pe(this.getRuntimeService("settings").snapshot()),"alive"),n=this.getRuntimeService("settings"),l=$(a),c=s[0],h=n.snapshot().videoMuted,u=this.previewGeneration,p=ds(this.getRuntimeService("settings").snapshot()),g=p?await this.getDmmPreview():{sources:null,error:null};if(!i())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,N=Ut(Object.keys(m),L),A=m[N],O=c?.currentTime||0,U=!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",A),j.load(),this.seekVideo(j,O),S.addClass("is-active");let H=await this.waitForDmmReady(j);if(!i()){j.pause();return}if(w=H&&(!U||await de(j,{context:"JavDB 高画质预览",notify:!1})),!i()){j.pause();return}if(H&&!w&&!j.muted&&(j.muted=!0,w=await de(j,{context:"JavDB 高画质预览静音重试",notify:!1})),!i()){j.pause();return}if(w?(c?.pause(),s.addClass("jhs-native-preview-hidden")):(S.removeClass("is-active"),await this.restoreNativePlayer(s,c,!0,U)),!i())return;if(!w&&!c){show.error("当前视频源无法播放"),this.disposePreviewSession();return}w&&rt.forEach((Q=>{let se=m[Q.quality];if(!se)return;let ge=w&&N===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 x=$("<div></div>").addClass("jhs-toolbar");if(this.getOptionalDependency("DetailPageButtonPlugin")&&x.append(Lt({actions:["blocked","favorite"],ids:{blocked:"video-filterBtn",favorite:"video-favoriteBtn"}})),x.append('<button type="button" class="jhs-btn jhs-btn--secondary" id="speed-btn">快进</button>'),!i())return;v.append(x),l.append(v),v.off("click.jhsVideo").on("click.jhsVideo",".jhs-video-quality-btn",(async L=>{let N=$(L.currentTarget);if(!N.hasClass("active"))try{if(!j?.isConnected||!i())return;let A=j.currentTime,O=S.attr("src"),U=!j.paused;S.attr("src",N.data("video-src")),j.load(),this.seekVideo(j,A);let H=await this.waitForDmmReady(j);if(!i())return;let Q=H&&(!U||await de(j,{context:"JavDB 画质切换",notify:!1}));if(!i())return;if(Q)v.find(".jhs-video-quality-btn").removeClass("active").attr("aria-pressed","false"),N.addClass("active").attr("aria-pressed","true");else{O&&(S.attr("src",O),j.load(),j.currentTime=A);let se=O&&await this.waitForDmmReady(j)&&(!U||await de(j,{context:"JavDB 画质切换回退",notify:!1}));if(!i())return;se||await this.restoreNativePlayer(s,c,!0,U)}}catch(A){clog.error("切换画质失败:",A)}})),$("#speed-btn").off("click.jhsVideo").on("click.jhsVideo",(()=>{let L=l.find("#jhs-preview-video.is-active")[0]||c;L?.isConnected&&this.isSessionOpen(r)&&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"}});r.stateCleanup?.(),r.stateCleanup=V?.on("car-state-changed",N=>{if(N.carNums?.includes(L.carNum)&&this.isSessionOpen(r))return E.render(L)}),r.stateCleanup&&r.scope.addCleanup(r.stateCleanup)}}};d(sn,"PreviewVideoPlugin");var ba=sn;function $c(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($c,"resolveDocument");function hs(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(hs,"normalizeJavStoreAssetUrl");function Tc(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(((r,i)=>a(i).text().trim().toUpperCase().includes(s.toUpperCase()))).map(((r,i)=>new URL(a(i).attr("href"),t).href)).get()}return[...$c(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(Tc,"parseJavStoreSearch");function Ac(o,e){if(typeof o?.find=="function"){let a=globalThis.jQuery??globalThis.$??o.constructor,i=o.find("a").filter(((l,c)=>a(c).text().trim()==="CLICK HERE!")).first().attr("href");if(!i)return null;let n=hs(i,e);return n?n.replace(".th",""):null}let t=[...$c(o).querySelectorAll("a")].find(a=>a.textContent?.trim()==="CLICK HERE!")?.getAttribute("href");if(!t)return null;let s=hs(t,e);return s?s.replace(".th",""):null}d(Ac,"parseJavStorePreview");var an=class an 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(i=>clog.error("长缩略图重新加载失败",i)))},"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;M&&$(".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 r=await this.getRuntimeService("scope")(),i=await s.resolve({carNum:e},{scope:r,settings:a,allowWhenDisabled:t.allowWhenDisabled===!0});return(Array.isArray(i)?i[0]:i)?.url||null}addImg(e,t){let s=hs(t);if(!s)return;let a=$(".screen-container").empty(),r=$("<img>").attr({src:s,alt:e,loading:"lazy"});M&&a.append(r.addClass("jhs-layout-cad980f4")),B&&a.append($('<div class="photo-frame"></div>').append(r.attr("title",e).addClass("jhs-layout-d4a575e8"))),a.on("click",(i=>{i.stopPropagation(),i.preventDefault(),globalThis.showImageViewer(i.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":""}`,r=T(e);if(!r)return void $(".screen-container").empty().append($("<div></div>").addClass(a).text("无法获取番号,缩略图未加载"));let i=this.getScreenshotService().getSearchUrl({carNum:r}),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),i&&n.append(document.createTextNode(" 或 "),$('<a class="check-link" target="_blank" rel="noopener noreferrer">前往确认</a>').attr("href",i)),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(r);u?this.addImg("缩略图",u):this.showErrorFallback(r,null)}catch(u){this.showErrorFallback(r,u)}})).on("click",".check-link",(h=>{h.stopPropagation(),h.preventDefault(),window.open(i,"_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 r=await this.getRuntimeService("scope")();return ea({target:a,carNum:t,screenshot:this.getScreenshotService(),settings:this.getSettingsSnapshot(),scope:r,isActive:s})}renderInto(e,t,s){let a=$(e),r=$("<img>").attr({src:hs(t),alt:s,loading:"lazy"}).addClass("jhs-fc2-gallery__image"),i=$('<button type="button" class="jhs-btn jhs-fc2-gallery-item jhs-fc2-screenshot-thumbnail"></button>').attr("aria-label",`查看${s}大图`).append(r);a.empty().append(i).off("click.jhsScreenshot").on("click.jhsScreenshot",".jhs-fc2-screenshot-thumbnail",(n=>{n.preventDefault(),n.stopPropagation(),globalThis.showImageViewer(r[0])}))}};d(an,"ScreenShotPlugin");var wa=an;var Pc="jhs_img_cdn_index";function Fh(o,e,t,s=Date.now()){let a=new Map;for(let r of o)if(Array.isArray(r.newVideoList))for(let i of r.newVideoList){let n=typeof i=="object"?i:{},l=T(typeof i=="string"?i:i.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?.(" ")||""}`)),r.name&&!c.actresses.includes(r.name)&&c.actresses.push(r.name),r.starId&&!c.starIds.includes(r.starId)&&c.starIds.push(r.starId),r.actressType&&c.categories.add(r.actressType),a.set(l,c)}return[...a.values()].map((r=>{let i=e.get(r.carNum),n=q(i?.stateFlags),l=t[r.carNum]||null,c=l?l.action==="snoozed"&&l.until&&Date.parse(l.until)<=s?"pending":l.action:"pending";return{...r,actressName:r.actresses.join("、"),starId:r.starIds[0]||"",categories:[...r.categories],flags:n,decision:l,decisionState:c}}))}d(Fh,"aggregateNewVideoRecords");var rn=class rn extends I{constructor(){super(...arguments),P(this,"currentPage",1),P(this,"pageSize",30),P(this,"nvCurrentPage",1),P(this,"nvPageSize",60),P(this,"nvFlatListCache",[]),P(this,"nvAllItemsMap",new Map),P(this,"nvActressesCache",[]),P(this,"nvCarMapCache",new Map),P(this,"nvSortBy","publishTime_desc"),P(this,"nvSelected",new Set),P(this,"nvDecisionsCache",{}),P(this,"nvCoverCache",new Map),P(this,"nvActorCoverRequests",new Map),P(this,"nvRenderGeneration",0),P(this,"nvSearchDebounced",null),P(this,"nvInvalidationTimer",null),P(this,"nvWorkspaceReloadPromise",null),P(this,"nvWorkspaceReloadDirty",!1),P(this,"nvWorkspaceMounted",!1),P(this,"nvEventUnsubscribe",null),P(this,"taskStatusUnsubscribe",null),P(this,"nvCoverPreview",null),P(this,"nvWorkspaceRoot",null),P(this,"nvJavDbUrl",""),P(this,"nvRuleTime",8760),P(this,"avatarSources",[]),P(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=V.on("new-video-changed",(()=>this.scheduleWorkspaceReload()))),this.taskStatusUnsubscribe||(this.taskStatusUnsubscribe=V.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(Pc)||"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 r=T(typeof a=="string"?a:a.carNum);r&&!oe(q(e.get(r)?.stateFlags))&&!this.isDecisionHidden(r)&&t.add(r)})))),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)||"无":"任务已禁用",r=s.checkFavoriteActress_IntervalTime,i=t?e.getLocal(t.lastCheckNewVideoTimeKey)||"无":"任务已禁用",n=s.checkNewVideo_intervalTime;$("#checkFavoriteActress").attr("data-tip",`上次完整同步: ${a}; 检测间隔时间: ${r}小时`),$("#checkNewVideo").attr("data-tip",`上次整批检测: ${i}; 检测间隔时间: ${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)||"无":"任务已禁用",r=s.checkFavoriteActress_IntervalTime,i=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}; 检测间隔时间: ${r}小时">${this.actressSvg}<span>手动同步演员</span></button> <button type="button" class="jhs-btn jhs-btn--secondary" id="checkNewVideo" data-tip="上次整批检测: ${i}; 检测间隔时间: ${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),r=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(r).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 r=e.find("span").last(),i=r.text();e.attr("aria-busy","true").prop("disabled",!0),r.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),r.text(i),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(),Ue(s,{type:"loading",title:"加载中"});try{let a=await storageManager.getSetting(),[r,i,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=r,this.nvCarMapCache=i,this.nvDecisionsCache=n,this.nvJavDbUrl=c,this.nvRuleTime=ae(l,8760,{min:0});let h=Fh(r,i,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),Ue(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:"待运行"},r=d(i=>i?new Date(i).toLocaleString():"无","format");if(!t)return void e.empty().text("后台任务功能已禁用");e.empty(),["favoriteActress","newVideo","blacklist"].forEach((i=>{let n=t.getTaskStatusSnapshot(i),l=$('<div class="jhs-task-status"></div>');l.append($('<span class="jhs-task-status__name"></span>').text(`${s[i]}:${a[n.state]}`)),l.append($('<span class="jhs-task-status__meta"></span>').text(`上次完成 ${r(n.completedAt)};下次检查 ${n.nextAt?r(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,r=d(j=>this.getPendingNewVideoCount(j,a),"_newVideoCount"),i=$("#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:r,order:"desc"}],newVideoCount_asc:[{key:r,order:"asc"}]},l=[{key:r,order:"desc"},{key:"lastPublishTime",order:"desc"}],c=utils.genericSort(t,n[i]||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 Ue(e,{type:"empty",title:this.nvActressesCache.length?"没有符合当前筛选条件的演员":"暂无收藏演员"}),void this.renderPagination(h,u);let S=f.map((j=>{let x=Array.isArray(j.allName)?j.allName.join(","):"",k=String(j.name||""),_=String(j.remark||""),E=String(j.starId||""),L=this.getPendingNewVideoCount(j,a),N=j.lastPublishTime||"",A=Ye(`/actors/${encodeURIComponent(E)}?t=d`,v),O=Ye(j.avatar,v)||this.getRuntimeService("actressInfo").placeholderUrl("javdb"),U=gt(N,w),H="未知",Q="is-unknown";j.actressType===Ke?(H="无码",Q="is-uncensored"):j.actressType===We&&(H="有码",Q="is-censored");let se=String(N||"暂无记录"),ge=U?`停更 ${w/24/365} 年以上,下轮任务不再检测`:_||"暂无备注",De=$('<article class="actress-card"></article>').toggleClass("is-paused",U).attr("data-starId",E),ot=$('<div class="actress-card__badges"></div>');ot.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)),U&&ot.append('<span class="jhs-badge jhs-badge--neutral">停更</span>');let Ne=$('<a class="actress-card__profile" target="_blank" rel="noopener noreferrer"></a>').attr("href",A||"#"),z=$("<span></span>").append($('<span class="actress-card-name"></span>').text(k),$('<span class="actress-card-allname"></span>').attr("title",x).text(x||"暂无别名"));Ne.append($('<img class="actress-card-avatar" loading="lazy">').attr({src:O,alt:x}),z);let Z=$('<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||"暂无记录")))),re=$('<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),ps=$('<button type="button" class="jhs-btn jhs-btn--icon jhs-btn--ghost btn-delete-actress" title="取消收藏"></button>').attr({"aria-label":`取消收藏 ${k}`,"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 re.append(xt,ps,$('<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()),De.append(ot,Ne,Z,$('<p class="actress-card__note"></p>').attr("title",ge).text(ge),re)[0]}));e.empty().append(S),$(".btn-delete-actress").off("click").on("click",(j=>{j.preventDefault();let x=$(j.currentTarget).attr("data-starId"),k=c.find((_=>_.starId===x));utils.q(j,`是否取消收藏 ${C(k.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:x,baseUrl:_,csrfToken:E},{scope:await this.getRuntimeService("scope")()});L.success?(await storageManager.removeFavoriteActress(x),await V.emit("new-video-changed",{reason:"favorite-actress-removed"})):(show.error("移除失败"),clog.error("移除失败,返回值:",L))}))})),$(".btn-edit-actress").off("click").on("click",(j=>{j.preventDefault();let x=$(j.currentTarget).attr("data-starId"),k=c.find((_=>_.starId===x));k?this.editActress(k):show.error(`未找到 starId 为 ${x} 的女优记录。`)})),$(".btn-check-actress").off("click").on("click",(j=>{j.preventDefault();let x=$(j.currentTarget),k=x.attr("data-starId"),_=c.find((E=>E.starId===k));this.runManualTask(x,"检测中…",(()=>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((r=>{let i=e==="all"||e==="vr"?e==="all"||r.isVr:e==="unknown"?r.categories.length===0:r.categories.includes(e),n=t==="all"||t==="pending"?t==="all"||!oe(r.flags):!!r.flags[t],l=s==="all"||r.decisionState===s,c=!a||`${r.carNum} ${r.title} ${r.actressName}`.toUpperCase().includes(a);return i&&n&&l&&c})).sort(((r,i)=>(i.publishTime||"").localeCompare(r.publishTime||"")))}getActorCoverRequest(e,t){let s=t.get(e);if(s)return s;let a=this.getRuntimeService("scope")().then((r=>this.getRuntimeService("actressInfo").movies("javdb",{actorId:e,baseUrl:this.nvJavDbUrl},{scope:r}))).then((r=>{let i=new Map;return r.forEach((n=>n.carNum&&n.coverUrl&&i.set(T(n.carNum),{coverUrl:n.coverUrl,title:n.title}))),i})).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,r=[...new Set(e.filter((i=>!i.coverUrl&&!s.has(T(i.carNum))&&i.starId)).map((i=>i.starId)))];await Te(r,3,(async i=>{try{let n=await this.getActorCoverRequest(i,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(`获取演员封面失败: ${i}`,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 r=String($("#nvSearch").val()||"").trim(),i=["nvCategoryFilter","nvStateFilter","nvDecisionFilter"].some((n=>$("#"+n).val()!==(n==="nvCategoryFilter"?"all":"pending")));return this.nvAllItemsMap.size?r?Ue(e,{type:"empty",title:`没有找到“${r}”的作品`,actionLabel:"清除搜索",onAction:d(()=>{$("#nvSearch").val(""),this.nvCurrentPage=1,this.nvRenderGeneration++,this.renderNewVideoList()},"onAction")}):i?Ue(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")}):Ue(e,{type:"empty",title:"暂无待处理的新作品"}):Ue(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((r=>r.carNum)),{[s]:!0},{type:"new-video-batch-state",records:a.map((r=>({carNum:r.carNum,url:r.url||`/search?q=${encodeURIComponent(r.carNum)}`,names:r.actressName,publishTime:r.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((r=>r.carNum)),"manual")),"已移除")}))}))}renderBatchBar(){let e=$("#new-video-list-footer");if(!e.length)return;let t=new Set(this.nvFlatListCache.flatMap((r=>r.actresses||[r.actressName])).filter(Boolean)),s=this.nvSelected.size,a=this.nvFlatListCache.filter((r=>this.nvSelected.has(T(r.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(((r,i)=>{let n=0;switch(s){case"publishTime":n=(r.publishTime||"").localeCompare(i.publishTime||"");break;case"actress":n=(r.actressName||"").localeCompare(i.actressName||"");break;case"carNum":n=(r.carNum||"").localeCompare(i.carNum||"");break;case"voteCount":n=(r.voteCount||0)-(i.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,r=(this.nvCurrentPage-1)*a,i=r+a,n=s.slice(r,i),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||""),r=Ye(e.avatar,this.nvJavDbUrl)||"",i=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(r)}" 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(r)}" 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(i)}</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(((x,k)=>` <label class="jhs-option-row" for="cdn-${k}"> <input type="radio" id="cdn-${k}" name="cdn-source" value="${k}" ${k===w?"checked":""}> <span>${x.name} ${x.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((x,k)=>{utils.setupEscClose(k)},"success"),yes:d(async x=>{let k=$('input[name="cdn-source"]:checked').val(),_=parseInt(k,10);_!==this.avatarSourceIndex&&this.avatarSources[_]&&(this.avatarSourceIndex=_,this.getRuntimeService("storage").setLocal(Pc,_.toString()),show.ok(`CDN 源已切换为: ${this.avatarSources[_].name}`)),t.close(x)},"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 x=b.split(/[\uff0c,]/).map((_=>_.trim())).filter((_=>_.length>0)),k=w.split(/[\uff0c,]/).map((_=>_.trim())).filter((_=>_.length>0));e.avatar=f,e.name=v,e.allName=x,e.newVideoList=k,e.actressType=j,e.remark=S;try{await storageManager.updateFavoriteActress(e),await V.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="",r=$("#actress-pagination");if(t===0)return a='<span class="jhs-pagination__summary">共 0 条记录</span>',void r.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 i=Math.max(1,s-Math.floor(2.5)),n=Math.min(t,i+5-1);n-i<4&&(i=Math.max(1,n-5+1));for(let l=i;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>`,r.html(a),r.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"),r=s.val().trim(),i=a.val().trim().split(/[\uff0c,]/).map((p=>p.trim())).filter((p=>p.length>0));if(r&&i.unshift(r),i.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(i,p.id,{scope:g}):[]}catch(p){return void show.error(`头像数据加载或搜索失败: ${p.message||p}`)}finally{n.close()}if(l.length===0)return void show.error(`未找到与 '${i.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 x=l.length-u;v.text(`点击图片即可选择(已移除 ${u} 张错误图片,剩余 ${x} 张)`),x===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(rn,"NewVideoPlugin");var ya=rn;var nn=class nn{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(nn,"StorageQueue");var ja=nn;var on=class on extends I{constructor(){super(...arguments),this.singleTaskKey="checkNewActressActorFilterCar",this.taskConfig=null,this.storageQueue=new ja,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 r=0,i=!1,n=Math.max(1,Math.min(t,e.length)),l=Array.from({length:n},(async()=>{for(;!i;){let u=r++;if(u>=e.length)return;try{await a(e[u])}catch(g){throw this.isNetworkBlocked(g)&&(i=!0),g}let p=e.length-r;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===Se?"javbus.com":null,i=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:i},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)),r=$e(t.getLocal(s.attemptKey));return{...s,completed:a,attempt:r,pending:r!=null&&(a==null||r>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),r=Date.now(),i="idle";return this.activeTasks.has(e)?i="running":t.pending&&r<a?i="pending":(s==null||r>=a)&&(i="due"),{name:e,state:i,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),r=await this.getLatestTaskInterval(e),i=$e(s.getLocal(a.completedKey)),n=$e(s.getLocal(a.attemptKey)),l=$e(s.getLocal(a.nextKey));return l==null&&(l=n!=null&&(i==null||n>i)?n+3e5:i==null?0:i+36e5*r,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)),r=Math.floor(Date.now()/1e3)*1e3,i=a==null?r:Math.max(r,a+1e3);return t.setLocal(s.attemptKey,String(i)),t.setLocal(s.nextKey,String(i+3e5)),i}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 r=$e(s.getLocal(a.attemptKey))||0,i=Math.max(Math.floor(Date.now()/1e3)*1e3,r),n=await this.getLatestTaskInterval(e);s.setLocal(a.completedKey,utils.getNowStr("-",":",i)),s.setLocal(a.nextKey,String(i+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[i,n]of[[s,Be],[a,Se]])try{if(i&&t.hostname===new URL(i).hostname)return n}catch(l){clog.warn(`忽略无效的站点配置: ${i}`,l)}let{site:r}=Ct(e);return[Be,Se].includes(r)?r: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,r=!1;try{let i=await storageManager.getBlacklist();i=i.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 i){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(gt(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(x){if(t.networkFailed++,this.isNetworkBlocked(x))throw x;return void clog.error("检测屏蔽演员网络错误:",S,x)}try{let x=utils.htmlTo$dom(j);await this.storageQueue.addTask((async()=>{let k=await s.parseAndSaveFilterInfo(x,w,b,v);await storageManager.updateBlacklistItem({starId:b,name:w,checkTime:utils.getNowStr(),lastPublishTime:k.lastPublishTime})})),t.success++}catch(x){t.parseFailed++,clog.error("解析或保存黑名单演员失败:",S,x)}})),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),r=!0,this.renderBlacklistResult(t,g);try{await s.resetBtnTip()}catch(m){clog.error("刷新黑名单检测提示失败",m)}if(a)throw a;return t}catch(i){if(r||await this.finalizeTask("blacklist",!1),t.completed=!1,t.fatal=this.isNetworkBlocked(i),t.fatal)throw i;return t.parseFailed++,clog.error("黑名单整批检测失败",i),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,r=new URL(e,this.javDbUrl),i=0;for(;r;)try{if(r.origin!==s.origin||r.pathname!==s.pathname)throw new Error(`收藏演员分页地址越界: ${r.href}`);if(a.has(r.href))throw new Error(`收藏演员分页循环: ${r.href}`);if(i>=200)throw new Error("收藏演员分页超过 200 页");a.add(r.href),i++,clog.log(`正在抓取页面: ${r.href}`),$("#checkNewVideoMsg").text(`正在解析已收藏的演员: ${r.href}`);let n=await this.getRuntimeService("actressInfo").collection("javdb",{baseUrl:this.javDbUrl,pageUrl:r.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),r=n.nextUrl?new URL(n.nextUrl,r.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(`抓取 ${r?.href||e} 时发生错误,停止本轮同步:`,c),c}return{actors:t,pages:i}}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 r=await storageManager.getFavoriteActressList(),i=utils.genericSort(r,[{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 i)!e&&g.lastCheckTime&&this.isUnnecessaryCheck(g.lastCheckTime,c)?t.skippedInterval++:gt(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(x){t.parseFailed++,clog.error("解析或保存演员作品失败:",S,x)}}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?r.length?"整批检测结束":"收藏为空,整批检测完成":"整批检测未完成,5 分钟后补偿未完成项"),t.success>0&&await this.emitNewVideoChanged("task-completed"),s)throw s;return t}catch(r){if(a||await this.finalizeTask("newVideo",!1),t.completed=!1,t.fatal=this.isNetworkBlocked(r),t.fatal)throw r;return t.parseFailed++,this.renderCheckResult(t,"整批检测失败,5 分钟后补偿"),clog.error("新作品整批检测失败",r),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,r,i){let n=this.getSelector(t);t===Se&&e.find(".avatar-box").length>0&&e.find(".avatar-box").parent().remove();let l=qs(e,{boxSelector:t===Se?`${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:x,title:k,publishTime:_}=_e(S);_&&p.push(_),j&&(r.find(E=>k.includes(E)||j.includes(E))||i.has(j)||(()=>{let E=S.find("img").attr("src")||"";E&&!E.startsWith("http")&&(E=E.startsWith("/")?this.javDbUrl+E:this.javDbUrl+"/"+E);let L=x||"";L&&!L.startsWith("http")&&(L=L.startsWith("/")?this.javDbUrl+L:this.javDbUrl+"/"+L);let N=S.find(".score .value, .score").text().trim(),A=parseFloat(N)||0,O=N.match(/由(\d+)人/),U=0;if(O)U=parseInt(O[1]);else{let H=S.find(".score .count, .meta .count").text().trim();U=parseInt(H.replace(/[^\d]/g,""))||0}u.push({carNum:j,coverUrl:E,title:k||"",publishTime:_||"",score:A,voteCount:U,url:L})})())}let g=Gt(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,r){if(!e.length)return await storageManager.updateFavoriteActress({starId:t,lastCheckTime:utils.getNowStr(),newVideoList:[]}),0;let i=e.map(g=>g.publishTime).filter(Boolean),n=e.filter(g=>!g.carNum||r.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=Gt(i),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:r,name:i,starId:n}=e,l=`${this.javDbUrl}/actors/${n}?t=d`,c=$("#checkNewVideoMsg");try{clog.log("正在检测最新作品, 演员:",i,l),c.text(`正在检测最新作品, 演员: ${i}`);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,i,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(on,"TaskPlugin");var Sa=on;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 Vh(o){if(typeof zi=="function")return zi(o);let e=o.explicitContext;if(e?.carNum)return{context:e,source:"explicit"};let t=typeof ia=="function"?ia(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 r=a?.();if(r?.carNum)return{context:r,source:s}}return{context:null,source:"missing"}}d(Vh,"resolveOfflineMovieContext");var cn=class cn{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=[],r=[];for(let i of this.providers.values()){if(!i.capabilities.includes(s)){r.push(`${i.name}:不支持 ${s==="unknown"?"该资源格式":s.toUpperCase()}`);continue}if(!await i.isEnabled()){r.push(`${i.name}:未启用`);continue}let n=await this.getAvailability(i,t);["ready","unknown"].includes(n.authState)?a.push({provider:i,availability:n}):r.push(`${i.name}:${n.reason||"授权不可用"}`)}return this.unavailableReasons=r,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 r=await e.getAvailability({force:t});return this.availabilityCache.set(e.id,{time:Date.now(),value:r}),r}updateAvailability(e,t){this.availabilityCache.set(e,{time:Date.now(),value:t})}};d(cn,"OfflineProviderRegistry");var ln=cn,dn=class dn extends I{constructor(){super(),this.registry=new ln,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(!(M||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(),V&&e.addCleanup(V.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,r,i={})=>{let n=await t.getStoredToken();if(e?.disposed||i.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 r=`native-${e.site}`,i=$(t).find(`.jhs-offline-btn[data-jhs-offline-owner="${r}"]`).first();$(t).find(`.jhs-offline-btn[data-jhs-offline-owner="${r}"]`).not(i).remove(),i.length||(i=$('<button type="button" class="jhs-btn jhs-btn--secondary jhs-offline-btn jhs-offline-native">离线</button>').attr("data-jhs-offline-owner",r)),i.attr("data-resource",s),a.append(i)}))}async chooseCandidate(e,t){if(t.length===1)return t[0];let s=await storageManager.getSetting("offlineProviderMode","ask"),a=t.find((r=>r.provider.id===s));return a||new Promise((r=>{let i=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",(()=>{r(h),i.close(c)})))));let c=i.open({type:1,title:"选择离线服务",content:n,area:utils.getDialogArea("sm"),cancel:d(()=>r(null),"cancel"),end:d(()=>r(null),"end")})}))}getVideoInfo(e,t=null){let s=e?.[0]||e,a=this.getRuntimeService("host")?.locateListItems?.().find(i=>s&&i.contains(s));return Vh({explicitContext:t,trigger:e,listResolver:d(()=>a?_e(a):null,"listResolver"),nativeResolver:d(()=>window.isDetailPage?this.getPageInfo():null,"nativeResolver"),legacyResolver:d(()=>this.getPageInfo?.(),"legacyResolver"),logger:d(i=>clog.warn(i),"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,r=null,i={}){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:!!i.forceAvailabilityRefresh});if(!m.length&&!i.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===i.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:r})}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:r})}catch(w){clog.error("离线失败记录保存失败",w)}}show.error(`${p?.provider.name||""} 离线失败:${b}`)}finally{u?setTimeout(h,this.BUTTON_COOLDOWN_MS):h()}}};d(dn,"UnifiedOfflinePlugin");var xa=dn;function hn(o){return T(o)?.replace(/^FC2-/i,"")||null}d(hn,"normalize115Keyword");function un(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(un,"format115Size");function Ic(o,e,t={}){let s=o.match(/\.[^.]+$/)?.[0]||"",a=o.match(/-(?:U|UC|C|4K|8K|H265|HEVC|CN|CHS|CHT)\b/gi)||[],r=t.uppercase===!1?e:e.toUpperCase();return t.keepTitle&&(r+=` ${o.replace(s,"").replace(/^.*?\s+/,"")}`),t.keepSuffix!==!1&&(r+=[...new Set(a.map((i=>i.toUpperCase())))].join("")),`${r.slice(0,t.maxLength||180)}${s}`}d(Ic,"preview115Rename");var pn=class pn 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,r=hn(a);if(!r)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",r,{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} (${un(h.size)})`)):u.append($("<span></span>").text(`${h.name} (${un(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(!V)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=V.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 Te(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),r=T(a.find(".video-title strong").first().text());if(!(!r||e.dataset.jhs115State==="pending"))try{e.dataset.jhs115State="pending";let i=this.getRuntimeService("offline"),n=await i.searchFiles("one115",hn(r),{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(i.getPlayUrl("one115",n[0]),"_blank");let h=n.map((u=>`<a href="${C(i.getPlayUrl("one115",u))}" target="_blank">${C(u.name)}</a>`)).join("<br>");this.getRuntimeService("dialog").open({type:1,title:`${r} 115匹配`,content:`<div class="jhs-dialog-content">${h}</div>`,area:utils.getResponsiveArea(["560px","auto"])})}))}catch(i){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 单卡匹配失败",i)}}destroy(){this.matchGeneration=(this.matchGeneration||0)+1,this.stopMatching()}renameWithPreview(e,t,s){let a=Ic(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(r){clog.error("115 重命名失败",r),show.error("重命名失败:"+(r instanceof Error?r.message:String(r)))}}))}};d(pn,"OneOneFiveMatchPlugin");var ka=pn;var gn=class gn 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 r=a.indexOf("=");if(r<0)continue;let i=a.substring(0,r).trim(),n=a.substring(r+1);if(i&&/token/i.test(i)&&n)return{token:decodeURIComponent(n).trim(),source:`cookie.${i}`}}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`,r=t.getValue(a,"");r||(r=crypto.randomUUID?.()||`${Date.now()}-${crypto.getRandomValues(new Uint32Array(4)).join("-")}`,t.setValue(a,r));let i=t.getValue(this.tokenKey,""),n=await this.getStoredToken(),l=t.getValue(this.tokenMetaKey,null);if(n===s.token&&i.startsWith("AES:")&&l&&l.source===s.source)return;let c="AES:"+await Xt(s.token,r),h=this.getTokenFrom123Pan();e!==this.syncGeneration||h.token!==s.token||h.source!==s.source||t.getValue(this.tokenKey,"")!==i||t.getValue(a,"")!==r||(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 Xe(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(gn,"OneTwoThreeOfflinePlugin");var Ca=gn;function Rc(o){let e=0,t=0,s=0,a=0,r=0,i=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&&(r++,m&&i++),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:r,downloadedEffective:i,watchedRaw:n,watchedEffective:l,pending:c})}d(Rc,"computeLibraryStats");var mn=class mn{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(mn,"StatsRepository");var _a=mn;var fn=class fn extends I{constructor(){super(...arguments),this.statsRepository=null}getStatsRepository(){return this.statsRepository||(this.statsRepository=new _a({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:r}=await this.getStatsRepository().loadLibrarySnapshot(),i=Rc(t),n=i.total,l=new Map;t.forEach((A=>{let O=String(A.names||"").replace(/([一-鿿])\s+(?=[一-鿿])/g,"$1、").split(/[,,、]+/).map((U=>U.trim())).filter(Boolean);if(A.starId){let U=`id:${A.starId}`,H=l.get(U)||{starId:A.starId,name:O[0]||A.starId,count:0};H.count++,l.set(U,H)}else O.forEach((U=>{let H=`name:${U}`,Q=l.get(H)||{starId:"",name:U,count:0};Q.count++,l.set(H,Q)}))}));let c=[...l.values()].sort(((A,O)=>O.count-A.count||A.name.localeCompare(O.name))).slice(0,10),h=c[0]?.count||1,u=this.getRuntimeService("movie").externalSiteOrigin("javDbBtn",await storageManager.getSetting()),p=i.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:i.favoriteRaw,action:null},{label:"下载",value:i.downloadedRaw,action:null},{label:"已看",value:i.watchedRaw,action:null},{label:"手动屏蔽",value:i.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=[["收藏",i.favoriteEffective,i.unblocked,"var(--jhs-status-fav)"],["下载",i.downloadedEffective,i.unblocked,"var(--jhs-status-down)"],["已看",i.watchedEffective,i.unblocked,"var(--jhs-status-watch)"],["手动屏蔽",i.blocked,i.total,"var(--jhs-status-filter)"],["未鉴定",i.pending,i.unblocked,"var(--jhs-border-strong)"]],S=d((A,O,U,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(A)}">${C(A)}</a>`:`<span class="jhs-stats__label" title="${C(A)}">${C(A)}</span>`}<span class="jhs-stats__track"><span class="jhs-stats__bar" data-width="${U?Math.round(O/U*100):0}" data-color="${H}"></span></span><span class="jhs-stats__value">${O}${se&&U?` (${Math.round(O/U*100)}%)`:""}</span></div>`,"row"),j=d(A=>{let O=Date.now()-A*864e5,U={identified:0,downloaded:0,watched:0};return r.entries.filter((H=>H.commitState==="committed"&&Date.parse(H.createdAt)>=O)).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)&&U.identified++,!se.downloaded&&ge.downloaded&&U.downloaded++,!se.watched&&ge.watched&&U.watched++})))),U},"trend"),x=j(7),k=j(30),_=r.coverageStart?`活动记录仅覆盖自 ${C(r.coverageStart)} 起`:"仅统计 6.4.0 及之后产生的操作记录",E=d(A=>A.action?`<button type="button" class="jhs-btn jhs-stats__metric" data-action="${A.action}"${A.filter?` data-filter="${A.filter}"`:""}><strong>${A.value}</strong><span>${A.label}</span></button>`:`<div class="jhs-stats__metric"><strong>${A.value}</strong><span>${A.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((A=>S(A[0],A[1],A[2],A[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>${x.identified}</strong><span>近 7 天新增鉴定</span></div><div class="jhs-stats__metric"><strong>${x.downloaded}</strong><span>近 7 天标记下载</span></div><div class="jhs-stats__metric"><strong>${x.watched}</strong><span>近 7 天标记观看</span></div><div class="jhs-stats__metric"><strong>${k.identified}</strong><span>近 30 天新增鉴定</span></div><div class="jhs-stats__metric"><strong>${k.downloaded}</strong><span>近 30 天标记下载</span></div><div class="jhs-stats__metric"><strong>${k.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((A=>S(A.name,A.count,h,"var(--jhs-accent)",new URL(A.starId?`/actors/${encodeURIComponent(A.starId)}`:`/search?q=${encodeURIComponent(A.name)}`,u).href))).join("")}</div></section>`:""} </div>`,N=this.getRuntimeService("dialog");N.open({type:1,title:"统计",content:L,scrollbar:!1,ui:{size:"lg",body:"scroll"},area:utils.getDialogArea("lg"),anim:-1,success:d((A,O)=>{$(A).find(".jhs-stats__bar").each(((U,H)=>{$(H).css({"--jhs-value":`${$(H).data("width")}%`,"--jhs-bar":$(H).data("color")})})),$(A).find("button.jhs-stats__metric[data-action]").on("click",(U=>{let H=$(U.currentTarget),Q=H.data("action");if(N.close(O),Q==="new-video")return g?.openDialog?.();Q==="filter"&&m?.setQuickFilter?.(H.data("filter"))})),utils.setupEscClose(O)},"success")})}};d(fn,"StatsPlugin");var $a=fn;var vn=class vn 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=X.match(/\/(page|star\/[^/]+)\/(\d+)/);return e?parseInt(e[2],10):1}if(M){let e=X.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((i=>clog.error("瀑布流重试失败",i)))})),(()=>{let i=!1;e.listen(window,"scroll",(()=>{i||(i=!0,requestAnimationFrame((()=>{this.checkLoad(),this.checkScrollPosition(),i=!1})))}))})();let r=document.querySelector(t.nextPageSelector);this.nextUrl=r?.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,r=this.liveScope;try{if(!r||r.disposed||a!==this.generation)return;let i=await He(this.getRuntimeService("http"),this.nextUrl,r);if(!this.started||!this.liveScope||this.liveScope.disposed||a!==this.generation)return;clog.log("请求下一页内容:",this.nextUrl);let n=utils.htmlTo$dom(i);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(i){this.started&&this.loader&&this.setState("waterfall-error","加载失败,点击重试"),clog.error("加载失败:",i)}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","/rankings/movies","/rankings/playback","/rankings/top","/want_watch_videos","/watched_videos","jhs_source=123av"].some((t=>X.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(vn,"AutoPagePlugin");var Ta=vn;var bn=class bn 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(),r=document.createElement("button");r.type="button",r.className="jhs-btn jhs-btn--secondary jhs-copy-car-number",r.textContent="复制",r.addEventListener("click",(async function(i){i.preventDefault(),await utils.copyToClipboard("番号",a)&&(this.textContent="已复制",setTimeout((()=>{this.textContent="复制"}),1500))})),s.parentNode?.insertBefore(r,s.nextSibling)}}}};d(bn,"BusDetailPagePlugin");var Aa=bn;var wn=class wn 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(wn,"BusNavBarPlugin");var Pa=wn;var yn=class yn extends I{getName(){return"CompatibilityEnhancementsPlugin"}getStartupMode(){return"idle"}async initCss(){return Br.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 r=Hh(a);if(!r)return;let i=$(a).closest(".actor-box,.actress-card,[data-actress-card]");this.renderActressState(i,r.starId,e,t,"jhs-actress-card-state")}))}renderActressState(e,t,s,a,r){if(e.children(".jhs-actress-state-container").length)return;let i=$(`<span class="jhs-actress-state-container ${r}"></span>`);s.has(t)&&i.append('<span class="jhs-badge jhs-badge--fav">已关注</span>'),a.has(t)&&i.append('<span class="jhs-badge jhs-badge--danger">已拉黑</span>'),i.children().length&&e.append(i)}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 r=s.currentNode;!$(r.parentElement).closest("a,button,code,pre,textarea,.jhs-comment-image-link").length&&/(?:图|圖片|图片)\s*[一二三四五六七八九十\d]+/i.test(r.nodeValue||"")&&a.push(r)}a.forEach((r=>{let i=r.nodeValue||"",n=/(?:图|圖片|图片)\s*([一二三四五六七八九十\d]+)/gi,l=document.createDocumentFragment(),c=0,h;for(;h=n.exec(i);){h.index>c&&l.append(document.createTextNode(i.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<i.length&&l.append(document.createTextNode(i.slice(c))),r.replaceWith(l)}))}};d(yn,"CompatibilityEnhancementsPlugin");var Ia=yn;function Hh(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(Hh,"getActressIdentityFromLink");var jn=class jn extends I{getName(){return"DetailPageButtonPlugin"}constructor(){super(),this.answerCount=1,this.stateBinding=null,this.detailStateController=null}getDetailStateController(){return this.detailStateController||(this.detailStateController=new Mt(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(V?.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(Lt());let a=this.getOptionalDependency("DetailWorkspacePlugin")?.getSlot?.("summary-actions");a?.length?a.append(s):M?$(".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 r=this.getOptionalDependency("HighlightMagnetPlugin"),i=this.getRuntimeService("settings"),n=i.snapshot().enableMagnetsFilter??R;r||$("#enable-magnets-filter").remove(),$("#magnets-span").text(n===R?"关闭磁力过滤":"开启磁力过滤"),n===R&&r?.doFilterMagnet?.();let l=Ve({settings:i,key:"enableMagnetsFilter",fallback:ne,apply:d(c=>{let h=c===R,u=$("#magnets-span");h?(r?.doFilterMagnet?.(),u.text("关闭磁力过滤")):(r?.showAll?.(),u.text("开启磁力过滤"))},"apply"),onError:d(c=>{clog.error("磁力过滤设置保存失败,已恢复",c),show.error("磁力过滤设置保存失败,已恢复原设置")},"onError")});if($("#enable-magnets-filter").on("click",(async c=>{if(!r)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")(),r=loading();try{let i=await s.search("xunlei",{carNum:e},{scope:a});i&&i.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:i,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(i){clog.error(i),show.error(i)}finally{r.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"),r=await this.getRuntimeService("scope")(),i=await this.getRuntimeService("subtitle").download("xunlei",e,{scope:r}),n="字幕预览";s==="ass"?n="ASS字幕预览 - "+t:s==="srt"&&(n="SRT字幕预览 - "+t);let l=i.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(i,t),!1},"btn1")})}catch(a){show.error(`预览失败: ${a instanceof Error?a.message:String(a)}`),clog.error("预览字幕文件出错:",a)}else show.error("仅支持预览ASS和SRT字幕文件")}};d(jn,"DetailPageButtonPlugin");var Ra=jn;var Sn=class Sn 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(Sn,"DetailPagePlugin");var Ea=Sn;var xn=class xn 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,r)=>$(r).is("#sample-waterfall")||$(r).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(),r=e.attr("data-jhs-workspace-site")==="javdb"?e.children(".video-meta-panel").first():e.children(".row.movie").first();r.length&&s.insertAfter(r),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(((r,i)=>!$(i).closest("[data-jhs-slot]").length)).each(((r,i)=>a.append(i)))}))}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)),V&&V.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(xn,"DetailWorkspacePlugin");var Da=xn;var kn=class kn 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,r=null,i=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),r!==h&&(r=h,s.addCleanup(()=>{u.off(".jhsFc2Navigation"),u.find('.item a[data-jhs-fc2-primary="true"]').off(".jhsFc2Navigation")})))},"ensureAttached");await i();let n=null,l=d(()=>{n==null&&(n=setTimeout(()=>{n=null,i().catch(h=>clog.warn("FC2 动态导航保护失败",h))},80))},"reprotect");s.addCleanup(()=>{n!=null&&(clearTimeout(n),n=null)});let c=V.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:r,aHref:i,fc2Source:n}=_e(a);if(!r?.includes("FC2-")||!i)continue;let l=n||await t.resolveFc2Source({url:i})||"",c=a.find("a").first();if(!c.length)continue;a.attr({"data-jhs-original-url":i,"data-jhs-fc2-source":l,"data-jhs-fc2-protected":"true"}),c.attr("data-jhs-fc2-primary","true")}catch(r){clog.warn("FC2 导航保护初始化失败",r)}}}bindFc2Navigation(e,t){let s='.item a[data-jhs-fc2-primary="true"]',a=d(async r=>{if(r.type==="auxclick"&&r.button!==1||r.type==="click"&&r.button&&r.button!==0||r.shiftKey||r.altKey||$(r.target).closest("div.meta-buttons,[class^='jhs-match-']").length)return;let i=$(r.currentTarget).closest(".item"),n=!!(r.ctrlKey||r.metaKey||r.button===1),l=d((p,g,m)=>{clog.error("打开 FC2 详情失败,回退原始链接",m),n?utils.openPage(p,g,!0,{event:r,newTab:!0}):window.location.href=p},"fallbackToNative"),c,h,u;try{let p=_e(i);c=p.carNum,h=i.attr("data-jhs-original-url")||p.aHref,u=p.fc2Source}catch(p){if(h=i.attr("data-jhs-original-url")||i.find("a").first().attr("href"),c=i.find(".video-title strong").first().text().trim(),!h)return;r.preventDefault(),r.stopPropagation(),l(h,c,p);return}if(!(!c?.includes("FC2-")||!h)){r.preventDefault(),r.stopPropagation();try{let p=await t.resolveMovieIdForRecord(c,h),g=u||await t.resolveFc2Source({url:h})||"";n?await t.openFc2Page(p,c,h,{event:r,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((r,i)=>{$(i).off("click.jhsFc2Navigation auxclick.jhsFc2Navigation").on("click.jhsFc2Navigation auxclick.jhsFc2Navigation",a)})}};d(kn,"Fc2NavigationPlugin");var Na=kn;var Cn=class Cn 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&&(X.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,r)=>this.readTagName(r)===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((r=>r!==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"),r=$(".jhs-fold-category-btn"),i=a.snapshot().foldCategoryCollapsed===!0,[n,l]=i?["展开","icon-angle-double-down"]:["折叠","icon-angle-double-up"];r.find("span").text(n).end().find("i").attr("class",l),window.location.href.includes("noFold=1")||e[i?"hide":"show"]();let c=Ve({settings:a,key:"foldCategoryCollapsed",fallback:!1,apply:d(h=>{i=h===!0;let[u,p]=i?["展开","icon-angle-double-down"]:["折叠","icon-angle-double-up"];r.find("span").text(u).end().find("i").attr("class",p),e[i?"hide":"show"]()},"apply"),onError:d(h=>{clog.error("分类折叠设置保存失败,已恢复",h),show.error("分类折叠设置保存失败,已恢复原设置")},"onError")});r.on("click",(async h=>{h.preventDefault(),await c(!i)}))}};d(Cn,"FoldCategoryPlugin");var La=Cn;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(V?.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((r=>{let i=e.getTitleTarget(r);if(!i)return;let n=$(i),l=n.text().toLowerCase(),c=this.getQualitySignals(l,e.hasSubtitleTag(r));$(r).removeClass("high-quality").show().addClass("magnet-row"),l.includes("4k")&&n.css("color","var(--jhs-status-filter-text)"),c.highQuality&&(a=!0,$(r).addClass("high-quality")),this.injectScoreBadge(n,n.text()),s.push(r)})),a&&s.forEach((r=>$(r).hasClass("high-quality")||$(r).hide())),this.updateFilterHint(a)}injectScoreBadge(e,t){try{if(e.find(".jhs-magnet-score").length>0)return;let s=cs({title:t||"",seeders:0}),a=s.total,r=a>=70?"高":a>=40?"中":"低",i=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}">${r} ${a}</span>`).css({color:n,backgroundColor:i});e.append(c)}catch(s){clog.debug("磁力评分徽章注入失败,已忽略",s)}}getQualitySignals(e,t=!1){return Ui(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 Ma=_n;var $n=class $n 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($n,"SelectionModel");var Ba=$n;var Tn=class Tn extends Ba{constructor(){super(e=>ee(e?.carNum)??String(e?.id??""))}};d(Tn,"HistorySelectionModel");var Oa=Tn;var An=class An{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(An,"HistoryRepository");var Ua=An;function qh(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(qh,"buildCarNumCell");function Jh(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(Jh,"buildNamesCell");function Wh(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 r=document.createElement("button");r.type="button",r.className="jhs-btn jhs-btn--ghost sub-btns-toggle",r.setAttribute("aria-haspopup","menu"),r.setAttribute("aria-expanded","false");let i=document.createElement("span");i.textContent="更多操作",r.appendChild(i),a.appendChild(r);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",Me,""],["history-filterBtn",Le,""]];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(Wh,"buildActionButtons");function Kh(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(Kh,"buildEditRecordForm");var Pn=class Pn extends I{constructor(){super(...arguments),this.tableObj=null,this.historyRoot=null,this.historySelectionModel=new Oa,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 Ua({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(){M&&($(".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">${tt}</option> <option value="favorite">${st}</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 r=$(a.currentTarget);s.find("#searchCarNum").val(r.text()),await this.reloadTable()})).on("change.jhsHistory","#dataType",(async()=>{await this.reloadTable()})).on("click.jhsHistory","[data-history-view]",(async a=>{let r=$(a.currentTarget).data("history-view");s.find("[data-history-view]").removeClass("active"),$(a.currentTarget).addClass("active"),await this.showHistoryView(r)})).on("click",".jhs-undo-activity",(async a=>{try{let r=await this.historyRepository.undo($(a.currentTarget).data("transaction"));show.info(`撤销完成:${r.reverted.length} 项成功,${r.conflicts.length} 项冲突`),await this.renderActivityHistory()}catch(r){clog.error("撤销失败:",r),show.error("撤销失败,请稍后重试")}})).on("click",".jhs-copy-offline",(async a=>{await utils.copyToClipboard("离线资源",$(a.currentTarget).data("resource"))})).on("click",".jhs-retry-offline",(async a=>{let r=$(a.currentTarget).data("id"),i=(await this.historyRepository.offline()).find(l=>l.id===r),n=this.getOptionalDependency("UnifiedOfflinePlugin");i&&n&&await n.submitResource(a,i.resource,$(a.currentTarget),{carNum:i.carNum},i.id,{forceAvailabilityRefresh:!0,preferredProviderId:i.providerId}),await this.renderOfflineHistory()})).on("click",".jhs-open-offline",(async a=>{let r=$(a.currentTarget).data("id"),i=(await this.historyRepository.offline()).find(c=>c.id===r),n=this.getOptionalDependency("UnifiedOfflinePlugin")?.registry?.providers?.get(i?.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(i=>i.undoState==="reverted").length,r=s.changes.filter(i=>i.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} · 冲突 ${r}`),$("<p></p>").text(s.changes.map(i=>i.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"),r=a?.registry?.providers?.get?.(s.providerId),i=$('<div class="jhs-toolbar"></div>').append($('<button type="button" class="jhs-btn jhs-copy-offline">复制资源</button>').attr("data-resource",s.resource));a&&r&&i.append($('<button type="button" class="jhs-btn jhs-retry-offline">重试</button>').attr("data-id",s.id)),r&&typeof r.openUrl=="function"&&i.append($('<button type="button" class="jhs-btn jhs-open-offline">打开服务</button>').attr("data-id",s.id)),i.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),i))})}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,r)=>{r.checked=this.isHistoryAllFiltered(),r.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(((r,i)=>{i!==a&&(i.classList.remove("show"),i.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"]'),r=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 i=t.key==="Home"?0:t.key==="End"?a.length-1:t.key==="ArrowDown"?(r+1+a.length)%a.length:(r-1+a.length)%a.length;a.eq(i).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"),r=a.attr("data-car-num"),i=a.attr("data-href"),n=d(async l=>{try{let c=Ce(l);if(!c)throw new TypeError(`无效历史状态操作: ${l}`);await this.historyRepository.toggle(r,c,{type:"history-state",record:{carNum:r,url:i}}),await this.reloadTable()}catch(c){clog.error("历史记录操作失败:",c),show.error("操作失败")}},"s");if(s.hasClass("history-filterBtn")){let l=this.tableObj?.getRow(r)?.getData();q(l?.stateFlags).blocked?n(ce):utils.q(t,`是否屏蔽${C(r)}?`,(()=>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,r):s.hasClass("history-detailBtn")&&this.handleClickDetail(t,{carNum:r,url:i}).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(),r="",i="";if(s.hasClass("multiple-history-filterBtn")?(r="屏蔽",i=ce):s.hasClass("multiple-history-favoriteBtn")?(r="收藏",i=ue):s.hasClass("multiple-history-hasDownBtn")?(r="已下载",i=pe):s.hasClass("multiple-history-hasWatchBtn")?(r="已观看",i=me):s.hasClass("multiple-history-deleteBtn")&&(r="移除",i="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},是否标记为${r}?`,(async()=>{let l=loading();try{if(i==="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=Ce(i);if(!c)throw new TypeError(`无效历史批量操作: ${i}`);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(`${tt} (${this.filterCount})`),this.historyRoot.find('#dataType option[value="favorite"]').text(`${st} (${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"),r={filter:"blocked",favorite:"favorite",hasDown:"downloaded",hasWatch:"watched"}[s],i=s==="all"?t:s==="waitCheck"?t.filter((l=>!oe(l.stateFlags))):r?t.filter((l=>q(l.stateFlags)[r])):t,n=String(this.historyRoot.find("#searchCarNum").val()||"").trim();if(n){let l=n.toLowerCase().replace("-c","").replace("-uc","").replace("-4k","");i=i.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;i.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 i}async getDataList(e,t,s){this.historySorters=Array.isArray(s)?s.map(c=>({...c})):[];let a=await this.getFilteredHistoryData(this.historySorters),r=a.length,i=Math.ceil(r/t),n=(e-1)*t,l=n+t;return this.historyFilteredCount=r,{maxPage:i,dataList:a.slice(n,l),totalCount:r}}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,r=s.size,i=s.sort;return await this.getDataList(a,r,i)},"ajaxRequestFunc"),dataReceiveParams:{last_page:"maxPage",last_row:"totalCount",data:"dataList"},paginationSize:50,paginationSizeSelector:[50,100,1e3],paginationCounter:d((e,t,s,a,r)=>`共 ${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=>qh(e.getData().carNum),"formatter")},{title:"演员",field:"names",minWidth:200,sorter:"string",responsive:5,headerSort:!0,formatter:d(e=>Jh(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",tt],[a.favorite,"fav",st],[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(),r=Wh(a);return s((()=>{r.querySelector(".history-editBtn")?.addEventListener("click",(i=>{this.editRecord(a)}))})),r},"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),r=await s.resolveMovieIdForRecord(t.carNum,t.url);M?s.openFc2Dialog(r,t.carNum,t.url,{source:a}):B&&await s.openFc2Page(r,t.carNum,t.url,{newTab:!0},{source:a});return}if(M){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||"",r=e.remark||"",i=q(e.stateFlags),n=$(),l=Kh(i),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(r);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(!i.blocked&&m.blocked)return utils.q(null,`是否屏蔽${C(e.carNum)}?`,(()=>{f()})),!1;await f()},"yes")})}};d(Pn,"HistoryPlugin");var za=Pn;var In=class In extends I{constructor(){super(),this.ownedRankingSortOverride=null}getName(){return"ListPageButtonPlugin"}async handle(){if(!window.isListPage)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(i=>clog.error("排序状态同步失败",i))},"onSettingsChanged");t.addEventListener("settings.changed",s),e.addCleanup((()=>t.removeEventListener("settings.changed",s))),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 r=$(".jhs-sort-menu");if(t===R&&!s){a.prop("disabled",!0).attr("title","瀑布流模式仅支持默认排序"),$("#jhs-sort-current").text("默认(瀑布流)"),r.find(".jhs-sort-option").attr("aria-checked","false"),r.find('[data-sort-method="default"]').attr("aria-checked","true"),await this.sortItems("default");return}let i=this.activeSortMethod(),n={default:"默认",rateCount:"评价人数",date:"时间"},l=Object.prototype.hasOwnProperty.call(n,i)?n[i]:n.default;a.prop("disabled",!1).attr("title","选择列表排序方式"),$("#jhs-sort-current").text(l),r.find(".jhs-sort-option").attr("aria-checked","false"),r.find(`[data-sort-method="${i}"]`).attr("aria-checked","true"),await this.sortItems()}async createMenuBtn(e,t=null){let s=!!this.getOptionalDependency("NewVideoPlugin"),a=!!this.getOptionalDependency("BlacklistPlugin"),r=!!this.getOptionalDependency("ListPagePlugin");if(M){let l=X.includes("/actors/"),c=$(".main-tabs, .tabs").first(),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 X.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);X.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> `:""} ${r?` <button type="button" id="favoriteAllVideo" class="jhs-btn jhs-btn--fav" data-tip="${this.getBatchActionTip("favorite")}"><span>批量收藏</span></button> <button type="button" id="hasDownAllVideo" class="jhs-btn jhs-btn--down" data-tip="${this.getBatchActionTip("download")}"><span>批量标记已下载</span></button> `:""} ${X.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=X.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> `:""}${r?` <button type="button" id="favoriteAllVideo" class="jhs-btn jhs-btn--fav" data-tip="${this.getBatchActionTip("favorite")}"><span>批量收藏</span></button> <button type="button" id="hasDownAllVideo" class="jhs-btn jhs-btn--down" data-tip="${this.getBatchActionTip("download")}"><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 i=$("#newVideoCount").detach(),n=$("#newVideoBtn > span");n.length&&n.empty().append(document.createTextNode("新作品 ("),i,document.createTextNode(")"))}sortMenuHtml(e,t="选择列表排序方式"){let s={default:"默认",rateCount:"评价人数",date:"时间"},a=typeof e=="string"&&e in s?e:"default",r=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">${r}</span></button><div class="jhs-popover jhs-sort-menu" role="menu" aria-label="排序方式">${Object.entries(s).map((([i,n])=>`<button type="button" class="jhs-btn jhs-btn--ghost jhs-sort-option" role="menuitemradio" aria-checked="${i===e?"true":"false"}" data-sort-method="${i}" 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=M?$(".actor-section-name"):$(".avatar-box .photo-info .pb10");if(a.length===0)return void show.error("获取演员名称失败");let r=a.text().trim().split(",")[0];this.loadObj=loading();try{await e?.filterAllVideo?.(r)}catch(i){clog.error(i)}finally{this.loadObj.close()}})),$("#favoriteAllVideo").on("click",(async s=>{let a=this.buildBatchScope();this.loadObj=loading();try{await t?.batchSaveAllVideos?.(a,ue)}catch(r){clog.error(r)}finally{this.loadObj.close()}})),$("#hasDownAllVideo").on("click",(async s=>{let a=this.buildBatchScope();this.loadObj=loading();try{await t?.batchSaveAllVideos?.(a,pe)}catch(r){clog.error(r)}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((r=!1)=>{s.removeClass("is-open"),t.attr("aria-expanded","false"),r&&t.trigger("focus")},"close");t.on("click",(r=>{r.preventDefault(),r.stopPropagation();let i=!s.hasClass("is-open");s.toggleClass("is-open",i),t.attr("aria-expanded",String(i)),i&&s.find('[aria-checked="true"]').trigger("focus")})),s.on("click",".jhs-sort-option",(async r=>{let i=$(r.currentTarget),n=i.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"),i.attr("aria-checked","true"),$("#jhs-sort-current").text(i.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",(r=>{let i=s.find(".jhs-sort-option"),n=i.index(r.currentTarget);if(r.key==="Escape")return r.preventDefault(),a(!0);if(!["ArrowDown","ArrowUp","Home","End"].includes(r.key))return;r.preventDefault();let l=r.key==="Home"?0:r.key==="End"?i.length-1:r.key==="ArrowDown"?(n+1)%i.length:(n-1+i.length)%i.length;i.eq(l).trigger("focus")})),$(document).off("click.jhsSortMenu").on("click.jhsSortMenu",(r=>{$(r.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 r=this.getSelector(),i=$(r.boxSelector),n=$(r.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(i):i.empty().append(c)}isHitShowPage(){return je(window.location).kind==="playback-ranking"}isOwnedRankingPage(){return M&&["movie-ranking","playback-ranking","top250-ranking"].includes(je(window.location).kind)}isExternalFc2CatalogPage(){return M&&je(window.location).kind==="external-fc2-catalog"}getBatchActionTip(e){let t=this.isOwnedRankingPage()?"当前榜单页面":this.isExternalFc2CatalogPage()?"当前片库页面":"当前搜索全部分页";return e==="favorite"?`收藏${t}中符合当前筛选的作品`:`标记${t}中符合当前筛选的作品为已下载`}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 M&&window.location.pathname==="/search_advanced"&&new URLSearchParams(window.location.search).get("type")==="3"}supportsSorting(){return this.supportsLiveSorting()?!0:!(M&&window.location.pathname==="/search_advanced")}supportsLiveSorting(){return this.isOwnedRankingPage()||this.isFc2ListPage()}buildBatchScope(){if(!(M?X.includes("/actors/"):X.includes("/star/")))return{kind:"search",displayName:this.isOwnedRankingPage()?"当前榜单页面":this.isExternalFc2CatalogPage()?"当前片库页面":"当前搜索条件",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 r of $(e.itemSelector).toArray()){if(s>=t)break;let i=$(r),n=q(JSON.parse(i.attr("data-jhs-flags")||"{}")),l=JSON.parse(i.attr("data-jhs-visibility")||"{}");oe(n)||ft(n,l)||(await a.openMovieDetail(i,{autoplay:!0,newTab:!1}),s++)}s===0&&show.info("没有需鉴定的视频")}};d(In,"ListPageButtonPlugin");var Fa=In;function Va(){if(!V)throw new Error("List EventBus 未初始化");return V}d(Va,"getListEventBus");function Gh(o){return o?.jquery?o:$(o)}d(Gh,"normalizeCard");var Qh=new Set(["tagPosition","defaultQuickFilterTab"]),jt={IS_FILTERED:{text:tt,color:"var(--jhs-status-filter)",on:"var(--jhs-status-filter-on)",reasonType:"单番号屏蔽",isCounted:!0,countKey:"currentPageFilterCount"},IS_FAVORITE:{text:st,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"}},Rn=class Rn 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=>Qh.has(c))||await this.requestListRefresh({reason:"event-refresh",full:!0})},"refreshAll");["legacy-refresh","blacklist-rules-changed","filter-rules-changed","settings-changed"].forEach((n=>e.addCleanup(Va().on(n,a)))),e.addCleanup(Va().on("car-state-changed",(async n=>{let l=this.getIndexedItems(n.carNums||[]);await this.requestListRefresh({items:l,reason:"car-state-changed",full:!0})})));let r=t.snapshot().hoverBigImg;this.configureHoverPreview(r===R?"yes":"no"),this.cleanRepeatId(),this.replaceHdImg(),this.addJumpPageControl(),this.fixBusTitleBox();let i=this.advanceListGeneration();await this.doFilter(i),await this.createQuickFilter(),this.reconcileListItems(null,i),await this.bindClick(),this.rememberTagExpand(),$(this.getSelector().itemSelector).attr("data-jhs-processed","true"),this.rebuildItemIndex(),await Va().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(i=>this.refreshItems.add(i)),this.recordListPhase("refresh-request:"+t),this.refreshRunning)return this.refreshPromise;this.refreshRunning=!0;let r=d(async()=>{try{for(;this.refreshDirty;){let i=this.refreshAllRequested,n=this.refreshVisibilityRequested&&!i,l=[...this.refreshItems];this.refreshDirty=!1,this.refreshAllRequested=!1,this.refreshVisibilityRequested=!1,this.refreshItems.clear();let c=this.captureListRevision();this.recordListPhase("refresh-start",i?null:l.length);let h;if(i?(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(i?null:l,c),i){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=r()}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}">${Ee[c]}</button>`)).join(""),s=Qt.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}">${Ee[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>`;M?$(e.boxSelector).before(a):B&&$(".masonry").before(a);let r=$("#jhs-quick-filter"),i=r.find(".jhs-quick-filter__toggle"),n=r.find(".jhs-quick-filter__menu"),l=d((c=!1)=>{n.removeClass("is-open"),i.attr("aria-expanded","false"),c&&i.trigger("focus")},"closeMenu");r.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=r.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")})),i.on("click",(c=>{c.preventDefault(),c.stopPropagation();let h=!n.hasClass("is-open");n.toggleClass("is-open",h),i.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(r).length||l()})),this.activeQuickFilter||(this.activeQuickFilter=Ae(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(((r,i)=>{let n=$(i),l=q(JSON.parse(n.attr("data-jhs-flags")||"{}")),c=JSON.parse(n.attr("data-jhs-visibility")||"{}"),h=n.attr("data-jhs-recent")==="yes";Sl({filter:t,flags:l,visibilityReasons:c,recent:h})?n.show():n.hide()}))}setQuickFilter(e,{syncUi:t=!0}={}){this.filterRevision+=1,this.activeQuickFilter=Ae(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=Ae(this.activeQuickFilter),t=mt.includes(e),s=$("#jhs-quick-filter"),a=s.find(".jhs-segmented__item"),r=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"),r.attr("aria-checked","false").filter(`[data-jhs-filter="${e}"]`).attr("aria-checked","true"),s.find(".jhs-quick-filter__label").text(t?"更多筛选":`筛选:${Ee[e]}`),$(".jhs-mobile-filter-label").text(`筛选:${Ee[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",r=$(".actor-tags .content");a&&r.hasClass("collapse")&&e[0].click(),e.on("click",(function(){let i=!$(".actor-tags .content").hasClass("collapse");clog.debug("触发"),t.setLocal(s,i.toString())}))}checkDom(e=null){if(!window.isListPage)return;let t=this.getSelector(),s=document.querySelector(t.boxSelector);if(!s)return void clog.error("没有找到容器节点!");e&&e.observe(s,(a=>{for(let r of a){this.removeIndexedItems(r.removedNodes),r.addedNodes.length&&(this.advanceListGeneration(),this.recordListPhase("dom-added",r.addedNodes.length));for(let i of r.addedNodes){if(i.nodeType!==Node.ELEMENT_NODE)continue;let n=i;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 r=[...this.pendingItems].filter(n=>n.isConnected&&n.dataset.jhsProcessed!=="true"),i=this.captureListRevision();this.pendingItems.clear(),this.processTimer=null,r.length&&this.processAddedItems(r,i).catch(n=>clog.error("列表增量处理失败",n))}),100))}),{childList:!0,subtree:!1})}async processAddedItems(e,t=this.captureListRevision()){let s=this.getSelector(),a=e.flatMap(i=>[...i.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(i=>i.dataset.jhsProcessed="true"),this.indexItems(e),await Va().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(r=>t.add(r)))}),t.size&&this.itemIndex.forEach(((s,a)=>{s.forEach(r=>{t.has(r)&&s.delete(r)}),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(r=>r.isConnected?t.add(r):a.delete(r)),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 r=((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="${r}">${r}</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(r=>clog.error("JavBus图片高度修正失败",r))})),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,r,i]=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;i.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===Oe?n:l,m=T(u.carNum);g.has(m)||g.set(m,u.names)}return this.filterContext={titleKeywords:e,settings:a,carMap:r,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 r=q(JSON.parse(a.attr("data-jhs-flags")||"{}")),i=JSON.parse(a.attr("data-jhs-visibility")||"{}"),n=ft(r,i);e.total++,r.favorite&&e.favorite++,r.downloaded&&e.downloaded++,r.watched&&e.watched++,n&&e.blockedItems++,!oe(r)&&!n&&e.pending++,r.blocked&&e.debug.manualBlocked++,i.keyword&&e.debug.keywordBlocked++,i.actorBlacklist&&e.debug.actorBlocked++,i.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 Te(e,3,(async(a,r)=>{try{r>0&&r%8===0&&await this.yieldListFrame(),await this.translate(Gh(a))}catch(i){t++,s??(s=i)}})),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:r,carMap:i,recentCarNums:n,actorCarNumToNameMap:l,actressCarNumToNameMap:c}=await this.getFilterContext(),h=utils.time("读取数据耗时");if(!this.isCurrentListGeneration(t))return!1;let u=is({titleKeywords:a,settings:r,carMap:i,recentCarNums:n,actorCarNumToNameMap:l,actressCarNumToNameMap:c});utils.time("组装数据耗时");let p=utils.time("组装数据耗时"),g=r?.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:x,visibilityReasons:k,hardHidden:_}=ns({carNum:S,title:j},u,{filter:s}),E=k.keyword?Ti(u.titleKeywords,j,S):null;w.attr("data-jhs-flags",JSON.stringify(x)).attr("data-jhs-visibility",JSON.stringify(k)).attr("data-jhs-recent",n.has(S)?R:ne).attr("data-jhs-tag-position",g);let L=JSON.stringify({flags:x,visibilityReasons:k,P:g});if(w.attr("data-jhs-state-signature")!==L){w.attr("data-jhs-state-signature",L),w.find(".jhs-status-tags").remove();let N=[[x.blocked,jt.IS_FILTERED,"单番号屏蔽"],[x.favorite,jt.IS_FAVORITE,""],[x.downloaded,jt.IS_HAS_DOWN,""],[x.watched,jt.IS_HAS_WATCH,""],[k.keyword,jt.IS_KEYWORD_FILTER,E||"未知"],[k.actorBlacklist,jt.IS_ACTOR_FILTER,l.get(S)||""],[k.actressBlacklist,jt.IS_ACTRESS_FILTER,c.get(S)||""]].filter(A=>A[0]);if(N.length){let A=$(`<span class="jhs-status-tags ${g==="rightTop"?"jhs-status-tags--right":"jhs-status-tags--left"}"></span>`);if(N.forEach((([,O,U])=>{let H=$(`<span class="jhs-badge ${M?"jhs-badge--success":"jhs-badge--neutral"} status-tag" data-tip="${C(U)}" title="">${C(O.text)}</span>`);H.css({color:O.on,backgroundColor:O.color}),A.append(H)})),M)w.find(".tags").append(A);else if(B){let O=w.find(".item-tag");O.length?O.append(A):w.find(".photo-info > span > div").append(A)}}}_||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:r=null}={}){let i=Ce(t);if(!i)throw new TypeError(`不支持的状态操作: ${t}`);let n=Ae(s),l=Ee[n],c=e?.kind==="actor",h=c?String(e.recordName||""):"",u=je(window.location).kind,p=["movie-ranking","playback-ranking","top250-ranking"].includes(u),g=u==="external-fc2-catalog",m=p||g,f=g?"当前片库页":"当前榜单页",v=m?n==="all"?`将处理${f}内的所有作品,包括屏蔽项。`:`将处理${f}内符合「${l}」筛选的作品。`:n==="all"?"将处理当前搜索全部分页的所有作品,包括屏蔽项。":`将处理当前搜索全部分页中符合「${l}」筛选的作品。`;if(a&&!await new Promise(k=>utils.q(null,v,()=>k(!0),()=>k(!1))))return{cancelled:!0};let b=Vs();if(!b)return show.error("已有批量任务正在执行"),{cancelled:!0,busy:!0};let w,S=d(x=>{let k=w?.find(".jhs-batch-progress__label");k&&k.length?k.text(x):clog.debug(x)},"setProgress"),j=d(({page:x,scanned:k,matched:_})=>{S(`已扫描 ${x} 页 · 匹配 ${_} 项`),clog.debug(`批量扫描第 ${x} 页 · 已扫描 ${k} · 匹配 ${_}`)},"onProgress");try{let x=await this.getRuntimeService("scope")(),k=await this.createEvaluationContext(),_=d(()=>oc(b)||!!x?.disposed,"isCancelled");w=this.showBatchProgress(b),this.setBatchButtonsDisabled(!0);let E=await Fs({startDom:r?$(r):$(document),currentUrl:m||r?null:window.location.href,firstPageUrl:m||r?null:this.getRuntimeService("host")?.resolveFirstPageUrl?.(window.location.href)??window.location.href,itemSelector:this.getSelector().requestDomItemSelector,nextPageSelector:this.getSelector().nextPageSelector,maxPages:m?1:200,fetchHtml:d(async N=>He(this.getRuntimeService("http"),N,x),"fetchHtml"),parseItem:d(N=>{let A=_e(N);return c?A:{...A,names:rc(N)}},"parseItem"),evaluate:d(N=>ns({carNum:N.carNum,title:N.title||""},k,{filter:n}),"evaluate"),isCancelled:_,onProgress:j});if(_())return w?.remove(),{cancelled:!0};w?.find("#jhs-batch-cancel").prop("disabled",!0).attr("title","正在写入,无法取消"),S("正在写入,无法取消…");let L=0;for(let N=0;N<E.length&&!_();N+=75){let A=E.slice(N,N+75);await this.getRuntimeService("state").patch(A.map(O=>O.carNum),{[i]:!0},{type:"actor-page-batch-state",records:A.map(O=>({carNum:O.carNum,url:O.url||"",names:O.names??h,publishTime:O.publishTime||"",fc2Source:O.fc2Source}))}),L+=A.length,S(`已更新 ${L}/${E.length} 项`)}return S(`批量完成:匹配 ${E.length} 项 · 已更新 ${L} 项`),setTimeout(()=>w?.remove(),1800),{matched:E.length,updated:L}}catch(x){throw clog.error("批量操作失败:",x),S("批量操作失败"),w?.addClass("jhs-batch-progress--error"),setTimeout(()=>w?.remove(),2500),x}finally{Nt(b)&&Hs(b),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:r,publishTime:i,fc2Source:n}=this.findCarNumAndHref(s),l=M?$(".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(r)),await this.getRuntimeService("state").patch(a,{blocked:!0},{record:{carNum:a,url:r,names:c,publishTime:i,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 r=e?.jquery?e:$(e),{carNum:i,aHref:n}=this.findCarNumAndHref(r);if(!i||!n)return;let l=a||!!t&&(t.ctrlKey||t.metaKey||t.button===1);if(i.includes("FC2-"))return;let c=new URL(n,window.location.origin);s&&c.searchParams.set("autoPlay","1"),utils.openPage(c.href,i,!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((r=>clog.error("打开影片详情失败",r))))}))}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 He(this.getRuntimeService("http"),e,s),r=utils.htmlTo$dom(a);M?t=r.find(".female").prev().map(((i,n)=>$(n).text())).get().join(" "):B&&(t=r.find('span[onmouseover*="star_"] a').map(((i,n)=>$(n).text())).get().join(" ")),clog.debug("解析到名称:",t)}return t}findCarNumAndHref(e){try{return _e(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(M)/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)\//,r=/(\.jpg|\.jpeg|\.png)$/i;a.test(t)?(s=s.replace(a,"/$1/cover/").replace(r,"_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 r=a.target;a.isIntersecting&&(this.hdImageObserver?.unobserve(r),delete r.dataset.jhsHdObserved,this._scheduleHdUpgrade(r))}))}),{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");M?(a.contents().each(((r,i)=>{i.nodeType!==3||(i.textContent||"").trim()===""||(i.textContent||"").includes(s)||(i.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,r=t.find(".video-title");if(M?(s=r.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 i=this.translationGeneration,n=this.getRuntimeService("settings"),l=await this.getRuntimeService("scope")(),c=await this.getRuntimeService("translation").translate(s,{cacheAlias:a,scope:l});i!==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;M&&(a=t.find(".video-title strong").text().trim());let r=t.find(".video-title");r.contents().each(((i,n)=>{n.nodeType!==3||!s||(n.textContent||"").trim()===""||a&&(n.textContent||"").includes(a)||(n.textContent=" "+s+" ")})),r.removeAttr("title")})}addJumpPageControl(){let e="gemini-jump-page-control";if($("#"+e).length>0||$(".pagination-link.is-current").length===0)return;let t=utils.getUrlParam(X,"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:"跳转"}),r=$("<li>",{id:e}).append(s).append(a);$(".pagination-list").append(r);let i=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",i),s.on("keypress",(function(n){n.which===13&&(i(),n.preventDefault())}))}};d(Rn,"ListPagePlugin");var Ha=Rn;var En=class En 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"),r=e.find(".jhs-commandbar__right");if(!a.length||!r.length)return;!e.find(".jhs-commandbar__primary").length&&!t("#waitCheckBtn")&&a.append('<div class="jhs-commandbar__primary"></div>');let i=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(i))})),i.children().length&&a.append(i),!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(r)));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),r.append(p)}!e.find(".jhs-commandbar__batch").length&&!["#filterAllVideo","#favoriteAllVideo","#hasDownAllVideo"].every(t)&&r.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(r),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 r=a.element;r?.isConnected&&e.append(r)}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=M?$(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"),r=!!this.getOptionalDependency("ListPagePlugin"),i=!!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=Ae(this.getOptionalDependency("ListPagePlugin")?.activeQuickFilter),S=[...mt,...Qt].map(((x,k)=>`${k===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="${x===w}" tabindex="-1" data-jhs-filter="${x}">${Ee[x]}</button>`)).join(""),j=Object.entries(f).map((([x,k])=>`<button type="button" role="menuitemradio" class="jhs-btn jhs-btn--ghost jhs-mobile-sort-option" aria-checked="${x===v}" tabindex="-1" data-jhs-sort="${x}">${k}</button>`)).join("");g=t((a?e("check","开始鉴定"):"")+(i?e("newVideo","新作品"):"")+(n?e("blacklist","黑名单"):"")+(p?e("history","鉴定记录"):"")+(a?e("sort",`排序: ${b}`,'aria-haspopup="menu" aria-expanded="false"'):"")+(r?e("quickFilter",`<span class="jhs-mobile-filter-label">筛选:${Ee[w]}</span>`,'aria-haspopup="menu" aria-expanded="false"'):""))+s+t(e("logger","运行日志")+(l?e("setting","设置"):""))+(r?`<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:Le,label:"屏蔽",key:"filter"},{action:"fav",icon:Me,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)"},r=q(t?.stateFlags),i=new Set;r.blocked&&i.add("filter"),r.favorite&&i.add("fav"),r.downloaded&&i.add("down"),r.watched&&i.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");i.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"),r=s.find(".jhs-mobile-sort-menu"),i=s.find('[data-action="quickFilter"]'),n=s.find('[data-action="sort"]'),l=d((p=!1)=>{s.removeClass("jhs-fab-filter-open"),i.attr("aria-expanded","false"),p&&i.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)})),r.on("keydown",".jhs-mobile-sort-option",(p=>{let g=r.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=r.find('.jhs-mobile-sort-option[aria-checked="true"]').first();r.find(".jhs-mobile-sort-option").attr("aria-checked","false"),$(p.currentTarget).attr("aria-checked","true");try{await this.getOptionalDependency("ListPageButtonPlugin")?.selectSortMethod?.(g)}catch(v){r.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"),i.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=r.find('[aria-checked="true"]');return void(m.length?m.first():r.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(En,"MobileBottomBarPlugin");var qa=En;var Dn=class Dn 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,r)=>{let i=$(r);i.text().toLowerCase().includes(s)&&i.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="/search_advanced?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 r=s[a].getAsFile();$("#search-keyword").blur();let i=this.getOptionalDependency("SearchByImagePlugin");return i?void i.open((()=>{i.handleImageFile(r),i.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(Dn,"NavBarPlugin");var Ja=Dn;var Nn=class Nn extends I{constructor(){super(...arguments),P(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 r=await this.getRuntimeService("scope")(),i=await He(this.getRuntimeService("http"),new URL(a,window.location.href),r),n=utils.htmlTo$dom(i);return this.parseMovieList(n,t)}};d(Nn,"WantAndWatchedVideosPlugin");var Wa=Nn;var Ln=class Ln 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((i=>{let n=$(i);n.text().toLowerCase().includes(e)?s++:n.parent().parent().hide()})),s===0&&show.error("该番号无字幕!");let a=$(".sec-title"),r=String(a.html()||"").replace(/^\d+/,String(s));a.html(r)}};d(Ln,"SubTitleCatPlugin");var Ka=Ln;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 r=await this.getRuntimeService("scope")(),i=e??this.getPageInfo().carNum;await Xs({root:s.root,carNum:i,translation:this.getRuntimeService("translation"),scope:r,isActive:d(()=>(a.snapshot().translateTitle??R)===R,"isActive")})}};d(Mn,"TranslatePlugin");var Ga=Mn;var F=d((o,e,t,s,a,r=[],i={})=>hl({id:o,featureId:e,legacyPluginId:t.legacyPluginId??t.name,plugin:t,sites:s,order:a,requires:r,routes:i.routes??(e==="detail"?["detail","owned-detail"]:[]),surfaces:i.surfaces??(e==="detail"?["detail-page"]:[])}),"manifest"),Qa=Object.freeze([F("list.core","list",Ha,["javdb","javbus"],{javdb:1,javbus:1},[Y.host,y.translation,y.http,y.storage,y.state,y.settings]),F("list.auto-page","list",Ta,["javdb","javbus"],{javdb:2,javbus:5},[y.http,y.settings]),F("detail.fc2-owned","detail",ta,["javdb"],{javdb:3},[y.movie,y.magnet,y.dialog,y.account,y.credential,y.translation,y.settings,y.storage,y.screenshot,y.review,y.related,y.state],{routes:["list","detail","owned-detail"],surfaces:["list-card","detail-page"]}),F("detail.fc2-navigation","detail",Na,["javdb"],{javdb:4},[Y.host],{routes:["list"],surfaces:["list-card"]}),F("list.fold-category","list",La,["javdb"],{javdb:5},[y.settings]),F("list.actions","list",Fa,["javdb","javbus"],{javdb:5,javbus:2},[y.settings]),F("library.history","library",za,["javdb","javbus"],{javdb:6,javbus:4},[y.dialog,y.movie,y.settings,y.state]),F("settings.core","settings",zs,["javdb","javbus"],{javdb:7,javbus:3},[Y.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]),F("identity.javdb-navigation","identity",Ja,["javdb"],{javdb:8},[y.movie]),F("discovery.hit-show","discovery",sa,["javdb"],{javdb:9},[Y.host]),F("discovery.top250","discovery",da,["javdb"],{javdb:10},[Y.host]),F("identity.image-search","identity",Is,["javdb","javbus"],{javdb:11,javbus:6},[y.dialog,y.storage,y.imageSearch]),F("detail.cover-state-actions","detail",va,["javdb","javbus"],{javdb:12,javbus:8},[y.storage,y.settings,y.movie,y.state],{routes:["list","detail","owned-detail"],surfaces:["list-card","detail-page"]}),F("detail.fc2-lookup","detail",Qs,["javdb"],{javdb:13},[Y.host,y.movie],{routes:["list","detail","owned-detail"],surfaces:["list-card","detail-page"]}),F("detail.javdb-native","detail",Ea,["javdb"],{javdb:14}),F("detail.workspace","detail",Da,["javdb","javbus"],{javdb:15,javbus:11},[Y.host]),F("detail.reviews","detail",ca,["javdb","javbus"],{javdb:16,javbus:13},[Y.host,y.review,y.movie,y.settings,y.storage]),F("detail.related","detail",la,["javdb"],{javdb:17},[Y.host,y.related,y.settings]),F("detail.page-state-actions","detail",Ra,["javdb","javbus"],{javdb:18,javbus:12},[y.movie,y.dialog,y.subtitle,y.state,y.settings]),F("detail.native-magnets","detail",Ma,["javdb","javbus"],{javdb:19,javbus:15},[Y.host,y.settings]),F("detail.javdb-preview","detail",ba,["javdb"],{javdb:20},[y.storage,y.settings,y.movie,y.dialog]),F("library.keyword-filter","library",Ws,["javdb","javbus"],{javdb:21,javbus:14}),F("identity.actress-info","identity",Ps,["javdb"],{javdb:22},[y.actressInfo,y.settings]),F("detail.external-sites","detail",oa,["javdb","javbus"],{javdb:23,javbus:19},[Y.host,y.movie,y.storage,y.settings]),F("external-bridge.translation","external-bridge",Ga,["javdb","javbus"],{javdb:24,javbus:20},[y.translation,y.settings]),F("library.state-actions","library",Wa,["javdb"],{javdb:25},[y.http,y.state]),F("detail.external-magnets","detail",na,["javdb","javbus"],{javdb:26,javbus:17},[y.storage,y.http,y.magnet]),F("detail.screenshot","detail",wa,["javdb","javbus"],{javdb:27,javbus:18},[y.screenshot,y.settings]),F("library.blacklist","library",Js,["javdb","javbus"],{javdb:28,javbus:21},[Y.host,y.dialog,y.storage,y.http,y.state]),F("library.favorite-actresses","library",ua,["javdb"],{javdb:29}),F("discovery.new-video","discovery",ya,["javdb"],{javdb:30},[y.dialog,y.storage,y.actressInfo,y.movie,y.state]),F("discovery.scheduler","discovery",Sa,["javdb","javbus"],{javdb:31,javbus:22},[y.storage,y.http,y.actressInfo,y.movie,y.state]),F("stats.dashboard","stats",$a,["javdb","javbus"],{javdb:32,javbus:23},[y.diagnostics,y.dialog,y.movie,y.state]),F("responsive-shell.bottom-bar","responsive-shell",qa,["javdb","javbus"],{javdb:33,javbus:24},[Y.host,y.settings,y.profile]),F("external-bridge.115-match","external-bridge",ka,["javdb","javbus"],{javdb:34,javbus:25},[Y.host,y.dialog,y.offline,y.settings]),F("external-bridge.offline","external-bridge",xa,["javdb","javbus"],{javdb:35,javbus:26},[Y.host,y.dialog,y.offline,y.state,y.settings]),F("compatibility.enhancements","compatibility",Ia,["javdb","javbus"],{javdb:36,javbus:27},[y.state]),F("identity.javbus-navigation","identity",Pa,["javbus"],{javbus:7}),F("detail.javbus-images","detail",pa,["javbus"],{javbus:9}),F("detail.javbus-native","detail",Aa,["javbus"],{javbus:10}),F("detail.javbus-preview","detail",fa,["javbus"],{javbus:16},[y.settings,y.storage,y.movie]),F("external-bridge.123pan","external-bridge",Ca,["javdb","javbus","123pan"],{javdb:0,javbus:0,"123pan":1},[y.storage]),F("external-bridge.javtrailers","external-bridge",aa,["javtrailers"],{javtrailers:1}),F("external-bridge.subtitle","external-bridge",Ka,["subtitlecat"],{subtitlecat:1})]),Ec=new Set,Dc=new Set;for(let o of Qa){if(Ec.has(o.id))throw new Error(`Duplicate contribution id: ${o.id}`);if(Dc.has(o.legacyPluginId))throw new Error(`Duplicate legacy plugin contribution: ${o.legacyPluginId}`);Ec.add(o.id),Dc.add(o.legacyPluginId)}function Nc(o,e,t){o.setDependencyDeclarations(bl),e.setContributionManifests?.(Qa),o.setCatalogDescriptors(Qa.filter(s=>s.sites.includes(t)).map(s=>({name:s.legacyPluginId,disableable:e.isFeatureDisableable(s.featureId)}))),Qa.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),r={};r.scope=()=>e.getContributionScope(s.featureId,s.id,s.legacyPluginId);let i=new Map([[Y.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=i.get(n);if(!l)throw new Error(`Legacy contribution ${s.id} has no runtime name for ${String(n)}`);r[l]=a[n]}o.register(s.plugin,r,{disableable:e.isFeatureDisableable(s.featureId)})})}d(Nc,"registerSitePlugins");function Lc(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(Lc,"attachCompatibilityFacade");function qe(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(qe,"assertPort");var Je=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 Bn=class Bn{constructor(e={}){this.location=e.location??window.location,this.openWindow=e.open??window.open.bind(window),qe(this,"NavigationPort",Je.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(Bn,"BrowserNavigationAdapter");var Ya=Bn;var On=class On{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(On,"BrowserStyleAdapter");var Za=On;var Un=class Un{constructor(e,t,s,a,r=()=>{}){this.forage=e,this.localStore=t,this.gmGetValue=s,this.gmSetValue=a,this.gmDeleteValue=r}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 Xa=Un;var zn=class zn{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:W.layer,...e};return e.ui?kt(t,globalThis.utils):t}};d(zn,"LayerDialogAdapter");var er=zn;var Fn=class Fn{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),r=d(()=>t.abort(),"onAbort"),i=a>0?setTimeout((()=>{s=!0,t.abort()}),a):null;e.signal?.addEventListener("abort",r,{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{i!==null&&clearTimeout(i),e.signal?.removeEventListener("abort",r)}}requestWithUserscript(e){return new Promise((t,s)=>{let a=!1,r,i=d((l,c)=>{a||(a=!0,e.signal?.removeEventListener("abort",n),l(c))},"finish"),n=d(()=>{r?.abort?.(),i(s,new D("ABORTED","网络请求已取消",{source:"UserscriptHttpAdapter"}))},"onAbort");r=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=>i(t,{status:l.status,data:l.response??l.responseText,responseText:l.responseText??"",finalUrl:l.finalUrl||e.url,responseHeaders:l.responseHeaders??""}),"onload"),onerror:d(l=>i(s,new D("NETWORK_ERROR","网络请求失败",{source:"UserscriptHttpAdapter",cause:l,retryable:!0})),"onerror"),ontimeout:d(()=>i(s,new D("TIMEOUT","网络请求超时",{source:"UserscriptHttpAdapter",retryable:!0})),"ontimeout"),onabort:d(()=>i(s,new D("ABORTED","网络请求已取消",{source:"UserscriptHttpAdapter"})),"onabort")}),e.signal?.aborted?n():e.signal?.addEventListener("abort",n,{once:!0})})}};d(Fn,"UserscriptHttpAdapter");var tr=Fn;async function Mc(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(Mc,"digestKey");var Vn=class Vn{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),r=`${e}:${this.namespaceVersion}:${t}`,i=Date.now(),n=this.storage,l=a?.get(r);if(l&&l.expiresAt>i)return this.diagnostics?.recordCache(!0),{hit:!0,value:l.value,negative:l.negative};if(l&&a?.delete(r),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 Mc(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<=i)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(r,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 r=Math.min(2592e6,Math.max(0,Number(a.ttlMs)||0));if(!r||a.scope==="public"&&a.generation!=null&&a.generation!==this.generation(e))return;let i={value:s,expiresAt:Date.now()+r,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,i);return}if(a.generation!=null&&a.generation!==this.generation(e))return;let h=this._publicPrefix(e)+await Mc(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,...i,lastUsed:Date.now()}),a.generation!=null&&a.generation!==this.generation(e)){await c.remove(h).catch(()=>{});return}n?.set(l,i),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(r=>r.startsWith("jhs_http_public_cache:v"))){let r=await this.storage.get(a).catch(()=>null);if(!r||r.version!==this.namespaceVersion||!Number.isFinite(r.expiresAt)||r.expiresAt<=t){await this.storage.remove(a).catch(()=>{});continue}s.push({key:a,lastUsed:Number(r.lastUsed)||0})}if(s.length>500){s.sort((a,r)=>a.lastUsed-r.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(r=>r.startsWith(s)).map(r=>t.remove(r).catch(()=>{})))}catch{}}async clearPublic(){return this.clearAll()}async invalidateNamespace(){return this.clearAll()}};d(Vn,"CacheService");var sr=Vn;var Hn=class Hn{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}`,r=await this.cache.get("actress-info",a,{scope:"public"});if(r.hit)return r.value;let i=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:i}),c}return null}async movies(e,t,s={}){let a=this.integrations.list("actor.movies").find(i=>i.id===e);if(!a)return[];let r=this.integrations.getAdapter(a.id);return typeof r?.listActorMovies=="function"?r.listActorMovies(t,s):[]}async collection(e,t,s={}){let a=this.integrations.list("actor.collection").find(i=>i.id===e);if(!a)throw new TypeError(`Actor collection provider is unavailable: ${e}`);let r=this.integrations.getAdapter(a.id);if(typeof r?.listActorCollection!="function")throw new TypeError(`Actor collection is unavailable: ${e}`);return r.listActorCollection(t,s)}async uncollect(e,t,s={}){let a=this.integrations.list("actor.uncollect").find(i=>i.id===e);if(!a)throw new TypeError(`Actor provider is unavailable: ${e}`);let r=this.integrations.getAdapter(a.id);if(typeof r?.uncollectActor!="function")throw new TypeError(`Actor uncollect is unavailable: ${e}`);return r.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 r=this.integrations.getAdapter(a.id);if(r?.getSources?.().some(i=>i.id===t))return r.searchAvatars(e,{...s,sourceId:t})}return[]}placeholderUrl(e){let t=this.integrations.getAdapter(e);return typeof t?.actorPlaceholderUrl=="function"?t.actorPlaceholderUrl():""}};d(Hn,"ActressInfoService");var ar=Hn;var Yh=/^(?:authorization|cookie|set-cookie|password|token|secret|credential)$/i;function qn(o,e=""){return Yh.test(e)?"[redacted]":Array.isArray(o)?o.map(t=>qn(t)):o&&typeof o=="object"?Object.fromEntries(Object.entries(o).map(([t,s])=>[t,qn(s,t)])):typeof o!="string"?o:o.replace(/(https?:\/\/)([^\s/@:]+):([^\s/@]+)@/gi,"$1[redacted]@")}d(qn,"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({...qn(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 rr=Jn;var Wn=class Wn{constructor(e){this.port=qe(e,"DialogPort",Je.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(Wn,"DialogService");var ir=Wn;var Zh=[/^10\./,/^127\./,/^169\.254\./,/^192\.168\./,/^172\.(?:1[6-9]|2\d|3[01])\./,/^0\./];function Xh(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"):Zh.some(t=>t.test(e))}d(Xh,"isPrivateLiteral");var Kn=class Kn{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:"||Xh(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(Kn,"ExternalUrlPolicy");var nr=Kn;function us(o){if(o==null||typeof o!="object")return JSON.stringify(o);if(Array.isArray(o))return`[${o.map(us).join(",")}]`;let e=o;return`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${us(e[t])}`).join(",")}}`}d(us,"stableSerialize");async function Bc(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(Bc,"sha256");function eu(o){let e=new URL(o),t=[...e.searchParams.entries()].sort(([s,a],[r,i])=>s.localeCompare(r)||a.localeCompare(i));e.search="";for(let[s,a]of t)e.searchParams.append(s,a);return e.hash="",e.href}d(eu,"canonicalizeUrl");function tu(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),r=t.includes("cf-chl-")||t.includes("cf_chl_opt"),i=t.includes("/cdn-cgi/challenge-platform/")||t.includes("challenge-platform");return s||a&&(r||i)||[403,429,503].includes(e)&&r&&i}d(tu,"isCloudflareChallenge");function su(o,e){return o<=0?Promise.resolve():new Promise((t,s)=>{let r=setTimeout(d(()=>{e?.removeEventListener("abort",i),t()},"finish"),o),i=d(()=>{clearTimeout(r),s(new D("ABORTED","请求已取消",{source:"HttpService"}))},"onAbort");e?.addEventListener("abort",i,{once:!0}),Promise.resolve().then(()=>e?.aborted&&i())})}d(su,"waitForRetry");async function au(o){let e=String(o.method??"GET").toUpperCase(),t=Object.fromEntries(Object.entries(o.headers??{}).map(([i,n])=>[i.toLowerCase(),String(n)])),s=[...new Set((o.varyHeaders??[]).map(i=>String(i).toLowerCase()))].sort(),a=Object.fromEntries(s.map(i=>[i,t[i]??""])),r={providerId:String(o.providerId),cacheNamespace:String(o.cacheNamespace??o.providerId??"default"),method:e,canonicalUrl:eu(o.url),bodyHash:await Bc(us(o.body??null)),responseType:String(o.responseType??"text"),cacheScope:String(o.cacheScope??"none"),varyHeadersHash:await Bc(us(a)),sessionScopeId:o.cacheScope==="session"?String(o.sessionScopeId??""):""};if(r.cacheScope==="session"&&!r.sessionScopeId)throw new TypeError("sessionScopeId is required for session requests");return Object.freeze(r)}d(au,"createRequestKey");var Gn=class Gn{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 r=e.urlPolicy,i=this.urlPolicy.assertAllowed(e.url,r);if(s!=="GET"||a==="none")return this.executeUnderlying({...e,method:s,url:i.href,signal:t?.signal},r);let n=String(e.cacheNamespace??e.providerId??"default"),l=await au({...e,method:s,url:i.href,cacheScope:a,cacheNamespace:n});t?.assertActive();let c=us(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:i.href,signal:m.signal},r).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))),r=new Set((e.acceptableStatuses??[]).map(c=>Number(c)).filter(Number.isFinite)),i=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}i.state==="half-open"&&(i.probing=!0,n=!0);try{let u=await this.port.request(e);if(this.urlPolicy.assertFinalUrl(u.finalUrl||e.url,t),tu(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(r.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 su(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&&(i.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")},r;try{r=t?.ownRequestConsumer(a)}catch(l){throw a.release(),e.promise.catch(()=>{}),l}this.updateDiagnostics();let i=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}),i=d(()=>t.signal.removeEventListener("abort",h),"removeAbortListener")})]):e.promise).finally(()=>{i(),r?.(),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(Gn,"HttpService");var or=Gn;var Qn=class Qn{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),r=String(e||"");if(r.startsWith("data:"))r=await a.upload(r,t);else{let i;try{i=new URL(r)}catch(n){throw new D("INVALID_URL","图片 URL 无效",{source:"ImageSearchService",cause:n})}if(!["http:","https:"].includes(i.protocol))throw new D("INVALID_URL","图片 URL 必须使用 HTTP/HTTPS",{source:"ImageSearchService"});r=i.href}return Object.freeze({imageUrl:r,targets:a.createTargets(r)})}};d(Qn,"ImageSearchService");var lr=Qn;var Yn=class Yn{constructor(e){this.port=qe(e,"NavigationPort",Je.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(Yn,"NavigationService");var cr=Yn;var Zn=class Zn{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 r=await a.search(e,t);this.providers.updateHealth(a.id,{ok:!0}),Array.isArray(r)&&s.push(...r)}catch(r){this.providers.updateHealth(a.id,{ok:!1,error:r instanceof Error?r.message:String(r)})}return s}async listNative(e,t={}){let s=typeof e.providerId=="string"?e.providerId:"javdb",a=(this.integrations?.list("movie.magnets")??[]).find(i=>i.id===s);if(!a)return[];let r=this.integrations?.getAdapter(a.id);return typeof r?.listMagnets=="function"?r.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 r=this.integrations?.getAdapter(a.id);if(r?.getSources?.().some(i=>i.id===e))return r.search(e,t,s)}return[]}getSourceTargetUrl(e,t,s={}){for(let a of this.integrations?.list("magnet.search")??[]){let r=this.integrations?.getAdapter(a.id);if(r?.getSources?.().some(i=>i.id===e))return r.targetUrl(e,t,s)}return null}assess(e){return xc(e)}};d(Zn,"MagnetService");var dr=Zn;var Xn=class Xn{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")??[],r=typeof e.providerId=="string"?e.providerId:null,i=r?a.filter(n=>n.id===r):[...a].sort((n,l)=>+(l.id==="javdb")-+(n.id==="javdb"));for(let n of i){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,r=a?s.filter(i=>i.id===a):s;for(let i of r){let n=this.integrations?.getAdapter(i.id);if(typeof n?.getDetail=="function")return n.getDetail(e,t)}return null}async rankings(e={}){return this.playbackRankings(e)}async playbackRankings(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(i=>i.id===e);if(!a)throw new TypeError(`Movie catalog provider is unavailable: ${e}`);let r=this.integrations?.getAdapter(a.id);if(typeof r?.listCatalog!="function")throw new TypeError(`Movie catalog operation is unavailable: ${e}`);return r.listCatalog(t,s)}async people(e,t,s={}){let a=(this.integrations?.list("movie.credits")??[]).find(i=>i.id===e);if(!a)return Object.freeze({actors:Object.freeze([]),seller:null});let r=this.integrations?.getAdapter(a.id);return typeof r?.getPeople=="function"?r.getPeople(t,s):Object.freeze({actors:Object.freeze([]),seller:null})}async images(e,t,s={}){let a=(this.integrations?.list("movie.images")??[]).find(i=>i.id===e);if(!a)return[];let r=this.integrations?.getAdapter(a.id);return typeof r?.getImages=="function"?r.getImages(t,s):[]}async preview(e,t,s={}){let a=(this.integrations?.list("movie.preview")??[]).find(i=>i.id===e);if(!a)throw new TypeError(`Movie preview provider is unavailable: ${e}`);let r=this.integrations?.getAdapter(a.id);if(typeof r?.getPreviewForMovie!="function")throw new TypeError(`Movie preview operation is unavailable: ${e}`);return r.getPreviewForMovie(t,s)}sourceUrls(e,t){return Object.freeze(t.map(s=>{try{let a=this.integrations?.getAdapter(s),r=typeof a?.detailUrl=="function"?a.detailUrl(e):null;return r?Object.freeze({providerId:s,url:r}):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],r=a&&this.integrations?.getAdapter(a.id);return typeof r?.searchSite!="function"?Object.freeze({searchUrl:"",matches:Object.freeze([])}):r.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(Xn,"MovieIdentityService");var hr=Xn;var eo=class eo{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 r=this.integrations.getAdapter(e);if(typeof r.renameFile!="function")throw new TypeError(`Integration ${e} does not support file rename`);return r.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 r of s)try{let i=await r.submit(e,t);return this.providers.updateHealth(r.id,{ok:!0}),i}catch(i){a.push(i),this.providers.updateHealth(r.id,{ok:!1,error:i instanceof Error?i.message:String(i)})}throw new AggregateError(a,s.length?"所有离线 Provider 均失败":"没有可用的离线 Provider")}};d(eo,"OfflineService");var ur=eo;var to=class to 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(to,"ProfileService");var pr=to;var so=class so{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(so,"RelatedService");var gr=so;var ao=class ao{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(ao,"ReviewService");var mr=ao;var Ft="javstore",Oc=new Set([Ft]),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(r=>r.id)):null;if(s&&!s.length)return null;if(t.providerId){if(a&&!a.has(t.providerId))return null;let r=this.providers.get?.(t.providerId);return r?r.enabled===!1||!r.capabilities?.includes("screenshot")?null:this.resolveFromProvider(r,e,t):this.resolveIntegration(t.providerId,e,t)}for(let r of await this.providers.getAvailable("screenshot",t)){if(a&&!a.has(r.id))continue;let i=await this.resolveFromProvider(r,e,t);if(i)return i}return a&&!a.has(Ft)?null:this.resolveIntegration(Ft,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(!Oc.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 r=this.integrations?.getAdapter(a.id);if(typeof r?.getImages!="function")return null;let i=await r.getImages(t,s);return Array.isArray(i)&&i.length?i:null}getSearchUrl(e,t=null){if(!Oc.has(Ft)||t&&!this.isEnabled(t)||t&&!this.getEnabledProviders(t).some(s=>s.id===Ft))return null;for(let s of this.integrations?.list("movie.images")??[]){if(s.id!==Ft)continue;let a=this.integrations?.getAdapter(s.id);if(typeof a?.getSearchUrl=="function")return a.getSearchUrl(e)}return null}};d(ro,"ScreenshotService");var fr=ro;var io="translation_cache_v2",no="translation:v1:",oo=class oo{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`${no}${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 r=await t.get(io);for(let[n,l]of Object.entries(r?.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 i=await t.keys();for(let n of i.filter((l=>l.startsWith(no)))){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,r]of this.memoryCache)r.expiresAt<=e&&(this.memoryCache.delete(a),t=!0);let s=this.memoryCache.size-1e3;if(s>0)for(let[a]of[...this.memoryCache].sort(((r,i)=>r[1].lastUsed-i[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(io,{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(io),await Promise.all(t.filter((s=>s.startsWith(no))).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",r=this.cacheKey(e,s,a),i=this.cacheGeneration,n=this.memoryCache.get(r);if(n?.expiresAt>Date.now())return n.lastUsed=Date.now(),this.schedulePersist(),n.value;n&&this.memoryCache.delete(r);let l=t.cacheAlias&&this.readLegacyCache()[t.cacheAlias];if(s==="ja"&&a==="zh-CN"&&typeof l=="string"&&l)return this.remember(r,l,i);if(await this.hydrate(),n=this.memoryCache.get(r),n?.expiresAt>Date.now())return n.lastUsed=Date.now(),this.schedulePersist(),n.value;let c=this.inflight.get(r);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(r,g,i):g})().finally((()=>this.inflight.delete(r)));return this.inflight.set(r,h),h}};d(oo,"TranslationService");var vr=oo;var lo=class lo{constructor(e){this.integrations=e}async search(e,t,s={}){let a=this.integrations.list("subtitle.search").find(i=>i.id===e);if(!a)return[];let r=this.integrations.getAdapter(a.id);return typeof r?.search=="function"?r.search(t,s):[]}async download(e,t,s={}){let a=this.integrations.list("subtitle.download").find(i=>i.id===e);if(!a)throw new TypeError(`Subtitle provider is unavailable: ${e}`);let r=this.integrations.getAdapter(a.id);if(typeof r?.download!="function")throw new TypeError(`Subtitle download is unavailable: ${e}`);return r.download(t,s)}};d(lo,"SubtitleService");var br=lo;var co=class co{constructor(e){this.integrations=e}async login(e,t,s={}){let a=this.integrations.list("account.login").find(i=>i.id===e);if(!a)throw new TypeError(`Account provider is unavailable: ${e}`);let r=this.integrations.getAdapter(a.id);if(typeof r?.login!="function")throw new TypeError(`Account login is unavailable: ${e}`);return r.login(t,s)}};d(co,"AccountService");var wr=co;var ho=class ho 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),r=[...new Set([...Object.keys(t),...Object.keys(s)])].filter(i=>t[i]!==s[i]);return r.length&&this.dispatchEvent(new CustomEvent("settings.changed",{detail:Object.freeze({name:r.length===1?r[0]:null,value:void 0,names:Object.freeze([...r]),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 r of s)delete a[r]},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:{},r={...a},i=e(r);if(i&&typeof i=="object"&&typeof i.then=="function")throw new TypeError("Settings update mutator must be synchronous");for(let[h,u]of Object.entries(this.normalizers))Object.prototype.hasOwnProperty.call(r,h)&&typeof u=="function"&&(r[h]=u(r[h]));let n=Object.freeze(r),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(ho,"SettingsService");var yr=ho;var uo=class uo{constructor(e){this.port=qe(e,"StoragePort",Je.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(uo,"StorageService");var jr=uo;var go=class go{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,r={}){let i=new URL(t.replace(/^\/+/,""),this.baseUrl),n=await this.http.request({providerId:"webdav",method:e,url:i.href,headers:{...this.authHeaders(),...s},body:a,responseType:"text",cacheScope:"none",...r,timeout:1e4,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,a){let r=d(async(i,n,l)=>{let c=performance.now(),h="success",u,p;try{return await n()}catch(g){if(h="error",g&&typeof g=="object"){let m=g;u=typeof m.code=="string"?m.code:void 0,p=Number.isFinite(m.details?.status)?m.details.status:void 0}throw g}finally{try{a?.({stage:i,result:h,durationMs:Math.round(performance.now()-c),...l==null?{}:{bytes:l},...u?{code:u}:{},...p==null?{}:{status:p},timeoutMs:1e4})}catch{}}},"runStage");await r("建目录",()=>this.ensureFolder(e)),await r("上传",()=>this.request("PUT",`${e}/${t}`,{"Content-Type":"text/plain"},s),s.length)}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 r=1;r<s.length;r++){let i=s[r],n=d(u=>i.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(go,"WebDavClient");var po=go,mo=class mo{constructor(e,t=void 0,s=void 0){this.http=e,this.credential=t,this.settings=s}createClient(e){return new po(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 r of["url","username"])Object.prototype.hasOwnProperty.call(e,r)&&(a[r==="url"?"webDavUrl":"webDavUsername"]=String(e[r]||""))})}catch(a){throw s&&await this.credential.set("jhs_webdav_password",t.password),a}return this.getProfile()}};d(mo,"WebDavService");var Sr=mo;var Ie=Object.freeze({installationSecret:"jhs_credential_install_secret",webDavPassword:"jhs_webdav_password",javdbToken:"jhs_appAuthorization"}),fo=class fo{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(Ie.installationSecret,"")||this.legacyStorage?.getItem?.(Ie.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?Xe(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 Xe(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(),r={schema:2,id:crypto.randomUUID(),secret:a,ciphertext:await Xt(s,a)};await this.storage.setValue(e,r);let i=await this.storage.getValue(e,"");if(JSON.stringify(i)!==JSON.stringify(r)||await this.decode(i)!==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?.(Ie.installationSecret)||"",a=d(p=>this.decodeLegacy(p,s),"decodeLegacy"),r=[],i={},n=[],l=e?.snapshot?.()||{},c=this.legacyStorage?.getItem?.(Ie.javdbToken)||"",h=String(l.webDavPassword||"");for(let[p,g]of[[Ie.javdbToken,c],[Ie.webDavPassword,h]]){let m;try{m=await this.storage.getValue(p,"")}catch{r.push({key:p,code:"CREDENTIAL_MIGRATION_READ_FAILED"});continue}if(!m&&!g||m&&typeof m=="object"&&(p===Ie.javdbToken||!g||m.deleted===!0))continue;let f,v;try{f=m?await this.decode(m):await a(g),m&&typeof m=="string"&&p===Ie.javdbToken&&(f=await a(f)),v=g?await a(g):""}catch{r.push({key:p,code:"LEGACY_CREDENTIAL_UNREADABLE"});continue}try{(!m||typeof m=="string")&&await this.set(p,f)}catch{r.push({key:p,code:"CREDENTIAL_MIGRATION_WRITE_FAILED"});continue}g&&f===v&&await this.get(p)===f&&(this.cleanupTargets.set(p,f),p===Ie.webDavPassword&&(i.webDavPassword=g))}let u=await this.validateLegacyCleanup({settingKeys:Object.keys(i),settingValues:i,pageKeys:n});return t.deferCleanup||(u.settingKeys.length&&e?.update&&await e.update(p=>{for(let g of u.settingKeys)p[g]===i[g]&&delete p[g]}),await this.cleanupLegacyPageStorage(u.pageKeys,e)),{migrated:!!(c||h||s),cleanup:u,issues:r}}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(Ie.webDavPassword)&&await this.get(Ie.webDavPassword)===this.cleanupTargets.get(Ie.webDavPassword)&&t.push(s);return{...e,settingKeys:t}}async cleanupLegacyPageStorage(e=[],t=null){this.cleanupValues.clear(),this.cleanupTargets.clear()}};d(fo,"CredentialService");var xr=fo;var vo=class vo{constructor(e){this.port=qe(e,"StylePort",Je.style)}register(e,t){return this.port.register(e,t)}remove(e){return this.port.remove(e)}};d(vo,"StyleRegistry");var kr=vo;var bo=class bo{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(bo,"CommandRegistry");var Cr=bo;var wo=class wo{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 r=new D("DUPLICATE_TOKEN",`Duplicate declared dependency: ${String(a)}`,{source:"DependencyContainer"});throw this.diagnostics?.recordError?.(r),r}if(s.add(a),!this.values.has(a)){let r=new D("MISSING_DEPENDENCY",`Missing declared dependency: ${String(a)}`,{source:"DependencyContainer"});throw this.diagnostics?.recordError?.(r),r}Object.defineProperty(t,a,{value:this.values.get(a),enumerable:!0})}return Object.freeze(t),new Proxy(t,{get:d((a,r,i)=>{if((typeof r=="symbol"?Symbol.keyFor(r):null)?.startsWith("jhs.")&&!s.has(r)){let l=new D("UNDECLARED_DEPENDENCY",`Undeclared dependency access: ${String(r)}`,{source:"DependencyContainer"});throw this.diagnostics?.recordError?.(l),l}return Reflect.get(a,r,i)},"get")})}};d(wo,"DependencyContainer");var _r=wo;var yo=class yo{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=Re(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 r=this.contributionManifests.get(t);return r?.routes?.length&&!r.routes.includes(this.route)||r?.surfaces?.length&&!r.surfaces.some(i=>this.activeSurfaces().has(i))?!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(r=>this.diagnostics.updateScope(r),"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),r=Object.freeze(e.contributes.filter(n=>!this.disabled.has(n))),i=await e.activate(a,Object.freeze({scope:s,enabledContributions:r,route:this.route}));for(let n of e.providesCommands){let l=i?.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),r.forEach(n=>this.diagnostics.setContribution(n,!0)),this.diagnostics.recordStartup(e.id,performance.now()-t),Object.freeze({manifest:e,scope:s,enabledContributions:r,dispose:d(()=>{i?.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),r.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(yo,"FeatureRuntime");var $r=yo;var jo=class jo{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(jo,"ProviderRegistry");var Tr=jo;var Uc=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 ru(o,e,t={}){let s=o.cachePolicy==="none"?"none":o.cachePolicy?.[e],a={...Uc[s]||Uc.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(ru,"resolveIntegrationCachePolicy");function iu(o,e){let t=d((a,r={})=>ru(e,a,r),"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 r=String(a.providerId||"");return e.capabilities.find(i=>r.includes(String(i).split(".").pop()||""))||e.capabilities[0]},"inferCapability");return Object.freeze({request(a,r,i){let n=typeof a=="string",l=n?a:s(a),c=n?r||{}:a||{},h=n?i:r;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(iu,"createIntegrationRequestFacade");var So=class So{constructor(e,t){this.container=e,this.diagnostics=t,this.manifests=new Map,this.adapters=new Map}register(e){try{let t=J(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),r=Object.create(null);for(let l of s.requires)Object.defineProperty(r,l,{value:l===y.http?iu(a[l],s):a[l],enumerable:!0});Object.freeze(r);let i=s.createClient(r),n=s.createAdapter(i,r);return this.adapters.set(e,n),n}catch(a){throw this.diagnostics.recordError(a),a}}};d(So,"IntegrationRegistry");var Ar=So;var nu=new Set(["live","nextNavigation","manual"]),ou=new Set(["boolean","select","number","text","password","json"]),lu=new Set(["full","quick"]);function cu(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(!ou.has(t))throw new TypeError(`Setting descriptor has invalid type: ${e} (${t})`);let s=o.effect??"live";if(!nu.has(s))throw new TypeError(`Setting descriptor has invalid effect: ${e} (${s})`);let a=Array.isArray(o.surfaces)?[...new Set(o.surfaces)].filter(r=>lu.has(r)):[];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(cu,"normalizeSettingDescriptor");var xo=class xo{constructor(){this.descriptors=new Map}register(e){let t=cu(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(xo,"SettingsRegistry");var Pr=xo;function zc(o){let e={type:"boolean",effect:"live"},t="yes",s="no",a=d((i,n,l,c={})=>o.register({key:i,owner:n,label:l,...e,defaultValue:c.defaultValue??t,...c}),"toggle"),r=d((i,n,l,c)=>{let h=Number(i);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(i=>be(i,!1),"normalize")}),a("enable115Offline","OfflineFeature","115 离线下载",{description:"支持 Magnet 与 ED2K。",surfaces:["full"],section:"cloud",defaultValue:!1,normalize:d(i=>be(i,!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(i=>["ask","123","115"].includes(String(i))?String(i):"ask","normalize")}),a("enable115Match","OfflineFeature","115 文件匹配",{description:"根据当前番号查找网盘中已存在的视频。",surfaces:["full"],section:"cloud",defaultValue:!1,normalize:d(i=>be(i,!1),"normalize")}),a("enable115LoginRedirect","OfflineFeature","未登录时提供登录入口",{description:"提交失败时显示 115 登录地址。",surfaces:["full"],section:"cloud",defaultValue:!1,normalize:d(i=>be(i,!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(i=>r(i,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(i=>r(i,60,1,1440),"normalize")})}d(zc,"registerDefaultSettings");function Fc(o){let e=new rr({legacyHttp:o.legacyHttp}),t=new te("app:root",{onChange:d(Ne=>e.updateScope(Ne),"onChange")}),s=new _r(e),a=new Ya,r=new tr(o.gmRequest),i=new Xa(o.storageForage,o.localStorage,o.gmGetValue,o.gmSetValue,o.gmDeleteValue),n=new er(o.layer),l=new Za,c=new nr({localOrigins:o.localOrigins}),h=new cr(a),u=new jr(i),p=new sr({diagnostics:e,storage:u}),g=new ir(n),m=new kr(l),f=new Pr;zc(f);let v=new yr(u,{afterPersist:d(async(Ne,z)=>{o.legacyStorage?.invalidateSettingCache?.(),await o.eventBus?.emit?.("settings-changed",{changedNames:z,source:"service"})},"afterPersist"),normalizers:f.normalizers()}),b=new or(r,c,{diagnostics:e,cache:p,settings:v});e.setNetworkController(b);let w=new xr(u,o.localStorage),S=new Sr(b,w,v);t.listen(v,"settings.changed",Ne=>{if(!(Ne.detail?.names??[]).includes("trustedLocalOrigins"))return;let Z=v.snapshot().trustedLocalOrigins;c.replaceLocalOrigins(Array.isArray(Z)?Z:[])}),o.eventBus&&t.addCleanup(o.eventBus.on("settings-changed",async(Ne,z)=>{let Z=z.originId!==o.eventBus.originId,re=z.originId===o.eventBus.originId&&z.payload?.source==="legacy";!Z&&!re||(o.legacyStorage?.invalidateSettingCache?.(),await v.refresh())})),typeof window<"u"&&t.listen(window,"pageshow",async()=>{o.legacyStorage?.invalidateSettingCache?.(),await v.refresh()});let j=new pr({scope:t,settings:v}),x=new Cr,k=new Tr(e),_=new Ar(s,e),E=new hr(_),L=new ar(_,p),N=new lr(_),A=new mr(_),O=new gr(_),U=new dr(k,_),H=new fr(k,_),Q=new vr(_,u),se=new br(_),ge=new wr(_),De=new ur(k,_);s.register(Y.navigation,a).register(Y.http,r).register(Y.storage,i).register(Y.dialog,n).register(Y.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,N).register(y.review,A).register(y.related,O).register(y.magnet,U).register(y.screenshot,H).register(y.offline,De).register(y.translation,Q).register(y.subtitle,se).register(y.account,ge).register(Qe.command,x).register(Qe.provider,k).register(Qe.integration,_).register(Qe.settings,f),o.hostAdapter&&s.register(Y.host,o.hostAdapter),o.hostAdapters?.javdb&&s.register(Y.javdbHost,o.hostAdapters.javdb),o.hostAdapters?.javbus&&s.register(Y.javbusHost,o.hostAdapters.javbus);let ot=new $r({container:s,commands:x,diagnostics:e,disabled:o.disabled,site:o.site,route:o.route});return s.register(Qe.feature,ot),Object.freeze({rootScope:t,container:s,ports:Object.freeze({navigationPort:a,httpPort:r,storagePort:i,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:N,review:A,related:O,magnet:U,screenshot:H,translation:Q,subtitle:se,account:ge,offline:De}),registries:Object.freeze({commands:x,providers:k,integrations:_,settings:f,features:ot})})}d(Fc,"createAppContext");var Jk=Object.freeze({censored:"censored",uncensored:"uncensored"});function Ir(o){if(typeof o.carNum!="string"||!o.carNum)throw new TypeError("MovieRef.carNum is required");return Object.freeze({...o})}d(Ir,"defineMovieRef");function Vt(o){if(typeof o.carNum!="string"||!o.carNum)throw new TypeError("MovieDetail.carNum is required");return Object.freeze({...o})}d(Vt,"defineMovieDetail");function ko(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(ko,"resolveDocument");function Co(o,e="https://123av.com"){let t=new Map;if(typeof o?.find!="function"){for(let a of ko(o).querySelectorAll(".card")){let r=a.querySelector('a.card__link[href*="/cn/v/fc2-ppv-"]'),i=r?.getAttribute("href"),n=r?.textContent?.trim()??"",l=n.match(/FC2-PPV-(\d+)/i);if(!i||!l)continue;let c=`FC2-${l[1]}`,h=new URL(i,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,r)=>{let i=s(r),n=i.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:i.find("img.card__img[src]").first().attr("src")||"",carNum:u,href:p.href,title:c.replace(/^FC2-PPV-\d+\s*[—–-]\s*/i,"").trim(),preview:i.find(".card__poster[data-preview]").first().attr("data-preview")||null})})),[...t.values()]}d(Co,"parse123AvCards");function Vc(o){let e=new Map;return o.flat().forEach((t=>e.set(t.carNum,t))),[...e.values()]}d(Vc,"merge123AvCards");function Hc(o,e="https://123av.com"){if(typeof o?.find!="function"){let r=ko(o),i=r.querySelector('a[rel="last"]')?.getAttribute("href");if(i){let c=Number.parseInt(new URL(i,e).searchParams.get("page")??"",10);if(Number.isFinite(c))return c}let n=Number.parseInt(r.querySelector("input.pager__input[max]")?.getAttribute("max")??"",10);if(Number.isFinite(n))return n;let l=r.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 r=Number.parseInt(new URL(t,e).searchParams.get("page")??"",10);if(Number.isFinite(r))return r}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(Hc,"parse123AvSourceMaxPage");function qc(o,e){let t=new URL(e).pathname.match(/fc2-ppv-(\d+)/i),s=t?t[1]:null,a=typeof o?.find=="function"?null:ko(o),r=a?a.querySelector("h1.watch__title")?.textContent?.trim()??"":o.find("h1.watch__title").first().text().trim(),i=s?r.replace(new RegExp(`^FC2-PPV-${s}\\s*[—–-]\\s*`,"i"),"").trim():r,l=(a?a.body?.textContent??"":o.find("body").text()).match(/发布日期\s*(\d{4}-\d{2}-\d{2})/)?.[1]||"";return{id:s,publishDate:l,title:i,moviePoster:null}}d(qc,"parse123AvVideoInfo");var Rr="https://123av.com";function du(o){try{let e=new URL(String(o||Rr));return e.protocol!=="https:"?Rr:e.origin}catch{return Rr}}d(du,"normalizeBaseOrigin");function hu(o,e=null){let t=d(()=>du(e?.snapshot().av123Url),"baseOrigin"),s=d((a,r,i="movie.detail")=>{let n=new URL(a).origin,l=n===Rr;return o.request({providerId:"av123",capability:i,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}},r)},"request");return Object.freeze({contracts:["MovieRef","MovieDetail"],origin:t,searchUrl(a){let r=ee(a?.carNum);return r?`${t()}/cn/search?keyword=${encodeURIComponent(r)}`:null},detailUrl(a){let r=ee(a.carNum)?.match(/^FC2-(\d+)$/)?.[1];return a.url?new URL(a.url).href:r?`${t()}/cn/v/fc2-ppv-${r}`:null},matchesUrl(a){try{let r=new URL(a);return r.origin===t()||/^\/cn\/v\/fc2-ppv-\d+\/?$/i.test(r.pathname)}catch{return!1}},async listCatalog(a={},r={}){let i=Math.max(1,Number(a.page)||1),n=String(a.keyword||"").trim(),c=(n?[i]:[i*2-1,i*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,r.scope,n?"movie.search":"movie.catalog"))),u=h.map((m,f)=>Co(m.data,m.finalUrl||c[f])),p=Vc(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?Hc(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,r={}){let i=ee(a.carNum);if(!i)return null;let n=this.searchUrl({carNum:i});if(!n)return null;let l=await s(n,r.scope,"movie.search"),c=Co(l.data,l.finalUrl||n).find(h=>ee(h.carNum)===i);return c?Ir({carNum:i,url:c.href,providerId:"av123"}):null},async getDetail(a,r={}){let i=ee(a.carNum),n=i?.match(/^FC2-(\d+)$/)?.[1];if(!i||!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,r.scope),h=qc(c.data,c.finalUrl||l);if(!h.title)throw new TypeError("123AV detail is malformed");return Vt({carNum:i,title:h.title,releaseDate:h.publishDate||null,url:c.finalUrl||l,providerId:"av123"})}})}d(hu,"create123AvAdapter");var Jc=J({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=>hu(o.http,o.settings),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.search":"public-7d","movie.detail":ke.externalDetail,"movie.catalog":"public-7d"},quality:"silver"});function uu(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(uu,"resolveDocument");function Wc(o,e){let t=uu(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(Wc,"parseDmmPreview");function Kc(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,""),r=t.toLowerCase().replace(/-/g,"");return Object.freeze(o.result.items.flatMap(i=>{let n=String(i?.content_id??""),l=String(i?.maker_product??"");return!n.toLowerCase().includes(r)&&l.toLowerCase()!==s&&!n.toLowerCase().includes(a)?[]:[Object.freeze({serviceCode:String(i.service_code??""),floorCode:String(i.floor_code??""),contentId:n,pageUrl:new URL(String(i.URL)).href})]}).slice(0,2))}d(Kc,"parseDmmItemCandidates");function Gc(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(r){throw new we("dmm","PARSE_ERROR",`解析播放器脚本 JSON 失败: ${r instanceof Error?r.message:String(r)}`,{cause:r,url:e})}if(!Array.isArray(s))throw new we("dmm","PARSE_ERROR","解析画质链接失败: bitrates 字段不是一个数组或不存在",{url:e});let a={};for(let r of s){let i=r?.src;if(typeof i!="string"||!i.endsWith(".mp4"))continue;let n=new URL(i,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(Gc,"parseDmmPlayerSources");var _o=["dmm.co.jp","dmm.com"];function pu(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 Wc(a.data,a.finalUrl||s.href)},async getPreviewForMovie(e,t={}){let s=String(e.carNum),a=s.replace(/-/g,""),r=[s.replace("-","00"),s,a],i=this.searchUrl(e),n=[],l=null,c=!1;for(let p of r){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=Kc(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:i,searchUrl:i,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 Gc(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?i:n[0].pageUrl,searchUrl:i,matchType:n.length>1?"multiple":"single"})}})}d(pu,"createDmmAdapter");var Qc=J({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=>pu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.preview":"none"},quality:"silver"});var Yc=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 Zc(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(Zc,"siteDefinition");function gu(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"),r=[];for(let i of a.querySelectorAll(e.itemSelector)){let n=e.textSelector?i.querySelector(e.textSelector):i;if((e.titleAttribute?i.getAttribute("title")||"":n?.textContent?.trim()||"").toLowerCase().includes(t.toLowerCase()))if(e.directDetail)r.push(new URL(`/${encodeURIComponent(t)}`,`${s}/`).href);else{let c=e.hrefSelector?i.querySelector(e.hrefSelector):i,h=c?.getAttribute("href");if(!h)throw new D("PARSE_ERROR","外部站点结果缺少链接",{source:e.id});r.push(new URL(h,`${s}/`).href)}}return Object.freeze([...new Set(r)])}d(gu,"parseExternalSiteResults");function mu(o){return Object.freeze({contracts:["ExternalSiteResult"],getSites(e={}){return Object.freeze(Yc.map(t=>Zc(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=Yc.find(u=>u.id===e);if(!a)throw new D("UNSUPPORTED",`未知外部站点:${e}`,{source:"external-sites"});let r=Zc(a,s.settings||{}),i=r.searchUrl(t),n=new URL(i),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:i,responseType:"text",urlPolicy:c},s.scope);return Object.freeze({searchUrl:i,matches:gu(h.data,a,t,r.baseUrl)})}})}d(mu,"createExternalSitesAdapter");var Xc=J({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=>mu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.external-sites":"public-1d","navigation.external":"none"},quality:"silver"});function ed(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(ed,"resolveDocument");function td(o,e){let t=new URL(e).pathname.match(/(?:articles?|videos?)\/(\d+)/i)?.[1],s=ee(t?`FC2-${t}`:""),a=ed(o).querySelector("h1")?.textContent?.trim()??"";if(!s||!a)throw new TypeError("FC2PPVDB detail is malformed");return Vt({carNum:s,title:a,url:new URL(e).href})}d(td,"parseFc2PpvDbDetail");function sd(o,e){let t=ed(o),s=new URL(e),a=[...t.querySelectorAll("div")],r=a.find(h=>h.textContent?.trim().startsWith("女優:")),i=a.find(h=>h.textContent?.trim().startsWith("販売者:")),n=[...r?.querySelectorAll("a[href]")??[]].map(h=>Object.freeze({name:h.textContent?.trim()||"",url:new URL(h.getAttribute("href")||"",s).href})).filter(h=>h.name),l=i?.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(sd,"parseFc2PpvDbPeople");function fu(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,r="movie.detail")=>o.request({capability:r,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 r=e(s),i=await t(r,a.scope,"movie.detail");return td(i.data,i.finalUrl||r.href)},async getPeople(s,a={}){let r=e(s),i=await t(r,a.scope,"movie.credits");return sd(i.data,i.finalUrl||r.href)}})}d(fu,"createFc2PpvDbAdapter");var ad=J({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=>fu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.detail":ke.externalDetail,"movie.credits":ke.externalDetail},quality:"silver"});function rd(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 r=new URL(a.getAttribute("src")||"",e);r.protocol==="https:"&&s.add(r.href)}return Object.freeze([...s].map(a=>Object.freeze({url:a,providerId:"fc2content"})))}d(rd,"parseFc2ContentImages");function vu(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}/`,r=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 rd(r.data,r.finalUrl||a)}})}d(vu,"createFc2ContentAdapter");var id=J({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=>vu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.images":ke.externalDetail},quality:"silver"});function nd(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(nd,"parseGoogleTranslation");var bu="https://translate-pa.googleapis.com/v1/translate";function wu(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(bu);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 nd(a.data)}})}d(wu,"createGoogleTranslateAdapter");var od=J({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=>wu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"text.translate":"none"},quality:"silver"});var $o=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 yu(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,r]of Object.entries(t))if(!(!r||typeof r!="object"||Array.isArray(r)))for(let[i,n]of Object.entries(r)){if(typeof n!="string")continue;let l=i.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(yu,"parseGfriendsCatalog");function ju(o){return Object.freeze({contracts:["ActorAvatar"],getSources:d(()=>Object.freeze($o.map(e=>Object.freeze({id:e.id,name:e.name,recommended:e.recommended}))),"getSources"),async searchAvatars(e,t={}){let s=$o.find(n=>n.id===(t.sourceId||$o[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),r=yu(a.data,s.contentBaseUrl),i=new Set;return e.map(n=>String(n).toLowerCase().trim()).filter(Boolean).forEach(n=>r.get(n)?.forEach(l=>i.add(l))),Object.freeze([...i])}})}d(ju,"createGfriendsAdapter");var ld=J({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=>ju(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"person.avatar-search":"public-7d"},quality:"silver"});var cd=J({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 Su="https://api.imgur.com/3/image",xu="d70305e7c3ac5c6",ku=Object.freeze({trustClass:"builtin-public",hosts:["imgur.com","google.com","yandex.ru"]}),Cu=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 _u(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(_u,"parseImgurUpload");function $u(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 r=0;r<t.length;r+=1)s[r]=t.charCodeAt(r);let a=new FormData;return a.append("image",new Blob([s],{type:e[1]}),"jhs-image"),a}d($u,"dataUrlToFormData");function Tu(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:Su,body:$u(e),headers:{Authorization:`Client-ID ${xu}`},responseType:"json",urlPolicy:ku,timeout:3e4},t.scope);return _u(s.data)},createTargets(e){let t=encodeURIComponent(e);return Object.freeze(Cu.map(s=>Object.freeze({id:s.id,name:s.name,url:s.urlTemplate.replace("{imageUrl}",t),iconUrl:s.iconUrl})))}})}d(Tu,"createImageSearchAdapter");var dd=J({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=>Tu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"image.upload":"none","image.search-targets":"none"},quality:"silver"});var hd=0,Er="";function To(){let o=Math.floor(Date.now()/1e3);if(Er&&o-hd<=20)return Er;let e=globalThis.md5;if(typeof e!="function")throw new Error("Missing userscript vendor runtime: md5");return hd=o,Er=`${o}.lpw6vgqzsp.${e(`${o}71cf27bb3c0bcdf207b64abecddc970098c7421ee7203b9cdae54478478a199e7d5a6e1a57691123c1a931c057842fb73ba3b3c83bcd69c17ccf174081e3d8aa`)}`,Er}d(To,"createJavDbSignature");var ud="https://jdforrepam.com";function Au(o,e=To,t=null){let s=d(r=>{let i=new URL(r).origin,n=new URL(r).hostname;return n==="javdb.com"||n.endsWith(".javdb.com")?{trustClass:"builtin-public",hosts:["javdb.com"],expectedOrigin:i}:{trustClass:"custom-public",expectedOrigin:i}},"hostPolicy"),a=d(async(r,i,n={},l={},c="movie.detail")=>{let h=new URL(r,ud);return Object.entries(i).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(r,i={}){let n=new URL("/api/v1/sessions",ud);Object.entries({username:r.username,password:r.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"]}},i.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(r,i={}){let n=new URL(r.baseUrl||"https://javdb.com").origin,l=new URL(`/actors/${encodeURIComponent(r.actorId)}?t=d`,n),c=await o.request({providerId:"javdb-host",capability:"actor.movies",method:"GET",url:l.href,responseType:"text",urlPolicy:s(n)},i.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(r,i={}){let n=new URL(r.baseUrl||"https://javdb.com").origin,l=new URL(r.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)},i.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(r,i={}){let n=new URL(r.baseUrl||"https://javdb.com").origin,l=new URL(`/actors/${encodeURIComponent(r.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":r.csrfToken},urlPolicy:s(n)},i.scope);return Object.freeze({success:typeof c.data=="string"&&c.data.includes("removeClass")})},async resolveMovie(r,i={}){let n=ee(r.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"},i,{"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(r,i={}){let n=String(r.movieId||"").trim();if(!n)throw new TypeError("JavDB movie id is required");let l=await a(`/api/v4/movies/${encodeURIComponent(n)}`,{},i,{},"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(r,i={}){let n=String(r.movieId||"").trim();if(!n)return[];let l=await a(`/api/v1/movies/${encodeURIComponent(n)}/magnets`,{},i,{},"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(r={}){let i=await a("/api/v1/rankings/playback",{period:r.period||"daily",filter_by:r.filter||"high_score"},r,{},"movie.ranking");if(!Array.isArray(i?.data?.movies))throw new Error(i?.message||"JavDB ranking response is invalid");return i.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(r,i={}){let n=String(r.movieId||"").trim();if(!n)return[];let l=await a(`/api/v1/movies/${encodeURIComponent(n)}/reviews`,{page:i.page??1,sort_by:"hotly",limit:i.limit??20},i,{},"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(r,i={}){let n=String(r.movieId||"").trim();if(!n)return[];let l=await a("/api/v1/lists/related",{movie_id:n,page:i.page??1,limit:i.limit??20},i,{},"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(Au,"createJavDbAdapter");var pd=J({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,Y.javdbHost],createClient:d(o=>Object.freeze({http:o[y.http],hostAdapter:o[Y.javdbHost]}),"createClient"),createAdapter:d(o=>Au(o.http,To,o.hostAdapter),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.search":"public-7d","movie.detail":ke.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 gd(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(gd,"resolveDocument");function Pu(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=[...gd(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(Pu,"readMovieRef");function Iu(o,e){let t=Pu(o,e);if(!t)throw new TypeError("JavBus movie identifier is missing");return Ir({carNum:t,url:new URL(e).href})}d(Iu,"parseJavBusMovieRef");function md(o,e){let t=Iu(o,e),s=typeof o?.find=="function"?null:gd(o),a=s?s.querySelector("h3")?.textContent?.trim()||t.carNum:o.find("h3").first().text().trim()||t.carNum,r=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 Vt({...t,title:a,coverUrl:r?new URL(r,e).href:null,providerId:"javbus"})}d(md,"parseJavBusMovieDetail");function Ru(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,r=await o.request({providerId:"javbus",capability:"movie.detail",method:"GET",url:a,responseType:"text",urlPolicy:{trustClass:"builtin-public",hosts:["javbus.com"]}},t.scope);return md(r.data,r.finalUrl||a)},async getImages(e,t={}){let s=await this.getDetail(e,t);return s.coverUrl?[Object.freeze({url:s.coverUrl,providerId:"javbus"})]:[]}})}d(Ru,"createJavBusAdapter");var fd=J({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=>Ru(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.detail":ke.externalDetail,"movie.images":ke.externalDetail},quality:"silver"});function Eu(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),r=await e(a,s.scope),i=Tc(r.data,t.carNum,r.finalUrl||a);if(!i.length)return[];for(let n of i)try{let l=await e(n,s.scope),c=Ac(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(Eu,"createJavStoreAdapter");var vd=J({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=>Eu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"movie.images":"screenshot-7d"},quality:"silver"});var bd=J({id:"javtrailers",trustClass:"builtin-public",hosts:["javtrailers.com"],capabilities:["movie.preview"],requires:[Y.http,y.urlPolicy],createClient:d(()=>Object.freeze({id:"javtrailers"}),"createClient"),createAdapter:d(()=>Object.freeze({contracts:["MoviePreview"]}),"createAdapter"),createHostAdapter:null,cachePolicy:"none",quality:"bronze"});var Du="https://115.com",Nu=Object.freeze({trustClass:"builtin-public",hosts:["115.com"]});function Lu(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(Lu,"parsePayload");function Mu(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(Mu,"classify115OfflineError");function Bu(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(Bu,"normalize115SearchResults");function Ou(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:Nu},s.scope),"request");return Object.freeze({contracts:["AccountStatus","CloudFile","OfflineSubmission"],homeUrl:Du,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 r=await e(a.href,{capability:"file.search",scope:s.scope,force:s.force});return Bu(r.data)},async submit(t,s={}){if(!/^magnet:/i.test(t)&&!/^ed2k:/i.test(t))throw new D("UNSUPPORTED","Unsupported offline URL",{source:"one115"});let r=(await e(`https://115.com/?ct=offline&ac=space&_=${Date.now()}`,{capability:"offline.submit",scope:s.scope})).data;if(!r?.sign)throw new D("AUTH_REQUIRED","115 未登录或离线空间信息获取失败",{source:"one115"});let i=new URLSearchParams({url:t,wp_path_id:s.folderId||"",uid:String(r.uid||""),sign:r.sign,time:String(r.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:i,responseType:"text",headers:{"Content-Type":"application/x-www-form-urlencoded"}}),l=Lu(n.data);if(!l||l.state===!1||l.state===0){let c=String(l?.error_msg||l?.error||l?.msg||"115 离线任务创建失败"),h=Mu(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 r=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:r,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(Ou,"createOne115Adapter");var wd=J({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=>Ou(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"account.status":"none","file.search":"none","file.rename":"none","offline.submit":"none"},quality:"silver"});var Uu=Object.freeze({trustClass:"builtin-public",hosts:["123pan.com"]});function yd(o){let e=new Uint32Array(256);for(let s=0;s<256;s+=1){let a=s;for(let r=0;r<8;r+=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(yd,"crc32");function zu(){let o=new Uint32Array(1);return crypto.getRandomValues(o),o[0]%1e7}d(zu,"secureNonce");function Fu(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??zu(),a=e.now??new Date,r=new Date(a.getTime()+6e4*a.getTimezoneOffset()+288e5),n=[...`${r.getFullYear()}${String(r.getMonth()+1).padStart(2,"0")}${String(r.getDate()).padStart(2,"0")}${String(r.getHours()).padStart(2,"0")}${String(r.getMinutes()).padStart(2,"0")}`].map(p=>t[Number(p)]).join(""),l=yd(n),c=Math.floor(r.getTime()/1e3),h=new URL(o),u=yd(`${c}|${s}|${h.pathname}|web|3|${l}`);return h.searchParams.set(String(l),`${c}-${s}-${u}`),h.href}d(Fu,"signPan123Url");function jd(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(jd,"parsePayload");function Sd(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(Sd,"assertSuccess");function Vu(o,e={}){let t=d(async(s,a,r,i,n)=>{let l=Fu(`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 ${r}`,"App-Version":"3",platform:"web",Origin:"https://yun.123pan.com",Referer:"https://yun.123pan.com/"},urlPolicy:Uu},i)},"request");return Object.freeze({contracts:["OfflineResolvedResource","OfflineSubmission"],homeUrl:"https://yun.123pan.com",async resolve(s,a={}){let{token:r,scope:i}=a;if(!r)throw new D("AUTH_REQUIRED","尚未同步 123 授权",{source:"pan123"});let n=await t("/b/api/v2/offline_download/task/resolve",{urls:s},r,i,"offline.resolve"),l=Sd(jd(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:r,scope:i}=a;if(!r)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}]},r,i,"offline.submit");return Sd(jd(c.data),"提交"),Object.freeze({fileCount:n.length,totalSize:l})},async submit(s,a={}){let r=await this.resolve(s,a);return this.submitResolved(r,a)}})}d(Vu,"createPan123Adapter");var xd=J({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=>Vu(o.http,{getTimeout:d(()=>Number(o.settings.snapshot().httpTimeout??5e3),"getTimeout")}),"createAdapter"),createHostAdapter:null,cachePolicy:{"offline.resolve":"none","offline.submit":"none"},quality:"silver"});function Hu(){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(Hu,"createSubtitleCatAdapter");var kd=J({id:"subtitlecat",trustClass:"builtin-public",hosts:["subtitlecat.com"],capabilities:["subtitle.search"],requires:[],createClient:d(()=>Object.freeze({id:"subtitlecat"}),"createClient"),createAdapter:d(()=>Hu(),"createAdapter"),createHostAdapter:null,cachePolicy:"none",quality:"bronze"});var Cd=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 _d(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(_d,"normalizeMagnet");function qu(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(r=>{if(r.textContent?.includes("置顶"))return[];let i=r.querySelector("td:nth-child(2) a"),n=i?.getAttribute("title")||i?.textContent?.trim()||"";if(!n.toLowerCase().includes(e.toLowerCase()))return[];let l=_d({title:n,magnet:r.querySelector('td:nth-child(3) a[href^="magnet:"]')?.getAttribute("href"),size:r.querySelector("td:nth-child(4)")?.textContent?.trim(),date:r.querySelector("td:nth-child(5)")?.textContent?.trim(),seeders:r.querySelector("td:nth-child(6)")?.textContent?.trim(),leechers:r.querySelector("td:nth-child(7)")?.textContent?.trim()},t);return l?[l]:[]}))}d(qu,"parseTorrentSource");function Ju(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),r=Number.isFinite(a)?new Date(1e3*a).toISOString().slice(0,10):"",i=_d({title:s.name,magnet:`magnet:?xt=urn:btih:${s.hash}`,size:`${(Number(s.size)/1073741824).toFixed(2)} GB`,date:r},"btsow");return i?[i]:[]}))}d(Ju,"parseBtsowSource");function Wu(o){let e=d(t=>Cd.find(s=>s.id===t),"find");return Object.freeze({contracts:["Magnet","MagnetSource"],getSources:d(()=>Object.freeze(Cd.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 r=e(t);if(!r)throw new D("UNSUPPORTED",`未知磁力来源:${t}`,{source:"torrent-sources"});return`${new URL(a.baseUrl||r.baseUrl).origin}${r.searchPath(s)}`},async search(t,s,a={}){let r=e(t);if(!r)throw new D("UNSUPPORTED",`未知磁力来源:${t}`,{source:"torrent-sources"});let i=new URL(a.baseUrl||r.baseUrl).origin,l=new URL(i).hostname!==r.domain?{trustClass:"custom-public",expectedOrigin:i}:{trustClass:"builtin-public",hosts:[r.domain],expectedOrigin:i};if(r.id==="btsow"){let u=await o.request({capability:"magnet.search",providerId:"magnet:btsow",method:"POST",url:`${i}/search`,body:JSON.stringify([{search:s},50,1]),headers:{"Content-Type":"application/json"},responseType:"json",urlPolicy:l},a.scope);return Ju(u.data)}let c=`${i}${r.searchPath(s)}`,h=await o.request({capability:"magnet.search",providerId:`magnet:${r.id}`,method:"GET",url:c,responseType:"text",urlPolicy:l},a.scope);return qu(h.data,s,r.id)}})}d(Wu,"createTorrentSourcesAdapter");var $d=J({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=>Wu(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 Td(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"),r=t.querySelector('a[title="身長"]')?.closest("tr")?.querySelector("td"),i=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&&!r&&!n)throw new TypeError("Wikipedia actress information is missing");let c=Number.parseInt(St(a?.textContent??""),10),h=St(r?.textContent??"").split(" ")[0],u=St(i?.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(Td,"parseWikipediaActressInfo");function Ku(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 Td(a.data,a.finalUrl||s)}catch(r){if(r instanceof TypeError&&/actress information is missing/.test(r.message))return null;throw r}}})}d(Ku,"createWikipediaAdapter");var Ad=J({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=>Ku(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"person.actress-info":ke.externalDetail},quality:"silver"});function Pd(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(Pd,"parseXunleiSubtitles");var Id=["xunlei.com"];function Gu(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 r=await o.request({providerId:"xunlei",capability:"subtitle.search",method:"GET",url:a.href,responseType:"json",urlPolicy:{trustClass:"builtin-public",hosts:Id}},t.scope);return Pd(r.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(Gu,"createXunleiAdapter");var Rd=J({id:"xunlei",trustClass:"builtin-public",hosts:Id,capabilities:["subtitle.search","subtitle.download"],requires:[y.http],createClient:d(o=>Object.freeze({http:o[y.http]}),"createClient"),createAdapter:d(o=>Gu(o.http),"createAdapter"),createHostAdapter:null,cachePolicy:{"subtitle.search":"public-1d","subtitle.download":"public-1d"},quality:"silver"});var Ed=Object.freeze([Jc,Qc,Xc,ad,id,ld,od,cd,dd,pd,fd,vd,bd,wd,xd,kd,$d,Ad,Rd]);function Qu(o,e){let t=o.close;o.close=function(a){let r=t.call(this,a);return e?.releaseEscClose?.(a),setTimeout(()=>{let i=document.querySelectorAll(".layui-layer-shade").length;document.documentElement.style.overflow=i>0?"hidden":""},10),r};let s=o.open;o.open=function(a={}){a=kt(a,e);let r=a.success;return s.call(this,{...a,success(i,n){typeof r=="function"&&r.call(this,i,n),e.setupEscClose(n)}})}}d(Qu,"patchLayerRuntime");function Yu(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(Yu,"importVendorStyles");async function Zu(o){let e=await o.getSetting("disabledPlugins","[]"),t=Ge(e),s=$t(t);return{migrated:s,needsMigration:JSON.stringify(t)!==JSON.stringify(s)}}d(Zu,"readDisabledPluginSettings");async function Xu(o,e,t,s,a,r,i=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(r||"")&&(n.videoMuted=r==="yes");for(let h of i?.cleanup?.settingKeys||[])n[h]===i.cleanup.settingValues?.[h]&&delete n[h]})}d(Xu,"persistBootstrapMigration");async function ep(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(ep,"resolveLocalOrigins");async function Dd(){try{if(Ct(window.location).isJavDB){let E=Io(window.location);if(E)return void window.location.replace(E)}let o=performance.now(),e=globalThis.__jhsBrowserDiagnostics,t=d(E=>e&&((e.bootstrapPhases||(e.bootstrapPhases={}))[E]=performance.now()-o),"markPhase"),s=Ro(window.location),a=ll(),r=nl(),{utils:i,gmHttp:n,storageManager:l,stateService:c}=il(r);t("legacy-runtime"),Object.assign(globalThis,{utils:i,gmHttp:n,storageManager:l,stateService:c,jhsEventBus:r}),["blacklist-rules-changed","filter-rules-changed","legacy-refresh"].forEach((E=>r.on(E,(()=>l._invalidateCache())))),r.on("car-state-changed",()=>l._invalidateCache(l.car_list_key)),Qu(a.layer,i),await Promise.resolve(),Yu(i),t("pre-settings");let h=await Zu(l),u=h.migrated,p=await ep(l),g=new $s,m=new _s,f=M?g:B?m:null,v=f?.detectRoute()??"other",b=Fc({gmRequest:globalThis.GM_xmlhttpRequest,gmGetValue:globalThis.GM_getValue,gmSetValue:globalThis.GM_setValue,gmDeleteValue:globalThis.GM_deleteValue,legacyHttp:n,legacyStorage:l,eventBus:r,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"),Vo(b.services.styles,Ho()),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"),x=localStorage.getItem("jhs_videoMuted");w.cleanup=await b.services.credential.validateLegacyCleanup(w.cleanup),await Xu(b.services.settings,h,p,S,j,x,w),await b.services.credential.cleanupLegacyPageStorage(w.cleanup?.pageKeys,b.services.settings),t("settings-migration");let k=ol(b.rootScope,{clogMsgCount:b.services.settings.snapshot().clogMsgCount});t("logger"),Oo(b.rootScope),zo(b.rootScope),t("theme-ui"),b.services.diagnostics.setBrowserMetadata({userAgent:navigator.userAgent,platform:navigator.platform,...globalThis.__jhsBrowserTestMetadata??{}}),Object.assign(globalThis,k),w.issues?.length&&k.show.info("部分旧凭证未能安全迁移,已保留原数据,请重新保存对应凭证"),p.notice&&k.show.info(p.notice);let _=new ys({diagnostics:b.services.diagnostics});for(let E of Ed)b.registries.integrations.register(E);for(let E of vl)b.registries.features.register(E);return Nc(_,b.registries.features,s.site),t("registry"),Lc({pluginManager:_,utils:i,gmHttp:n,storageManager:l,stateService:c,jhsEventBus:r,clog:k.clog,show:k.show,loading:k.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(Ht(b.services.settings.snapshot().themeMode))]),t("plugin-css"),M&&/(^|;)\s*locale\s*=\s*en\s*($|;)/i.test(document.cookie)&&k.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(Dd,"bootstrapJhs");function Nd(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(Nd,"mountBootstrapError");Dd().catch(Nd);})();