From ad7b03fcc9399e45eb0cc9eabb17f2a7fcd25acb Mon Sep 17 00:00:00 2001 From: HxZou <2664007056@qq.com> Date: Tue, 28 Jul 2026 19:26:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=B8=BB=E4=BF=A1=E6=81=AF=E6=B5=81?= =?UTF-8?q?=E6=9C=89=E7=95=8C=E6=A0=91=E7=8A=B6=E8=AF=84=E8=AE=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在父回复下支持可配置的 2–5 层 DOM 树嵌套,设置中与「展开二级回复」联动;修复空壳展开按钮与引导线拼接,并同步相关手册与功能目录(changelog 留待发版)。 --- dist/awesome-linuxdo-reader.build.json | 14 +- dist/awesome-linuxdo-reader.user.js | 648 +- docs/guide/thread-context.md | 30 +- docs/public/feature-catalog.json | 10 +- docs/settings/motion-and-other.md | 8 +- docs/settings/other.md | 8 +- docs/settings/reference.md | 4 +- work/main.css | 8686 +-- work/main.js | 78854 ++++++++++++----------- 9 files changed, 44426 insertions(+), 43836 deletions(-) diff --git a/dist/awesome-linuxdo-reader.build.json b/dist/awesome-linuxdo-reader.build.json index 5d49c2a..b2b6cf0 100644 --- a/dist/awesome-linuxdo-reader.build.json +++ b/dist/awesome-linuxdo-reader.build.json @@ -2,18 +2,18 @@ "schemaVersion": 1, "source": { "path": "work/main.js", - "bytes": 1817184, - "sha256": "4068430857320cc01f6466b46b3544a72b5f889a9eae24cff60fa772d6c2ffac" + "bytes": 1880144, + "sha256": "d54147448ed6c2105c86d4454af4c58fd093394e1dc91fcd05e5a32664ecfa9b" }, "metadata": { - "bytes": 2810, - "sha256": "40e714a6105f6803b6fad8a2f7e68ae4c7dff952d4b718ac3d0c0cdd10c27cfa" + "bytes": 2859, + "sha256": "d10e067d36c84712b9151877ba81c186250e212a2a671a0792dba175ceb531fe" }, "artifact": { "path": "dist/awesome-linuxdo-reader.user.js", - "bytes": 963590, - "gzipBytes": 324687, - "sha256": "d66868fec40828ae46aa5fa076a3ffa9548e44bc12c0b7bced2d8f0b1e0a6d19" + "bytes": 974395, + "gzipBytes": 327816, + "sha256": "3bdc2133c7246819505756d99bb12d34ae6b96504babbfe278aa30581ea3052f" }, "compiler": { "name": "esbuild", diff --git a/dist/awesome-linuxdo-reader.user.js b/dist/awesome-linuxdo-reader.user.js index 0e3be50..0f1984b 100644 --- a/dist/awesome-linuxdo-reader.user.js +++ b/dist/awesome-linuxdo-reader.user.js @@ -1,75 +1,75 @@ // ==UserScript== -// @name Awesome LinuxDo Reader -// @name:zh-CN 更流畅的 LinuxDo 阅读器 -// @namespace https://github.com/sunbigfly/awesome-linuxdo-reader -// @version 0.1.16 -// @license MIT -// @description 为 LINUX DO 深度适配、全面兼容标准 Discourse 站点的沉浸式增强阅读器,支持长帖上下文、原站互动、非中文正文翻译、自定义站点与个性布局。 -// @description:en Deeply adapted for LINUX DO and compatible with standard Discourse sites, with threaded reading, native interactions, body translation, custom sites, and personalized layouts. -// @author sunbigfly -// @homepageURL https://github.com/sunbigfly/awesome-linuxdo-reader -// @supportURL https://github.com/sunbigfly/awesome-linuxdo-reader/issues -// @match https://linux.do/* -// @match https://community.brave.com/* -// @match https://devforum.roblox.com/* -// @match https://community.openai.com/* -// @match https://community.home-assistant.io/* -// @match https://forum.cfx.re/* -// @match https://community.spiceworks.com/* -// @match https://forum.arduino.cc/* -// @match https://discussions.unity.com/* -// @match https://community.cloudflare.com/* -// @match https://forums.unrealengine.com/* -// @match https://forum.obsidian.md/* -// @match https://forum.cursor.com/* -// @match https://forum.godotengine.org/* -// @match https://community.n8n.io/* -// @match https://forum.mikrotik.com/* -// @match https://meta.discourse.org/* -// @match https://discuss.python.org/* -// @match https://forums.swift.org/* -// @match https://discourse.julialang.org/* -// @match https://users.rust-lang.org/* -// @match https://*/* -// @icon https://cdn3.ldstatic.com/optimized/4X/6/a/6/6a6affc7b1ce8140279e959d32671304db06d5ab_2_512x512.png -// @grant GM_getValue -// @grant GM_setValue -// @grant GM_xmlhttpRequest -// @grant GM_getResourceText -// @grant unsafeWindow -// @connect connect.linux.do -// @connect credit.linux.do -// @connect translate.googleapis.com -// @connect edge.microsoft.com -// @connect api-edge.cognitive.microsofttranslator.com -// @connect * -// @run-at document-start -// @resource ldpReaderStyles https://cdn.jsdelivr.net/gh/sunbigfly/awesome-linuxdo-reader@6f32c5f548d440963c1c0abb2160908b609f5aec/work/main.css#sha256=0738f4c1470861e1c7fcf29db5b8cb76f788896740492e2a2fc760c90691ff7e -// @require https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.js -// @require https://cdn.jsdelivr.net/npm/pinyin-pro@3.18.2/dist/index.js -// @require https://cdn.jsdelivr.net/npm/hls.js@1.6.16/dist/hls.min.js +// @name Awesome LinuxDo Reader +// @name:zh-CN 更流畅的 LinuxDo 阅读器 +// @namespace https://github.com/sunbigfly/awesome-linuxdo-reader +// @version 0.1.16 +// @license MIT +// @description 为 LINUX DO 深度适配、全面兼容标准 Discourse 站点的沉浸式增强阅读器,支持长帖上下文、原站互动、非中文正文翻译、自定义站点与个性布局。 +// @description:en Deeply adapted for LINUX DO and compatible with standard Discourse sites, with threaded reading, native interactions, body translation, custom sites, and personalized layouts. +// @author sunbigfly +// @homepageURL https://github.com/sunbigfly/awesome-linuxdo-reader +// @supportURL https://github.com/sunbigfly/awesome-linuxdo-reader/issues +// @match https://linux.do/* +// @match https://community.brave.com/* +// @match https://devforum.roblox.com/* +// @match https://community.openai.com/* +// @match https://community.home-assistant.io/* +// @match https://forum.cfx.re/* +// @match https://community.spiceworks.com/* +// @match https://forum.arduino.cc/* +// @match https://discussions.unity.com/* +// @match https://community.cloudflare.com/* +// @match https://forums.unrealengine.com/* +// @match https://forum.obsidian.md/* +// @match https://forum.cursor.com/* +// @match https://forum.godotengine.org/* +// @match https://community.n8n.io/* +// @match https://forum.mikrotik.com/* +// @match https://meta.discourse.org/* +// @match https://discuss.python.org/* +// @match https://forums.swift.org/* +// @match https://discourse.julialang.org/* +// @match https://users.rust-lang.org/* +// @match https://*/* +// @icon https://cdn3.ldstatic.com/optimized/4X/6/a/6/6a6affc7b1ce8140279e959d32671304db06d5ab_2_512x512.png +// @grant GM_getValue +// @grant GM_setValue +// @grant GM_xmlhttpRequest +// @grant GM_getResourceText +// @grant unsafeWindow +// @connect connect.linux.do +// @connect credit.linux.do +// @connect translate.googleapis.com +// @connect edge.microsoft.com +// @connect api-edge.cognitive.microsofttranslator.com +// @connect * +// @run-at document-start +// @resource ldpReaderStyles https://cdn.jsdelivr.net/gh/sunbigfly/awesome-linuxdo-reader@6f32c5f548d440963c1c0abb2160908b609f5aec/work/main.css#sha256=0738f4c1470861e1c7fcf29db5b8cb76f788896740492e2a2fc760c90691ff7e +// @require https://cdn.jsdelivr.net/npm/katex@0.16.22/dist/katex.min.js +// @require https://cdn.jsdelivr.net/npm/pinyin-pro@3.18.2/dist/index.js +// @require https://cdn.jsdelivr.net/npm/hls.js@1.6.16/dist/hls.min.js // ==/UserScript== -(function(){"use strict";const b0="awesome-linuxdo-reader:custom-discourse-sites:v1",y0=new Set(["linux.do","community.brave.com","devforum.roblox.com","community.openai.com","community.home-assistant.io","forum.cfx.re","community.spiceworks.com","forum.arduino.cc","discussions.unity.com","community.cloudflare.com","forums.unrealengine.com","forum.obsidian.md","forum.cursor.com","forum.godotengine.org","community.n8n.io","forum.mikrotik.com","meta.discourse.org","discuss.python.org","forums.swift.org","discourse.julialang.org","users.rust-lang.org"]);function v0(e){const t=String(e||"").trim();if(!t)return"";try{const r=new URL(/^[a-z][a-z\d+.-]*:\/\//i.test(t)?t:`https://${t}`);return r.protocol==="https:"&&!r.username&&!r.password?r.hostname.toLowerCase():""}catch{return""}}function rp(){try{const e=globalThis.GM_getValue?.(b0,[]);return Array.isArray(e)?[...new Set(e.map(v0).filter(Boolean))]:[]}catch{return[]}}const Tl=location.hostname.toLowerCase(),w0="awesome-linuxdo-reader:ldc-user-bridge:v1",S0=e=>Promise.resolve(globalThis.GM_setValue?.(w0,{data:e,cachedAt:Date.now()})).then(()=>e);if(Tl==="credit.linux.do"){const e=async()=>{try{const r=await fetch("/api/v1/oauth/user-info",{credentials:"include",headers:{Accept:"application/json"}}),o=r.ok?(await r.json())?.data:null;o&&await S0(o)}catch{}},t=()=>setTimeout(()=>void e(),1e3);document.readyState==="complete"?t():window.addEventListener("load",t,{once:!0});return}if(!y0.has(Tl)&&!rp().includes(Tl))return;function _0(e){const t=globalThis.GM_setValue;if(typeof t!="function")throw new Error("脚本没有全局站点存储权限");return Promise.resolve(t(b0,[...new Set(e)].sort()))}function rT(e){const t=globalThis.GM_xmlhttpRequest;return typeof t!="function"?Promise.reject(new Error("脚本没有跨站检测权限")):new Promise((r,o)=>t({method:"GET",url:`https://${e}/site/basic-info.json`,headers:{Accept:"application/json"},responseType:"json",anonymous:!0,timeout:8e3,onload:n=>{const s=n.response;n.status>=200&&n.status<300&&s?.title?r(s):o(new Error("未检测到 Discourse"))},ontimeout:()=>o(new Error("检测超时,请稍后重试")),onerror:()=>o(new Error("站点无法访问"))}))}const vt=location.origin,Lt=document.documentElement,ke=e=>document.createElement(e),C0="0.1.16",bs=globalThis.unsafeWindow,zr=(e,t,r={connect:!1})=>Object.freeze({id:e,name:t,capabilities:Object.freeze(r)}),E0=zr("discourse",location.hostname),Ia=Object.freeze({"linux.do":zr("linux-do","LINUX DO",{boosts:!0,reactions:!0,postVoting:!0,topicVoting:!0,connect:!0,categoryExperts:!0,follows:!0,sharedIssue:!0}),"community.openai.com":zr("openai-community","OpenAI Community"),"community.brave.com":zr("brave-community","Brave Community"),"devforum.roblox.com":zr("roblox-developer-forum","Roblox Developer Forum"),"forum.cfx.re":zr("cfx-forum","Cfx.re Forum"),"community.spiceworks.com":zr("spiceworks-community","Spiceworks Community"),"discussions.unity.com":zr("unity-discussions","Unity Discussions"),"community.cloudflare.com":zr("cloudflare-community","Cloudflare Community"),"forums.unrealengine.com":zr("epic-developer-community","Epic Developer Community"),"forum.obsidian.md":zr("obsidian-forum","Obsidian Forum"),"forum.cursor.com":zr("cursor-community","Cursor Community"),"forum.godotengine.org":zr("godot-forum","Godot Forum"),"community.n8n.io":zr("n8n-community","n8n Community"),"forum.mikrotik.com":zr("mikrotik-forum","MikroTik Forum"),"meta.discourse.org":zr("discourse-meta","Discourse Meta"),"discuss.python.org":zr("python-discussions","Python Discussions"),"forums.swift.org":zr("swift-forums","Swift Forums"),"discourse.julialang.org":zr("julia-discourse","Julia Discourse"),"community.home-assistant.io":zr("home-assistant-community","Home Assistant Community"),"forum.arduino.cc":zr("arduino-forum","Arduino Forum"),"users.rust-lang.org":zr("rust-users","Rust Users Forum")})[location.hostname.toLowerCase()]||E0,zn=Ia.name||location.hostname,oT=Ia===E0?"":Ia.id==="linux-do"?"zh-CN":"en";function nT(){return!/^zh(?:[-_]|$)/i.test(oT)}const op=90*1e3,M0=1500,sT=5e3,$0=20,Nh=Object.freeze({color:"#0888cc",radius:10,borderWidth:1,rate:.8,count:2}),ys=Object.freeze({radius:Object.freeze({min:0,max:24,step:1,integer:!0}),borderWidth:Object.freeze({min:0,max:4,step:1,integer:!0}),rate:Object.freeze({min:.5,max:2,step:.1,integer:!1}),count:Object.freeze({min:1,max:6,step:1,integer:!0})}),xa=Object.freeze([{key:"color",pref:"jumpHighlightColor",label:"提示颜色",type:"color",format:String,help:"选择跳转目标楼层的闪烁颜色;提示使用半透明底色避免遮住正文,并用同色细轮廓准确呈现所选颜色。选择时实时预览,统一保存。"},{key:"radius",pref:"jumpHighlightRadius",label:"提示圆角",ariaLabel:"跳转提示圆角",format:e=>`${e}px`,help:`控制闪烁背景的圆角,可在 ${ys.radius.min}–${ys.radius.max}px 之间调整。拖动时实时预览,统一保存。`},{key:"borderWidth",pref:"jumpHighlightBorderWidth",label:"提示轮廓宽度",ariaLabel:"跳转提示轮廓宽度",format:e=>`${e}px`,help:`控制闪烁轮廓的宽度,可在 ${ys.borderWidth.min}–${ys.borderWidth.max}px 之间调整;设为 0px 可关闭边框,颜色跟随闪烁颜色。拖动时实时预览,统一保存。`},{key:"rate",pref:"jumpHighlightRate",label:"闪烁速度",ariaLabel:"跳转提示闪烁速度",format:e=>`${e.toFixed(1)} 次/秒`,help:`控制每秒闪烁次数,可在 ${ys.rate.min}–${ys.rate.max} 次/秒之间调整;数值越大闪得越快。拖动时实时预览,统一保存。`},{key:"count",pref:"jumpHighlightCount",label:"闪烁次数",ariaLabel:"跳转提示闪烁次数",format:e=>`${e} 次`,help:`控制一次跳转连续闪烁多少次,可在 ${ys.count.min}–${ys.count.max} 次之间调整。拖动时实时预览,统一保存。`}]),R0=`${vt}/favicon.ico`,aT=`data:image/svg+xml,${encodeURIComponent('')}`;let Al=R0,np=[R0,aT];function iT(e){const t=String(e||"").trim();if(!t)return"";if(/^data:image\//i.test(t))return t;try{const r=new URL(t,vt);return/^https?:$/i.test(r.protocol)?r.href:""}catch{return""}}function T0(){const e=np.slice();An("[data-ldp-site-logo]").forEach(t=>{t._ldpSiteLogoCandidates=e,t._ldpSiteLogoIndex=0,t.onerror=()=>{const r=Number(t._ldpSiteLogoIndex||0)+1;t._ldpSiteLogoIndex=r;const o=t._ldpSiteLogoCandidates?.[r];o?t.src=o:t.onerror=null},t.src!==Al?t.src=Al:t.complete&&t.naturalWidth===0&&t.onerror()})}function A0(e){const t=[...new Set((e||[]).map(iT).filter(Boolean))];t.length&&(np=[...t,...np.filter(r=>!t.includes(r))],Al=np[0],T0())}function lT(){const e=It("service:site-settings"),t=document.querySelector(".d-header #site-logo,.d-header img.logo-big,.d-header img.logo-small,.custom-logo-link img"),r=document.querySelector('link[rel~="apple-touch-icon"]'),o=document.querySelector('link[rel~="icon"]');return[e?.large_icon,e?.apple_touch_icon,e?.favicon,e?.logo_small,e?.mobile_logo,e?.logo,t?.currentSrc||t?.src,r?.href,o?.href]}async function cT(){A0(lT());const e=new AbortController,t=setTimeout(()=>e.abort(),5e3);try{const r=await fetch(`${vt}/site/basic-info.json`,{credentials:"same-origin",headers:{Accept:"application/json"},cache:"force-cache",signal:e.signal});if(!r.ok)return;const o=await r.json();A0([o.large_icon_url,o.apple_touch_icon_url,o.favicon_url,o.logo_small_url,o.mobile_logo_url,o.logo_url])}catch(r){r?.name!=="AbortError"&&console.warn("[LDP] site logo discovery failed",r)}finally{clearTimeout(t)}}const dT="https://sunbigfly.github.io/awesome-linuxdo-reader/",uT="https://greasyfork.org/zh-CN/scripts/580986-linux-do-boost-%E5%A2%9E%E5%BC%BA",kh="fr-init-once",pT="https://github.com/F9y4ng/GreasyFork-Scripts/",fT="https://github.com/F9y4ng/GreasyFork-Scripts/blob/master/LICENSE",Lh=(()=>{const e=navigator.userAgent||"",t=/Firefox\//.test(e),r=/AppleWebKit\//.test(e)&&!/(?:Chrome|Chromium|Edg|OPR|CriOS|FxiOS)\//.test(e);return Object.freeze({stroke:t?.03:r?.05:.015,shadow:t?.55:r?.45:.75,macSmoothing:/Mac/.test(navigator.platform||"")})})();function mT(){Lt.style.setProperty("--ldp-font-rendering-stroke-runtime",`${Lh.stroke}px currentcolor`),Lt.style.setProperty("--ldp-font-rendering-shadow-runtime",`0 0 ${Lh.shadow}px #7c7c7cdd`),Lt.toggleAttribute("data-ldp-font-mac-smoothing",Lh.macSmoothing)}const Ih="linuxdo-enhanced-reader:prefs",P0="awesome-linuxdo-reader-settings",sp=5,ap="linuxdo-enhanced-reader:history",xh="linuxdo-enhanced-reader:reader-queue:v1",N0="linuxdo-enhanced-reader:reply-branches:v1",k0="linuxdo-enhanced-reader:reply-window:v1",hT="linuxdo-enhanced-reader:cache:topics",gT="linuxdo-enhanced-reader:cache:topic-nav-icons",bT="linuxdo-enhanced-reader:cache:users",yT="linuxdo-enhanced-reader:cache:notifications",qh="linuxdo-enhanced-reader:shared-request-state:v1",Dh="linuxdo-enhanced-reader:shared-request-flow:v1",ip="linuxdo-enhanced-reader:cloudflare-challenge:v1",vT=15*1e3,Oh="linuxdo-enhanced-reader:read-success:v1",wT="linuxdo-enhanced-reader:read-request:v1",L0=60*1e3,lp="linuxdo-enhanced-reader:embedded-reload-state:v1",ST=30*1e3,Fh="linuxdo-enhanced-reader:avatars:v1",cp="linuxdo-enhanced-reader:emoji-images:v1",Pl="linuxdo-enhanced-reader:lightbox-images:v1",_T="linuxdo-enhanced-reader:responses:v1",ad="responses",I0=1,dp=1,CT=750,ET=3e3,oo=60*1e3,id=60*oo,Oo=24*id,x0=90*Oo,Bh=90*Oo,Hh=7*Oo,MT="ldp-scroll-lock",Nl="ldp_native",Uh="linuxdo-enhanced-reader:native-tab",$T="0.16.22",RT=[25,50,100,125,150,200],q0=56,D0=120,O0=25,jh=18,up=50,F0=50,B0=200,H0=50,U0=250,j0=100,pp=80,z0=Object.freeze(["light","dark","system"]),TT=Object.freeze({light:"明",dark:"暗",system:"系统"}),AT=[["--secondary","#ffffff","#171b20"],["--primary","#20252b","#e7edf3"],["--primary-high","#333a42","#cbd4dc"],["--primary-medium","#68737e","#98a4af"],["--primary-low-mid","#b8c0c8","#4a5560"],["--primary-low","#d7dde3","#39414a"],["--primary-very-low","#f2f4f6","#242a31"],["--secondary-low","#4b545d","#363c43"],["--secondary-medium","#89929c","#7f8790"],["--secondary-high","#dfe3e6","#c9d0d8"],["--secondary-very-high","#f7f8f9","#e3e8ed"],["--tertiary","#47855f","#78c295"],["--tertiary-low","#dceee2","#223a2c"],["--header_background","#ffffff","#171b20"],["--header_primary","#20252b","#e7edf3"],["--header_primary-low","#e7eaed","#2a3037"],["--header_primary-low-mid","#b7bec6","#4a5560"],["--header_primary-medium","#68737e","#98a4af"],["--header_primary-high","#333a42","#cbd4dc"],["--highlight","#fff0a8","#6b5a16"],["--highlight-low","#fff8d8","#302b18"],["--highlight-medium","#ffe47a","#8a7420"],["--highlight-high","#806200","#ffe47a"],["--quaternary","#d86645","#f08a67"],["--danger","#c84545","#ff7b72"],["--danger-low","#f7dddd","#44262a"],["--danger-low-mid","#efb5b5","#6b353b"],["--success","#47855f","#78c295"],["--success-low","#dceee2","#223a2c"],["--love","#dc6542","#ff8a65"],["--love-low","#f7ddd5","#472b25"],["--d-link-color","#2870b8","#71b7ff"],["--d-post-aside-background","#f7f9fa","#20262d"],["--ldp-zebra-color","#f7f7f7","#1b2b21"],["--ldp-reply-line-color","#47855f","#78c295"],["--ldp-quote-line-color","#d7d7d7","#46505a"],["--ldp-divider-line-color","#e5e5e5","#343b44"],["--ldp-request-metric-pine","#315f47","#86b49a"],["--ldp-request-metric-navy","#365673","#8eacc8"],["--ldp-request-metric-plum","#5e4b72","#b09bc4"],["--ldp-request-metric-bronze","#72551f","#c5a36d"],["--ldp-request-metric-wine","#743f47","#c7929a"]],an=Object.freeze(Object.fromEntries(["light","dark"].map((e,t)=>[e,Object.freeze(Object.fromEntries(AT.map(([r,...o])=>[r,o[t]])))]))),PT=an.light["--tertiary"],NT=an.light["--d-link-color"],kT="#f7f7f7",LT="#f7f7f7",zh=0,Wh=16,W0=10,V0=1,IT="#6dab85",Si=.5,_i=4,fp=.5,Vh=1,Gh=0,Qh=16,G0=15,Q0=1,xT="#d7d7d7",Y0=.5,qT="#e5e5e5",mp=.5,DT="#dba7a7",OT="#f87171",Yh=180,X0=720,K0=300,J0=10,Z0=[{id:"main-request",title:"楼层数据加载",description:"设置每次从服务器加载多少楼层;只影响单批数据量,不等于页面同时显示的楼层数。",fields:[{key:"pageSize",pref:"performancePageSize",presets:[16,40,48],limits:{min:12,max:64,step:1,integer:!0},title:"每次加载楼层数",unit:"个",inputMode:"numeric",description:"接近已加载内容边缘时,一次再取多少楼层;数值越大,等待次数越少,但单次下载和处理更重。",help:"阅读接近已加载内容边缘时,一次向服务器请求多少个楼层。它只决定单批响应大小,不改变页面同时保留的楼层数量。"}]},{id:"dom",title:"页面楼层保留",description:"控制当前页面前后保留多少楼层;远处内容会卸载以节省内存,不会因此发起网络请求。",fields:[{key:"streamOverscanViewports",pref:"performanceStreamOverscan",presets:[.35,1.25,2],limits:{min:.25,max:3,step:.05},title:"屏幕外预留范围",unit:"屏",inputMode:"decimal",description:"在当前可见区域前后额外保留多少屏内容;数值越大,快速滚动越不容易看到空白,但更占内存。",help:"在当前屏幕前后额外保留多少屏楼层元素。它只影响页面渲染和内存,不会发起楼层请求,并受“同时保留楼层上限”约束。"},{key:"streamMaxItems",pref:"performanceStreamMaxItems",presets:[28,72,96],limits:{min:24,max:128,step:1,integer:!0},title:"同时保留楼层上限",unit:"个",inputMode:"numeric",description:"页面同时保留的楼层数量上限;离当前阅读位置较远的楼层会卸载,滚回时再恢复。",help:"首次进入、滚动和跳转期间,页面最多同时保留多少个主楼层元素。远处楼层会从页面结构中卸载,并用等高占位保持滚动位置。"}]},{id:"nested",title:"二级回复预加载",description:"父楼层接近屏幕时,自动加载它下面的直接回复。",fields:[{key:"nestedPrefetchViewports",pref:"performanceNestedPrefetch",presets:[.35,1.25,2],limits:{min:0,max:3,step:.05},title:"提前加载距离",unit:"屏",inputMode:"decimal",description:"0 表示父楼层进入屏幕后再加载;大于 0 表示提前对应屏数加载。每个父楼层首批最多加载 20 条直接回复。",help:"父楼层距离当前屏幕多远时开始加载直接回复。0 表示进入屏幕后加载;数值越大越早加载,也会更早产生网络请求。"}]},{id:"request",title:"网络请求节奏",description:"帖子、楼层、二级回复、消息和用户资料共用这些限制;遇到原站操作或限流时会自动放慢。",fields:[{key:"requestMaxConcurrent",pref:"performanceRequestConcurrency",presets:[1,3,4],limits:{min:1,max:4,step:1,integer:!0},title:"同时请求上限",unit:"路",inputMode:"numeric",description:"最多允许多少个阅读器请求同时进行;实际数量可能因多个页面、原站操作或限流而更低。",help:"阅读器网络请求同时进行的最高数量。多个脚本实例、原站操作、服务器限流和恢复状态只会继续降低实际数量。"},{key:"requestMinInterval",pref:"performanceRequestInterval",presets:[220,90,80],limits:{min:80,max:500,step:10,integer:!0},title:"请求最短间隔",unit:"ms",inputMode:"numeric",description:"正常情况下,两次请求开始之间至少间隔多久;原站繁忙或出现 429 时会自动延长。",help:"正常状态下两次阅读器请求开始的最短间隔。自适应调度可以延长它,且不会在恢复后一次性补发积压请求。"},{key:"requestRateTarget",pref:"performanceRequestRateTarget",presets:[80,80,80],limits:{min:50,max:95,step:1,integer:!0},title:"限流额度使用比例",unit:"%",inputMode:"numeric",description:"只使用服务器已探测请求额度的一部分,为原站操作保留余量;比例越低越保守。",help:"阅读器计划使用服务器 10 秒与 60 秒请求额度的比例。它只控制请求启动节奏,不改变每次加载楼层数或二级回复数量。"}]}],hp=Z0.flatMap(e=>e.fields),ld=Object.freeze(Object.fromEntries(["low","balanced","high"].map((e,t)=>[e,Object.freeze(Object.fromEntries(hp.map(r=>[r.key,r.presets[t]])))]))),kl=Object.freeze(Object.fromEntries(hp.map(e=>[e.key,Object.freeze(e.limits)]))),gp=Object.freeze(Object.fromEntries(hp.map(e=>[e.key,e.pref]))),Xh=Object.freeze(Object.keys(gp)),Ro=Object.freeze(["left","main","gap","timeline","right"]),ew=Object.freeze({left:"左侧留白",main:"正文区域",gap:"正文与时间轴间距",timeline:"楼层时间轴",right:"右侧留白"}),vs="composerWindow",cd=Object.freeze({left:0,main:88,gap:0,timeline:8,right:4}),Ll=Object.freeze({left:15,main:70,gap:5,timeline:8,right:2}),Ci="system",Wn=Object.freeze({site:Object.freeze({label:"跟随原站",stack:"inherit"}),system:Object.freeze({label:"系统默认字体",stack:"system-ui,sans-serif"}),cjkSans:Object.freeze({label:"中文无衬线",stack:'"Noto Sans CJK SC","Microsoft YaHei","PingFang SC",system-ui,sans-serif'}),serif:Object.freeze({label:"衬线",stack:'"Noto Serif CJK SC","Songti SC",SimSun,serif'}),monospace:Object.freeze({label:"等宽",stack:"ui-monospace,SFMono-Regular,Consolas,monospace"}),custom:Object.freeze({label:"自定义本机字体",stack:""})}),dd=400,tw=Object.freeze([300,400,500,600]),Kh=Object.freeze({300:"细",400:"常规",500:"中等",600:"半粗"}),rw=50,ow=200,FT=100,ws=Object.freeze({title:Object.freeze({pref:"hostEmbeddedTitleScale",label:"主题标题",defaultScale:110,properties:[["--ldp-host-topic-title-size",15]]}),avatar:Object.freeze({pref:"hostEmbeddedAvatarScale",label:"头像",defaultScale:80,properties:[["--ldp-host-topic-avatar-size",32],["--ldp-host-topic-avatar-size-medium",24],["--ldp-host-topic-avatar-size-small",20]]}),stats:Object.freeze({pref:"hostEmbeddedStatsScale",label:"主题统计信息",defaultScale:120,properties:[["--ldp-host-topic-stats-size",10],["--ldp-host-topic-stats-label-size",9],["--ldp-host-topic-stats-row-offset",-4]]}),labelCard:Object.freeze({pref:"hostEmbeddedLabelCardScale",label:"标签卡片",defaultScale:100,properties:[["--ldp-host-label-card-height",22],["--ldp-host-label-card-font-size",11],["--ldp-host-label-card-icon-size",14],["--ldp-host-label-card-gap",3],["--ldp-host-label-card-padding",7]]})}),ta=Object.freeze(["interface","post","composer"]),ra=Object.freeze({interface:Object.freeze({label:"界面文字",family:"family",customFamily:"customFamily",weight:"weight",color:"interfaceColor",scale:"interface"}),post:Object.freeze({label:"帖子正文",family:"postFamily",customFamily:"postCustomFamily",weight:"postWeight",color:"postColor",scale:"post"}),composer:Object.freeze({label:"回复输入框",family:"composerFamily",customFamily:"composerCustomFamily",weight:"composerWeight",color:"composerColor",scale:"composer"})}),Jh=Object.freeze({label:"嵌入阅读时的原站主题列表",family:"hostFontFamily",customFamily:"hostFontCustomFamily",weight:"hostFontWeight",color:"hostFontColor"}),Fo=Object.freeze({hostFontFamily:Ci,hostFontCustomFamily:"",hostFontWeight:dd,hostFontColor:""}),nw=Object.freeze([...ta,"host"]),Zh=Object.freeze(["family","customFamily","weight","interfaceColor","interface","postFamily","postCustomFamily","postWeight","postColor","post","composerFamily","composerCustomFamily","composerWeight","composerColor","composer"]),Ei=Object.freeze({family:Ci,customFamily:"",weight:dd,interfaceColor:"",interface:92,postFamily:Ci,postCustomFamily:"",postWeight:dd,postColor:"",post:95,composerFamily:Ci,composerCustomFamily:"",composerWeight:dd,composerColor:"",composer:pp}),Il=Object.freeze({preset:"50",custom:50}),eg=Object.freeze(["accentColor","linkColor","zebraColor","listZebraColor","replyLineColor","quoteLineColor","dividerLineColor","floorPreviewColor"]),BT=Object.freeze({accentColor:Object.freeze({saturationMax:82,light:[30,55],dark:[58,78]}),linkColor:Object.freeze({saturationMax:90,light:[30,55],dark:[60,80]}),zebraColor:Object.freeze({saturationMax:70,light:[92,100],dark:[10,20]}),listZebraColor:Object.freeze({saturationMax:38,light:[88,98],dark:[10,20]}),replyLineColor:Object.freeze({saturationMax:76,light:[30,58],dark:[55,78]}),quoteLineColor:Object.freeze({saturationMax:50,light:[72,92],dark:[22,42]}),dividerLineColor:Object.freeze({saturationMax:40,light:[80,94],dark:[18,34]}),floorPreviewColor:Object.freeze({saturationMax:88,light:[35,58],dark:[58,78]})}),sw=Object.freeze(["accentColor","linkColor","zebraColor","zebraRadius","listZebraColor","structureColorsEnabled","replyLineColor","replyLineWidth","replyLineRadius","quoteLineColor","quoteLineWidth","dividerLineColor","dividerLineWidth","floorPreviewColor","floorPreviewHeight"]),Jo=Object.freeze({accentColor:PT,accentColorDark:an.dark["--tertiary"],linkColor:NT,linkColorDark:an.dark["--d-link-color"],zebraColor:kT,zebraColorDark:an.dark["--ldp-zebra-color"],zebraRadius:W0,listZebraColor:LT,listZebraColorDark:an.dark["--primary-very-low"],structureColorsEnabled:!0,replyLineColor:IT,replyLineColorDark:an.dark["--ldp-reply-line-color"],replyLineWidth:Vh,replyLineRadius:G0,quoteLineColor:xT,quoteLineColorDark:an.dark["--ldp-quote-line-color"],quoteLineWidth:Y0,dividerLineColor:qT,dividerLineColorDark:an.dark["--ldp-divider-line-color"],dividerLineWidth:mp,floorPreviewColor:DT,floorPreviewColorDark:OT,floorPreviewHeight:K0}),aw=Object.freeze(sw.flatMap(e=>eg.includes(e)?[e,`${e}Dark`]:[e])),ud=Object.freeze({"--ldp-font-micro":9,"--ldp-font-xs":10,"--ldp-font-sm":11,"--ldp-font-ui":12,"--ldp-font-base":13,"--ldp-font-md":14,"--ldp-font-lg":15,"--ldp-font-xl":16,"--ldp-font-2xl":17,"--ldp-font-3xl":18}),HT=14,oa=Object.freeze({left:0,main:40,gap:0,timeline:6,right:0}),iw=1080,UT=.94,jT=.86,na=360,Mi=320,Ss=700,zT=12,WT=9,VT=9.5,no=8,lw=8,cw=560,GT=38,bp=360,dw=Math.round(window.innerWidth*.45),tg=680,yp=Object.freeze(["floating","fullpage","embed-left","embed-right"]),vp=Object.freeze(["floating","fullpage"]),uw=Object.freeze({floating:Object.freeze({mode:"floating",floating:!0,fullPage:!1,embedded:!1,side:""}),fullpage:Object.freeze({mode:"fullpage",floating:!1,fullPage:!0,embedded:!1,side:""}),"embed-left":Object.freeze({mode:"embed-left",floating:!1,fullPage:!1,embedded:!0,side:"left"}),"embed-right":Object.freeze({mode:"embed-right",floating:!1,fullPage:!1,embedded:!0,side:"right"})}),wp=16,QT=Object.freeze(["counter","text"]),Vn=Object.freeze({mode:"counter",prefix:"",counterMarker:"+",counterStep:1,fixedSuffix:""}),rg=ld.balanced,YT=24,pw=oo,XT=240,KT=10*oo,JT=20,ZT=20,eA=20,fw=60,tA=24*id,rA=5*oo,oA=32,nA=512,Sp=10,eo={all:{mode:"notifications",source:"notifications",label:"全部",icon:"bell",types:[]},replies:{mode:"notifications",source:"user-actions",label:"回复",icon:"reply",types:["replied","quoted"],actionTypes:[6,9],pageSize:30},likes:{mode:"notifications",source:"user-actions",label:"赞",icon:"heart",types:["liked","liked_consolidated"],actionTypes:[2],pageSize:30},mentions:{mode:"notifications",source:"user-actions",label:"@提及",icon:"at",types:["mentioned","group_mentioned"],actionTypes:[7],pageSize:30},edits:{mode:"notifications",source:"user-actions",label:"编辑",icon:"pencil",types:["edited"],actionTypes:[11],pageSize:30},links:{mode:"notifications",source:"user-actions",label:"链接",icon:"link2",types:["linked","linked_consolidated"],actionTypes:[17],pageSize:30},boosts:{mode:"notifications",source:"boosts-received",label:"Boosts",icon:"rocket",types:["boost"],pageSize:20},reactions:{mode:"notifications",source:"reactions-received",label:"回应",icon:"smile",types:["reaction"],pageSize:20},inbox:{mode:"messages",source:"private-messages",path:"private-messages",label:"最新",icon:"mail",pageSize:30},sent:{mode:"messages",source:"private-messages",path:"private-messages-sent",label:"已发送",icon:"reply",pageSize:30},newMessages:{mode:"messages",source:"private-messages",path:"private-messages-new",label:"新",icon:"plus",pageSize:30},unreadMessages:{mode:"messages",source:"private-messages",path:"private-messages-unread",label:"未读",icon:"bell",pageSize:30},archive:{mode:"messages",source:"private-messages",path:"private-messages-archive",label:"归档",icon:"database",pageSize:30},botMessages:{mode:"messages",source:"private-messages",path:"private-messages-warnings",label:"机器人聊天",icon:"messageSquare",pageSize:30}},sA=Object.freeze({mentioned:"at",replied:"reply",quoted:"messageSquare",posted:"messageSquare",group_mentioned:"at",liked:"heart",liked_consolidated:"heart",reaction:"smile",boost:"rocket",following:"userPlus",following_created_topic:"messageSquare",following_replied:"reply",watching_first_post:"bell",watching_category_or_tag:"bell",private_message:"mail",invited_to_private_message:"userPlus",group_message_summary:"mail",chat_mention:"at",chat_message:"messageSquare",chat_invitation:"userPlus",chat_group_mention:"at",chat_quoted:"messageSquare",chat_watched_thread:"bell",edited:"pencil",invitee_accepted:"userPlus",moved_post:"cornerDownRight",linked:"link2",granted_badge:"award",invited_to_topic:"userPlus",custom:"bell",topic_reminder:"bell",post_approved:"check",code_review_commit_approved:"check",membership_request_accepted:"check",membership_request_consolidated:"userPlus",bookmark_reminder:"bookmark",votes_released:"hand",event_reminder:"bell",event_invitation:"mail",assigned:"userRound",question_answer_user_commented:"messageSquare",new_features:"lightbulb",admin_problems:"alertTriangle",linked_consolidated:"link2",upcoming_change_available:"alertTriangle",upcoming_change_automatically_promoted:"alertTriangle",suggested_edit_created:"pencil",suggested_edit_accepted:"check",circles_activity:"activity"}),mo={history:{storageKey:ap,maxAge:365*Oo},topics:{maxAge:180*Oo,maxEntries:8,storedMaxEntries:64,storedMaxBytes:64*1024*1024},topicNavIcons:{storageKey:gT,maxAge:180*Oo,maxEntries:512},users:{storageKey:bT,maxAge:180*Oo,maxEntries:128,storedMaxEntries:256,storedMaxBytes:16*1024*1024},notifications:{storageKey:yT,maxAge:180*Oo,maxEntries:32,storedMaxEntries:64,storedMaxBytes:8*1024*1024},responses:{maxAge:365*Oo,storedMaxEntries:256,storedMaxBytes:32*1024*1024},assets:{maxAge:90*Oo}},mw=[{key:"history",label:"浏览历史",help:"勾选“浏览历史”后再点下方清理,会删除阅读器保存的主题、最近阅读楼层和查看时间;不会删除浏览器本身的访问历史。"},{key:"topics",label:"帖子与楼层内容",help:"勾选“帖子与楼层内容”后清理,会删除本机保存的帖子信息、楼层正文、回复关系、分类标签图标和相关接口数据;下次打开时会重新联网获取。"},{key:"users",label:"用户资料卡",help:"勾选“用户资料卡”后清理,会删除用户名、简介、徽章、用户组等资料快照和相关接口数据;头像仍归“头像、表情与原图”单独管理。"},{key:"notifications",label:"通知与消息",help:"勾选“通知与消息”后清理,会删除通知分页、已读状态、跳转位置和发送者摘要;头像资源保留,也不会删除站点账号里的真实消息。"},{key:"responses",label:"收藏、回应与其他数据",help:"勾选“收藏、回应与其他数据”后清理,会删除收藏列表、给出的回应与点赞、表情目录和其他通用接口结果;不会撤销站点上的真实收藏或回应。"},{key:"assets",label:"头像、表情与原图",help:"勾选“头像、表情与原图”后清理,会删除头像、Boost 表情和实际查看过的原图资源;不会删除帖子中的线上图片。"}],og=Object.freeze(["Reaction","Topic","Post"]),aA=Object.freeze({Reaction:"回应",Topic:"帖子",Post:"楼层"}),ng=0,sg=15,hw=15,iA=20,_s=200,lA=100,cA=40,dA=80,uA=2,pA=900,fA=700,gw=.01,mA=Object.freeze(["portal","constellation","corridor","typewave","crystal","marginalia","chapters","quoteecho","footnotes","inkverse"]),bw="quoteecho",sa={topicReaderMode:"fullpage",imageProfile:Il,lightboxOriginalByDefault:!0,lightboxCommentsExpandedByDefault:!0,lightboxDescriptionExpanded:!1,lightboxDescriptionHeight:D0,lightboxCommentsWidthPercent:O0,themeMode:"system",fontRenderingEnabled:!0,fontRenderingOnHost:!0,...Fo,hostEmbeddedTitleScale:ws.title.defaultScale,hostEmbeddedAvatarScale:ws.avatar.defaultScale,hostEmbeddedStatsScale:ws.stats.defaultScale,hostEmbeddedLabelCardScale:ws.labelCard.defaultScale,fontProfile:Ei,appearanceProfile:Jo,...af(rg,"balanced"),layoutProfile:cd,fullpageLayoutProfile:Ll,...zS({},"readerWindow"),listReaderMode:"floating",listReaderEmbedWidth:dw,...WS({},vs),historySortMode:"recent-viewed",bookmarkTabOrder:og,historyButtonsAlwaysVisible:!0,readerQueueAlwaysVisibleWhenEmpty:!0,historyEdgeTriggerPercent:hw,loadingAnimation:bw,translationMode:"original",openTopicsAtFirstPost:!1,doubleEscapeToCloseReader:!1,confirmNativeComposerClose:!0,topicActionRailVisible:!0,topicActionRailFixed:!1,topicActionRailPosition:{x:"left",y:.95},expandNestedRepliesByDefault:!0,expandLeafNestedReplies:!1,aggregateDescendantReplies:!0,hideNestedReplyFloors:!0,...df(Nh),boostCopyMode:Vn.mode,boostCopyPrefix:Vn.prefix,boostCopyCounterMarker:Vn.counterMarker,boostCopyCounterStep:Vn.counterStep,boostCopyFixedSuffix:Vn.fixedSuffix},yw=vI()||hm(location.href);yw&&$I();const vw=(co(location.href)||{}).topicId||null;let Yt=null,To=null;const ag=new Map,ig=new Map;let $i=null,pd=null;const ww=new Set;let Cs=0,Ao=null;const kr=[],xl=new Map;let Po="",lg=!1;const Sw=new Map;let ql=0,fd=0,_p=!1,Ri={x:null,y:null,dock:""},$t=null,ln=null,Bo=null,cg=null,qa=null;const Gn=new Map;let Dl=null,Ti=null,Cp=null;vw&&Lt.classList.add("ldp-route-takeover");const Ep=10,dg=20,hA=40,gA=1,_w=1500,Da=15e3,bA=24,yA=6,vA=6,wA=1.12,SA=1200,ug=600*1e3,Cw=4e3,_A=5e3,Ew=300*1e3,Mw=600*1e3,$w=128,pg=10*1e3,Mp=60*1e3,CA=30*1e3,Ol=Mp+Da+15e3,EA=35*1e3,$p=50,fg=200,Rw=1200,Tw=900*1e3,Ai=10*1e3,MA=1800,No=[],md=[],Es=Symbol("ldpRequestFlowFetchMeta"),mg=new WeakMap;let Fl=null,Aw=!1,Rp=!1,hg=!1;const Ms=Object.freeze({topic:"正文",nested:"二级回复",avatar:"头像",media:"图片媒体",user:"用户资料",bookmark:"收藏",notification:"消息",realtime:"实时通道",presence:"在线状态",reaction:"回应操作",search:"搜索",read:"已读上报",asset:"静态资源",other:"其他"}),$A=Object.freeze({reader:"阅读器",host:"原站",browser:"资源"}),RA=Object.freeze({priority:"优先级",concurrency:"并发槽",cooldown:"429 退避","endpoint-cooldown":"端点熔断",interval:"启动间隔","10s":"10 秒窗口","60s":"60 秒窗口"}),TA=Object.freeze({reader:"阅读器",host:"原站/未标",shared:"页面共享"});let AA=0;function vo(){const e=globalThis.performance;return e&&Number.isFinite(e.timeOrigin)&&D(e.now)?e.timeOrigin+e.now():Date.now()}function Tp(){if(!Rp)return"";let e="";try{e=String(new Error().stack||"")}catch{}const t=/\b(?:requestFlowCallSite|beginRequestFlow|trackedFetch|trackedSend|waitForReaderRequestPermit|requestCachedJSON|requestJSON|fetchJSON|runTask|apiSend)\b/,r=e.split(` -`).map(o=>o.trim()).find((o,n)=>n>0&&o&&!t.test(o)&&!/\b(?:native code|Promise\.then)\b/.test(o));return r?r.replace(/(?:https?|chrome-extension):\/\/[^\s)]+/g,o=>{const n=o.match(/(:\d+:\d+)$/)?.[1]||"",s=n?o.slice(0,-n.length):o;try{const a=new URL(s);return`${a.origin}${a.pathname}${n}`}catch{return s.split(/[?#]/,1)[0]+n}}).replace(/^at\s+/,"").slice(0,220):""}function Pw(e,t=-1/0){let r=0,o=No.length;for(;rr-o).join(",")}`}function NA(e){try{const t=Date.now()-L0,r=JSON.parse(localStorage.getItem(Oh)||"[]");return Array.isArray(r)&&r.some(o=>o?.fingerprint===e&&Number(o.at)>t)}catch{return!1}}function kA(e){const t=Date.now()-L0;let r=[];try{r=JSON.parse(localStorage.getItem(Oh)||"[]")}catch{}r=(Array.isArray(r)?r:[]).filter(o=>Number(o?.at)>t&&o?.fingerprint!==e).slice(-15),r.push({fingerprint:e,at:Date.now()});try{localStorage.setItem(Oh,JSON.stringify(r))}catch{}}function gg(e){return e?["http:","https:"].includes(e.protocol)?`${e.origin===location.origin?"":e.host}${e.pathname||"/"}`.slice(0,180):`${e.protocol.replace(":","")||"本地"}资源`:"未知请求"}function Ni(e,t="",r="GET"){const o=String(e?.pathname||"").toLowerCase(),n=String(e?.hostname||"").toLowerCase(),s=String(t||"").toLowerCase();return/\/posts\/\d+\/replies(?:\.json)?$/.test(o)?"nested":/\/user_avatar\/|\/letter_avatar\//.test(o)||/avatar/.test(n)?"avatar":/\/(?:uploads|optimized)\//.test(o)||/\.(?:avif|gif|jpe?g|png|webp|svg|mp4|webm|mp3|ogg)(?:$|\/)/.test(o)?"media":/\/bookmarks?(?:\/|\.|$)|remove_bookmarks/.test(o)?"bookmark":/\/notifications?(?:\/|\.|$)/.test(o)?"notification":/\/message-bus(?:\/|$)/.test(o)?"realtime":/\/presence\//.test(o)?"presence":/\/search(?:\/|\.|$)|\/filter(?:\/|\.|$)/.test(o)?"search":/topic-timings|\/timings(?:\/|\.|$)/.test(o)?"read":/\/u\/|\/directory_items|\/session\/current|\/category-experts\//.test(o)?"user":/post_actions|user_actions|discourse-reactions|\/boosts?(?:\/|\.|$)|\/emojis\.json$/.test(o)?"reaction":/\/t\/|\/posts(?:\/|\.|$)|\/posts\/by_number\//.test(o)?"topic":["GET","HEAD"].includes(r)?["img","image","video","audio"].includes(s)?"media":["css","link","script","font"].includes(s)?"asset":"other":"reaction"}function Ap(e=Date.now()){const t=e-Tw;let r=0;for(;rRw&&No.splice(0,No.length-Rw);md.length&&md[0].atl.toLowerCase().startsWith(s));if(a)return a.slice(a.indexOf(":")+1).trim()}return""}if(!e||!D(e.get))return"";for(const o of t){const n=e.get(o);if(n!=null&&n!=="")return String(n)}return""}function Iw(e){const t=String(e??"").match(/-?\d+(?:\.\d+)?/);if(!t)return NaN;const r=Number(t[0]);return Number.isFinite(r)?r:NaN}function LA(e,t=Date.now()){const r=String(e??"").trim(),o=Number(r);if(!Number.isFinite(o)){const n=Date.parse(r);return Number.isFinite(n)?Math.max(0,n-t):0}return o>0?o>1e12?Math.max(0,o-t):o>t/1e3-Oo/1e3?Math.max(0,o*1e3-t):Math.max(0,o*1e3):0}function yg(e){const t=/10[_-]?(?:secs?|seconds?)/i.test(String(e||"")),r=/60[_-]?(?:secs?|seconds?)|minute/i.test(String(e||""));return{short:t,long:r,known:t||r,label:t&&r?"10s+60s":t?"10s":r?"60s":"unknown"}}function IA(e){const t=String(e?.serverLimit||"");if(!t)return[];const r=String(e?.serverRemaining||"").split(","),o=String(e?.serverReset||"").split(","),n=yg(e?.rateLimitCode),s=new Map;return t.split(",").forEach((a,l)=>{const c=Iw(a);if(!(c>0))return;const d=String(a).match(/(?:^|;)\s*w\s*=\s*"?(\d+)/i),u=d?Number(d[1]):0,f=LA(o[l]||o[0]);let m=u>0&&u<=15?"10s":u>15&&u<=90?"60s":"";if(d&&!m)return;if(!m){const{short:w,long:A}=n;if(f>9e4&&!w&&!A)return;m=w&&!A?"10s":A&&!w?"60s":c<=$p*2?"10s":"60s"}const g={window:m,limit:c,remaining:Iw(r[l]||(l===0?r[0]:"")),resetDelay:f},b=s.get(m);(!b||g.limit=200&&e.status<400;let s=null;if($t&&(n||r&&e.status===429))try{s=Ao?.snapshot()}catch{}if(n&&$t&&e.serverLimit&&$t.noteServerLimits({policies:IA(e),rateTarget:s?s.requestRateTarget/100:.8,shortBudgetCap:s?s.configuredShortWindowBudget:40,longBudgetCap:s?s.configuredLongWindowBudget:160}),n&&$t&&$t.noteSuccess({host:r,recoveryProbe:o&&e.recoveryProbe,shortBudgetCap:s?s.configuredShortWindowBudget:40,longBudgetCap:s?s.configuredLongWindowBudget:160}),r&&e.status===429&&$t){const a=e.retryAfter.trim()?Number(e.retryAfter):NaN,l=!Number.isFinite(a)&&e.retryAfter?Date.parse(e.retryAfter):0,c=Number.isFinite(a)?a*1e3:l?Math.max(0,l-Date.now()):_w;$t.noteRateLimit({wait:Math.max(1e3,c),window:yg(e.rateLimitCode).label,shortBudget:s?s.shortWindowBudget:40,longBudget:s?s.longWindowBudget:160})}}function xw(e,t,r,o){const n=Pi(t);n&&(e.path=gg(n),e.sameOrigin=n.origin===vt,e.type==="other"&&(e.type=Ni(n,e.transport,e.method)));const s=typeof o=="string"?o.split(/\r?\n/):null,a=Number(Bl(o,["Content-Length"],s));return Np(e,{status:r,size:Number.isFinite(a)?a:0,...Object.fromEntries(Object.entries(Pp).map(([l,c])=>[l,Bl(o,c,s)]))}),n}function qw(e){if(!e||e.origin!==vt)return 0;const t=e.pathname.match(/^\/t\/(?:[^/]+\/)?(\d+)(?:\/|\.json|$)/);return t?Number(t[1]):0}function xA(e,t,r){if(!e||e.source!=="host"||e.method!=="GET")return;const o=qw(t),n=r?.post_stream;if(!o||Number(r?.id)!==o||!n||!Array.isArray(n.stream)||!Array.isArray(n.posts))return;const s=String(o),a=$r.get(s);if(a&&a.scope===Yn()&&Cd(a)>=Number(e.startedAt||0))return;const l=Zo.get(s);if(!(l&&Number(l.startedAt||0)>e.startedAt))for(Zo.delete(s),Zo.set(s,{topic:r,at:Date.now(),startedAt:e.startedAt}),so(o,r,{fetchedAt:Date.now(),source:"host"});Zo.size>HA;)Zo.delete(Zo.keys().next().value)}function qA(e,t,r){if(!(!t||e.source!=="host"||e.method!=="GET"||t.status<200||t.status>=300||!qw(r)))try{if(!String(t.getResponseHeader("Content-Type")||"").toLowerCase().includes("json"))return;const n=t.responseType==="json"?t.response:JSON.parse(t.responseText);xA(e,r,n)}catch{}}function DA(e){const t=String(e?.initiatorType||"").toLowerCase();if(!e)return;const r=Pi(e.name);if(!r||!["http:","https:"].includes(r.protocol))return;const o=performance.timeOrigin+Number(e.startTime||0),n=Math.max(0,Number(e.duration)||0),s=Math.max(0,Number(e.transferSize||e.encodedBodySize)||0),a=gg(r);if(["fetch","xmlhttprequest"].includes(t)){let c=null;for(let d=Pw(o-100);do+100)break;!Number.isFinite(f)||u.controlOnly||u.resourceTimed||u.transport!==t||u.path!==a||(!c||Math.abs(f-o)({version:2,updatedAt:0,events:[],intents:[],active:[],policies:[],flights:[],cacheEpoch:0,shortBudget:0,longBudget:0,shortServerBudget:0,longServerBudget:0,cooldownUntil:0,nextProbeAt:0,shortServerBlockUntil:0,longServerBlockUntil:0,rateLimited:!1,successfulSinceLimit:0,lastRateLimitWindow:"",learnedUntil:0}),d=(ne={},R=e)=>({contextId:String(R),shortBudget:Math.max(1,Math.floor(Number(ne.shortBudget)||$p)),longBudget:Math.max(1,Math.floor(Number(ne.longBudget)||fg)),minInterval:Math.max(0,Math.floor(Number(ne.minInterval)||0)),maxConcurrent:Math.max(1,Math.floor(Number(ne.maxConcurrent)||1))}),u=(ne,R=Date.now())=>{const v=ne&&typeof ne=="object"?ne:c();return v.version=2,v.events=(Array.isArray(v.events)?v.events:[]).map(S=>({at:Number(S?.at)||0})).filter(S=>S.at>R-Mp&&S.at<=R).sort((S,I)=>S.at-I.at).slice(-600),v.intents=(Array.isArray(v.intents)?v.intents:[]).filter(S=>S&&Number(S.expiresAt)>R).slice(-120),v.active=(Array.isArray(v.active)?v.active:[]).filter(S=>S&&Number(S.expiresAt)>R).slice(-32),v.policies=(Array.isArray(v.policies)?v.policies:[]).filter(S=>S?.contextId&&Number(S.expiresAt)>R).map(S=>({...d(S,S.contextId),expiresAt:Number(S.expiresAt)})).slice(-32),v.flights=(Array.isArray(v.flights)?v.flights:[]).map(S=>({...S,heartbeatAt:Number(S?.heartbeatAt)||Math.max(0,Number(S?.expiresAt)-Ol)})).filter(S=>S?.token&&Number(S.expiresAt)>R&&Number(S.heartbeatAt)>R-EA).sort((S,I)=>Number(S.expiresAt)-Number(I.expiresAt)).slice(-120),v.cacheEpoch=Math.max(0,Math.floor(Number(v.cacheEpoch)||0)),v.shortBudget=Math.max(0,Number(v.shortBudget)||0),v.longBudget=Math.max(0,Number(v.longBudget)||0),v.shortServerBudget=Math.max(0,Number(v.shortServerBudget)||0),v.longServerBudget=Math.max(0,Number(v.longServerBudget)||0),v.cooldownUntil=Math.max(0,Number(v.cooldownUntil)||0),v.nextProbeAt=Math.max(0,Number(v.nextProbeAt)||0),v.shortServerBlockUntil=Math.max(0,Number(v.shortServerBlockUntil)||0),v.longServerBlockUntil=Math.max(0,Number(v.longServerBlockUntil)||0),v.successfulSinceLimit=Math.max(0,Number(v.successfulSinceLimit)||0),v.lastRateLimitWindow=String(v.lastRateLimitWindow||""),v.learnedUntil=Math.max(0,Number(v.learnedUntil)||0),v.learnedUntil<=R?(v.shortBudget=0,v.longBudget=0,v.shortServerBudget=0,v.longServerBudget=0,v.rateLimited=!1,v.successfulSinceLimit=0,v.lastRateLimitWindow=""):v.rateLimited=v.rateLimited===!0,v},f=(ne=Date.now())=>{try{return u(JSON.parse(localStorage.getItem(qh)||"null"),ne)}catch{return c()}},m=()=>{o.forEach(ne=>ne()),o.clear()},g=async ne=>{const R=()=>{const S=Date.now(),I=f(S),x=ne(I,S);I.updatedAt=S;try{localStorage.setItem(qh,JSON.stringify(I))}catch{}try{l&&l.postMessage({type:"updated",contextId:e})}catch{}return m(),x},v=navigator.locks;return D(v?.request)?v.request(t,{mode:"exclusive"},R):R()},b=ne=>{const R=navigator.locks;return D(R?.request)?R.request(r,{mode:"exclusive"},ne):Promise.resolve().then(ne)},w=(ne,R,v,S)=>{const I=Math.max(1,Math.floor(Math.min(v,ne.shortBudget||v,ne.shortServerBudget||v))),x=Math.max(1,Math.floor(Math.min(S,ne.longBudget||S,ne.longServerBudget||S))),me=ne.events.filter(Je=>Je.at>R-pg),ie=ne.events,O=(Je,st,pt)=>Je.length=Ie&&We?"10s":Ie?"60s":""}},A=(ne,R,v)=>{const S=w(ne,R,v.shortBudget,v.longBudget),I=Math.max(0,ne.cooldownUntil-R),x=ne.events.length&&Number(ne.events[ne.events.length-1].at)||0;return{windows:S,cooldownDelay:I,intervalDelay:Math.max(0,x+v.minInterval-R)}},U=(ne,R,v={})=>{const S={...d(v),expiresAt:R+CA},I=ne.policies.findIndex(x=>x.contextId===e);return I>=0?ne.policies[I]=S:ne.policies.push(S),S},P=(ne,R)=>{const v={shortBudget:R.shortBudget,longBudget:R.longBudget,minInterval:R.minInterval,maxConcurrent:Math.min(ne.rateLimited?2:1/0,R.maxConcurrent)};return ne.policies.forEach(S=>{S.contextId!==e&&(v.shortBudget=Math.min(v.shortBudget,S.shortBudget),v.longBudget=Math.min(v.longBudget,S.longBudget),v.minInterval=Math.max(v.minInterval,S.minInterval),v.maxConcurrent=Math.min(v.maxConcurrent,S.maxConcurrent))}),v},$=(ne,R)=>{const v=Math.min(2,Math.floor(Math.max(0,R-ne.queuedAt)/5e3));return Number(ne.priority)-v},H=(ne,R)=>new Promise((v,S)=>{let I=!1;const x=Xe=>{I||(I=!0,clearTimeout(O),o.delete(me),R&&R.removeEventListener("abort",ie),Xe())},me=()=>x(v),ie=()=>x(()=>S(new DOMException("Aborted","AbortError"))),O=setTimeout(me,Math.max(25,Math.min(1e3,ne||80)));o.add(me),R&&R.addEventListener("abort",ie,{once:!0})}),pe=ne=>{g(R=>{R.intents=R.intents.filter(v=>v.id!==ne)})},ae=async(ne={})=>{const R=`${e}:intent:${++s}`,v=Number.isFinite(ne.priority)?ne.priority:tt.visible,S=ne.signal;let I=!1,x="";try{for(;!a&&!S?.aborted;){const me=await g((ie,O)=>{const Xe=U(ie,O,ne),qe=P(ie,Xe),ce=ie.intents.find(Pt=>Pt.id===R);if(ce?ce.expiresAt=O+15e3:ie.intents.push({id:R,contextId:e,priority:v,queuedAt:O,expiresAt:O+15e3}),ie.intents.sort((Pt,Mt)=>$(Pt,O)-$(Mt,O)||Pt.queuedAt-Mt.queuedAt),!ie.intents.length||ie.intents[0].id!==R)return{granted:!1,wait:80,reason:"priority"};if(ie.active.length>=qe.maxConcurrent)return{granted:!1,wait:80,reason:"concurrency"};const{windows:Ee,cooldownDelay:We,intervalDelay:Ie}=A(ie,O,qe),Je=ie.rateLimited&&!We&&!Ee.serverDelay&&Ee.delay>0&&!Ie&&v<=tt.visible&&O>=ie.nextProbeAt,st=Math.max(We,Ie,Je?0:Ee.delay);if(st>0)return{granted:!1,wait:st,reason:We?"cooldown":Ie?"interval":Ee.blockingWindow};ie.intents.shift(),Je&&(ie.nextProbeAt=O+SA),ie.events.push({at:O});const pt=`${e}:permit:${++s}`;return ie.active.push({id:pt,contextId:e,expiresAt:O+Da+5e3}),{granted:!0,permitId:pt,startedAt:O,recoveryProbe:Je}});if(me.granted)return I=!0,{...me,waitReason:x};if(me.cancelled)throw x=String(me.reason||x||"cancelled"),new DOMException(x,"AbortError");x=String(me.reason||x),await H(me.wait,S)}throw new DOMException("Aborted","AbortError")}finally{I||pe(R)}},K=ne=>{if(!vg(ne)||a)return;const R=`${e}:host-active:${ne.id}`;ne.sharedRequestActiveId=R,ne.sharedRequestStart=g((v,S)=>{const I=Math.max(S-5e3,Math.min(S,Number(ne.startedAt)||S));v.events.push({at:I}),v.active.push({id:R,contextId:e,expiresAt:S+Da+5e3})})},ye=ne=>{ne&&g(R=>{R.active=R.active.filter(v=>v.id!==ne)})},W=ne=>{!ne||!ne.sharedRequestActiveId||Promise.resolve(ne.sharedRequestStart).catch(()=>{}).then(()=>{ye(ne.sharedRequestActiveId)})},V=ne=>g((R,v)=>{const S=String(ne||"");if(!S)return{producer:!0,flightId:""};const I=R.flights.find(me=>me.token===S);if(I)return{producer:!1,flightId:I.id,expiresAt:I.expiresAt,cacheEpoch:Number(I.cacheEpoch)||0};const x=`${e}:flight:${++s}`;return R.flights.push({id:x,token:S,contextId:e,cacheEpoch:R.cacheEpoch,heartbeatAt:v,expiresAt:v+Ol}),{producer:!0,flightId:x,expiresAt:v+Ol,cacheEpoch:R.cacheEpoch}}),G=(ne,R)=>!ne||!R?Promise.resolve():g(v=>{v.flights=v.flights.filter(S=>S.token!==String(ne)||S.id!==String(R))}),B=(ne,R)=>!ne||!R?Promise.resolve(!1):g((v,S)=>{const I=v.flights.find(x=>x.token===String(ne)&&x.id===String(R));return I?(I.heartbeatAt=S,I.expiresAt=S+Ol,!0):!1}),te=(ne,R,v,S)=>b(async()=>{const I=f();return I.cacheEpoch===Number(v||0)&&I.flights.some(me=>me.token===String(ne)&&me.id===String(R))?(await S(),!0):!1}),he=()=>b(()=>g(ne=>(ne.cacheEpoch++,ne.cacheEpoch))),Me=async(ne,R,v=Date.now()+Ol)=>{const S=String(ne||"");for(;!a&&Date.now()me.token===S);if(!x)return!0;await H(Math.min(1e3,Math.max(25,x.expiresAt-Date.now())),R)}if(R?.aborted)throw new DOMException("Aborted","AbortError");return!1},Ae=(ne={})=>{g((R,v)=>{const S=w(R,v,ne.shortBudget,ne.longBudget),I=String(ne.window||"unknown"),x=I==="unknown"||I.includes("10s"),me=I==="unknown"||I.includes("60s");if(x){const ie=Math.max(1,Math.ceil(S.shortCount*.9));R.shortBudget=R.shortBudget?Math.min(R.shortBudget,ie):ie}if(me){const ie=Math.max(1,Math.ceil(S.longCount*.9));R.longBudget=R.longBudget?Math.min(R.longBudget,ie):ie}R.cooldownUntil=Math.max(R.cooldownUntil,v+Math.max(1e3,Number(ne.wait)||0)),R.nextProbeAt=R.cooldownUntil,R.rateLimited=!0,R.successfulSinceLimit=0,R.lastRateLimitWindow=I,R.learnedUntil=v+ug})},se=()=>g(ne=>(["shortBudget","longBudget","shortServerBudget","longServerBudget","cooldownUntil","nextProbeAt","shortServerBlockUntil","longServerBlockUntil","successfulSinceLimit","learnedUntil"].forEach(R=>{ne[R]=0}),ne.rateLimited=!1,ne.lastRateLimitWindow="",!0)),Ye=(ne={})=>{const R=Math.min(.95,Math.max(.5,Number(ne.rateTarget)||.8)),v=Math.max(1,Math.floor(Number(ne.shortBudgetCap)||40)),S=Math.max(1,Math.floor(Number(ne.longBudgetCap)||160)),I=(Array.isArray(ne.policies)?ne.policies:[]).map(O=>{const Xe=O&&O.window==="10s"?"10s":O&&O.window==="60s"?"60s":"",qe=Math.max(0,Number(O?.limit)||0),ce=Xe==="10s"?v:S;return{window:Xe,limit:qe,remaining:Number(O?.remaining),resetDelay:Math.max(0,Number(O?.resetDelay)||0),cap:ce,desired:Math.max(1,Math.min(ce,Math.floor(qe*R)))}}).filter(O=>O.window&&O.limit>0);if(!I.length)return;const x=Date.now(),me=f(x);I.some(O=>{const Xe=O.window==="10s"?"shortServerBudget":"longServerBudget",qe=O.window==="10s"?"shortServerBlockUntil":"longServerBlockUntil",ce=Number(me[Xe])||0,Ee=ce||O.cap,We=O.desired0&&O.desired>ce,Ie=Math.max(1,Math.ceil(O.limit*(1-R))),Je=Number.isFinite(O.remaining)&&O.remaining<=Ie&&O.resetDelay>0,st=Je?x+O.resetDelay:0,pt=Je?st>Number(me[qe]||0)+500:Number(me[qe]||0)>x;return We||pt})&&g((O,Xe)=>{let qe=!1;I.forEach(ce=>{const Ee=ce.window==="10s"?"shortServerBudget":"longServerBudget",We=ce.window==="10s"?"shortServerBlockUntil":"longServerBlockUntil",Ie=ce.window==="10s"?pg:Mp,Je=Number(O[Ee])||0;if(!Je&&ce.desiredJe){const Pt=Math.max(1,Math.ceil((ce.desired-Je)*.35)),Mt=Math.min(ce.desired,Je+Pt);O[Ee]=Mt>=ce.cap&&ce.desired>=ce.cap?0:Mt,qe=!0}const st=Math.max(1,Math.ceil(ce.limit*(1-R)));if(Number.isFinite(ce.remaining)&&ce.remaining<=st&&ce.resetDelay>0){const Pt=Xe+Math.min(Ie+1e3,ce.resetDelay);Pt>Number(O[We]||0)+500&&(O[We]=Pt,qe=!0)}else Number(O[We]||0)>Xe&&(O[We]=0,qe=!0)}),qe&&(O.learnedUntil=Math.max(O.learnedUntil,Xe+ug))})},Z=(ne={})=>{const R=f();!R.rateLimited&&!R.shortBudget&&!R.longBudget||g((v,S)=>{if(S=vA))return;const me=Math.max(1,Number(ne.shortBudgetCap)||$p),ie=Math.max(1,Number(ne.longBudgetCap)||fg),O=ne.recoveryProbe?wA:1.04;v.shortBudget&&(v.shortBudget=Math.min(me,Math.max(v.shortBudget*O,v.shortBudget+(ne.recoveryProbe?2:1)))),v.longBudget&&(v.longBudget=Math.min(ie,Math.max(v.longBudget*O,v.longBudget+(ne.recoveryProbe?6:3)))),v.successfulSinceLimit>=yA?(v.rateLimited=!1,v.successfulSinceLimit=0):v.rateLimited||(v.successfulSinceLimit=0);const Xe=!v.shortBudget||v.shortBudget>=me,qe=!v.longBudget||v.longBudget>=ie;!v.rateLimited&&Xe&&qe&&(v.shortBudget=0,v.longBudget=0),v.learnedUntil=S+ug})},Ge=(ne,R,v=0,S=1,I=Date.now())=>{const x=f(I),me=P(x,d({shortBudget:ne,longBudget:R,minInterval:v,maxConcurrent:S})),{windows:ie,cooldownDelay:O,intervalDelay:Xe}=A(x,I,me),qe=Math.max(O,Xe,ie.delay),ce=new Set([...x.policies.map(Ee=>Ee.contextId),...x.intents.map(Ee=>Ee.contextId),...x.active.map(Ee=>Ee.contextId)].filter(Boolean));return{...ie,queued:x.intents.length,active:x.active.length,instances:Math.max(1,ce.size),maxConcurrent:me.maxConcurrent,minInterval:me.minInterval,coordinationMode:D(navigator.locks?.request)?"atomic":"best-effort",coolingDown:O>0,cooldownRemaining:O,nextPermitDelay:qe,blockingReason:O?"cooldown":Xe?"interval":ie.blockingWindow,rateLimited:x.rateLimited,lastRateLimitWindow:x.lastRateLimitWindow}},xe=ne=>{ne.key===qh&&m()},ze=ne=>{try{l&&l.postMessage({type:"cache",contextId:e,message:ne})}catch{}},we=ne=>{const R=ne?.data;R&&R.type==="cache"&&R.contextId!==e&&n.forEach(v=>{try{v(R.message||{})}catch{}}),m()};try{l=new globalThis.BroadcastChannel(Dh),l.addEventListener("message",we)}catch{}return window.addEventListener("storage",xe),{contextId:e,acquirePermit:ae,recordHostStart:K,recordHostFinish:W,finishPermit:ye,acquireCacheFlight:V,releaseCacheFlight:G,renewCacheFlight:B,writeCacheFlight:te,invalidateCacheWrites:he,waitForCacheFlight:Me,noteRateLimit:Ae,resetRateLimits:se,noteServerLimits:Ye,noteSuccess:Z,snapshot:Ge,publishCache:ze,subscribeCache(ne){return D(ne)?(n.add(ne),()=>n.delete(ne)):()=>{}},destroy(){a||(a=!0,g(ne=>{ne.intents=ne.intents.filter(R=>R.contextId!==e),ne.active=ne.active.filter(R=>R.contextId!==e),ne.policies=ne.policies.filter(R=>R.contextId!==e),ne.flights=ne.flights.filter(R=>R.contextId!==e)}),window.removeEventListener("storage",xe),l&&l.close(),l=null,n.clear(),m())}}}function wg(){if(!hg){const e=Ft("jquery"),t=e&&(e.default||e);if(D(t)){const r=t(document);r.on("ajaxSend.ldpRequestFlow",(o,n,s={})=>{const a=String(s.type||s.method||"GET").toUpperCase();mg.set(n,{event:bg(s.url,{method:a,[Es]:{callSite:""}},"xmlhttprequest"),url:s.url})}),r.on("ajaxComplete.ldpRequestFlow",(o,n)=>{const s=mg.get(n);if(!s)return;mg.delete(n);let a="";try{a=n.getAllResponseHeaders()}catch{}const l=xw(s.event,n.responseURL||s.url,n.status,a);qA(s.event,n,l)}),hg=!0}}if(Rp&&!Fl&&D(window.PerformanceObserver))try{Fl=new window.PerformanceObserver((e,t,r)=>{e.getEntries().forEach(DA);const o=Math.max(0,Number(r?.droppedEntriesCount)||0);o&&md.push({at:vo(),count:o}),Ap()}),Fl.observe({type:"resource",buffered:!Aw}),Aw=!0}catch{}return hg}function Dw(e){if(Rp=e===!0,Rp){wg();return}Fl&&Fl.disconnect(),Fl=null}function Hl(e,t={}){const r=t[Es]||{},o={...t,[Es]:{...r,source:"reader"}},n=bg(e,o,"fetch");let s;try{s=window.fetch(e,t)}catch(a){throw Np(n,{error:a?.name||"fetch_error"}),a}return Promise.resolve(s).then(a=>(xw(n,a?.url,a?.status,a?.headers),a),a=>{throw Np(n,{error:a?.name||"fetch_error"}),a})}$t=FA(),wg();function Sg(){return Ao?.resetRateLimits?(Ao.resetRateLimits(),!0):!$t||!$t.resetRateLimits?!1:($t.resetRateLimits(),!0)}const tt=Object.freeze({target:-2,topic:-1,scroll:0,visible:1,nested:2,userCard:1,auxiliary:3,background:4}),_g=64,Ul=180,jl=[".ldp-user-link[data-user-card]",".ldp-user-avatar-card[data-user-card]",".ldp-topic-owner-link[data-user-card]","html.ldp-reader-workspace :is(.topic-list-item,.latest-topic-list-item) :is(.posters,.topic-poster) [data-user-card]"].join(","),BA=250,Ow=500,HA=8,Zo=new Map,$r=new Map,hd=new Map,Oa=new Map,$s=new Map,ki=new Map,Fa=new Map,Qn=new Map,gd=new Map,Rs=new Map,kp=new Map,zl=new Map,Ba=new Map,Lp=new Map,Ip=new WeakSet,xp=new Map,qp=new Map,Li=new Map,Dp=new Map,Wl=[{label:"头像",cacheName:Fh,objectUrls:Ba,requests:Lp,maxEntries:512,maxBytes:32*1024*1024},{label:"表情",cacheName:cp,objectUrls:xp,requests:qp,maxEntries:512,maxBytes:16*1024*1024},{label:"原图",cacheName:Pl,objectUrls:Li,requests:Dp,maxEntries:24,maxBytes:96*1024*1024}],Op=new Set,bd=new Map;let Ha=new AbortController,aa=!1;const Wr=new Map,Cg=new Map,Fp=new Map,Fw=new WeakMap,UA=96,jA=24*1024*1024,Eg=32,zA=512;let Ii=null,Bw=!1,yd=null,Hw=0;const xi=new Map,Mg=new Set;let Ua=null,Bp=0;function WA(){let e=0;for(Wr.forEach(t=>{e+=Math.max(0,Number(t?.bytes)||0)});Wr.size>UA||e>jA&&Wr.size>1;){const t=Wr.keys().next().value,r=Wr.get(t);e-=Math.max(0,Number(r?.bytes)||0),Wr.delete(t)}}function $g(e,t){Wr.delete(e),Wr.set(e,t),WA()}function Hp(e,t){return e&&typeof e=="object"&&Fw.set(e,Number(t)||Date.now()),e}function Uw(e){return Number(e&&typeof e=="object"&&Fw.get(e))||0}function ia(e){const t=String(e||"");let r=2166136261;for(let o=0;o>>0).toString(36)}function vd(){if(Ii)return Ii;if(typeof indexedDB>"u")return Promise.resolve(null);let e;return e=new Promise(t=>{let r=!1;const o=s=>{if(r){s&&s.close();return}r=!0,t(s)};let n;try{n=indexedDB.open(_T,1)}catch{o(null);return}n.onupgradeneeded=()=>{const s=n.result,a=s.objectStoreNames.contains(ad)?n.transaction.objectStore(ad):s.createObjectStore(ad,{keyPath:"id"});a.indexNames.contains("kind")||a.createIndex("kind","kind",{unique:!1}),a.indexNames.contains("tags")||a.createIndex("tags","tags",{unique:!1,multiEntry:!0})},n.onsuccess=()=>{const s=n.result;s.onversionchange=()=>{s.close(),Ii===e&&(Ii=null)},o(s)},n.onerror=()=>o(null),n.onblocked=()=>o(null)}),Ii=e,e.then(t=>{!t&&Ii===e&&(Ii=null)}),e}function wd(e,t,r){return new Promise(o=>{try{const n=e.transaction(ad,t);n.oncomplete=()=>o(!0),n.onerror=n.onabort=()=>o(!1),r(n.objectStore(ad))}catch{o(!1)}})}function Up(e,t){$t&&$t.publishCache({action:e,...t})}function jw(e){try{const t=new URL(String(e||""),location.href);["track_visit","forceLoad","_"].forEach(o=>t.searchParams.delete(o));const r=t.searchParams.getAll("post_ids[]").sort((o,n)=>String(o).localeCompare(String(n)));return r.length&&(t.searchParams.delete("post_ids[]"),r.forEach(o=>t.searchParams.append("post_ids[]",o))),t.searchParams.sort(),t.hash="",t}catch{return null}}function Yn(){const e=Number(To?.id)||0,t=String(Yt||"").trim().toLocaleLowerCase(),r=e?`id:${e}`:t?`username:${t}`:Yt===""?"anonymous":"";if(r)return`account:${ia(r)}`;const o=String((document.querySelector('meta[name="csrf-token"]')||{}).content||"");return o?`session:${ia(o)}`:"session:anonymous"}function Rg(e,t={},r={}){const o=String(t.method||"GET").toUpperCase(),n=jw(e);if(o!=="GET"||!n||n.origin!==vt)return null;const s=n.pathname,a=new Set;let l="responses",c=id,d=30*Oo,u=!0;const f=s.match(/^\/t\/(?:[^/]+\/)?(\d+)(?:\/|\.json|$)/),m=s.match(/^\/posts\/by_number\/(\d+)\/(\d+)\.json$/),g=s.match(/^\/posts\/(\d+)(?:\/replies)?\.json$/),b=s.match(/^\/u\/([^/]+)(?:\/[^/]+)?\.json$/),w=s.match(/^\/u\/[^/]+\/bookmarks\.json$/),A=/^\/discourse-reactions\/posts\/reactions(?:\.json)?$/.test(s),U=String(n.searchParams.get("filter")||"").split(","),P=s==="/user_actions.json"&&U.includes("1"),$=s==="/notifications.json"||s==="/user_actions.json"&&U.some(ae=>["2","6","7","9","11","17"].includes(ae))||s==="/discourse-reactions/posts/reactions-received.json"||/^\/discourse-boosts\/users\/[^/]+\/boosts-received\.json$/.test(s)||/^\/topics\/private-messages(?:-(?:sent|new|unread|archive|warnings))?\/[^/]+\.json$/.test(s);f&&a.add(`topic:${f[1]}`),m&&(a.add(`topic:${m[1]}`),a.add(`post-number:${m[1]}:${m[2]}`)),g&&a.add(`post:${g[1]}`),n.searchParams.getAll("post_ids[]").forEach(ae=>a.add(`post:${ae}`));const H=Number(n.searchParams.get("post_id"));if(H&&a.add(`post:${H}`),$)l="notifications",c=oo,d=5*oo,u=!1,a.add("notifications");else if(w)c=oo,a.add("bookmarks");else if(A||P)c=oo,a.add("reactions-given");else if(s==="/search.json")c=oo,d=5*oo,u=!1;else if(f||m||g||s==="/post_voting/comments")l="topics",c=s.includes("/replies.json")||s==="/post_voting/comments"?5*oo:30*oo,d=180*Oo;else if(s.startsWith("/category-experts/endorsable-categories/")){l="users",c=oo,d=5*oo,u=!1;const ae=s.match(/^\/category-experts\/endorsable-categories\/([^/.]+)\.json$/);ae&&a.add(`user:${decodeURIComponent(ae[1]).toLocaleLowerCase()}`)}else if(b||s.startsWith("/directory_items.json")){l="users",c=24*id,d=180*Oo,b&&a.add(`user:${decodeURIComponent(b[1]).toLocaleLowerCase()}`);const ae=n.searchParams.get("username");ae&&a.add(`user:${ae.toLocaleLowerCase()}`)}return{id:`${Yn()}|${n.href}`,kind:l,tags:[...a],freshFor:c,retainFor:d,persist:u,cacheMode:r.cacheMode||"default"}}async function jp(e){const t=Wr.get(e);if(t)return Wr.delete(e),Wr.set(e,t),t;const r=await vd();if(!r)return null;let o=null;return await wd(r,"readonly",n=>{const s=n.get(e);s.onsuccess=()=>{o=s.result||null}}),o&&$g(e,o),o}async function zp(e){Wr.delete(e),await Tg(e,t=>t.delete(e)),Up("response-delete",{token:ia(e)})}function zw(e,t,r=e.bytes){const o=Date.now();return{id:e.id,kind:e.kind,tags:e.tags,storedAt:o,expiresAt:o+e.retainFor,bytes:Number.isFinite(r)?Math.max(0,Number(r)):yS(t),value:t}}function Tg(e,t,r){const o=Fp.get(e)||Promise.resolve();return Jl(Fp,e,o.catch(()=>{}).then(()=>vd()).then(n=>n&&wd(n,"readwrite",t)).then(n=>r?r(n):n).catch(()=>null))}function Ag(e,t){const r=zw(e,t);return $g(e.id,r),e.persist?(Bw||(Bw=!0,D(navigator.storage?.persist)&&navigator.storage.persist().catch(()=>!1)),Tg(e.id,o=>o.put(r),o=>{o&&Up("response-write",{token:ia(e.id)})})):Promise.resolve()}function Pg(e,t){const r=Number(e);return r>0?{id:`${Yn()}|snapshot:topic:${r}`,kind:"topics",tags:[`topic:${r}`],freshFor:op,retainFor:mo.topics.maxAge,persist:!0,bytes:t}:null}function ja(e){return e?.post_stream||{}}function Ww(e){const t=ja(e),r=Array.isArray(t.posts)?t.posts:[];let n=4096+(Array.isArray(t.stream)?t.stream:[]).length*16;return r.forEach(s=>{!s||typeof s!="object"||(n+=1024,["cooked","raw","name","username","display_username","avatar_template"].forEach(a=>{n+=String(s[a]||"").length*2}))}),n}function VA(e,t){const r=String(Number(e)||"");if(!r||!D(t))return()=>{};hd.has(r)||hd.set(r,new Set);const o=hd.get(r);return o.add(t),()=>{o.delete(t),o.size||hd.delete(r)}}function Ng(e,t){const r=hd.get(String(Number(e)||""));!r||!r.size||!t||r.forEach(o=>{try{o(t)}catch{}})}function GA(e,t){let r=null,o=null,n=!1;return Tg(e.id,s=>{const a=s.get(e.id);a.onsuccess=()=>{const c=a.result?.value,d=c&&c.version===dp&&Number(c.topicId)===Number(t.topicId)&&c.topic;d&&Number(c.updatedAt)>Number(t.updatedAt)?(n=Sd(c.topic,t.topic),o={...c,lastAccessAt:Math.max(Number(c.lastAccessAt)||0,Number(t.lastAccessAt)||0),topic:c.topic}):(d&&(n=Sd(t.topic,c.topic)),o=t),r=zw(e,o,Ww(o.topic));try{s.put(r)}catch{r=null,o=null}},a.onerror=()=>{r=null,o=null}},s=>(s&&r&&($g(e.id,r),Up("response-write",{token:ia(e.id)})),s&&o?{payload:o,mergedPosts:n}:null))}async function Vw(e){const t=String(Number(e)||""),r=Oa.get(t);r?.timer&&clearTimeout(r.timer),Oa.delete(t);const o=$r.get(t),n=Yn();if(!o||o.scope!==n||!o.topic)return;const s=Pg(t,Ww(o.topic));if(!s)return;const a=await GA(s,{version:dp,topicId:Number(t),fetchedAt:Number(o.fetchedAt)||Date.now(),lastAccessAt:Number(o.lastAccessAt)||Date.now(),updatedAt:Number(o.updatedAt)||Date.now(),topic:o.topic});if(!a)return;const l=a.payload;l.topic!==o.topic||Number(l.updatedAt)!==Number(o.updatedAt)?Vp(t,l.topic,{fetchedAt:l.fetchedAt,lastAccessAt:l.lastAccessAt,updatedAt:l.updatedAt,full:!0,notify:!0,source:"snapshot-merge"}):a.mergedPosts&&Ng(t,l.topic),$t&&$t.publishCache({action:"topic-snapshot-write",topicId:Number(t),scopeToken:ia(n),updatedAt:Number(l.updatedAt)||Date.now()})}function kg(e){const t=String(Number(e)||""),r=$r.get(t);if(!t||!r||r.scope!==Yn())return;const o=Date.now(),n=Oa.get(t);n?.timer&&clearTimeout(n.timer);const s=Number(n?.firstQueuedAt)||o,a=Math.min(o+CT,s+ET),l=setTimeout(()=>{Vw(t)},Math.max(0,a-o));Oa.set(t,{firstQueuedAt:s,timer:l})}function Vl(e){(e==null?[...Oa.keys()]:[String(Number(e)||"")]).forEach(r=>{const o=Oa.get(r);o?.timer&&clearTimeout(o.timer),Oa.delete(r)})}function Gw(){return Promise.all(Array.from(Oa.keys(),e=>Vw(e)))}function Sd(e,t){const r=e?.post_stream,o=t?.post_stream;if(!r||!o)return!1;const n=Array.isArray(r.posts)?r.posts:[],s=new Map(n.map((l,c)=>[Number(l?.id),c]));let a=!1;return(Array.isArray(o.posts)?o.posts:[]).forEach(l=>{const c=Number(l?.id);!c||s.has(c)||(s.set(c,n.length),n.push(l),a=!0)}),r.posts=n,(!Array.isArray(r.stream)||!r.stream.length)&&Array.isArray(o.stream)&&(r.stream=o.stream.slice(),a=!0),a}async function Qw(e,t={}){const r=Pg(e);if(!r)return null;t.preferStored===!0&&Wr.delete(r.id);const o=await jp(r.id),n=o?.value,s=Date.now(),a=Number(n?.fetchedAt)||Number(o?.storedAt)||0;if(!n||n.version!==dp||Number(n.topicId)!==Number(e)||!n.topic||!(a>0)||s-a>mo.topics.maxAge)return o&&await zp(r.id),null;const l=String(Number(e)),c=$r.get(l),d=Number(n.updatedAt)||Number(o.storedAt)||a;if(c&&c.scope===Yn()&&c.topic){const u=Sd(c.topic,n.topic),f=Number(c.updatedAt)||0;if(f>d||f===d&&t.preferStored!==!0)return u&&Ng(e,c.topic),c.topic;Sd(n.topic,c.topic)}return Vp(e,n.topic,{fetchedAt:a,lastAccessAt:s,updatedAt:d,full:!0,notify:!0,source:t.preferStored===!0?"shared-snapshot":"snapshot"}),n.topic}function Yw(e){const t=String(e||"").trim().toLocaleLowerCase();return t?{id:`${Yn()}|snapshot:reactions-given:${encodeURIComponent(t)}`,kind:"responses",tags:["reactions-given"],freshFor:oo,retainFor:30*Oo,persist:!0}:null}async function QA(e){const t=Yw(e);if(!t)return null;const r=await jp(t.id);if(!r)return null;const o=Number(r.storedAt||0),n=Date.now()-o,s=r.value||{};return!(o>0)||n>t.retainFor||s.version!==1||!Array.isArray(s.entries)?(await zp(t.id),null):{entries:s.entries,storedAt:o,fresh:n<=t.freshFor}}function Xw(e,t){const r=Yw(e);r&&Ag(r,{version:1,entries:Array.isArray(t)?t:[]})}function YA(e){if(!e||e.name==="AbortError")return!1;const t=Number(e.status||0);return!t||t===408||t===429||t>=500}async function XA(e,t,r,o){if(r.cacheMode==="bypass")return o();const n=Rg(e,t,r);if(!n)return o();let s=await jp(n.id);const a=Number(s?.storedAt||0);let l=s?Date.now()-Number(s.storedAt||0):1/0;if(s&&l>n.retainFor)await zp(n.id),s=null,l=1/0;else if(s&&n.cacheMode!=="refresh"&&l<=n.freshFor)return Hp(s.value,s.storedAt);const c=`${n.cacheMode}:${n.id}`,d=Cg.get(c);if(d)return d;const u=(async()=>{const f=n.persist&&$t?ia(n.id):"",m=async()=>{Wr.delete(n.id);const w=await jp(n.id),A=Number(w?.storedAt||0),U=w?Date.now()-A:1/0;return!w||U>n.retainFor?void 0:(s=w,l=U,(n.cacheMode==="refresh"?A>a:U<=n.freshFor)?Hp(w.value,A):void 0)};let g=null,b=0;try{if(f){const A=Date.now()+Ol*2+5e3;for(;!g;){if(Date.now()>=A)throw Bd("等待共享缓存请求超时");const U=await $t.acquireCacheFlight(f);if(!U.producer){if(!await $t.waitForCacheFlight(f,t.signal,A))throw Bd("等待共享缓存请求超时");const H=await m();if(H!==void 0)return H;continue}g=U,b=setInterval(()=>{$t.renewCacheFlight(f,U.flightId).then($=>{$||!b||(clearInterval(b),b=0)}).catch(()=>{})},15e3);const P=await m();if(P!==void 0)return P}}const w=Hp(await o(),Date.now());return g&&$t?await $t.writeCacheFlight(f,g.flightId,g.cacheEpoch,()=>Ag(n,w)):await Ag(n,w),w}catch(w){if(r.allowStaleOnError!==!1&&s&&l<=n.retainFor&&YA(w))return Hp(s.value,s.storedAt);throw w}finally{b&&clearInterval(b),b=0,g&&$t&&await $t.releaseCacheFlight(f,g.flightId)}})();return Jl(Cg,c,u)}async function KA(e,t){const r=await vd();return r?wd(r,e,o=>{const n=o.openCursor();n.onsuccess=()=>{const s=n.result;s&&(t(s.value||{},s),s.continue())}}):!1}function JA(e,t,r){const o=new Set,n=new Map;return e.forEach(s=>{const a=String(s?.id||"");if(!a)return;if(t(s)<=r){o.add(a);return}const l=mo[s.kind]?s.kind:"responses";let c=n.get(l);c||(c=[],n.set(l,c)),c.push(s)}),n.forEach((s,a)=>{const l=mo[a]||mo.responses,c=Math.max(0,Number(l.storedMaxEntries)||0),d=Math.max(0,Number(l.storedMaxBytes)||0);if(!c&&!d)return;let u=0,f=0;s.sort((m,g)=>Number(g?.storedAt||0)-Number(m?.storedAt||0)),s.forEach(m=>{const g=Math.max(0,Number(m?.bytes)||0),b=c>0&&u>=c,w=d>0&&f+g>d;if(b||w){o.add(String(m.id));return}u++,f+=g})}),o}async function Kw(e=!1){const t=Date.now();if(!e&&t-Hw{const n=Number(o?.expiresAt);if(n>0)return n;const s=String(o?.id||""),a=s.indexOf("|"),l=a>=0?Rg(s.slice(a+1)):null;return Number(o?.storedAt||0)+(l?l.retainFor:mo.responses.maxAge)};return yd=(async()=>{const o=await vd();if(!o)return;let n=!1;!await wd(o,"readwrite",a=>{const l=[],c=a.openCursor();c.onsuccess=()=>{const d=c.result;if(d){const u=d.value||{};l.push({id:u.id,kind:u.kind,storedAt:u.storedAt,expiresAt:u.expiresAt,bytes:u.bytes}),d.continue();return}JA(l,r,t).forEach(u=>{Wr.delete(u),a.delete(u)}),n=!0}})||!n||(Hw=t)})().finally(()=>{yd=null}),yd}async function ho({kinds:e=[],tags:t=[],all:r=!1}={}){$t&&await $t.invalidateCacheWrites(),Fp.size&&await Promise.all([...Fp.values()]);const o=new Set(e),n=new Set(t);Wr.forEach((a,l)=>{(r||o.has(a.kind)||(a.tags||[]).some(c=>n.has(c)))&&Wr.delete(l)});const s=await vd();s&&await wd(s,"readwrite",a=>{if(r)a.clear();else{const l=[...Array.from(o,u=>[a.index("kind"),u]),...Array.from(n,u=>[a.index("tags"),u])],c=new Set;let d=l.length;l.forEach(([u,f])=>{const m=u.getAllKeys(IDBKeyRange.only(f));m.onsuccess=()=>{(m.result||[]).forEach(g=>c.add(g)),d--,d||c.forEach(g=>a.delete(g))},m.onerror=()=>{d--,d||c.forEach(g=>a.delete(g))}})}}),Up("response-clear",{kinds:e,tags:t,all:r})}async function ZA(){await Kw(!0);const e={topics:{count:0,bytes:0},users:{count:0,bytes:0},notifications:{count:0,bytes:0},responses:{count:0,bytes:0}};let t=0,r=0;const o=new Set,n=new Set,s=new Set,a=new Set,l={bookmarks:0,reactions:0,other:0},c=()=>({topics:{...e.topics,topicIds:[...o],postCount:n.size,topicSnapshotCount:t,topicRequestCount:r},users:{...e.users,userNames:[...s]},notifications:{...e.notifications,notificationIds:[...a]},responses:{...e.responses,responseRecords:l}});return await KA("readonly",d=>{const u=e[d.kind];if(u){u.count++,u.bytes+=Math.max(0,Number(d.bytes)||0);const f=new Set(Array.isArray(d.tags)?d.tags.map(String):[]);if(d.kind==="topics"){f.forEach(A=>{const U=String(A).match(/^topic:(\d+)$/);U&&o.add(Number(U[1]))});const m=d.value,g=String(d.id||"").includes("|snapshot:topic:")||!!(m&&m.version===dp&&m.topicId&&m.topic);g?t++:r++;const b=g&&m?m.topic:m,w=Number(m?.topicId||b?.id||0);w>0&&o.add(w),Lr(b).forEach(A=>{const U=Number(A?.topic_id||w||0);U>0&&o.add(U);const P=Number(A?.id||0),$=Number(A?.post_number||0);P>0?n.add(`id:${P}`):U>0&&$>0&&n.add(`number:${U}:${$}`)})}else if(d.kind==="users"){f.forEach(b=>{const w=b.match(/^user:(.+)$/);w?.[1]&&s.add(w[1].toLocaleLowerCase())});const m=d.value||{},g=[m.user,m];(Array.isArray(m.directory_items)?m.directory_items:[]).forEach(b=>{g.push(b&&(b.user||b))}),g.forEach(b=>{const w=sr(b?.username).toLocaleLowerCase();w&&s.add(w)})}else if(d.kind==="notifications"){const m=d.value&&Array.isArray(d.value.notifications)?d.value.notifications:[];L_(a,m)}else d.kind==="responses"&&(f.has("bookmarks")?l.bookmarks++:f.has("reactions-given")?l.reactions++:l.other++)}}),c()}function eP(e,t,r){const o=jw(e);if(o&&o.pathname==="/topics/timings")return[];const n=new Set,s=Object.assign({},t||{},r||{}),a=Number(s.topic_id||s.topicId||s.bookmarkable_type==="Topic"&&s.bookmarkable_id||0),l=Number(s.post_id||s.postId||s.bookmarkable_type==="Post"&&s.bookmarkable_id||r?.post&&r.post.id||0);if(a&&n.add(`topic:${a}`),l&&n.add(`post:${l}`),o){const c=o.pathname.match(/^\/t\/(?:[^/]+\/)?(\d+)/),d=o.pathname.match(/^\/(?:posts|post_actions)\/(\d+)/),u=o.pathname.match(/^\/discourse-reactions\/posts\/(\d+)/),f=o.pathname.match(/^\/(?:u|follow|category-experts\/endorse)\/([^/.]+)/);c&&n.add(`topic:${c[1]}`),d&&n.add(`post:${d[1]}`),u&&(n.add(`post:${u[1]}`),n.add("reactions-given")),o.pathname==="/post_actions"&&Number(t?.id)&&n.add(`post:${Number(t.id)}`),(o.pathname==="/post_actions"||/^\/post_actions\/\d+/.test(o.pathname))&&n.add("reactions-given"),(o.pathname==="/bookmarks"||o.pathname.startsWith("/bookmarks/")||/\/remove_bookmarks$/.test(o.pathname))&&n.add("bookmarks"),f&&n.add(`user:${decodeURIComponent(f[1]).toLocaleLowerCase()}`),o.pathname.startsWith("/notifications/")&&n.add("notifications")}return[...n]}function Wp(e,t=1200){let r=!1;const o=()=>{r||e()};if(D(requestIdleCallback)){const s=requestIdleCallback(o,{timeout:t});return()=>{r=!0,D(cancelIdleCallback)&&cancelIdleCallback(s)}}const n=setTimeout(o,t);return()=>{r=!0,clearTimeout(n)}}function _d(e){const t=Di(e),r=Number(mo[e]?.maxEntries)||0;if(!(!t||!r))for(;t.size>r;)t.delete(t.keys().next().value)}function Cd(e){return Number(e?.fetchedAt)||Number(e?.at)||0}function Vp(e,t,r={}){const o=String(Number(e)||"");if(!o||!t)return null;const n=Date.now(),s=String(r.scope||Yn()),a=$r.get(o),l=a&&a.scope===s?a:null,c={topic:t,scope:s,fetchedAt:Number(r.fetchedAt)||Cd(l)||n,lastAccessAt:Number(r.lastAccessAt)||n,updatedAt:Number(r.updatedAt)||n,source:String(r.source||l?.source||"memory")};return $r.delete(o),$r.set(o,c),_d("topics"),r.notify!==!1&&Ng(o,t),c}function Gl(e){const t=String(Number(e)||"");if(!t)return null;const r=Date.now(),o=Yn();let n=$r.get(t);if(n&&n.scope!==o){if(Yt===null&&String(n.scope||"").startsWith("account:"))return null;n.source==="host"&&r-Cd(n)<=op?(n.scope=o,n.updatedAt=r,kg(t)):($r.delete(t),n=null)}if(n&&r-Cd(n)>mo.topics.maxAge&&($r.delete(t),n=null),!n){const s=Zo.get(t);Zo.delete(t),s&&r-Number(s.at||0)<=op&&(n=Vp(t,s.topic,{fetchedAt:Number(s.at)||r,source:"host"}),kg(t))}return n?($r.delete(t),n.lastAccessAt=r,$r.set(t,n),n.topic):null}function so(e,t,r={}){Vp(e,t,r)&&kg(e)}function sr(e){return String(e||"").replace(/^@/,"").trim()}function za(e){return`${Yn()}|${e}`}function Gp(e){const t=za(sr(e)),r=ki.get(t);return r?Date.now()-Number(r.at||0)>mo.users.maxAge?(ki.delete(t),Mn("users"),null):(ki.delete(t),r.at=Date.now(),ki.set(t,r),r.user||null):null}function qi(e,t,r=250){const o=sr(e);if(!o||!t)return;const n=za(o);ki.delete(n),ki.set(n,{user:t,at:Date.now()}),_d("users"),Mn("users",r)}function Di(e){return e==="topics"?$r:e==="topicNavIcons"?$s:e==="users"?ki:e==="notifications"?Rs:null}function Lg(e){const t=mo[e];if(!t||!t.storageKey||e==="history")return[];try{const r=JSON.parse(localStorage.getItem(t.storageKey)||"null");return!r||r.version!==I0||!Array.isArray(r.entries)?[]:r.entries}catch{return[]}}function Ig(e,t){const r=mo[e];if(!r)return[];const o=Date.now(),n=Yt===null?"":e==="notifications"?za("tabs-v7:"):e==="users"?za(""):"",s=(Array.isArray(t)?t:[]).filter(a=>!Array.isArray(a)||a.length!==2||a[0]==null||!a[1]||n&&!String(a[0]).startsWith(n)?!1:Number.isFinite(Number(a[1].at))&&o-Number(a[1].at)<=r.maxAge);return r.maxEntries?s.slice(-r.maxEntries):s}function Jw(e){return!!e&&(e.name==="QuotaExceededError"||e.name==="NS_ERROR_DOM_QUOTA_REACHED"||e.code===22||e.code===1014)}function tP(e){const t=mo[e],r=Di(e);if(!t||!r)return;const o=new Map(Lg(e).map(([s,a])=>[String(s),a]));r.forEach((s,a)=>{const l=String(a),c=o.get(l);(!c||Number(s?.at||0)>=Number(c?.at||0))&&(o.delete(l),o.set(l,s))});const n=Ig(e,[...o.entries()]);for(;;)try{n.length?localStorage.setItem(t.storageKey,JSON.stringify({version:I0,entries:n})):localStorage.removeItem(t.storageKey);break}catch(s){if(!Jw(s)||!n.length)return;n.shift()}r.clear(),n.forEach(([s,a])=>r.set(String(s),a)),$t&&$t.publishCache({action:"map-update",key:e})}function xg(){if(Ua){const t=Ua;Ua=null,t()}Bp=0;const e=[...Mg];Mg.clear(),e.forEach(tP)}function Mn(e,t=2e3){if(!Di(e)||!mo[e]?.storageKey)return;Mg.add(e);const r=Math.max(0,Number(t)||0),o=Date.now()+r;Ua&&Bp<=o||(Ua&&Ua(),Bp=o,Ua=Wp(()=>{Ua=null,Bp=0,xg()},r))}function rP(){try{localStorage.removeItem(hT)}catch{}["topicNavIcons","users","notifications"].forEach(e=>{const t=Di(e);if(!t)return;const r=Lg(e),o=Ig(e,r);o.forEach(([n,s])=>t.set(String(n),s)),e==="notifications"&&o.forEach(([,n])=>{const s=n?.value&&n.value.notifications;Array.isArray(s)&&s.forEach(a=>{const l=Ln(a),c=a.acting_user_avatar_template||a.avatar_template||l.acting_user_avatar_template||l.avatar_template||"",d=Jn(a);d&&c&&Hd(d,c)})}),o.length!==r.length&&Mn(e)})}function oP(e){const t=Di(e);if(!t)return;let r=!1;Ig(e,Lg(e)).forEach(([o,n])=>{const s=String(o),a=t.get(s);(!a||Number(n?.at||0)>Number(a?.at||0))&&(t.delete(s),t.set(s,n),r=!0)}),_d(e),r&&Mn(e,0)}function Zw(e){(Array.isArray(e)?e:[]).forEach(t=>{t==="topics"&&(Vl(),Zo.clear());const r=Di(String(t));r&&r.clear(),t==="users"&&(Fa.clear(),Qn.clear(),gd.clear()),t==="notifications"&&kp.clear()})}function nP(e){const t=String(e?.action||"");if(t==="topic-snapshot-write"){const r=Number(e.topicId);if(!(r>0)||String(e.scopeToken||"")!==ia(Yn()))return;const o=Pg(r);o&&Wr.delete(o.id),Qw(r,{preferStored:!0});return}if(t==="map-update"){oP(String(e.key||""));return}if(t==="map-delete"&&e.key==="topics"){const r=String(e.entryKey||"");$r.delete(r),Zo.delete(r),Vl(r);return}if(t==="map-clear"){Zw(e.keys);return}if(t==="response-write"||t==="response-delete"){const r=String(e.token||"");for(const o of Wr.keys())r&&ia(o)===r&&Wr.delete(o);return}if(t==="response-clear"){const r=new Set(Array.isArray(e.kinds)?e.kinds:[]),o=new Set(Array.isArray(e.tags)?e.tags:[]);Wr.forEach((n,s)=>{(e.all||r.has(n.kind)||(n.tags||[]).some(a=>o.has(a)))&&Wr.delete(s)})}}function cn(){try{const e=JSON.parse(localStorage.getItem(ap)||"[]");if(!Array.isArray(e))return[];const t=mo.history,r=e.filter(o=>o&&Number(o.topicId)>0&&Number(o.viewedAt||0)>=Date.now()-t.maxAge);return r.length!==e.length?Wa(r):r}catch{return[]}}function qg(e){return Number(e?.firstViewedAt||e?.viewedAt)||0}function Dg(e){return Oe.historySortMode==="recent-viewed"?Number(e?.viewedAt)||0:qg(e)}function Og(e=cn()){return e.slice().sort((t,r)=>Dg(r)-Dg(t)||Number(r.topicId||0)-Number(t.topicId||0))}function Wa(e){const t=Array.isArray(e)?e.slice():[];for(;;)try{return t.length?localStorage.setItem(ap,JSON.stringify(t)):localStorage.removeItem(ap),lP(t),t}catch(r){if(!Jw(r)||!t.length)return t;t.pop()}}function Ed(e){const t=e instanceof Set?[...e]:Array.isArray(e)?e:[];return[...new Set(t.map(r=>Math.floor(Number(r)||0)).filter(r=>r>0))].sort((r,o)=>r-o)}function Qp(e){return Ed(e?.readPostNumbers)}function Fg(e,t=0,r=[]){const o=Number(e?.id);if(!o)return;const n=cn(),s=n.find(g=>Number(g.topicId)===o),a=Math.max(1,Math.floor(Number(t)||Number(s?.postNumber)||1)),l=Ed([...Qp(s),...Ed(r),a]),d=(e?.post_stream&&Array.isArray(e.post_stream.posts)?e.post_stream.posts:[]).find(g=>Number(g?.post_number)===1),u=Date.now(),f={topicId:o,title:String(e.title||`帖子 #${o}`),postsCount:Math.max(0,Number(e.posts_count)||0),avatarTemplate:String(e.details?.created_by&&e.details.created_by.avatar_template||d?.avatar_template||""),ownerUsername:String(e.details?.created_by&&e.details.created_by.username||d?.username||e._opUsername||""),postNumber:a,readPostNumbers:l,firstViewedAt:qg(s)||u,viewedAt:u};Wa([f,...n.filter(g=>Number(g.topicId)!==o)]);const m=Ct?._ldpReaderShell;D(m?.refreshHistoryPanel)&&m.refreshHistoryPanel()}function Yp(e){const t=e&&typeof e=="object"?e:{postNumber:e},r=Math.floor(Number(t.postNumber));if(!(r>0))return null;const o=Number(t.postOffset),n=Number(t.scrollTop);return{postNumber:r,postOffset:Number.isFinite(o)?o:0,scrollTop:Number.isFinite(n)?Math.max(0,n):0}}function eS(e){const t=Math.floor(Number(e?.number));return t>0?{number:t,scrollTop:Math.max(0,Number(e.scrollTop)||0),offset:Number.isFinite(Number(e.offset))?Number(e.offset):12}:null}function Bg(e){const t=Math.floor(Number(e?.rootPostNumber));return t>0?{rootPostNumber:t,point:eS(e.point)}:null}function Hg(e){const t=Math.floor(Number(e?.topicId)),r=Math.floor(Number(e?.postNumber));if(!(t>0)||!(r>0))return null;const o=Math.floor(Number(e?.parentPostNumber)),n=Yp(e?.anchor?.viewport);return{topicId:t,postNumber:r,parentPostNumber:o>0?o:0,nested:e?.nested===!0&&o>0,anchor:n?{viewport:n,replyWindow:Bg(e.anchor.replyWindow),quoteHighlight:null}:null}}function Ug(e){const t=Math.floor(Number(e?.postNumber)),r=String(e?.text||e?.quoteText||"");return t>0&&r?{postNumber:t,text:r,source:Hg(e.source),active:e.active!==!1}:null}function $n(e){const t=e&&typeof e=="object"&&"viewport"in e?e:{viewport:e},r=Yp(t.viewport);return r?{viewport:r,replyWindow:Bg(t.replyWindow),quoteHighlight:Ug(t.quoteHighlight)}:null}function tS(e){const t={};return!e||typeof e!="object"||Object.entries(e).forEach(([r,o])=>{const n=Number(r),s=$n(o);n>0&&s&&(t[n]=s)}),t}function Oi(e,t=1){const r=e?._ldpReaderShell?.activeContext,o=Yp((D(e?._ldpCaptureHistoryViewport)?e._ldpCaptureHistoryViewport():null)||mm(r)||t);return o?{viewport:o,replyWindow:Bg(D(r?.replyThreadWindow?._ldpCaptureAnchorState)?r.replyThreadWindow._ldpCaptureAnchorState():null),quoteHighlight:Ug(r?.quoteHighlightState)}:null}function Xp(e){const t=Number(e);return Number.isFinite(t)?Math.min(sg,Math.max(ng,Math.round(t))):hw}function rS(e,t){const r=Number(e),o=l=>[...new Set((Array.isArray(l)?l:[]).map(Number).filter(c=>c>0&&c!==r))];if(t&&(Array.isArray(t.back)||Array.isArray(t.forward)))return{back:o(t.back),forward:o(t.forward),states:tS(t.states)};const n=Og().map(l=>Number(l.topicId)).filter(l=>l>0),s=n.indexOf(r),a=Oe.historySortMode==="first-viewed"&&s>=0;return{back:o(a?n.slice(s+1):n),forward:o(a?n.slice(0,s).reverse():[]),states:{}}}function sP(e,t,r){const o=e.querySelector(".ldp-reader-history-back"),n=e.querySelector(".ldp-reader-history-forward");if(!o||!n)return()=>{};const s=o.closest(".ldp-reader-history-edge"),a=n.closest(".ldp-reader-history-edge"),l=e.querySelector(".ldp-modal"),c=Ho();let d=null,u=!1,f=!1;const m=(B,te)=>{u!==B&&(u=B,s?.classList.toggle("is-active",B)),f!==te&&(f=te,a?.classList.toggle("is-active",te))},g=()=>{m(!1,!1)},b=()=>{d=null},w=()=>{const B=Xp(Oe.historyEdgeTriggerPercent);if(B<=0)return d={backLimit:0,forwardLimit:0,enabled:!1},d;const te=l.getBoundingClientRect(),he=te.width*B/100;return d={backLimit:te.left+he,forwardLimit:te.right-he,enabled:!0},d},A=()=>{const B=Oe.historyButtonsAlwaysVisible===!0;e.classList.toggle("ldp-history-buttons-always-visible",B),b(),B&&g()},U=B=>{if(!l||Oe.historyButtonsAlwaysVisible===!0||B.pointerType&&B.pointerType!=="mouse"){g();return}const te=d||w(),he=te.enabled&&B.clientX<=te.backLimit,Me=te.enabled&&B.clientX>=te.forwardLimit,Ae=B.target instanceof Element?B.target:null,se=!!Ae&&o.contains(Ae),Ye=!!Ae&&n.contains(Ae);if(!he&&!Me&&!se&&!Ye){g();return}if(Ae?.closest(".ldp-settings-popover,.ldp-notifications-popover,.ldp-history-popover,.ldp-bookmarks-popover")){g();return}m(he||se,Me||Ye)},P=B=>{Oe.historyButtonsAlwaysVisible!==!0&&(!B.pointerType||B.pointerType==="mouse")&&w()},$=()=>{g(),b()};l&&c.listen(l,"pointerenter",P),l&&c.listen(l,"pointermove",U),l&&c.listen(l,"pointerleave",$),c.listen(window,"resize",b),c.listen(e,"ldp-reader-window-change",b),c.listen(e,"ldp-reader-workspace-change",b),e._ldpSyncHistoryButtonVisibilityPreference=A,A(),o.setAttribute("aria-keyshortcuts","ArrowLeft"),n.setAttribute("aria-keyshortcuts","ArrowRight");const H=B=>cn().find(te=>Number(te.topicId)===Number(B))?.title||`帖子 #${B}`,pe=B=>{la(B)},ae=()=>{o.disabled=!1,n.disabled=!1;const B=r.back[0],te=r.forward[0];if(o.hidden=!B,n.hidden=!te,s&&(s.hidden=!B),a&&(a.hidden=!te),B){const he=`上一条历史:${H(B)}`;rt(o,he)}if(te){const he=`下一条历史:${H(te)}`;rt(n,he)}pe(o),pe(n)},K=B=>{const te=B==="back",Me=(te?r.back:r.forward)[0];if(!Me)return;o.disabled=!0,n.disabled=!0;const Ae=Number(e.querySelector(".ldp-topic-timeline-track")?.getAttribute("aria-valuenow"))||1,se={...r.states,[Number(t)]:Oi(e,Ae)},Ye=$n(se[Me]),Z=te?{back:r.back.slice(1),forward:[Number(t),...r.forward],states:se}:{back:[Number(t),...r.back],forward:r.forward.slice(1),states:se};lo(Me,{targetPostNumber:Ye?.viewport.postNumber||0,restoreState:Ye||void 0,historyNavigation:Z,settleTargetJump:!0})},ye=()=>pe(o),W=()=>pe(n);c.listen(o,"click",()=>K("back")),c.listen(n,"click",()=>K("forward")),c.listen(o,"pointerenter",ye),c.listen(n,"pointerenter",W);const V=B=>{if(Ct!==e||!e.isConnected||B.defaultPrevented||B.isComposing||B.altKey||B.ctrlKey||B.metaKey||B.shiftKey||to(".ldp-lightbox"))return;const te=B.key==="ArrowLeft"?o:B.key==="ArrowRight"?n:null;if(!te||te.hidden||te.disabled)return;const he=B.target instanceof Element?B.target:null;he&&he!==document.body&&he!==Lt&&!e.contains(he)||he&&(he.isContentEditable||he.closest("input,textarea,select,.ldp-topic-timeline-track"))||(bt(B),te.click())};c.listen(document,"keydown",V);const G=()=>{const B=rS(t);r.back=B.back,r.forward=B.forward,ae()};return e._ldpRefreshReaderHistoryNavigation=G,ae(),()=>{g(),c.destroy(),e._ldpRefreshReaderHistoryNavigation===G&&delete e._ldpRefreshReaderHistoryNavigation,e._ldpSyncHistoryButtonVisibilityPreference===A&&delete e._ldpSyncHistoryButtonVisibilityPreference}}function dn(e){const t=Number(e);return t>0&&xl.get(String(t))||null}function Md(e){const t=e?.x,r=e?.y,o=Number(t),n=Number(r),s=t!=null&&t!==""&&r!=null&&r!==""&&Number.isFinite(o)&&Number.isFinite(n);return{x:s?Math.max(0,Math.min(1,o)):null,y:s?Math.max(0,Math.min(1,n)):null,dock:s&&["left","right"].includes(e?.dock)?e.dock:""}}function oS(e=Ri){return Number.isFinite(e?.x)&&Number.isFinite(e?.y)}function nS(){if(fd&&clearTimeout(fd),fd=0,_p)return;const e=kr.map(r=>{const o=String(r?.avatarSource||"");return{topicId:Number(r?.topicId)||0,title:String(r?.title||""),avatarTemplate:String(r?.avatarTemplate||""),avatarSource:/^https?:\/\//i.test(o)?o:"",ownerUsername:String(r?.ownerUsername||""),addedAt:Math.max(0,Number(r?.addedAt)||0),pinned:r&&r.pinned===!0,totalCount:Math.max(0,Number(r?.totalCount)||0),urlPostNumber:Math.max(0,Number(r?.urlPostNumber)||0),anchor:$n(r?.anchor)}}).filter(r=>r.topicId>0),t=Md(Ri);try{e.length||oS(t)?localStorage.setItem(xh,JSON.stringify({version:1,entries:e,surface:t})):localStorage.removeItem(xh)}catch(r){console.warn("[LDP] 阅读队列保存失败",r?.name||"storage-error")}}function Fi(){_p||fd||(fd=setTimeout(nS,250))}function aP(){let e=[],t=null;try{const o=JSON.parse(localStorage.getItem(xh)||"null");e=Array.isArray(o)?o:Array.isArray(o?.entries)?o.entries:[],t=!Array.isArray(o)&&o&&o.surface}catch{return}if(Ri=Md(t),!e.length)return;const r=new Set;_p=!0;try{e.forEach(o=>{const n=Number(o?.topicId);if(!(n>0)||r.has(n))return;r.add(n);const s=tf(n,{title:o.title,avatarTemplate:o.avatarTemplate,avatarSource:o.avatarSource,ownerUsername:o.ownerUsername},{prefetch:!1,silent:!0});s&&(s.addedAt=Math.max(0,Number(o.addedAt)||0)||s.addedAt,s.pinned=o.pinned===!0,s.totalCount=Math.max(s.totalCount,Number(o.totalCount)||0),s.urlPostNumber=Math.max(0,Number(o.urlPostNumber)||0),s.anchor=$n(o.anchor||o.viewport)||s.anchor)})}finally{_p=!1}}function sS(e,t={},r=null){const o=Number(e),n=r||Gl(o),s=cn().find(c=>Number(c.topicId)===o),l=(n?.post_stream&&Array.isArray(n.post_stream.posts)?n.post_stream.posts:[]).find(c=>Number(c?.post_number)===1);return{title:String(t.title||n?.title||s?.title||`帖子 #${o}`).replace(/\s+/g," ").trim(),avatarTemplate:String(t.avatarTemplate||n?.details&&n.details.created_by&&n.details.created_by.avatar_template||l?.avatar_template||s?.avatarTemplate||""),avatarSource:String(t.avatarSource||""),ownerUsername:String(t.ownerUsername||n?.details&&n.details.created_by&&n.details.created_by.username||l?.username||s?.ownerUsername||""),navMetadata:Ts(t.navMetadata||{},Od(n)),totalCount:Math.max(0,Number(n&&(n.highest_post_number||n.posts_count))||0,Number(s?.postsCount)||0),historyPostNumber:Math.max(0,Number(s?.postNumber)||0),urlPostNumber:Math.max(0,Number(t.urlPostNumber)||0),readPostNumbers:Qp(s)}}function aS(e,t){const r=e&&e.nodeType===Node.ELEMENT_NODE?e:null,o=r?.closest("tr.topic-list-item,.topic-list-item,.latest-topic-list-item,.search-result-topic,.fps-result,.category-topic-link"),n=o?.querySelector('a.raw-topic-link[href*="/t/"],a.title[href*="/t/"],.link-top-line a[href*="/t/"],a[href*="/t/"]'),s=o?.querySelector(":is(.posters,.topic-poster) img.avatar,img.avatar"),a=o?.querySelector("[data-user-card]"),l=co(n&&(n.getAttribute("href")||n.href));return{title:String(r&&r.dataset.topicTitle||n&&(n.dataset.topicTitle||n.textContent)||r?.textContent||`帖子 #${t}`).replace(/\s+/g," ").trim(),avatarTemplate:String(s?.dataset.ldpAvatarOriginalTemplate||s?.dataset.ldpAvatarTemplate||s?.dataset.avatarTemplate||""),avatarSource:String(s&&(s.currentSrc||s.src)||""),ownerUsername:String(a&&a.dataset.userCard||""),navMetadata:ma(r,t),urlPostNumber:Math.max(0,Number(l?.postNumber)||0)}}function iP(e){const t=ja(e),r=Array.isArray(t.stream)?t.stream.filter(Boolean):[],o=new Set(r.map(Number).filter(Boolean)),n=new Set((Array.isArray(t.posts)?t.posts:[]).map(s=>Number(s?.id)).filter(s=>s&&(!o.size||o.has(s))));return{total:r.length||Math.max(0,Number(e?.posts_count)||0),loaded:n.size}}function lP(e){const t=new Map((Array.isArray(e)?e:[]).map(o=>[String(Number(o?.topicId)||0),o]));let r=!1;kr.forEach(o=>{const n=t.get(String(o.topicId)),s=n?new Set([...o.seenPostNumbers,...Qp(n)]):new Set;(s.size!==o.seenPostNumbers.size||[...s].some(a=>!o.seenPostNumbers.has(a)))&&(o.seenPostNumbers=s,r=!0),!n&&o.progressPersistTimer&&(clearTimeout(o.progressPersistTimer),o.progressPersistTimer=0)}),r&&Rn()}function iS(e){if(!e)return;const t=Ed(e.seenPostNumbers);if(!t.length)return;const r=cn(),o=r.find(d=>Number(d.topicId)===Number(e.topicId)),n=Qp(o),s=Ed([...n,...t]),a=Math.max(s[s.length-1]||0,Number(e.totalCount)||0,Number(o?.postsCount)||0);if(s.length===n.length&&Number(o?.postsCount)>=a)return;const l=Date.now(),c={...o||{},topicId:Number(e.topicId),title:String(e.title||o?.title||`帖子 #${e.topicId}`),postsCount:a,avatarTemplate:String(e.avatarTemplate||o?.avatarTemplate||""),ownerUsername:String(e.ownerUsername||o?.ownerUsername||""),postNumber:Math.max(1,Number(o?.postNumber)||Number(e.anchor?.viewport.postNumber)||s[s.length-1]||1),readPostNumbers:s,firstViewedAt:qg(o)||l,viewedAt:Number(o?.viewedAt)||l};delete c.readPostNumber,Wa([c,...r.filter(d=>Number(d.topicId)!==Number(e.topicId))])}function cP(e){!e||e.progressPersistTimer||(e.progressPersistTimer=setTimeout(()=>{e.progressPersistTimer=0,iS(e)},500))}function Kp(e){e&&(e.progressPersistTimer&&clearTimeout(e.progressPersistTimer),e.progressPersistTimer=0,iS(e))}function dP(e,t){const r=Math.max(0,Math.floor(Number(t)||0));return!e||!r||e.seenPostNumbers.has(r)?!1:(e.seenPostNumbers.add(r),cP(e),!0)}function Jp(e){const t=Math.max(0,Number(e?.totalCount)||0);return!e||!t?0:Math.max(0,Math.min(100,e.seenPostNumbers.size/t*100))}function lS(e){return!e||Oe.openTopicsAtFirstPost===!0?1:Math.max(1,Number(e.urlPostNumber)||Number(e.anchor?.viewport.postNumber)||1)}function Zp(e){const t=Math.max(0,Number(e.totalCount)||0),r=Math.max(0,Number(e.anchor?.viewport.postNumber)||0),o=e.seenPostNumbers.size,n=Math.round(Jp(e)),s=e.pinned?"已固定 · ":"";if(String(e.topicId)===Po)return`${s}阅读进度 ${n}% · 已读 ${o}/${t||"?"}${r?` · 当前 #${r}`:""}`;const a=`正文 ${Math.max(0,Number(e.loadedCount)||0)}/${t||"?"}${e.nestedTotalCount>0?` · 二级回复 ${Math.max(0,Number(e.nestedLoadedCount)||0)}/${e.nestedTotalCount}`:""}${e.mediaTotalCount>0?` · 图片 ${Math.max(0,Number(e.mediaLoadedCount)||0)}/${e.mediaTotalCount}`:""}`;return e.loadState==="ready"?`${s}已预加载 · ${a} · 阅读进度 ${n}%`:e.loadState==="loading"?`${s}正在预加载 · ${a} · 阅读进度 ${n}%`:e.loadState==="partial"?`${s}已分层预加载 · ${a} · 阅读进度 ${n}%`:e.loadState==="error"?`${s}预加载失败 · 阅读进度 ${n}%,点击重试`:`${s}等待预加载 · 阅读进度 ${n}%`}function cS(e){const t=String(e.ownerUsername||e.title||"?").trim().slice(0,1).toUpperCase()||"?",r=Kn(e.avatarTemplate||e.avatarSource,64,"ldp-reader-queue-avatar-image",t);return r||`${$e(t)}`}function Va(e){if(!e||!Ct)return;const t=Ct.querySelector(".ldp-reader-queue");if(!t)return;const r=String(Number(e.topicId)),o=Jp(e),n=Zp(e),s=t.querySelector(`.ldp-reader-queue-bubble[data-reader-queue-topic-id="${r}"]`);if(s){["queued","loading","partial","ready","error"].forEach(d=>s.classList.toggle(`is-${d}`,e.loadState===d));const l=`${o*3.6}deg`;s.style.getPropertyValue("--ldp-reader-queue-progress")!==l&&s.style.setProperty("--ldp-reader-queue-progress",l),s.classList.toggle("is-progress-complete",o>=100),rt(s,`${e.title},${n}`);const c=`${e.title} · ${n}`;s.dataset.ldpTooltipLabel!==c&&(s.dataset.ldpTooltipLabel=c)}const a=t.querySelector(`.ldp-reader-queue-row[data-reader-queue-topic-id="${r}"]`);if(a){const l=a.querySelector(".ldp-reader-queue-row-progress"),c=`${o*3.6}deg`;l?.style.getPropertyValue("--ldp-reader-queue-progress")!==c&&l?.style.setProperty("--ldp-reader-queue-progress",c),l?.classList.toggle("is-progress-complete",o>=100);const d=a.querySelector(".ldp-reader-queue-row-copy strong");d&&d.textContent!==e.title&&(d.textContent=e.title);const u=a.querySelector(".ldp-reader-queue-row-copy small");u&&u.textContent!==n&&(u.textContent=n)}}function jg(e){const t=e?.querySelector(".ldp-reader-queue-bubbles"),r=e?.querySelector(".ldp-reader-queue-scroll-hint");if(!t||!r)return;const o=Math.max(0,t.scrollHeight-t.clientHeight),n=o>=2;if(r.hidden=!n,!n)return;const s=t.scrollTop>=o-2;r.classList.toggle("is-up",s),r.dataset.scrollDirection=s?"-1":"1",rt(r,s?"回到队列上方头像":"显示下方更多队列头像")}function dS(e){const t=e?.querySelector(".ldp-reader-queue-toggle"),r=t?.querySelector("b");if(!t||!r)return;const o=!e.classList.contains("is-preview-collapsed");go(t,o),rt(t,kr.length?`${o?"收纳":"展开"}队列头像预览;拖动可移动,贴边可隐藏;悬停显示队列详情,共 ${kr.length} 篇`:"关闭空阅读队列入口")}function zg(e){const t=e?.closest(".ldp-modal");if(!t)return null;const r=t.getBoundingClientRect(),o=t.querySelector(":scope > .ldp-header")?.getBoundingClientRect(),n=Math.max(0,t.clientHeight-e.offsetHeight);return{modal:t,modalRect:r,maxLeft:Math.max(0,t.clientWidth-e.offsetWidth),maxTop:n,minTop:Math.max(0,Math.min(n,(o?.bottom||r.top)-r.top))}}function uS(e,t,r){const o=e?.closest(".ldp-overlay"),n=o?.classList.contains("ldp-fullpage")&&t?.modal?.clientWidth>700?o.querySelector(".ldp-topic-action-rail:not([hidden])"):null;if(!n)return r;const s=n.getBoundingClientRect(),a=s.top-t.modalRect.top,l=s.bottom-t.modalRect.top,c=e.offsetHeight,d=Math.max(12,Math.round((e.querySelector(".ldp-reader-queue-toggle")?.offsetHeight||0)/2)),u=w=>Math.max(t.minTop,Math.min(t.maxTop,w)),f=w=>w+c+d<=a||w>=l+d,m=u(r);if(f(m))return m;const g=u(Math.max(t.minTop,t.maxTop*.12));if(f(g))return g;const b=[a-d-c,l+d].filter(w=>w>=t.minTop&&w<=t.maxTop);return b.length?b.reduce((w,A)=>Math.abs(A-r)0)||!(c>0))return;const d=(H,pe,ae)=>Math.max(pe,Math.min(ae,H)),u=s.left+n,f=Math.max(u,s.right-n-l),m=s.top+n,g=Math.max(m,s.bottom-n-c),b=a.left-u-n,w=s.right-n-a.right-n,A=e.classList.contains("is-docked-right")||ww,U=d(A?a.left-n-l:a.right+n,u,f);let P=d(a.top,m,g);const $=[...o.querySelectorAll(":scope > .ldp-reader-window-capsule,.ldp-modal > .ldp-header,.ldp-rate-limit-notice:not([hidden])")].filter(H=>getComputedStyle(H).display!=="none").map(H=>H.getBoundingClientRect()).concat(a).sort((H,pe)=>H.top-pe.top);for(const H of $){if(U>=H.right+n||U+l<=H.left-n||P>=H.bottom+n||P+c<=H.top-n)continue;const pe=d(H.bottom+n,m,g);P=pe+c<=s.bottom-n?pe:d(H.top-n-c,m,g)}t.classList.add("is-collision-positioned"),t.style.left=`${Math.round(U-a.left)}px`,t.style.top=`${Math.round(P-a.top)}px`}function $d(e){if(!e)return;const t=zg(e),r=t?.modal,o=e.closest(".ldp-overlay"),n=Md(Ri),s=oS(n),a=t?.modalRect,c=(o?.classList.contains("ldp-fullpage")&&r?.clientWidth>700?o.querySelector(".ldp-topic-action-rail:not([hidden]) .ldp-topic-action-rail-toggle"):null)?.getBoundingClientRect(),d=a&&c?.width?Math.max(0,Math.min(r.clientWidth-e.offsetWidth,c.left+c.width/2-a.left-e.offsetWidth/2)):null,u=Number.isFinite(d);e.classList.toggle("is-docked-left",s&&!u&&n.dock==="left"),e.classList.toggle("is-docked-right",s&&!u&&n.dock==="right");const f=e.querySelector(".ldp-reader-queue-toggle")?.getBoundingClientRect(),m=e.querySelector(".ldp-reader-queue-bubbles");if(a&&f&&m){const g=a.bottom-f.bottom,b=Math.min(m.scrollHeight,Number.parseFloat(getComputedStyle(m).maxHeight)||m.scrollHeight);e.classList.toggle("is-preview-reversed",!e.classList.contains("is-preview-collapsed")&&gg)}if(!s||!r||e.hidden){if(!s&&(e.style.removeProperty("left"),e.style.removeProperty("top"),e.style.removeProperty("bottom"),e.classList.remove("is-runtime-positioned"),r&&r.clientWidth>700)){const g=r.querySelector(".ldp-reader-main"),b=g?Number.parseFloat(getComputedStyle(g).gridTemplateColumns):e.offsetWidth,w=t.maxTop,A=u?d:(Math.max(b||0,e.offsetWidth)-e.offsetWidth)/2;e.style.left=`${Math.round(Math.max(0,Math.min(r.clientWidth-e.offsetWidth,A)))}px`,e.style.top=`${Math.round(uS(e,t,Math.max(t.minTop,w*.12)))}px`,e.classList.add("is-runtime-positioned")}pS(e);return}e.classList.add("is-runtime-positioned"),e.style.left=`${Math.round(u?d:t.maxLeft*n.x)}px`,e.style.top=`${Math.round(uS(e,t,Math.max(t.minTop,t.maxTop*n.y)))}px`,pS(e)}function Wg(e){const t=e?.querySelector(".ldp-reader-queue");if(!t)return;const r=t.querySelector(".ldp-reader-queue-toggle"),o=r?.querySelector("b"),n=t.querySelector(".ldp-reader-queue-bubbles"),s=t.querySelector(".ldp-reader-queue-scroll-hint"),a=t.querySelector(".ldp-reader-queue-panel"),l=t.querySelector(".ldp-reader-queue-list"),c=t.querySelector(".ldp-reader-queue-panel-count"),d=t.querySelector(".ldp-reader-queue-clear"),u=a&&!a.hidden,f=t.dataset.readerQueueActiveTopicId||"",m=n?n.scrollTop:0;if(t.hidden=!kr.length&&!Oe.readerQueueAlwaysVisibleWhenEmpty,t.classList.toggle("is-empty",!kr.length),!r||!o||!n||!s||!a||!l||!c||!d)return;o.textContent=kr.length?String(kr.length):"×",dS(t),c.textContent=`${kr.length} 篇`,d.disabled=!kr.some(b=>!b.pinned),Vr(n),n.innerHTML=kr.map(b=>{const w=String(b.topicId)===Po,A=Jp(b);return` - ${b.pinned?``:""} - `}).join(""),Vr(l),l.innerHTML=kr.map(b=>{const w=String(b.topicId)===Po,A=Jp(b);return`
`}).join(""),Gr(l),l.innerHTML=Lr.map(b=>{const w=String(b.topicId)===Po,R=af(b);return`
- - ${cS(b)} + + ${wS(b)} ${$e(b.title)} - ${$e(Zp(b))} + ${$e(lf(b))} ${b.loadState==="error"?``:""} @@ -78,13 +78,36 @@ aria-pressed="${b.pinned?"true":"false"}">${ue("pin")} -
`}).join(""),wo(n,tt.auxiliary),wo(l,tt.auxiliary);const g=f!==Po;if(t.dataset.readerQueueActiveTopicId=Po,g){const b=n.querySelector(".ldp-reader-queue-bubble.is-active");if(b){const w=b.offsetTop,A=w+b.offsetHeight;wn.scrollTop+n.clientHeight&&(n.scrollTop=Math.max(0,A-n.clientHeight+4))}}else n.scrollTop=Math.min(m,Math.max(0,n.scrollHeight-n.clientHeight));jg(t),a.hidden=!u,ar(r,u),$d(t)}function Rn(){document.querySelectorAll(".ldp-reader-queue-add[data-reader-queue-topic-id]").forEach(e=>{const t=!!dn(e.dataset.readerQueueTopicId);e.dataset.readerQueueAdded!==String(t)&&fS(e,t)}),D(Ct?._ldpSyncReaderQueue)&&Ct._ldpSyncReaderQueue()}function fS(e,t){const r=t?"从阅读队列移除":"加入阅读队列并后台预加载";e.dataset.readerQueueAdded=String(t),e.classList.toggle("is-added",t),e.innerHTML=ue(t?"check":"plus"),rt(e,r),e.setAttribute("title",r)}function ef(e,t,r=0,o={}){if(!e||!t)return;const n=sS(e.topicId,e,t);e.title=n.title,e.avatarTemplate=n.avatarTemplate||e.avatarTemplate,e.avatarSource=n.avatarSource||e.avatarSource,e.ownerUsername=n.ownerUsername||e.ownerUsername,e.navMetadata=n.navMetadata,e.urlPostNumber=n.urlPostNumber||e.urlPostNumber||0;const s=iP(t);e.totalCount=Math.max(0,Number(r)||s.total||e.totalCount||0),e.loadedCount=Math.min(e.totalCount||s.loaded,s.loaded),e.totalCount>0&&e.loadedCount>=e.totalCount&&e.prefetchEnriched?e.loadState="ready":e.loadState==="ready"&&(e.loadState="queued"),e.error="",Fi(),o.progressOnly===!0?Va(e):Rn()}function tf(e,t={},r={}){const o=Number(e);if(!(o>0))return null;let n=dn(o);const s=sS(o,t);if(n)n.title=s.title||n.title,n.avatarTemplate=s.avatarTemplate||n.avatarTemplate,n.avatarSource=s.avatarSource||n.avatarSource,n.ownerUsername=s.ownerUsername||n.ownerUsername,n.navMetadata=Ts(s.navMetadata,n.navMetadata),n.urlPostNumber=s.urlPostNumber||n.urlPostNumber||0,n.totalCount=Math.max(Number(n.totalCount)||0,s.totalCount),s.readPostNumbers.forEach(a=>n.seenPostNumbers.add(a)),!n.anchor&&s.historyPostNumber&&(n.anchor=$n(s.historyPostNumber)),n.loadState==="error"&&r.retry===!0&&(n.loadState="queued",n.error="");else{n={topicId:o,title:s.title,avatarTemplate:s.avatarTemplate,avatarSource:s.avatarSource,ownerUsername:s.ownerUsername,navMetadata:s.navMetadata,addedAt:Date.now(),loadState:"queued",loadedCount:0,nestedLoadedCount:0,nestedTotalCount:0,mediaLoadedCount:0,mediaTotalCount:0,totalCount:s.totalCount,urlPostNumber:s.urlPostNumber,anchor:s.historyPostNumber?$n(s.historyPostNumber):null,seenPostNumbers:new Set(s.readPostNumbers),progressPersistTimer:0,prefetchController:null,prefetchEnriched:!1,switching:!1,pinned:!1,error:""},kr.push(n),xl.set(String(o),n);const a=Gl(o);a&&ef(n,a)}return Fi(),Rn(),r.prefetch!==!1&&Bi(),n}function Vg(e,t){const r=dn(e),o=$n(t);!r||!o||(r.anchor=o,Fi(),Rn())}function uP(e){e&&(Po=String(e.topicId),e.prefetchController&&(e.prefetchController.abort(),e.prefetchController=null,e.loadState==="loading"&&(e.loadState="queued")),Rn())}async function Gg(e){const t=dn(e);if(!t||t.switching)return;if(String(t.topicId)===Po&&Ct&&Number(Ct.dataset.topicId)===t.topicId){const o=Ct.querySelector(".ldp-reader-queue-panel"),n=Ct.querySelector(".ldp-reader-queue-toggle");o&&(o.hidden=!0),n&&ar(n,!1);return}const r=Number(Ct&&Ct.dataset.topicId);r>0&&Vg(r,Oi(Ct)),t.switching=!0,Rn();try{const o=lS(t),n=Oe.openTopicsAtFirstPost===!0||t.urlPostNumber>0;await lo(t.topicId,{targetPostNumber:o,restoreViewport:n?{postNumber:o,postOffset:0}:void 0,restoreState:n?void 0:t.anchor||void 0,topicNavMetadata:t.navMetadata,readerQueueMetadata:t,settleTargetJump:!0})}finally{t.switching=!1,Rn()}}function rf(e){const t=dn(e);if(!t)return!1;const r=kr.indexOf(t),o=String(t.topicId)===Po;return Kp(t),t.prefetchController&&t.prefetchController.abort(),xl.delete(String(t.topicId)),r>=0&&kr.splice(r,1),Fi(),o&&(Po=""),Rn(),Bi(),!0}function pP(e){const t=dn(e);return t?(t.pinned=!t.pinned,Fi(),Rn(),ft(t.pinned?"已固定,离开后仍保留在队列":"已取消固定,离开后将自动出队"),!0):!1}function mS(e){const t=dn(e);return!t||t.pinned?!1:rf(t.topicId)}function fP(e){const t=kr.filter(s=>s.pinned),r=new Set(t),o=kr.filter(s=>!r.has(s));if(!o.length)return ft("队列中没有可清理的未固定文章"),!1;const n=new Set(o.map(s=>String(s.topicId)));return!!Cc(e,{title:"清理阅读队列?",message:t.length?`将移除 ${o.length} 篇未固定文章,保留 ${t.length} 篇固定文章。`:`将移除队列中的 ${o.length} 篇文章。`,note:"当前阅读不会关闭,正文、头像和图片缓存不会删除。",icon:"trash",confirmLabel:`清理 ${o.length} 篇`,onConfirm:()=>{const s=kr.filter(c=>n.has(String(c.topicId))&&!c.pinned);if(!s.length){ft("队列中没有可清理的未固定文章");return}const a=new Set(s);s.forEach(c=>{Kp(c),c.prefetchController&&c.prefetchController.abort(),xl.delete(String(c.topicId))});const l=kr.filter(c=>!a.has(c));kr.splice(0,kr.length,...l),dn(Po)||(Po=""),Fi(),Rn(),Bi(),ft(`已从队列清理 ${s.length} 篇文章`)}})}function mP(e,t){const r=ja(t),o=Array.isArray(r.stream)?r.stream.filter(Boolean):[];if(o.length<=_s)return o;const n=Array.isArray(r.posts)?r.posts:[],s=lS(e),l=+(n.find(A=>+(A?.post_number||0)===s)?.id||0),c=l?o.indexOf(l):-1,d=c>=0?c:Math.max(0,Math.min(o.length-1,s-1));if(Oe.openTopicsAtFirstPost!==!0&&+(e?.urlPostNumber||0)>0){const A=Math.min(d,lA);let U=Math.max(0,d-A),P=Math.min(o.length,d+_s-A);return U=Math.max(0,P-_s),P=Math.min(o.length,U+_s),o.slice(U,P)}if(d===0)return o.slice(0,_s);const u=Math.min(cA,_s),f=_s-u,m=Math.min(d,dA);let g=Math.max(0,d-m),b=Math.min(o.length,g+f);g=Math.max(0,b-f);const w=new Set(o.slice(0,u));return o.slice(g,b).forEach(A=>w.add(A)),w.size<_s&&o.slice(b,b+_s-w.size).forEach(A=>w.add(A)),[...w].slice(0,_s)}function hS(e,t,r=0){const o=e?.post_stream&&Array.isArray(e.post_stream.posts)?e.post_stream.posts:null;if(!o)return 0;const n=new Map(o.map((a,l)=>[+(a?.id||0),l]));let s=0;return Lr(t).forEach(a=>{const l=+(a?.id||0);if(!l)return;r>0&&!(+(a.reply_to_post_number||0)>0)&&(a.reply_to_post_number=+r);const c=n.get(l);c==null?(n.set(l,o.length),o.push(a)):Object.assign(o[c],a),s++}),s}function Qg(e,t){const r=+t,o=ja(e);return(Array.isArray(o.posts)?o.posts:[]).filter(n=>+(n?.reply_to_post_number||0)===r)}async function hP(e,t,r,o){const n=new Map,s=[],a=new Set,l=d=>{const u=+(d?.id||0);u&&(n.set(u,d),!(!(+(d.reply_count||0)>0)||a.has(u))&&(a.add(u),s.push(d)))};(Array.isArray(o)?o:[]).forEach(l);const c=()=>{e.nestedTotalCount=s.reduce((d,u)=>d+Math.max(0,+(u.reply_count||0)),0),e.nestedLoadedCount=s.reduce((d,u)=>d+Qg(t,u.post_number).length,0),Va(e)};c();for(let d=0;d=f)continue;let g=0;const b=new Set;for(;m.length0&&w.searchParams.set("after",String(g));let A;try{A=await ao(w.toString(),{signal:r.signal,key:`reader-queue-replies:${e.topicId}:${u.id}:${g}`,priority:tt.background})}catch(H){if(H&&H.name==="AbortError")throw H;break}const U=Lr(A),P=ky(U,u.post_number);P.length&&(hS(t,P,u.post_number),so(e.topicId,t)),m=Qg(t,u.post_number),m.forEach(l),c();const $=Ly(U);if(!U.length||U.length{const a=yo(s);/^https?:/i.test(a)&&r.add(a)},n=s=>{if(!s)return;const a=ke("template");a.innerHTML=String(s),a.content.querySelectorAll("img").forEach(l=>{o(l.getAttribute("src")||l.getAttribute("data-src")||l.getAttribute("data-large-src"))})};return(Array.isArray(e)?e:[]).forEach(s=>{n(s?.cooked),gC(s?.boosts).forEach(a=>n(a.cooked)),(Array.isArray(s?.reactions)?s.reactions:[]).forEach(a=>{Lo&&o(Lo.get(String(a?.id||"")))})}),(Array.isArray(t?.valid_reactions)?t.valid_reactions:[]).forEach(s=>{const a=String(typeof s=="string"?s:s&&(s.id||s.name)||"");Lo&&o(Lo.get(a))}),[...r]}function gS(){if(document.visibilityState!=="visible")return!0;const e=Ct?._ldpReaderShell?.activeContext;return e?e.readerSession?.isCurrent("opening")?!0:Date.now()-+(e.streamLastScrollAt||0){for(;so.length){const u=await ao(`${vt}/t/${e.topicId}.json?forceLoad=true`,{signal:t.signal,cacheMode:"refresh",key:`reader-queue-topic:${e.topicId}`,priority:tt.background,fetchOptions:Cb()});r&&Sd(u,r),r=u,so(e.topicId,r,{fetchedAt:Date.now(),source:"network"})}ef(e,r,0,{progressOnly:!0});const s=ja(r),a=Array.isArray(s.stream)?s.stream.filter(Boolean):[],l=mP(e,r);let c=new Set((Array.isArray(s.posts)?s.posts:[]).map(u=>Number(u?.id)).filter(Boolean)),d=l.filter(u=>!c.has(Number(u)));for(;d.length&&xl.has(String(e.topicId))&&String(e.topicId)!==Po;){await of(t);const u=d.slice(0,iA),f=u.map(b=>`post_ids[]=${encodeURIComponent(b)}`).join("&"),m=await ao(`${vt}/t/${e.topicId}/posts.json?${f}`,{signal:t.signal,key:`reader-queue-posts:${e.topicId}:${u.join(",")}`,priority:tt.background}),g=c.size;if(hS(r,m),c=new Set((Array.isArray(r.post_stream?.posts)?r.post_stream.posts:[]).map(b=>Number(b?.id)).filter(Boolean)),c.size<=g)throw new Error("预加载未返回新的楼层");so(e.topicId,r),ef(e,r,a.length,{progressOnly:!0}),d=l.filter(b=>!c.has(Number(b)))}if(d.length)e.loadState==="loading"&&(e.loadState="queued");else{const u=ja(r),f=new Map((Array.isArray(u.posts)?u.posts:[]).map(U=>[+(U?.id||0),U])),m=l.map(U=>f.get(+U)).filter(Boolean),g=await hP(e,r,t,m);if(t.signal.aborted||String(e.topicId)===Po)throw new DOMException("Aborted","AbortError");await bP(e,r,g,t),e.prefetchEnriched=!0;const b=a.every(U=>c.has(Number(U))),w=e.nestedLoadedCount>=e.nestedTotalCount,A=e.mediaLoadedCount>=e.mediaTotalCount;e.loadState=b&&w&&A?"ready":"partial"}}catch(r){r&&r.name==="AbortError"?e.loadState==="loading"&&(e.loadState="queued"):(e.loadState="error",e.error=String(r?.message||"预加载失败"))}finally{e.prefetchController===t&&(e.prefetchController=null),e.loadState==="error"?Rn():Va(e)}}function Bi(e=pA){lg||ql||document.visibilityState!=="visible"||!Ct||!Ao||(ql=setTimeout(()=>{if(ql=0,document.visibilityState!=="visible"||!Ct||!Ao)return;if(gS()){Bi();return}const t=kr.find(r=>String(r.topicId)!==Po&&r.loadState==="queued"&&!r.prefetchController);t&&(lg=!0,Promise.resolve(yP(t)).finally(()=>{lg=!1,Bi(300)}))},Math.max(0,Number(e)||0)))}function bS(){ql&&clearTimeout(ql),ql=0,kr.forEach(e=>e.prefetchController?.abort())}document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?Bi():bS()});function vP(e,t){let r=0,o=0,n=0;const s=d=>{if(!d.isIntersecting||d.intersectionRect.width<=0)return!1;const u=Math.max(1,d.boundingClientRect.height||1),f=Math.min(u,120,Math.max(36,u*.3));return d.intersectionRect.height>=f},a=()=>{r||(r=requestAnimationFrame(()=>{r=0,String(e.topicId)===String(t.topicId)&&Va(t)}))},l=new IntersectionObserver(d=>{let u=!1;d.forEach(f=>{const m=f.target,g=Number(m&&m.dataset.postNumber);g>0&&s(f)&&(u=dP(t,g)||u)}),u&&a()},{root:e.scrollRoot,threshold:[0,.1,.3]}),c=()=>{o=0;const d=n;if(n=0,String(e.topicId)!==String(t.topicId)||!(d>0))return;const u=RM(e,d);u&&(t.anchor=$n({viewport:u,replyWindow:t.anchor?.replyWindow}))};return{observe(d){d&&!d.classList.contains("ldp-nested-preview")&&l.observe(d)},unobserve(d){d&&l.unobserve(d)},sync(d){n=Math.max(0,Number(d)||0),o&&clearTimeout(o),o=setTimeout(c,240)},stop(){r&&cancelAnimationFrame(r),o&&clearTimeout(o),r=0,o=0,c(),l.disconnect(),Kp(t)}}}function wP(e){const t=e?.querySelector(".ldp-reader-queue");if(!t||e._ldpReaderQueueBound)return;e._ldpReaderQueueBound=!0;const r=t.querySelector(".ldp-reader-queue-panel"),o=t.querySelector(".ldp-reader-queue-toggle"),n=t.querySelector(".ldp-reader-queue-bubbles"),s=t.querySelector(".ldp-reader-queue-scroll-hint"),a=t.querySelector(".ldp-reader-queue-close"),l=t.querySelector(".ldp-reader-queue-clear"),c=Ho(),d=($,H,pe,ae)=>c.listen($,H,pe,ae);let u=0,f=null,m=0;const g=()=>requestAnimationFrame(()=>$d(t)),b=()=>{u&&clearTimeout(u),u=0},w=$=>{b(),r.hidden=!$,ar(o,$),$&&g()},A=()=>{b(),!r.contains(Jg())&&(u=setTimeout(()=>{u=0,w(!1)},180))},U=$=>{t.classList.toggle("is-preview-collapsed",!$),dS(t),$&&requestAnimationFrame(()=>jg(t)),r.hidden||g()},P=($,H=!1)=>{if(!f||$.pointerId!==f.pointerId)return;const pe=f;if(f=null,t.classList.remove("is-dragging"),o.hasPointerCapture(pe.pointerId)&&o.releasePointerCapture(pe.pointerId),!pe.moved)return;if(m=Date.now()+350,H){Ri=pe.previousState,$d(t);return}const ae=zg(t);if(!ae)return;const K=Math.max(0,Math.min(ae.maxLeft,Number.parseFloat(t.style.left)||0)),ye=Math.max(ae.minTop,Math.min(ae.maxTop,Number.parseFloat(t.style.top)||0)),W=K,V=ae.maxLeft-K,G=ae.modal.clientWidth*gw,B=Math.min(W,V)<=G?W<=V?"left":"right":"";Ri=Md({x:ae.maxLeft>0?B==="left"?0:B==="right"?1:K/ae.maxLeft:0,y:ae.maxTop>0?ye/ae.maxTop:0,dock:B}),$d(t),Fi()};d(o,"pointerdown",$=>{if($.button!==0||$.isPrimary===!1)return;const H=t.closest(".ldp-modal");if(!H)return;const pe=H.getBoundingClientRect(),ae=t.getBoundingClientRect();f={pointerId:$.pointerId,startX:$.clientX,startY:$.clientY,startLeft:ae.left-pe.left,startTop:ae.top-pe.top,previousState:Md(Ri),moved:!1},o.setPointerCapture($.pointerId)}),d(o,"pointermove",$=>{if(!f||$.pointerId!==f.pointerId)return;const H=$.clientX-f.startX,pe=$.clientY-f.startY;if(!f.moved&&Math.hypot(H,pe)<5)return;f.moved||(f.moved=!0,b(),w(!1),t.classList.remove("is-docked-left","is-docked-right","is-dock-revealed"),t.classList.add("is-dragging"));const ae=zg(t);if(!ae)return;const K=Math.max(ae.minTop,Math.min(ae.maxTop,f.startTop+pe));t.classList.add("is-runtime-positioned"),t.style.left=`${Math.round(Math.max(0,Math.min(ae.maxLeft,f.startLeft+H)))}px`,t.style.top=`${Math.round(K<=ae.minTop+o.offsetHeight/2?ae.minTop:K)}px`,$.preventDefault()}),d(o,"pointerup",$=>P($)),d(o,"pointercancel",$=>P($,!0)),d(o,"click",$=>{if(Date.now(){f||w(!0)}),d(o,"keydown",$=>{$.key==="ArrowDown"&&($.preventDefault(),w(!0),r.querySelector(".ldp-reader-queue-row")?.focus())}),d(t,"pointerenter",()=>{t.classList.add("is-dock-revealed"),b()}),d(t,"pointerleave",()=>{t.classList.remove("is-dock-revealed"),A()}),d(r,"focusin",b),d(r,"focusout",$=>{$.relatedTarget instanceof Node&&r.contains($.relatedTarget)||A()}),un(n),d(n,"scroll",()=>jg(t),{passive:!0}),d(s,"click",()=>{const $=Number(s.dataset.scrollDirection)||1,H=Yl();if($<0){n.scrollTo({top:0,behavior:H?"auto":"smooth"});return}const pe=Math.max(38,Math.round(n.clientHeight*.72));n.scrollBy({top:pe,behavior:H?"auto":"smooth"})}),d(a,"click",()=>{w(!1),o.focus()}),d(l,"click",()=>fP(e._ldpReaderShell?.activeContext)),d(t,"click",$=>{const H=$.target.closest(".ldp-reader-queue-bubble-remove");if(H){rf(H.dataset.readerQueueTopicId);return}const pe=$.target.closest(".ldp-reader-queue-bubble");if(pe){Gg(pe.dataset.readerQueueTopicId);return}const ae=$.target.closest(".ldp-reader-queue-row");if(!ae)return;const K=Number(ae.dataset.readerQueueTopicId);if($.target.closest(".ldp-reader-queue-remove")){rf(K);return}if($.target.closest(".ldp-reader-queue-pin")){pP(K);return}if($.target.closest(".ldp-reader-queue-retry")){tf(K,{},{retry:!0});return}Gg(K)}),d(t,"keydown",$=>{const H=$.target.closest(".ldp-reader-queue-row");if(!H)return;if($.key==="Escape"){$.preventDefault(),w(!1),o.focus();return}if($.key==="Enter"||$.key===" "){$.preventDefault(),Gg(H.dataset.readerQueueTopicId);return}if(!["ArrowUp","ArrowDown"].includes($.key))return;$.preventDefault();const pe=[...r.querySelectorAll(".ldp-reader-queue-row")],ae=pe.indexOf(H);pe[Math.max(0,Math.min(pe.length-1,ae+($.key==="ArrowDown"?1:-1)))]?.focus()}),d(e,"pointerdown",$=>{!r.hidden&&!$.target.closest(".ldp-reader-queue")&&w(!1)}),e._ldpSyncReaderQueue=()=>Wg(e),e._ldpSyncReaderQueuePosition=()=>$d(t),e._ldpDestroyReaderQueueSurface=()=>{b(),f&&P({pointerId:f.pointerId},!0),c.destroy(),delete e._ldpSyncReaderQueue,delete e._ldpSyncReaderQueuePosition,delete e._ldpDestroyReaderQueueSurface,e._ldpReaderQueueBound=!1},Wg(e)}function SP(e){if(e==="history")return cn();if(e==="topics")return[...$s.entries()];const t=Di(e);return t?[...t.entries()]:[]}function yS(e){try{return JSON.stringify(e).length*2}catch{return 0}}async function Yg(e,t,r){for(let o=0;o[s,{count:0,bytes:0}]));if(typeof caches>"u")return{count:0,bytes:0,groups:t};let r=0,o=0,n=[];try{n=await caches.keys()}catch{return{count:r,bytes:o,groups:t}}for(const s of e.filter(a=>n.includes(a)))try{const a=await caches.open(s),l=await a.keys();let c=0;await Yg(l,Eg,async d=>{const u=await a.match(d);if(!u)return;let f=Number(u.headers.get("content-length"));if(!(Number.isFinite(f)&&f>=0))try{f=(await u.blob()).size}catch{f=0}c+=f}),t[s]={count:l.length,bytes:c},r+=t[s].count,o+=c}catch{}return{count:r,bytes:o,groups:t}}async function CP(e,t){if(e==="assets")return _P(Wl.map(({cacheName:l})=>l));const r=SP(e),o=["topics","users","notifications","responses"].includes(e)?e:"",n=o?(await t)[o]:{count:0,bytes:0},s=Array.isArray(r)&&!r.length?0:yS(r),a={count:(Array.isArray(r)?r.length:0)+n.count,bytes:s+n.bytes};if(e==="history")a.topicCount=new Set(r.map(l=>Number(l?.topicId)).filter(Boolean)).size,a.historyRecordCount=r.length;else if(e==="topics"){const l=new Set(n.topicIds||[]);a.topicCount=l.size,a.postCount=Math.max(0,Number(n.postCount)||0),a.topicSnapshotCount=Math.max(0,Number(n.topicSnapshotCount)||0),a.topicRequestCount=Math.max(0,Number(n.topicRequestCount)||0),a.topicNavIconCount=r.length}else if(e==="users"){const l=new Set(n.userNames||[]);r.forEach(([c,d])=>{const u=sr(d?.user&&d.user.username||c).toLocaleLowerCase();u&&l.add(u)}),a.userCount=l.size,a.userProfileCount=r.length,a.userRequestCount=n.count}else if(e==="notifications"){const l=new Set(n.notificationIds||[]);r.forEach(([,c])=>{const d=c?.value&&Array.isArray(c.value.notifications)?c.value.notifications:[];L_(l,d)}),a.notificationCount=l.size,a.notificationPageCount=r.length,a.notificationRequestCount=n.count}else e==="responses"&&(a.responseRecords=n.responseRecords||{});return a}function Ga(e){const t=Math.max(0,Number(e)||0);return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}function EP(e,t){const o=mo[e]?" · 本机保存":"";if(e==="history")return`${t.topicCount||0} 个主题 · ${t.historyRecordCount||0} 条浏览记录 · ${Ga(t.bytes)}${o}`;if(e==="topics")return`${t.topicCount||0} 个主题 · 已缓存 ${t.postCount||0} 个楼层 · 快照 ${t.topicSnapshotCount||0} / 接口 ${t.topicRequestCount||0} / 图标 ${t.topicNavIconCount||0} · 共 ${t.count||0} 条记录 · ${Ga(t.bytes)}${o}`;if(e==="users")return`${t.userCount||0} 个用户 · 资料卡 ${t.userProfileCount||0} / 接口 ${t.userRequestCount||0} · 共 ${t.count||0} 条记录 · ${Ga(t.bytes)}${o}`;if(e==="notifications")return`${t.notificationCount||0} 条消息 · 分页 ${t.notificationPageCount||0} / 接口 ${t.notificationRequestCount||0} · 共 ${t.count||0} 条记录 · ${Ga(t.bytes)}${o}`;if(e==="responses"){const n=t.responseRecords||{};return`收藏 ${n.bookmarks||0} / 回应 ${n.reactions||0} / 其他 ${n.other||0} · 共 ${t.count||0} 条响应 · ${Ga(t.bytes)}${o}`}if(e==="assets"){const n=t.groups||{},s=(a,l)=>{const c=n[l]||{count:0,bytes:0};return`${a} ${c.count||0} 个(${Ga(c.bytes)})`};return[...Wl.map(({label:a,cacheName:l})=>s(a,l)),`共 ${t.count||0} 个资源 · ${Ga(t.bytes)}${o}`].join(" · ")}return`${t.count||0} 条 · ${Ga(t.bytes)}${o}`}function vS(e){const t=mo[e];return t?e==="responses"?"保留 30 天–1 年":e==="assets"?"头像与表情 90 天 · 原图 7 天":`最多 ${Math.max(1,Math.round(t.maxAge/(1440*60*1e3)))} 天`:""}async function MP(e){const t=new Set(Array.isArray(e)?e:[]),r=["topics","users","notifications","responses"].filter(s=>t.has(s)),o=["topics","topicNavIcons","users","notifications"].filter(s=>t.has(s)||s==="topicNavIcons"&&t.has("topics")),n=new Set([...t.has("users")?Array.from(Fa.values(),s=>s?.promise).filter(Boolean):[],...t.has("users")?gd.values():[],...t.has("notifications")?kp.values():[],...r.length?Cg.values():[]]);if(n.size&&await Promise.allSettled(n),t.has("history")&&Wa([]),Zw(o),o.forEach(s=>{const a=mo[s]?.storageKey;if(a)try{localStorage.removeItem(a)}catch{}}),t.has("assets")){aa=!0,Ha.abort(),bd.size&&await Promise.allSettled(bd.values());const s=[...Wl.flatMap(({requests:a})=>[...a.values()]),...Op];s.length&&await Promise.allSettled(s),Wl.forEach(({objectUrls:a,requests:l})=>{w_(a),l.clear()}),Op.clear(),bd.clear(),typeof caches<"u"&&await Promise.all(Wl.map(({cacheName:a})=>caches.delete(a).catch(()=>!1))),Ha=new AbortController,aa=!1}r.length&&await ho({kinds:r}),$t&&o.length&&$t.publishCache({action:"map-clear",keys:o})}function $P(e,...t){const r=Number(e),o=new Set(r>0?[`topic:${r}`]:[]);return t.filter(Boolean).forEach(n=>{(n?.post_stream&&Array.isArray(n.post_stream.stream)?n.post_stream.stream:[]).forEach(a=>{const l=Number(a);l>0&&o.add(`post:${l}`)}),Lr(n).forEach(a=>{const l=Number(a?.id);l>0&&o.add(`post:${l}`)})}),[...o]}async function RP(e,t){const r=String(e||""),o=$r.get(r),n=$P(e,t,o?.topic);Vl(e),Zo.delete(r),$r.delete(r),n.length&&await ho({tags:n})}rP();const TP=$t?$t.subscribeCache(nP):()=>{};Wp(()=>{Kw(),Ef(Fh,x0).then(()=>Ef(cp,Bh))},2e3),window.addEventListener("pagehide",e=>{kr.forEach(Kp),nS(),xg(),Gw(),e.persisted||(TP(),$t&&$t.destroy()),mI()});const Qa=ke("style"),wS=(()=>{const e=globalThis.GM_getResourceText;if(!D(e))return"";try{return e("ldpReaderStyles")||""}catch(t){return console.error("[Awesome LinuxDo Reader] 静态样式资源读取失败。",t),""}})();if(!wS.trim()){console.error("[Awesome LinuxDo Reader] 静态样式资源为空,已停止初始化。");return}Qa.textContent=wS;function Xg(){const e=document.head||Lt;e&&(Qa.parentNode!==e||e.lastElementChild!==Qa)&&e.appendChild(Qa)}Xg();function SS(){return document.head?[...document.head.querySelectorAll('link[rel~="stylesheet"],style')].filter(e=>e!==Qa&&e.dataset.ldpReaderShadow!=="1"&&e.dataset.ldpHostStyle!=="1"):[]}function _S(e){return!!(e&&Qa.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING)}function CS(e,t,r){if(!e||!t)return;const o=Gn.get(e),n=e.cloneNode(!0);if(n.removeAttribute("id"),n.dataset.ldpHostStyle="1",o?.isConnected)o.replaceWith(n);else{const s=SS(),a=s.indexOf(e),l=_S(e),c=s.slice(a+1).filter(f=>_S(f)===l).map(f=>Gn.get(f)).find(f=>f?.isConnected),d=t.querySelector("style[data-ldp-reader-shadow-guards]"),u=l?d||r?.nextSibling:r;t.insertBefore(n,c||u||t.firstChild)}Gn.set(e,n)}function AP(e,t){!e||!document.head||(e.querySelectorAll("[data-ldp-host-style]").forEach(r=>r.remove()),Gn.forEach(r=>r.remove()),Gn.clear(),SS().forEach(r=>CS(r,e,t)),!Dl&&(Dl=new MutationObserver(r=>{const o=new Set;r.forEach(s=>{if(s.type==="attributes"){o.add(s.target);return}const a=s.target.nodeType===Node.ELEMENT_NODE&&s.target.matches("style")?s.target:s.target.parentElement?.closest("style");a&&o.add(a),s.removedNodes.forEach(l=>{(l.nodeType===Node.ELEMENT_NODE&&l.matches('link[rel~="stylesheet"],style')?[l]:[...l.querySelectorAll?.('link[rel~="stylesheet"],style')||[]]).forEach(d=>{Gn.get(d)?.remove(),Gn.delete(d)})}),s.addedNodes.forEach(l=>{(l.nodeType===Node.ELEMENT_NODE&&l.matches('link[rel~="stylesheet"],style')?[l]:[...l.querySelectorAll?.('link[rel~="stylesheet"],style')||[]]).forEach(d=>o.add(d))})});const n=Bo?.querySelector("style[data-ldp-reader-shadow]");n&&o.forEach(s=>{if(s!==Qa){if(!s.isConnected||!s.matches('link[rel~="stylesheet"],style')){Gn.get(s)?.remove(),Gn.delete(s);return}CS(s,Bo,n)}})}),Dl.observe(document.head,{subtree:!0,childList:!0,attributes:!0,attributeFilter:["href","rel","media","disabled"]})))}function ES(e,t,r){if(!e||!t)return;const o=new Set(e.getAttributeNames().filter(n=>n!=="style"&&!n.startsWith("data-ldp-")));t.getAttributeNames().forEach(n=>{n!==r&&!o.has(n)&&t.removeAttribute(n)}),o.forEach(n=>{const s=n==="class"?[...e.classList].filter(a=>!a.startsWith("ldp-")).join(" "):e.getAttribute(n);t.getAttribute(n)!==s&&t.setAttribute(n,s)}),t.setAttribute(r,"1")}function MS(){ES(Lt,cg,"data-ldp-shadow-context-html"),ES(document.body,qa,"data-ldp-shadow-context-body")}function $S(){Dl&&Dl.disconnect(),Ti&&Ti.disconnect(),Dl=null,Ti=null,Cp&&Cp(),Cp=null,Gn.forEach(r=>r.remove()),Gn.clear();const e=ln,t=Bo;t&&Vr(t),t&&t.replaceChildren(),ln=null,Bo=null,cg=null,qa=null,e&&e.remove()}function RS(){return Ct?.isConnected?!1:([Ba,xp,Li].forEach(w_),!0)}function PP(){if(Ct?.isConnected)return!1;$S();const e=[...Lp.values(),...qp.values(),...Dp.values()];return RS(),e.length&&Promise.allSettled(e).then(RS),!0}function NP(e){if(!e||!Lt||!document.body)return null;let t=e.querySelector(":scope > html[data-ldp-shadow-context-html]");t||(t=ke("html"),t.dataset.ldpShadowContextHtml="1",e.appendChild(t));let r=t.querySelector(":scope > body[data-ldp-shadow-context-body]");return r||(r=ke("body"),r.dataset.ldpShadowContextBody="1",t.appendChild(r)),cg=t,qa=r,MS(),[...e.childNodes].forEach(o=>{o===t||o.nodeType!==Node.ELEMENT_NODE||o.matches('style,link[rel~="stylesheet"]')||r.appendChild(o)}),Ti||(Ti=new MutationObserver(o=>{o.some(n=>n.attributeName!=="style")&&MS()}),Ti.observe(Lt,{attributes:!0}),Ti.observe(document.body,{attributes:!0})),r}function Kg(){if(ln?.isConnected&&Bo)return Bo;if(!Lt||!document.body)return null;(ln||Bo)&&$S();let e=Lt.querySelector(":scope > .ldp-reader-portal-host");e||(e=ke("div"),e.className="ldp-reader-portal-host sciapp-ldp-owned",Lt.appendChild(e)),e.classList.add("sciapp-ldp-owned");const t=e.shadowRoot||e.attachShadow({mode:"open"});let r=t.querySelector("style[data-ldp-reader-shadow]");r||(r=Qa.cloneNode(!0),r.dataset.ldpReaderShadow="1",t.prepend(r));let o=t.querySelector("style[data-ldp-reader-shadow-guards]");return o||(o=ke("style"),o.dataset.ldpReaderShadowGuards="1",r.after(o)),AP(t,r),qa=NP(t),ln=e,Bo=t,Ja(),t}function Tn(e){const t=Kg();if(!t)throw new Error("reader portal unavailable");return(qa||t).appendChild(e),Nd(e),e}function to(e){return Bo?.querySelector(e)||document.querySelector(e)}function An(e){const t=Bo?[...Bo.querySelectorAll(e)]:[];return document.querySelectorAll(e).forEach(r=>{t.includes(r)||t.push(r)}),t}function kP(){const e=Kg();if(!e||e._ldpReaderIconTooltipReady)return;e._ldpReaderIconTooltipReady=!0;const t=ke("div");t.className="ldp-reader-icon-tooltip ldp-transient-surface",t.setAttribute("role","tooltip"),t.hidden=!0,(qa||e).appendChild(t);const r=Ho(),o=(f,m,g,b)=>r.listen(f,m,g,b);let n=null;const s=()=>{!n&&t.hidden&&!t.textContent||(n=null,ur(t,!0),ca(t,""))},a=f=>[...f.childNodes].some(m=>{if(m.nodeType===Node.TEXT_NODE)return!!String(m.textContent||"").trim();if(!(m instanceof Element)||m.matches(".ldp-icon,.ldp-logo,.ldp-notification-unread-badge"))return!1;const g=getComputedStyle(m);return g.display==="none"||g.visibility==="hidden"?!1:!!String(m.innerText||m.textContent||"").trim()}),l=f=>{if(!(f instanceof Element))return null;const m=f.closest('button,a,[role="button"],[data-ldp-tooltip-label],.ldp-nested-branch-toggle,.ldp-avatar-flair,.ldp-user-card-badge');if(!(m&&(m.closest(".ldp-overlay,.ldp-lightbox")||m.closest(".ldp-user-card-fallback,.ldp-avatar-viewer")||m.matches(".ldp-native-reader-trigger")))||m.hasAttribute("data-tooltip")||m.matches('.ldp-settings-tab,.ldp-topic-timeline-track,[data-reaction-picker][aria-expanded="true"]'))return null;const b=m.matches('button,[role="button"],.ldp-nested-branch-toggle'),w=m.matches("a")&&m.querySelector(".ldp-icon,.ldp-logo,img")&&!a(m),A=m.matches(".ldp-avatar-flair,.ldp-user-card-badge"),U=m.hasAttribute("data-ldp-tooltip-label");if(!b&&!w&&!A&&!U)return null;const P=m.matches(".ldp-title-jump")&&(m.closest(".ldp-modal")?.getBoundingClientRect().width||0)<=480&&m.scrollWidth>m.clientWidth+1,$=String(P?m.textContent:m.getAttribute("aria-label")||m.dataset.ldpTooltipLabel||"").trim();return $?{control:m,label:$}:null},c=(f,m=null)=>{const g=f.getBoundingClientRect(),b=t.getBoundingClientRect(),w=6,A=8;if(f.matches(".ldp-nested-rail-toggle,.ldp-nested-branch-toggle")&&m&&Number.isFinite(m.clientX)&&Number.isFinite(m.clientY)){let H=m.clientX+12;H+b.width>window.innerWidth-A&&(H=m.clientX-b.width-12);let pe=m.clientY+12;pe+b.height>window.innerHeight-A&&(pe=m.clientY-b.height-12),t.style.left=`${Math.round(Math.max(A,Math.min(H,window.innerWidth-b.width-A)))}px`,t.style.top=`${Math.round(Math.max(A,Math.min(pe,window.innerHeight-b.height-A)))}px`;return}let U=g.left+(g.width-b.width)/2;U=Math.max(A,Math.min(U,window.innerWidth-b.width-A));let P=g.top-b.height-w;P{const b=g||l(f);b&&(n=b.control,ca(t,b.label),t.classList.toggle("ldp-reader-history-tooltip",b.control.matches(".ldp-reader-history-nav")),t.classList.toggle("ldp-connect-help-tooltip",b.control.matches(".ldp-connect-metric")),ur(t,!1),c(b.control,m))},u=f=>f&&(f.matches(":hover")||f.matches(":focus-visible"));o(e,"ldp-tooltip-refresh",f=>{if(!(f.target instanceof Element))return;const m=f.target;n&&!n.isConnected&&s();const g=l(m);if(!g||m.hidden||!u(m)){m===n&&s();return}d(m,null,g)}),o(e,"click",f=>{const m=f.target instanceof Element&&f.target.closest(".ldp-avatar-flair,.ldp-user-card-badge");if(!m)return;bt(f);const g=String(m.dataset.ldpTooltipLabel||m.getAttribute("aria-label")||"").trim();if(!g)return;const b=w=>{m.dataset.ldpTooltipLabel=w,rt(m,w),la(m),setTimeout(()=>{!m.isConnected||m.dataset.ldpTooltipLabel!==w||(m.dataset.ldpTooltipLabel=g,rt(m,g),la(m))},900)};cm(g).then(()=>b("已复制")).catch(()=>b("复制失败"))},!0),o(e,"pointerover",f=>{const m=l(f.target);!m||f.relatedTarget instanceof Node&&m.control.contains(f.relatedTarget)||d(m.control,f,m)}),o(e,"pointerdown",f=>{f.target instanceof Element&&f.target.closest(".ldp-header[data-ldp-reader-drag-surface]")&&s()},!0),o(e,"pointermove",f=>{!n?.matches(".ldp-nested-rail-toggle,.ldp-nested-branch-toggle")||!(f.target instanceof Node)||!n.contains(f.target)||c(n,f)}),o(e,"pointerout",f=>{!n||f.relatedTarget instanceof Node&&n.contains(f.relatedTarget)||n.matches(":focus-visible")||s()}),o(e,"focusin",f=>d(f.target)),o(e,"focusout",()=>{queueMicrotask(()=>{u(n)||s()})}),o(e,"scroll",()=>{const f=e.querySelector(".ldp-reader-history-nav:hover");f?d(f):s()},!0),o(window,"resize",s),Cp=()=>{s(),r.destroy(),t.remove(),e._ldpReaderIconTooltipReady=!1}}function Jg(){let e=document.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e}function Zg(){const e=[],t=r=>{r&&!e.includes(r)&&e.push(r)};if(D(Bo?.getSelection))try{t(Bo.getSelection())}catch{}try{t(window.getSelection())}catch{}return e.find(r=>r.rangeCount>0&&!r.isCollapsed)||e.find(r=>r.rangeCount>0)||e[0]||null}function Fr(e,t){const o=(D(e?.composedPath)?e.composedPath():[]).find(n=>n&&n.nodeType===Node.ELEMENT_NODE&&n.matches(t));return o||(e?.target&&e.target.closest?e.target.closest(t):null)}function Hi(e,t){return!e||!t?!1:(D(e.composedPath)?e.composedPath():[]).includes(t)||t.contains(e.target)}function Rd(e,t){t.stopPropagation();const r=t.target instanceof Element?t.target:null,o=40,n=t.deltaMode===1?t.deltaX*o:t.deltaMode===2?t.deltaX*e.clientWidth:t.deltaX,s=t.deltaMode===1?t.deltaY*o:t.deltaMode===2?t.deltaY*e.clientHeight:t.deltaY;if(!r||!e.contains(r)){t.preventDefault();return}let a=r;for(;a&&e.contains(a);){const l=getComputedStyle(a),c=a.scrollWidth-a.clientWidth,d=a.scrollHeight-a.clientHeight,u=n&&c>1&&/(auto|scroll|overlay)/.test(l.overflowX)&&(n<0?a.scrollLeft>0:a.scrollLeft1&&/(auto|scroll|overlay)/.test(l.overflowY)&&(s<0?a.scrollTop>0:a.scrollTopRd(e,t),{passive:!1}))}function Ho(){const e=[];let t=!1;const r={add(o){return t?o():e.push(o),o},listen(o,n,s,a){return o.addEventListener(n,s,a),r.add(()=>o.removeEventListener(n,s,a)),s},observe(o,n,s){return o.observe(n,s),r.add(()=>o.disconnect()),o},timer(o,n){const s=setTimeout(o,n);return r.add(()=>clearTimeout(s)),s},raf(o){const n=requestAnimationFrame(o);return r.add(()=>cancelAnimationFrame(n)),n},destroy(){t||(t=!0,e.splice(0).reverse().forEach(o=>{try{o()}catch(n){console.warn("[LDP] lifecycle cleanup failed",n)}}))}};return r}function LP(e){const t=document.createDocumentFragment();return{parking:t,mount(r,o=e){return r&&o&&r.parentNode!==o&&o.append(r),r},park(r){return r&&r.parentNode!==t&&t.append(r),r},destroy(){Vr(t),t.replaceChildren()}}}function Ql(e,t,r,o=!1){e.forEach(n=>{const s=n.dataset[t]===r;n.classList.toggle("active",s),n.setAttribute("aria-selected",String(s)),o&&(n.tabIndex=s?0:-1)})}function TS(e,t,r,o=0){let n=0;const s=()=>{n&&(o?clearTimeout(n):cancelAnimationFrame(n),n=0)},a=()=>{n=0,r(e.value.trim())};return e.addEventListener("input",()=>{t.hidden=!e.value,s(),n=o?setTimeout(a,o):requestAnimationFrame(a)}),t.addEventListener("click",()=>{s(),e.value="",t.hidden=!0,r(""),e.focus()}),s}function IP(e,t,r,o){e.closest(".ldp-notification-pager").addEventListener("click",n=>{const s=n.target instanceof Element?n.target.closest("button"):null;if(s===e){if(r.page<=0)return;r.page--}else if(s===t){if(r.hasNext===!1)return;r.page++}else return;o()})}function AS(e,t){const r=t.length>0&&t.every(o=>e.has(o));t.forEach(o=>{r?e.delete(o):e.add(o)})}function PS(e,t,r,o,n,s){e.addEventListener("change",a=>{const l=a.target.closest(t),c=Number(l?.closest(r)?.dataset[o]);c>0&&(n[l.checked?"add":"delete"](c),s())})}function NS(e,t,r,o,n,s,a,l=()=>{}){const c=()=>{l(),r.clear(),a()};e.addEventListener("click",d=>{const u=d.target instanceof Element?d.target.closest("button"):null;if(u===o)t.multi=!0,t.scope="page";else if(u===n)t.multi=!1;else return;c()}),s.addEventListener("change",()=>{t.scope=s.value==="all"?"all":"page",r.clear(),a()})}function kS(e,t,r,o,n){if(e.key==="Escape"){bt(e),n(!0);return}if(e.key==="Enter"&&e.target===t){e.preventDefault(),r.querySelector(o)?.click();return}if(e.key!=="ArrowDown"&&e.key!=="ArrowUp")return;const s=[...r.querySelectorAll(o)];if(!s.length)return;e.preventDefault();const a=s.indexOf(document.activeElement),l=e.key==="ArrowDown"?1:-1,c=a<0?l>0?0:s.length-1:(a+l+s.length)%s.length;s[c].focus()}const $e=e=>String(e??"").replace(/[<>&]/g,t=>({"<":"<",">":">","&":"&"})[t]),Pe=e=>$e(e).replace(/"/g,""").replace(/'/g,"'");function bt(e){e.preventDefault(),e.stopPropagation()}function la(e){e.dispatchEvent(new CustomEvent("ldp-tooltip-refresh",{bubbles:!0,composed:!0}))}function ar(e,t){const r=String(t);e.getAttribute("aria-expanded")!==r&&e.setAttribute("aria-expanded",r)}function go(e,t){const r=String(t);e.getAttribute("aria-pressed")!==r&&e.setAttribute("aria-pressed",r)}function rt(e,t){e.getAttribute("aria-label")!==t&&e.setAttribute("aria-label",t)}function ur(e,t){e&&e.hidden!==t&&(e.hidden=t)}function ca(e,t){e&&e.textContent!==t&&(e.textContent=t)}function eb(e,t,r){const o=String(r);e&&e.getAttribute(t)!==o&&e.setAttribute(t,o)}function da(e,t,r){const o=String(r);e&&e.style.getPropertyValue(t)!==o&&e.style.setProperty(t,o)}function D(e){return typeof e=="function"}function Yl(){return D(window.matchMedia)&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}const LS={activity:'',database:'',image:'',type:'',alertTriangle:'',bell:'',headerBell:'',bellOff:'',bookmark:'',headerBookmark:'',check:'',square:'',squareCheck:'',circleX:'',arrowUp:'',chevronDown:'',chevronUp:'',chevronRight:'',download:'',upload:'',externalLink:'',copy:'',eyeOff:'',mail:'',palette:'',award:'',tag:'',heart:'',hand:'',history:'',headerHistory:'',info:'',lock:'',unlock:'',pin:'',pencil:'',trash:'',wrench:'',loader:'',maximize2:'',layoutGrid:'',panelLeft:'',panelRight:'',floatingWindow:'',messageSquare:'',minus:'',minimize2:'',cornerDownRight:'',reply:'',plus:'',rocket:'',sun:'',moon:'',monitor:'',settings:'',headerSettings:'',languages:'',smile:'',search:'',at:'',flag:'',link2:'',lightbulb:'',list:'',layers:'',gitBranch:'',listChecks:'',rotateCcw:'',share2:'',shieldHalved:'',userPlus:'',userRound:'',x:''};function ue(e,t){return``}function Ui(e,t,r){return r.map(([o,n,s,a=""])=>``).join("")}const tb=[{key:"accentColor",section:"interaction",label:"按钮与选中状态颜色",help:"控制阅读器的主强调色,包括主要按钮、选中态、焦点轮廓、开关开启态、时间轴和操作反馈;不会改变错误、警告、成功和点赞等语义颜色。选择时实时预览,统一保存。"},{key:"linkColor",section:"interaction",label:"正文链接颜色",help:"控制帖子正文中的 URL 链接颜色,与按钮和选中态的界面强调色分开设置;选择时实时预览,统一保存。"},{key:"zebraColor",section:"zebra",label:"背景颜色",ariaLabel:"交替楼层背景颜色",help:"设置阅读器正文楼层隔行出现的淡色背景,用来更容易分清相邻楼层。选择时实时预览,通过底部“保存全部更改”统一保存。"},{key:"zebraRadius",section:"zebra",label:"背景圆角",ariaLabel:"交替楼层背景圆角",range:[zh,Wh,V0],normalize:(e,t=W0)=>mf(e,t,zh,Wh,V0),help:`设置交替楼层背景的圆角,${zh}px 为直角,最高 ${Wh}px。拖动时实时预览,通过底部“保存全部更改”统一保存。`},{key:"listZebraColor",section:"list-zebra",label:"嵌入阅读列表背景",ariaLabel:"嵌入阅读时原站主题列表交替背景颜色",shareLabel:"嵌入阅读列表背景",help:`使用左右嵌入阅读时,设置 ${zn} 主题列表卡片的隔行色调;所选颜色会与原站背景适度混合。选择时实时预览,通过底部“保存全部更改”统一保存。`},{key:"replyLineColor",section:"reply-line",label:"颜色",ariaLabel:"回复连接线颜色",help:"控制阅读器里的关系线颜色,包括二级回复连线、上级回复预览、时间轴、特殊提示边框和大图评论层级线。选择时实时预览,统一保存。"},{key:"replyLineWidth",section:"reply-line",label:"粗细",ariaLabel:"回复连接线粗细",range:[Si,_i,fp],normalize:(e,t=Vh)=>gf(e,t),help:`控制回复关系线的基础粗细,可在 ${Si}–${_i}px 之间调整;二级回复树线、父子回复连接线和相关层级线会同步变化。拖动时实时预览,统一保存。`},{key:"replyLineRadius",section:"reply-line",label:"转角圆角",ariaLabel:"回复连接线转角圆角",shareLabel:"回复连接线圆角",range:[Gh,Qh,Q0],normalize:bf,help:`控制父子回复和二级回复连接线转折处的圆角,${Gh}px 为直角,最高 ${Qh}px。拖动时实时预览,统一保存。`},{key:"quoteLineColor",section:"quote-line",label:"颜色",ariaLabel:"引用线颜色",help:"控制帖子正文引用块和“引用某楼层”卡片左侧竖线的颜色,只改变引用提示线,不改变引用文字或背景。选择时实时预览,统一保存。"},{key:"quoteLineWidth",section:"quote-line",label:"粗细",ariaLabel:"引用线粗细",range:[Si,_i,fp],normalize:(e,t=Y0)=>gf(e,t),help:`控制引用线的基础粗细,可在 ${Si}–${_i}px 之间调整;不同引用样式会保留原有粗细层级。拖动时实时预览,统一保存。`},{key:"dividerLineColor",section:"divider-line",label:"颜色",ariaLabel:"界面分隔线颜色",help:"控制楼层边界、标题栏、设置与通知面板、嵌入阅读边界和大图查看器结构分隔线的颜色;按钮和输入框外框不会跟着改变。选择时实时预览,统一保存。"},{key:"dividerLineWidth",section:"divider-line",label:"粗细",ariaLabel:"界面分隔线粗细",range:[Si,_i,fp],normalize:(e,t=mp)=>gf(e,t),help:`控制界面结构分隔线的基础粗细,可在 ${Si}–${_i}px 之间调整;按钮和输入框外框不会跟着改变。拖动时实时预览,统一保存。`},{key:"floorPreviewColor",section:"floor-preview",label:"卡片强调颜色",ariaLabel:"上级回复预览卡片强调颜色",shareLabel:"上级回复预览颜色",help:"控制父楼层号悬停后插入的预览卡片边框、淡色背景和楼层标记颜色;不改变二级回复关系线。选择时实时预览,统一保存。"},{key:"floorPreviewHeight",section:"floor-preview",label:"卡片最大高度",ariaLabel:"上级回复预览卡片最大高度",shareLabel:"上级回复预览高度",range:[Yh,X0,J0],normalize:(e,t=K0)=>mf(e,t,Yh,X0,J0),help:`控制父回复插入预览在长内容时允许占用的最大高度,最低 ${Yh}px;内容较短时仍按实际高度显示,并始终受当前窗口可用高度限制。拖动时实时预览,统一保存。`}],xP=[{id:"interaction",title:"按钮与链接",description:"控制按钮、选中状态、焦点、时间轴和正文链接,不改变错误、警告、成功等状态颜色。",sections:["interaction"]},{id:"background",title:"交替内容背景",description:"用浅色背景区分相邻楼层,以及嵌入阅读时的原站主题列表卡片。",sections:[{id:"zebra",title:"交替楼层背景"},"list-zebra"]},{id:"structure",title:"关系线与分隔线",description:"分别控制回复连接线、引用线和界面分隔线;关闭后隐藏这些线条,已设置的样式会保留。",toggleKey:"structureColorsEnabled",toggleLabel:"显示关系线与分隔线",sections:[{id:"reply-line",title:"回复连接线"},{id:"quote-line",title:"引用线"},{id:"divider-line",title:"界面分隔线"}]},{id:"floor-preview",title:"上级回复预览卡片",description:"控制悬停上级楼层号后插入的预览卡片,不影响回复连接线和其他内容。",sections:["floor-preview"]}];function IS(e){return`ldp-${e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`)}`}function qP(e){const t=IS(e.key),r=e.range?``:``;return`
+
`}).join(""),_o(n,rt.auxiliary),_o(l,rt.auxiliary);const g=f!==Po;if(t.dataset.readerQueueActiveTopicId=Po,g){const b=n.querySelector(".ldp-reader-queue-bubble.is-active");if(b){const w=b.offsetTop,R=w+b.offsetHeight;wn.scrollTop+n.clientHeight&&(n.scrollTop=Math.max(0,R-n.clientHeight+4))}}else n.scrollTop=Math.min(m,Math.max(0,n.scrollHeight-n.clientHeight));Xg(t),a.hidden=!u,sr(r,u),xd(t)}function Tn(){document.querySelectorAll(".ldp-reader-queue-add[data-reader-queue-topic-id]").forEach(e=>{const t=!!un(e.dataset.readerQueueTopicId);e.dataset.readerQueueAdded!==String(t)&&ES(e,t)}),D(Ct?._ldpSyncReaderQueue)&&Ct._ldpSyncReaderQueue()}function ES(e,t){const r=t?"从阅读队列移除":"加入阅读队列并后台预加载";e.dataset.readerQueueAdded=String(t),e.classList.toggle("is-added",t),e.innerHTML=ue(t?"check":"plus"),nt(e,r),e.setAttribute("title",r)}function cf(e,t,r=0,o={}){if(!e||!t)return;const n=gS(e.topicId,e,t);e.title=n.title,e.avatarTemplate=n.avatarTemplate||e.avatarTemplate,e.avatarSource=n.avatarSource||e.avatarSource,e.ownerUsername=n.ownerUsername||e.ownerUsername,e.navMetadata=n.navMetadata,e.urlPostNumber=n.urlPostNumber||e.urlPostNumber||0;const s=_P(t);e.totalCount=Math.max(0,Number(r)||s.total||e.totalCount||0),e.loadedCount=Math.min(e.totalCount||s.loaded,s.loaded),e.totalCount>0&&e.loadedCount>=e.totalCount&&e.prefetchEnriched?e.loadState="ready":e.loadState==="ready"&&(e.loadState="queued"),e.error="",Hi(),o.progressOnly===!0?Ya(e):Tn()}function df(e,t={},r={}){const o=Number(e);if(!(o>0))return null;let n=un(o);const s=gS(o,t);if(n)n.title=s.title||n.title,n.avatarTemplate=s.avatarTemplate||n.avatarTemplate,n.avatarSource=s.avatarSource||n.avatarSource,n.ownerUsername=s.ownerUsername||n.ownerUsername,n.navMetadata=Ns(s.navMetadata,n.navMetadata),n.urlPostNumber=s.urlPostNumber||n.urlPostNumber||0,n.totalCount=Math.max(Number(n.totalCount)||0,s.totalCount),s.readPostNumbers.forEach(a=>n.seenPostNumbers.add(a)),!n.anchor&&s.historyPostNumber&&(n.anchor=$n(s.historyPostNumber)),n.loadState==="error"&&r.retry===!0&&(n.loadState="queued",n.error="");else{n={topicId:o,title:s.title,avatarTemplate:s.avatarTemplate,avatarSource:s.avatarSource,ownerUsername:s.ownerUsername,navMetadata:s.navMetadata,addedAt:Date.now(),loadState:"queued",loadedCount:0,nestedLoadedCount:0,nestedTotalCount:0,mediaLoadedCount:0,mediaTotalCount:0,totalCount:s.totalCount,urlPostNumber:s.urlPostNumber,anchor:s.historyPostNumber?$n(s.historyPostNumber):null,seenPostNumbers:new Set(s.readPostNumbers),progressPersistTimer:0,prefetchController:null,prefetchEnriched:!1,switching:!1,pinned:!1,error:""},Lr.push(n),Bl.set(String(o),n);const a=Zl(o);a&&cf(n,a)}return Hi(),Tn(),r.prefetch!==!1&&Ui(),n}function Zg(e,t){const r=un(e),o=$n(t);!r||!o||(r.anchor=o,Hi(),Tn())}function RP(e){e&&(Po=String(e.topicId),e.prefetchController&&(e.prefetchController.abort(),e.prefetchController=null,e.loadState==="loading"&&(e.loadState="queued")),Tn())}async function eb(e){const t=un(e);if(!t||t.switching)return;if(String(t.topicId)===Po&&Ct&&Number(Ct.dataset.topicId)===t.topicId){const o=Ct.querySelector(".ldp-reader-queue-panel"),n=Ct.querySelector(".ldp-reader-queue-toggle");o&&(o.hidden=!0),n&&sr(n,!1);return}const r=Number(Ct&&Ct.dataset.topicId);r>0&&Zg(r,Bi(Ct)),t.switching=!0,Tn();try{const o=vS(t),n=qe.openTopicsAtFirstPost===!0||t.urlPostNumber>0;await co(t.topicId,{targetPostNumber:o,restoreViewport:n?{postNumber:o,postOffset:0}:void 0,restoreState:n?void 0:t.anchor||void 0,topicNavMetadata:t.navMetadata,readerQueueMetadata:t,settleTargetJump:!0})}finally{t.switching=!1,Tn()}}function uf(e){const t=un(e);if(!t)return!1;const r=Lr.indexOf(t),o=String(t.topicId)===Po;return sf(t),t.prefetchController&&t.prefetchController.abort(),Bl.delete(String(t.topicId)),r>=0&&Lr.splice(r,1),Hi(),o&&(Po=""),Tn(),Ui(),!0}function $P(e){const t=un(e);return t?(t.pinned=!t.pinned,Hi(),Tn(),mt(t.pinned?"已固定,离开后仍保留在队列":"已取消固定,离开后将自动出队"),!0):!1}function MS(e){const t=un(e);return!t||t.pinned?!1:uf(t.topicId)}function TP(e){const t=Lr.filter(s=>s.pinned),r=new Set(t),o=Lr.filter(s=>!r.has(s));if(!o.length)return mt("队列中没有可清理的未固定文章"),!1;const n=new Set(o.map(s=>String(s.topicId)));return!!Nc(e,{title:"清理阅读队列?",message:t.length?`将移除 ${o.length} 篇未固定文章,保留 ${t.length} 篇固定文章。`:`将移除队列中的 ${o.length} 篇文章。`,note:"当前阅读不会关闭,正文、头像和图片缓存不会删除。",icon:"trash",confirmLabel:`清理 ${o.length} 篇`,onConfirm:()=>{const s=Lr.filter(c=>n.has(String(c.topicId))&&!c.pinned);if(!s.length){mt("队列中没有可清理的未固定文章");return}const a=new Set(s);s.forEach(c=>{sf(c),c.prefetchController&&c.prefetchController.abort(),Bl.delete(String(c.topicId))});const l=Lr.filter(c=>!a.has(c));Lr.splice(0,Lr.length,...l),un(Po)||(Po=""),Hi(),Tn(),Ui(),mt(`已从队列清理 ${s.length} 篇文章`)}})}function AP(e,t){const r=Va(t),o=Array.isArray(r.stream)?r.stream.filter(Boolean):[];if(o.length<=Ms)return o;const n=Array.isArray(r.posts)?r.posts:[],s=vS(e),l=+(n.find(R=>+(R?.post_number||0)===s)?.id||0),c=l?o.indexOf(l):-1,d=c>=0?c:Math.max(0,Math.min(o.length-1,s-1));if(qe.openTopicsAtFirstPost!==!0&&+(e?.urlPostNumber||0)>0){const R=Math.min(d,wA);let z=Math.max(0,d-R),P=Math.min(o.length,d+Ms-R);return z=Math.max(0,P-Ms),P=Math.min(o.length,z+Ms),o.slice(z,P)}if(d===0)return o.slice(0,Ms);const u=Math.min(SA,Ms),f=Ms-u,m=Math.min(d,_A);let g=Math.max(0,d-m),b=Math.min(o.length,g+f);g=Math.max(0,b-f);const w=new Set(o.slice(0,u));return o.slice(g,b).forEach(R=>w.add(R)),w.sizew.add(R)),[...w].slice(0,Ms)}function RS(e,t,r=0){const o=e?.post_stream&&Array.isArray(e.post_stream.posts)?e.post_stream.posts:null;if(!o)return 0;const n=new Map(o.map((a,l)=>[+(a?.id||0),l]));let s=0;return Ir(t).forEach(a=>{const l=+(a?.id||0);if(!l)return;r>0&&!(+(a.reply_to_post_number||0)>0)&&(a.reply_to_post_number=+r);const c=n.get(l);c==null?(n.set(l,o.length),o.push(a)):Object.assign(o[c],a),s++}),s}function tb(e,t){const r=+t,o=Va(e);return(Array.isArray(o.posts)?o.posts:[]).filter(n=>+(n?.reply_to_post_number||0)===r)}async function PP(e,t,r,o){const n=new Map,s=[],a=new Set,l=d=>{const u=+(d?.id||0);u&&(n.set(u,d),!(!(+(d.reply_count||0)>0)||a.has(u))&&(a.add(u),s.push(d)))};(Array.isArray(o)?o:[]).forEach(l);const c=()=>{e.nestedTotalCount=s.reduce((d,u)=>d+Math.max(0,+(u.reply_count||0)),0),e.nestedLoadedCount=s.reduce((d,u)=>d+tb(t,u.post_number).length,0),Ya(e)};c();for(let d=0;d=f)continue;let g=0;const b=new Set;for(;m.length0&&w.searchParams.set("after",String(g));let R;try{R=await io(w.toString(),{signal:r.signal,key:`reader-queue-replies:${e.topicId}:${u.id}:${g}`,priority:rt.background})}catch(U){if(U&&U.name==="AbortError")throw U;break}const z=Ir(R),P=jy(z,u.post_number);P.length&&(RS(t,P,u.post_number),ao(e.topicId,t)),m=tb(t,u.post_number),m.forEach(l),c();const M=zy(z);if(!z.length||z.length{const a=wo(s);/^https?:/i.test(a)&&r.add(a)},n=s=>{if(!s)return;const a=Ne("template");a.innerHTML=String(s),a.content.querySelectorAll("img").forEach(l=>{o(l.getAttribute("src")||l.getAttribute("data-src")||l.getAttribute("data-large-src"))})};return(Array.isArray(e)?e:[]).forEach(s=>{n(s?.cooked),TC(s?.boosts).forEach(a=>n(a.cooked)),(Array.isArray(s?.reactions)?s.reactions:[]).forEach(a=>{Lo&&o(Lo.get(String(a?.id||"")))})}),(Array.isArray(t?.valid_reactions)?t.valid_reactions:[]).forEach(s=>{const a=String(typeof s=="string"?s:s&&(s.id||s.name)||"");Lo&&o(Lo.get(a))}),[...r]}function $S(){if(document.visibilityState!=="visible")return!0;const e=Ct?._ldpReaderShell?.activeContext;return e?e.readerSession?.isCurrent("opening")?!0:Date.now()-+(e.streamLastScrollAt||0){for(;so.length){const u=await io(`${vt}/t/${e.topicId}.json?forceLoad=true`,{signal:t.signal,cacheMode:"refresh",key:`reader-queue-topic:${e.topicId}`,priority:rt.background,fetchOptions:Nb()});r&&Pd(u,r),r=u,ao(e.topicId,r,{fetchedAt:Date.now(),source:"network"})}cf(e,r,0,{progressOnly:!0});const s=Va(r),a=Array.isArray(s.stream)?s.stream.filter(Boolean):[],l=AP(e,r);let c=new Set((Array.isArray(s.posts)?s.posts:[]).map(u=>Number(u?.id)).filter(Boolean)),d=l.filter(u=>!c.has(Number(u)));for(;d.length&&Bl.has(String(e.topicId))&&String(e.topicId)!==Po;){await pf(t);const u=d.slice(0,vA),f=u.map(b=>`post_ids[]=${encodeURIComponent(b)}`).join("&"),m=await io(`${vt}/t/${e.topicId}/posts.json?${f}`,{signal:t.signal,key:`reader-queue-posts:${e.topicId}:${u.join(",")}`,priority:rt.background}),g=c.size;if(RS(r,m),c=new Set((Array.isArray(r.post_stream?.posts)?r.post_stream.posts:[]).map(b=>Number(b?.id)).filter(Boolean)),c.size<=g)throw new Error("预加载未返回新的楼层");ao(e.topicId,r),cf(e,r,a.length,{progressOnly:!0}),d=l.filter(b=>!c.has(Number(b)))}if(d.length)e.loadState==="loading"&&(e.loadState="queued");else{const u=Va(r),f=new Map((Array.isArray(u.posts)?u.posts:[]).map(z=>[+(z?.id||0),z])),m=l.map(z=>f.get(+z)).filter(Boolean),g=await PP(e,r,t,m);if(t.signal.aborted||String(e.topicId)===Po)throw new DOMException("Aborted","AbortError");await kP(e,r,g,t),e.prefetchEnriched=!0;const b=a.every(z=>c.has(Number(z))),w=e.nestedLoadedCount>=e.nestedTotalCount,R=e.mediaLoadedCount>=e.mediaTotalCount;e.loadState=b&&w&&R?"ready":"partial"}}catch(r){r&&r.name==="AbortError"?e.loadState==="loading"&&(e.loadState="queued"):(e.loadState="error",e.error=String(r?.message||"预加载失败"))}finally{e.prefetchController===t&&(e.prefetchController=null),e.loadState==="error"?Tn():Ya(e)}}function Ui(e=EA){gg||Hl||document.visibilityState!=="visible"||!Ct||!Ao||(Hl=setTimeout(()=>{if(Hl=0,document.visibilityState!=="visible"||!Ct||!Ao)return;if($S()){Ui();return}const t=Lr.find(r=>String(r.topicId)!==Po&&r.loadState==="queued"&&!r.prefetchController);t&&(gg=!0,Promise.resolve(LP(t)).finally(()=>{gg=!1,Ui(300)}))},Math.max(0,Number(e)||0)))}function TS(){Hl&&clearTimeout(Hl),Hl=0,Lr.forEach(e=>e.prefetchController?.abort())}document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?Ui():TS()});function IP(e,t){let r=0,o=0,n=0;const s=d=>{if(!d.isIntersecting||d.intersectionRect.width<=0)return!1;const u=Math.max(1,d.boundingClientRect.height||1),f=Math.min(u,120,Math.max(36,u*.3));return d.intersectionRect.height>=f},a=()=>{r||(r=requestAnimationFrame(()=>{r=0,String(e.topicId)===String(t.topicId)&&Ya(t)}))},l=new IntersectionObserver(d=>{let u=!1;d.forEach(f=>{const m=f.target,g=Number(m&&m.dataset.postNumber);g>0&&s(f)&&(u=MP(t,g)||u)}),u&&a()},{root:e.scrollRoot,threshold:[0,.1,.3]}),c=()=>{o=0;const d=n;if(n=0,String(e.topicId)!==String(t.topicId)||!(d>0))return;const u=OM(e,d);u&&(t.anchor=$n({viewport:u,replyWindow:t.anchor?.replyWindow}))};return{observe(d){d&&!d.classList.contains("ldp-nested-preview")&&l.observe(d)},unobserve(d){d&&l.unobserve(d)},sync(d){n=Math.max(0,Number(d)||0),o&&clearTimeout(o),o=setTimeout(c,240)},stop(){r&&cancelAnimationFrame(r),o&&clearTimeout(o),r=0,o=0,c(),l.disconnect(),sf(t)}}}function xP(e){const t=e?.querySelector(".ldp-reader-queue");if(!t||e._ldpReaderQueueBound)return;e._ldpReaderQueueBound=!0;const r=t.querySelector(".ldp-reader-queue-panel"),o=t.querySelector(".ldp-reader-queue-toggle"),n=t.querySelector(".ldp-reader-queue-bubbles"),s=t.querySelector(".ldp-reader-queue-scroll-hint"),a=t.querySelector(".ldp-reader-queue-close"),l=t.querySelector(".ldp-reader-queue-clear"),c=Uo(),d=(M,U,pe,ae)=>c.listen(M,U,pe,ae);let u=0,f=null,m=0;const g=()=>requestAnimationFrame(()=>xd(t)),b=()=>{u&&clearTimeout(u),u=0},w=M=>{b(),r.hidden=!M,sr(o,M),M&&g()},R=()=>{b(),!r.contains(sb())&&(u=setTimeout(()=>{u=0,w(!1)},180))},z=M=>{t.classList.toggle("is-preview-collapsed",!M),SS(t),M&&requestAnimationFrame(()=>Xg(t)),r.hidden||g()},P=(M,U=!1)=>{if(!f||M.pointerId!==f.pointerId)return;const pe=f;if(f=null,t.classList.remove("is-dragging"),o.hasPointerCapture(pe.pointerId)&&o.releasePointerCapture(pe.pointerId),!pe.moved)return;if(m=Date.now()+350,U){Ai=pe.previousState,xd(t);return}const ae=Kg(t);if(!ae)return;const W=Math.max(0,Math.min(ae.maxLeft,Number.parseFloat(t.style.left)||0)),be=Math.max(ae.minTop,Math.min(ae.maxTop,Number.parseFloat(t.style.top)||0)),re=W,K=ae.maxLeft-W,Y=ae.modal.clientWidth*$w,q=Math.min(re,K)<=Y?re<=K?"left":"right":"";Ai=Id({x:ae.maxLeft>0?q==="left"?0:q==="right"?1:W/ae.maxLeft:0,y:ae.maxTop>0?be/ae.maxTop:0,dock:q}),xd(t),Hi()};d(o,"pointerdown",M=>{if(M.button!==0||M.isPrimary===!1)return;const U=t.closest(".ldp-modal");if(!U)return;const pe=U.getBoundingClientRect(),ae=t.getBoundingClientRect();f={pointerId:M.pointerId,startX:M.clientX,startY:M.clientY,startLeft:ae.left-pe.left,startTop:ae.top-pe.top,previousState:Id(Ai),moved:!1},o.setPointerCapture(M.pointerId)}),d(o,"pointermove",M=>{if(!f||M.pointerId!==f.pointerId)return;const U=M.clientX-f.startX,pe=M.clientY-f.startY;if(!f.moved&&Math.hypot(U,pe)<5)return;f.moved||(f.moved=!0,b(),w(!1),t.classList.remove("is-docked-left","is-docked-right","is-dock-revealed"),t.classList.add("is-dragging"));const ae=Kg(t);if(!ae)return;const W=Math.max(ae.minTop,Math.min(ae.maxTop,f.startTop+pe));t.classList.add("is-runtime-positioned"),t.style.left=`${Math.round(Math.max(0,Math.min(ae.maxLeft,f.startLeft+U)))}px`,t.style.top=`${Math.round(W<=ae.minTop+o.offsetHeight/2?ae.minTop:W)}px`,M.preventDefault()}),d(o,"pointerup",M=>P(M)),d(o,"pointercancel",M=>P(M,!0)),d(o,"click",M=>{if(Date.now(){f||w(!0)}),d(o,"keydown",M=>{M.key==="ArrowDown"&&(M.preventDefault(),w(!0),r.querySelector(".ldp-reader-queue-row")?.focus())}),d(t,"pointerenter",()=>{t.classList.add("is-dock-revealed"),b()}),d(t,"pointerleave",()=>{t.classList.remove("is-dock-revealed"),R()}),d(r,"focusin",b),d(r,"focusout",M=>{M.relatedTarget instanceof Node&&r.contains(M.relatedTarget)||R()}),pn(n),d(n,"scroll",()=>Xg(t),{passive:!0}),d(s,"click",()=>{const M=Number(s.dataset.scrollDirection)||1,U=tc();if(M<0){n.scrollTo({top:0,behavior:U?"auto":"smooth"});return}const pe=Math.max(38,Math.round(n.clientHeight*.72));n.scrollBy({top:pe,behavior:U?"auto":"smooth"})}),d(a,"click",()=>{w(!1),o.focus()}),d(l,"click",()=>TP(e._ldpReaderShell?.activeContext)),d(t,"click",M=>{const U=M.target.closest(".ldp-reader-queue-bubble-remove");if(U){uf(U.dataset.readerQueueTopicId);return}const pe=M.target.closest(".ldp-reader-queue-bubble");if(pe){eb(pe.dataset.readerQueueTopicId);return}const ae=M.target.closest(".ldp-reader-queue-row");if(!ae)return;const W=Number(ae.dataset.readerQueueTopicId);if(M.target.closest(".ldp-reader-queue-remove")){uf(W);return}if(M.target.closest(".ldp-reader-queue-pin")){$P(W);return}if(M.target.closest(".ldp-reader-queue-retry")){df(W,{},{retry:!0});return}eb(W)}),d(t,"keydown",M=>{const U=M.target.closest(".ldp-reader-queue-row");if(!U)return;if(M.key==="Escape"){M.preventDefault(),w(!1),o.focus();return}if(M.key==="Enter"||M.key===" "){M.preventDefault(),eb(U.dataset.readerQueueTopicId);return}if(!["ArrowUp","ArrowDown"].includes(M.key))return;M.preventDefault();const pe=[...r.querySelectorAll(".ldp-reader-queue-row")],ae=pe.indexOf(U);pe[Math.max(0,Math.min(pe.length-1,ae+(M.key==="ArrowDown"?1:-1)))]?.focus()}),d(e,"pointerdown",M=>{!r.hidden&&!M.target.closest(".ldp-reader-queue")&&w(!1)}),e._ldpSyncReaderQueue=()=>Jg(e),e._ldpSyncReaderQueuePosition=()=>xd(t),e._ldpDestroyReaderQueueSurface=()=>{b(),f&&P({pointerId:f.pointerId},!0),c.destroy(),delete e._ldpSyncReaderQueue,delete e._ldpSyncReaderQueuePosition,delete e._ldpDestroyReaderQueueSurface,e._ldpReaderQueueBound=!1},Jg(e)}function DP(e){if(e==="history")return dn();if(e==="topics")return[...As.entries()];const t=Fi(e);return t?[...t.entries()]:[]}function AS(e){try{return JSON.stringify(e).length*2}catch{return 0}}async function rb(e,t,r){for(let o=0;o[s,{count:0,bytes:0}]));if(typeof caches>"u")return{count:0,bytes:0,groups:t};let r=0,o=0,n=[];try{n=await caches.keys()}catch{return{count:r,bytes:o,groups:t}}for(const s of e.filter(a=>n.includes(a)))try{const a=await caches.open(s),l=await a.keys();let c=0;await rb(l,Ng,async d=>{const u=await a.match(d);if(!u)return;let f=Number(u.headers.get("content-length"));if(!(Number.isFinite(f)&&f>=0))try{f=(await u.blob()).size}catch{f=0}c+=f}),t[s]={count:l.length,bytes:c},r+=t[s].count,o+=c}catch{}return{count:r,bytes:o,groups:t}}async function OP(e,t){if(e==="assets")return qP(Kl.map(({cacheName:l})=>l));const r=DP(e),o=["topics","users","notifications","responses"].includes(e)?e:"",n=o?(await t)[o]:{count:0,bytes:0},s=Array.isArray(r)&&!r.length?0:AS(r),a={count:(Array.isArray(r)?r.length:0)+n.count,bytes:s+n.bytes};if(e==="history")a.topicCount=new Set(r.map(l=>Number(l?.topicId)).filter(Boolean)).size,a.historyRecordCount=r.length;else if(e==="topics"){const l=new Set(n.topicIds||[]);a.topicCount=l.size,a.postCount=Math.max(0,Number(n.postCount)||0),a.topicSnapshotCount=Math.max(0,Number(n.topicSnapshotCount)||0),a.topicRequestCount=Math.max(0,Number(n.topicRequestCount)||0),a.topicNavIconCount=r.length}else if(e==="users"){const l=new Set(n.userNames||[]);r.forEach(([c,d])=>{const u=ar(d?.user&&d.user.username||c).toLocaleLowerCase();u&&l.add(u)}),a.userCount=l.size,a.userProfileCount=r.length,a.userRequestCount=n.count}else if(e==="notifications"){const l=new Set(n.notificationIds||[]);r.forEach(([,c])=>{const d=c?.value&&Array.isArray(c.value.notifications)?c.value.notifications:[];W_(l,d)}),a.notificationCount=l.size,a.notificationPageCount=r.length,a.notificationRequestCount=n.count}else e==="responses"&&(a.responseRecords=n.responseRecords||{});return a}function Xa(e){const t=Math.max(0,Number(e)||0);return t<1024?`${t} B`:t<1024*1024?`${(t/1024).toFixed(1)} KB`:`${(t/(1024*1024)).toFixed(1)} MB`}function FP(e,t){const o=ho[e]?" · 本机保存":"";if(e==="history")return`${t.topicCount||0} 个主题 · ${t.historyRecordCount||0} 条浏览记录 · ${Xa(t.bytes)}${o}`;if(e==="topics")return`${t.topicCount||0} 个主题 · 已缓存 ${t.postCount||0} 个楼层 · 快照 ${t.topicSnapshotCount||0} / 接口 ${t.topicRequestCount||0} / 图标 ${t.topicNavIconCount||0} · 共 ${t.count||0} 条记录 · ${Xa(t.bytes)}${o}`;if(e==="users")return`${t.userCount||0} 个用户 · 资料卡 ${t.userProfileCount||0} / 接口 ${t.userRequestCount||0} · 共 ${t.count||0} 条记录 · ${Xa(t.bytes)}${o}`;if(e==="notifications")return`${t.notificationCount||0} 条消息 · 分页 ${t.notificationPageCount||0} / 接口 ${t.notificationRequestCount||0} · 共 ${t.count||0} 条记录 · ${Xa(t.bytes)}${o}`;if(e==="responses"){const n=t.responseRecords||{};return`收藏 ${n.bookmarks||0} / 回应 ${n.reactions||0} / 其他 ${n.other||0} · 共 ${t.count||0} 条响应 · ${Xa(t.bytes)}${o}`}if(e==="assets"){const n=t.groups||{},s=(a,l)=>{const c=n[l]||{count:0,bytes:0};return`${a} ${c.count||0} 个(${Xa(c.bytes)})`};return[...Kl.map(({label:a,cacheName:l})=>s(a,l)),`共 ${t.count||0} 个资源 · ${Xa(t.bytes)}${o}`].join(" · ")}return`${t.count||0} 条 · ${Xa(t.bytes)}${o}`}function PS(e){const t=ho[e];return t?e==="responses"?"保留 30 天–1 年":e==="assets"?"头像与表情 90 天 · 原图 7 天":`最多 ${Math.max(1,Math.round(t.maxAge/(1440*60*1e3)))} 天`:""}async function BP(e){const t=new Set(Array.isArray(e)?e:[]),r=["topics","users","notifications","responses"].filter(s=>t.has(s)),o=["topics","topicNavIcons","users","notifications"].filter(s=>t.has(s)||s==="topicNavIcons"&&t.has("topics")),n=new Set([...t.has("users")?Array.from(Ua.values(),s=>s?.promise).filter(Boolean):[],...t.has("users")?Md.values():[],...t.has("notifications")?Bp.values():[],...r.length?Pg.values():[]]);if(n.size&&await Promise.allSettled(n),t.has("history")&&Qa([]),dS(o),o.forEach(s=>{const a=ho[s]?.storageKey;if(a)try{localStorage.removeItem(a)}catch{}}),t.has("assets")){da=!0,za.abort(),Rd.size&&await Promise.allSettled(Rd.values());const s=[...Kl.flatMap(({requests:a})=>[...a.values()]),...Vp];s.length&&await Promise.allSettled(s),Kl.forEach(({objectUrls:a,requests:l})=>{k_(a),l.clear()}),Vp.clear(),Rd.clear(),typeof caches<"u"&&await Promise.all(Kl.map(({cacheName:a})=>caches.delete(a).catch(()=>!1))),za=new AbortController,da=!1}r.length&&await go({kinds:r}),Rt&&o.length&&Rt.publishCache({action:"map-clear",keys:o})}function HP(e,...t){const r=Number(e),o=new Set(r>0?[`topic:${r}`]:[]);return t.filter(Boolean).forEach(n=>{(n?.post_stream&&Array.isArray(n.post_stream.stream)?n.post_stream.stream:[]).forEach(a=>{const l=Number(a);l>0&&o.add(`post:${l}`)}),Ir(n).forEach(a=>{const l=Number(a?.id);l>0&&o.add(`post:${l}`)})}),[...o]}async function UP(e,t){const r=String(e||""),o=$r.get(r),n=HP(e,t,o?.topic);Jl(e),en.delete(r),$r.delete(r),n.length&&await go({tags:n})}bP();const jP=Rt?Rt.subscribeCache(vP):()=>{};Zp(()=>{lS(),kf(Gh,V0).then(()=>kf(bp,Qh))},2e3),window.addEventListener("pagehide",e=>{Lr.forEach(sf),hS(),Ug(),nS(),e.persisted||(jP(),Rt&&Rt.destroy()),LI()});const Ka=Ne("style"),NS=(()=>{const e=globalThis.GM_getResourceText;if(!D(e))return"";try{return e("ldpReaderStyles")||""}catch(t){return console.error("[Awesome LinuxDo Reader] 静态样式资源读取失败。",t),""}})();if(!NS.trim()){console.error("[Awesome LinuxDo Reader] 静态样式资源为空,已停止初始化。");return}const zP=` + .ldp-children .ldp-children{margin-left:14px;padding-left:14px; + --ldp-nested-parent-drop:28px;--ldp-nested-branch-width:12px;--ldp-nested-parent-head-width:12px;} + .ldp-post[data-ldp-nest-depth="2"] > .ldp-children, + .ldp-post[data-ldp-nest-depth="3"] > .ldp-children, + .ldp-post[data-ldp-nest-depth="4"] > .ldp-children{margin-left:12px;padding-left:12px;} + /* Measured per-post line joint; overrides legacy axis-18px assumption. */ + .ldp-post.ldp-nested-branches-ready > .ldp-children > .ldp-post::before, + .ldp-post.ldp-nested-branches-ready > .ldp-children > .ldp-post::after{ + left:var(--ldp-nested-line-left,calc(var(--ldp-nested-axis-left) - var(--ldp-nested-gutter,18px)));} + /* Undo compact zoom on tree chrome so nested levels do not compound. */ + .ldp-children > .ldp-nested-preview > .ldp-children, + .ldp-children > .ldp-nested-preview > .ldp-collapse-replies, + .ldp-children > .ldp-nested-preview > .ldp-sub-loading, + .ldp-children > .ldp-nested-preview > .ldp-sub-actions{zoom:1;} + .ldp-children > .ldp-nested-preview > .ldp-collapse-replies{margin-top:2px;} + .ldp-nested-preview > .ldp-children > .ldp-nested-preview{--ldp-nested-content-scale:.95;--ldp-nested-component-scale:.93;} + .ldp-inline-reply-tree-enable-row.is-disabled{opacity:.55;cursor:not-allowed;} + .ldp-inline-reply-tree-enable-row.is-disabled .ldp-setting-switch input{cursor:not-allowed;} + .ldp-inline-reply-tree-depth-row{grid-template-columns:minmax(0,1fr) minmax(96px,132px);align-items:center;} + .ldp-inline-reply-tree-depth-row[hidden]{display:none;} + .ldp-inline-reply-tree-depth-row .ldp-inline-reply-tree-depth{width:100%;} + `;Ka.textContent=`${NS} +${zP}`;function ob(){const e=document.head||It;e&&(Ka.parentNode!==e||e.lastElementChild!==Ka)&&e.appendChild(Ka)}ob();function kS(){return document.head?[...document.head.querySelectorAll('link[rel~="stylesheet"],style')].filter(e=>e!==Ka&&e.dataset.ldpReaderShadow!=="1"&&e.dataset.ldpHostStyle!=="1"):[]}function LS(e){return!!(e&&Ka.compareDocumentPosition(e)&Node.DOCUMENT_POSITION_FOLLOWING)}function IS(e,t,r){if(!e||!t)return;const o=Yn.get(e),n=e.cloneNode(!0);if(n.removeAttribute("id"),n.dataset.ldpHostStyle="1",o?.isConnected)o.replaceWith(n);else{const s=kS(),a=s.indexOf(e),l=LS(e),c=s.slice(a+1).filter(f=>LS(f)===l).map(f=>Yn.get(f)).find(f=>f?.isConnected),d=t.querySelector("style[data-ldp-reader-shadow-guards]"),u=l?d||r?.nextSibling:r;t.insertBefore(n,c||u||t.firstChild)}Yn.set(e,n)}function WP(e,t){!e||!document.head||(e.querySelectorAll("[data-ldp-host-style]").forEach(r=>r.remove()),Yn.forEach(r=>r.remove()),Yn.clear(),kS().forEach(r=>IS(r,e,t)),!Ul&&(Ul=new MutationObserver(r=>{const o=new Set;r.forEach(s=>{if(s.type==="attributes"){o.add(s.target);return}const a=s.target.nodeType===Node.ELEMENT_NODE&&s.target.matches("style")?s.target:s.target.parentElement?.closest("style");a&&o.add(a),s.removedNodes.forEach(l=>{(l.nodeType===Node.ELEMENT_NODE&&l.matches('link[rel~="stylesheet"],style')?[l]:[...l.querySelectorAll?.('link[rel~="stylesheet"],style')||[]]).forEach(d=>{Yn.get(d)?.remove(),Yn.delete(d)})}),s.addedNodes.forEach(l=>{(l.nodeType===Node.ELEMENT_NODE&&l.matches('link[rel~="stylesheet"],style')?[l]:[...l.querySelectorAll?.('link[rel~="stylesheet"],style')||[]]).forEach(d=>o.add(d))})});const n=Ho?.querySelector("style[data-ldp-reader-shadow]");n&&o.forEach(s=>{if(s!==Ka){if(!s.isConnected||!s.matches('link[rel~="stylesheet"],style')){Yn.get(s)?.remove(),Yn.delete(s);return}IS(s,Ho,n)}})}),Ul.observe(document.head,{subtree:!0,childList:!0,attributes:!0,attributeFilter:["href","rel","media","disabled"]})))}function xS(e,t,r){if(!e||!t)return;const o=new Set(e.getAttributeNames().filter(n=>n!=="style"&&!n.startsWith("data-ldp-")));t.getAttributeNames().forEach(n=>{n!==r&&!o.has(n)&&t.removeAttribute(n)}),o.forEach(n=>{const s=n==="class"?[...e.classList].filter(a=>!a.startsWith("ldp-")).join(" "):e.getAttribute(n);t.getAttribute(n)!==s&&t.setAttribute(n,s)}),t.setAttribute(r,"1")}function DS(){xS(It,bg,"data-ldp-shadow-context-html"),xS(document.body,Fa,"data-ldp-shadow-context-body")}function qS(){Ul&&Ul.disconnect(),Pi&&Pi.disconnect(),Ul=null,Pi=null,Np&&Np(),Np=null,Yn.forEach(r=>r.remove()),Yn.clear();const e=cn,t=Ho;t&&Gr(t),t&&t.replaceChildren(),cn=null,Ho=null,bg=null,Fa=null,e&&e.remove()}function OS(){return Ct?.isConnected?!1:([ja,jp,xi].forEach(k_),!0)}function VP(){if(Ct?.isConnected)return!1;qS();const e=[...Hp.values(),...zp.values(),...Wp.values()];return OS(),e.length&&Promise.allSettled(e).then(OS),!0}function GP(e){if(!e||!It||!document.body)return null;let t=e.querySelector(":scope > html[data-ldp-shadow-context-html]");t||(t=Ne("html"),t.dataset.ldpShadowContextHtml="1",e.appendChild(t));let r=t.querySelector(":scope > body[data-ldp-shadow-context-body]");return r||(r=Ne("body"),r.dataset.ldpShadowContextBody="1",t.appendChild(r)),bg=t,Fa=r,DS(),[...e.childNodes].forEach(o=>{o===t||o.nodeType!==Node.ELEMENT_NODE||o.matches('style,link[rel~="stylesheet"]')||r.appendChild(o)}),Pi||(Pi=new MutationObserver(o=>{o.some(n=>n.attributeName!=="style")&&DS()}),Pi.observe(It,{attributes:!0}),Pi.observe(document.body,{attributes:!0})),r}function nb(){if(cn?.isConnected&&Ho)return Ho;if(!It||!document.body)return null;(cn||Ho)&&qS();let e=It.querySelector(":scope > .ldp-reader-portal-host");e||(e=Ne("div"),e.className="ldp-reader-portal-host sciapp-ldp-owned",It.appendChild(e)),e.classList.add("sciapp-ldp-owned");const t=e.shadowRoot||e.attachShadow({mode:"open"});let r=t.querySelector("style[data-ldp-reader-shadow]");r||(r=Ka.cloneNode(!0),r.dataset.ldpReaderShadow="1",t.prepend(r));let o=t.querySelector("style[data-ldp-reader-shadow-guards]");return o||(o=Ne("style"),o.dataset.ldpReaderShadowGuards="1",r.after(o)),WP(t,r),Fa=GP(t),cn=e,Ho=t,ti(),t}function An(e){const t=nb();if(!t)throw new Error("reader portal unavailable");return(Fa||t).appendChild(e),Hd(e),e}function ro(e){return Ho?.querySelector(e)||document.querySelector(e)}function Pn(e){const t=Ho?[...Ho.querySelectorAll(e)]:[];return document.querySelectorAll(e).forEach(r=>{t.includes(r)||t.push(r)}),t}function QP(){const e=nb();if(!e||e._ldpReaderIconTooltipReady)return;e._ldpReaderIconTooltipReady=!0;const t=Ne("div");t.className="ldp-reader-icon-tooltip ldp-transient-surface",t.setAttribute("role","tooltip"),t.hidden=!0,(Fa||e).appendChild(t);const r=Uo(),o=(f,m,g,b)=>r.listen(f,m,g,b);let n=null;const s=()=>{!n&&t.hidden&&!t.textContent||(n=null,fr(t,!0),fa(t,""))},a=f=>[...f.childNodes].some(m=>{if(m.nodeType===Node.TEXT_NODE)return!!String(m.textContent||"").trim();if(!(m instanceof Element)||m.matches(".ldp-icon,.ldp-logo,.ldp-notification-unread-badge"))return!1;const g=getComputedStyle(m);return g.display==="none"||g.visibility==="hidden"?!1:!!String(m.innerText||m.textContent||"").trim()}),l=f=>{if(!(f instanceof Element))return null;const m=f.closest('button,a,[role="button"],[data-ldp-tooltip-label],.ldp-nested-branch-toggle,.ldp-avatar-flair,.ldp-user-card-badge');if(!(m&&(m.closest(".ldp-overlay,.ldp-lightbox")||m.closest(".ldp-user-card-fallback,.ldp-avatar-viewer")||m.matches(".ldp-native-reader-trigger")))||m.hasAttribute("data-tooltip")||m.matches('.ldp-settings-tab,.ldp-topic-timeline-track,[data-reaction-picker][aria-expanded="true"]'))return null;const b=m.matches('button,[role="button"],.ldp-nested-branch-toggle'),w=m.matches("a")&&m.querySelector(".ldp-icon,.ldp-logo,img")&&!a(m),R=m.matches(".ldp-avatar-flair,.ldp-user-card-badge"),z=m.hasAttribute("data-ldp-tooltip-label");if(!b&&!w&&!R&&!z)return null;const P=m.matches(".ldp-title-jump")&&(m.closest(".ldp-modal")?.getBoundingClientRect().width||0)<=480&&m.scrollWidth>m.clientWidth+1,M=String(P?m.textContent:m.getAttribute("aria-label")||m.dataset.ldpTooltipLabel||"").trim();return M?{control:m,label:M}:null},c=(f,m=null)=>{const g=f.getBoundingClientRect(),b=t.getBoundingClientRect(),w=6,R=8;if(f.matches(".ldp-nested-rail-toggle,.ldp-nested-branch-toggle")&&m&&Number.isFinite(m.clientX)&&Number.isFinite(m.clientY)){let U=m.clientX+12;U+b.width>window.innerWidth-R&&(U=m.clientX-b.width-12);let pe=m.clientY+12;pe+b.height>window.innerHeight-R&&(pe=m.clientY-b.height-12),t.style.left=`${Math.round(Math.max(R,Math.min(U,window.innerWidth-b.width-R)))}px`,t.style.top=`${Math.round(Math.max(R,Math.min(pe,window.innerHeight-b.height-R)))}px`;return}let z=g.left+(g.width-b.width)/2;z=Math.max(R,Math.min(z,window.innerWidth-b.width-R));let P=g.top-b.height-w;P{const b=g||l(f);b&&(n=b.control,fa(t,b.label),t.classList.toggle("ldp-reader-history-tooltip",b.control.matches(".ldp-reader-history-nav")),t.classList.toggle("ldp-connect-help-tooltip",b.control.matches(".ldp-connect-metric")),fr(t,!1),c(b.control,m))},u=f=>f&&(f.matches(":hover")||f.matches(":focus-visible"));o(e,"ldp-tooltip-refresh",f=>{if(!(f.target instanceof Element))return;const m=f.target;n&&!n.isConnected&&s();const g=l(m);if(!g||m.hidden||!u(m)){m===n&&s();return}d(m,null,g)}),o(e,"click",f=>{const m=f.target instanceof Element&&f.target.closest(".ldp-avatar-flair,.ldp-user-card-badge");if(!m)return;yt(f);const g=String(m.dataset.ldpTooltipLabel||m.getAttribute("aria-label")||"").trim();if(!g)return;const b=w=>{m.dataset.ldpTooltipLabel=w,nt(m,w),pa(m),setTimeout(()=>{!m.isConnected||m.dataset.ldpTooltipLabel!==w||(m.dataset.ldpTooltipLabel=g,nt(m,g),pa(m))},900)};bm(g).then(()=>b("已复制")).catch(()=>b("复制失败"))},!0),o(e,"pointerover",f=>{const m=l(f.target);!m||f.relatedTarget instanceof Node&&m.control.contains(f.relatedTarget)||d(m.control,f,m)}),o(e,"pointerdown",f=>{f.target instanceof Element&&f.target.closest(".ldp-header[data-ldp-reader-drag-surface]")&&s()},!0),o(e,"pointermove",f=>{!n?.matches(".ldp-nested-rail-toggle,.ldp-nested-branch-toggle")||!(f.target instanceof Node)||!n.contains(f.target)||c(n,f)}),o(e,"pointerout",f=>{!n||f.relatedTarget instanceof Node&&n.contains(f.relatedTarget)||n.matches(":focus-visible")||s()}),o(e,"focusin",f=>d(f.target)),o(e,"focusout",()=>{queueMicrotask(()=>{u(n)||s()})}),o(e,"scroll",()=>{const f=e.querySelector(".ldp-reader-history-nav:hover");f?d(f):s()},!0),o(window,"resize",s),Np=()=>{s(),r.destroy(),t.remove(),e._ldpReaderIconTooltipReady=!1}}function sb(){let e=document.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e}function ab(){const e=[],t=r=>{r&&!e.includes(r)&&e.push(r)};if(D(Ho?.getSelection))try{t(Ho.getSelection())}catch{}try{t(window.getSelection())}catch{}return e.find(r=>r.rangeCount>0&&!r.isCollapsed)||e.find(r=>r.rangeCount>0)||e[0]||null}function Br(e,t){const o=(D(e?.composedPath)?e.composedPath():[]).find(n=>n&&n.nodeType===Node.ELEMENT_NODE&&n.matches(t));return o||(e?.target&&e.target.closest?e.target.closest(t):null)}function ji(e,t){return!e||!t?!1:(D(e.composedPath)?e.composedPath():[]).includes(t)||t.contains(e.target)}function Dd(e,t){t.stopPropagation();const r=t.target instanceof Element?t.target:null,o=40,n=t.deltaMode===1?t.deltaX*o:t.deltaMode===2?t.deltaX*e.clientWidth:t.deltaX,s=t.deltaMode===1?t.deltaY*o:t.deltaMode===2?t.deltaY*e.clientHeight:t.deltaY;if(!r||!e.contains(r)){t.preventDefault();return}let a=r;for(;a&&e.contains(a);){const l=getComputedStyle(a),c=a.scrollWidth-a.clientWidth,d=a.scrollHeight-a.clientHeight,u=n&&c>1&&/(auto|scroll|overlay)/.test(l.overflowX)&&(n<0?a.scrollLeft>0:a.scrollLeft1&&/(auto|scroll|overlay)/.test(l.overflowY)&&(s<0?a.scrollTop>0:a.scrollTopDd(e,t),{passive:!1}))}function Uo(){const e=[];let t=!1;const r={add(o){return t?o():e.push(o),o},listen(o,n,s,a){return o.addEventListener(n,s,a),r.add(()=>o.removeEventListener(n,s,a)),s},observe(o,n,s){return o.observe(n,s),r.add(()=>o.disconnect()),o},timer(o,n){const s=setTimeout(o,n);return r.add(()=>clearTimeout(s)),s},raf(o){const n=requestAnimationFrame(o);return r.add(()=>cancelAnimationFrame(n)),n},destroy(){t||(t=!0,e.splice(0).reverse().forEach(o=>{try{o()}catch(n){console.warn("[LDP] lifecycle cleanup failed",n)}}))}};return r}function YP(e){const t=document.createDocumentFragment();return{parking:t,mount(r,o=e){return r&&o&&r.parentNode!==o&&o.append(r),r},park(r){return r&&r.parentNode!==t&&t.append(r),r},destroy(){Gr(t),t.replaceChildren()}}}function ec(e,t,r,o=!1){e.forEach(n=>{const s=n.dataset[t]===r;n.classList.toggle("active",s),n.setAttribute("aria-selected",String(s)),o&&(n.tabIndex=s?0:-1)})}function FS(e,t,r,o=0){let n=0;const s=()=>{n&&(o?clearTimeout(n):cancelAnimationFrame(n),n=0)},a=()=>{n=0,r(e.value.trim())};return e.addEventListener("input",()=>{t.hidden=!e.value,s(),n=o?setTimeout(a,o):requestAnimationFrame(a)}),t.addEventListener("click",()=>{s(),e.value="",t.hidden=!0,r(""),e.focus()}),s}function XP(e,t,r,o){e.closest(".ldp-notification-pager").addEventListener("click",n=>{const s=n.target instanceof Element?n.target.closest("button"):null;if(s===e){if(r.page<=0)return;r.page--}else if(s===t){if(r.hasNext===!1)return;r.page++}else return;o()})}function BS(e,t){const r=t.length>0&&t.every(o=>e.has(o));t.forEach(o=>{r?e.delete(o):e.add(o)})}function HS(e,t,r,o,n,s){e.addEventListener("change",a=>{const l=a.target.closest(t),c=Number(l?.closest(r)?.dataset[o]);c>0&&(n[l.checked?"add":"delete"](c),s())})}function US(e,t,r,o,n,s,a,l=()=>{}){const c=()=>{l(),r.clear(),a()};e.addEventListener("click",d=>{const u=d.target instanceof Element?d.target.closest("button"):null;if(u===o)t.multi=!0,t.scope="page";else if(u===n)t.multi=!1;else return;c()}),s.addEventListener("change",()=>{t.scope=s.value==="all"?"all":"page",r.clear(),a()})}function jS(e,t,r,o,n){if(e.key==="Escape"){yt(e),n(!0);return}if(e.key==="Enter"&&e.target===t){e.preventDefault(),r.querySelector(o)?.click();return}if(e.key!=="ArrowDown"&&e.key!=="ArrowUp")return;const s=[...r.querySelectorAll(o)];if(!s.length)return;e.preventDefault();const a=s.indexOf(document.activeElement),l=e.key==="ArrowDown"?1:-1,c=a<0?l>0?0:s.length-1:(a+l+s.length)%s.length;s[c].focus()}const $e=e=>String(e??"").replace(/[<>&]/g,t=>({"<":"<",">":">","&":"&"})[t]),Pe=e=>$e(e).replace(/"/g,""").replace(/'/g,"'");function yt(e){e.preventDefault(),e.stopPropagation()}function pa(e){e.dispatchEvent(new CustomEvent("ldp-tooltip-refresh",{bubbles:!0,composed:!0}))}function sr(e,t){const r=String(t);e.getAttribute("aria-expanded")!==r&&e.setAttribute("aria-expanded",r)}function bo(e,t){const r=String(t);e.getAttribute("aria-pressed")!==r&&e.setAttribute("aria-pressed",r)}function nt(e,t){e.getAttribute("aria-label")!==t&&e.setAttribute("aria-label",t)}function fr(e,t){e&&e.hidden!==t&&(e.hidden=t)}function fa(e,t){e&&e.textContent!==t&&(e.textContent=t)}function ib(e,t,r){const o=String(r);e&&e.getAttribute(t)!==o&&e.setAttribute(t,o)}function ma(e,t,r){const o=String(r);e&&e.style.getPropertyValue(t)!==o&&e.style.setProperty(t,o)}function D(e){return typeof e=="function"}function tc(){return D(window.matchMedia)&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}const zS={activity:'',database:'',image:'',type:'',alertTriangle:'',bell:'',headerBell:'',bellOff:'',bookmark:'',headerBookmark:'',check:'',square:'',squareCheck:'',circleX:'',arrowUp:'',chevronDown:'',chevronUp:'',chevronRight:'',download:'',upload:'',externalLink:'',copy:'',eyeOff:'',mail:'',palette:'',award:'',tag:'',heart:'',hand:'',history:'',headerHistory:'',info:'',lock:'',unlock:'',pin:'',pencil:'',trash:'',wrench:'',loader:'',maximize2:'',layoutGrid:'',panelLeft:'',panelRight:'',floatingWindow:'',messageSquare:'',minus:'',minimize2:'',cornerDownRight:'',reply:'',plus:'',rocket:'',sun:'',moon:'',monitor:'',settings:'',headerSettings:'',languages:'',smile:'',search:'',at:'',flag:'',link2:'',lightbulb:'',list:'',layers:'',gitBranch:'',listChecks:'',rotateCcw:'',share2:'',shieldHalved:'',userPlus:'',userRound:'',x:''};function ue(e,t){return``}function zi(e,t,r){return r.map(([o,n,s,a=""])=>``).join("")}const lb=[{key:"accentColor",section:"interaction",label:"按钮与选中状态颜色",help:"控制阅读器的主强调色,包括主要按钮、选中态、焦点轮廓、开关开启态、时间轴和操作反馈;不会改变错误、警告、成功和点赞等语义颜色。选择时实时预览,统一保存。"},{key:"linkColor",section:"interaction",label:"正文链接颜色",help:"控制帖子正文中的 URL 链接颜色,与按钮和选中态的界面强调色分开设置;选择时实时预览,统一保存。"},{key:"zebraColor",section:"zebra",label:"背景颜色",ariaLabel:"交替楼层背景颜色",help:"设置阅读器正文楼层隔行出现的淡色背景,用来更容易分清相邻楼层。选择时实时预览,通过底部“保存全部更改”统一保存。"},{key:"zebraRadius",section:"zebra",label:"背景圆角",ariaLabel:"交替楼层背景圆角",range:[Jh,Zh,ow],normalize:(e,t=rw)=>_f(e,t,Jh,Zh,ow),help:`设置交替楼层背景的圆角,${Jh}px 为直角,最高 ${Zh}px。拖动时实时预览,通过底部“保存全部更改”统一保存。`},{key:"listZebraColor",section:"list-zebra",label:"嵌入阅读列表背景",ariaLabel:"嵌入阅读时原站主题列表交替背景颜色",shareLabel:"嵌入阅读列表背景",help:`使用左右嵌入阅读时,设置 ${Vn} 主题列表卡片的隔行色调;所选颜色会与原站背景适度混合。选择时实时预览,通过底部“保存全部更改”统一保存。`},{key:"replyLineColor",section:"reply-line",label:"颜色",ariaLabel:"回复连接线颜色",help:"控制阅读器里的关系线颜色,包括二级回复连线、上级回复预览、时间轴、特殊提示边框和大图评论层级线。选择时实时预览,统一保存。"},{key:"replyLineWidth",section:"reply-line",label:"粗细",ariaLabel:"回复连接线粗细",range:[Ci,Ei,Sp],normalize:(e,t=eg)=>Ef(e,t),help:`控制回复关系线的基础粗细,可在 ${Ci}–${Ei}px 之间调整;二级回复树线、父子回复连接线和相关层级线会同步变化。拖动时实时预览,统一保存。`},{key:"replyLineRadius",section:"reply-line",label:"转角圆角",ariaLabel:"回复连接线转角圆角",shareLabel:"回复连接线圆角",range:[tg,rg,sw],normalize:Mf,help:`控制父子回复和二级回复连接线转折处的圆角,${tg}px 为直角,最高 ${rg}px。拖动时实时预览,统一保存。`},{key:"quoteLineColor",section:"quote-line",label:"颜色",ariaLabel:"引用线颜色",help:"控制帖子正文引用块和“引用某楼层”卡片左侧竖线的颜色,只改变引用提示线,不改变引用文字或背景。选择时实时预览,统一保存。"},{key:"quoteLineWidth",section:"quote-line",label:"粗细",ariaLabel:"引用线粗细",range:[Ci,Ei,Sp],normalize:(e,t=aw)=>Ef(e,t),help:`控制引用线的基础粗细,可在 ${Ci}–${Ei}px 之间调整;不同引用样式会保留原有粗细层级。拖动时实时预览,统一保存。`},{key:"dividerLineColor",section:"divider-line",label:"颜色",ariaLabel:"界面分隔线颜色",help:"控制楼层边界、标题栏、设置与通知面板、嵌入阅读边界和大图查看器结构分隔线的颜色;按钮和输入框外框不会跟着改变。选择时实时预览,统一保存。"},{key:"dividerLineWidth",section:"divider-line",label:"粗细",ariaLabel:"界面分隔线粗细",range:[Ci,Ei,Sp],normalize:(e,t=_p)=>Ef(e,t),help:`控制界面结构分隔线的基础粗细,可在 ${Ci}–${Ei}px 之间调整;按钮和输入框外框不会跟着改变。拖动时实时预览,统一保存。`},{key:"floorPreviewColor",section:"floor-preview",label:"卡片强调颜色",ariaLabel:"上级回复预览卡片强调颜色",shareLabel:"上级回复预览颜色",help:"控制父楼层号悬停后插入的预览卡片边框、淡色背景和楼层标记颜色;不改变二级回复关系线。选择时实时预览,统一保存。"},{key:"floorPreviewHeight",section:"floor-preview",label:"卡片最大高度",ariaLabel:"上级回复预览卡片最大高度",shareLabel:"上级回复预览高度",range:[og,iw,cw],normalize:(e,t=lw)=>_f(e,t,og,iw,cw),help:`控制父回复插入预览在长内容时允许占用的最大高度,最低 ${og}px;内容较短时仍按实际高度显示,并始终受当前窗口可用高度限制。拖动时实时预览,统一保存。`}],KP=[{id:"interaction",title:"按钮与链接",description:"控制按钮、选中状态、焦点、时间轴和正文链接,不改变错误、警告、成功等状态颜色。",sections:["interaction"]},{id:"background",title:"交替内容背景",description:"用浅色背景区分相邻楼层,以及嵌入阅读时的原站主题列表卡片。",sections:[{id:"zebra",title:"交替楼层背景"},"list-zebra"]},{id:"structure",title:"关系线与分隔线",description:"分别控制回复连接线、引用线和界面分隔线;关闭后隐藏这些线条,已设置的样式会保留。",toggleKey:"structureColorsEnabled",toggleLabel:"显示关系线与分隔线",sections:[{id:"reply-line",title:"回复连接线"},{id:"quote-line",title:"引用线"},{id:"divider-line",title:"界面分隔线"}]},{id:"floor-preview",title:"上级回复预览卡片",description:"控制悬停上级楼层号后插入的预览卡片,不影响回复连接线和其他内容。",sections:["floor-preview"]}];function WS(e){return`ldp-${e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`)}`}function JP(e){const t=WS(e.key),r=e.range?``:``;return`
${e.label} ${r} -
`}function DP(e){const t=e.sections.map(o=>{const{id:n,title:s}=typeof o=="string"?{id:o}:o,a=tb.filter(c=>c.section===n).map(qP).join("");if(!s)return a;const l=`ldp-${n}-setting-group-title`;return`
+
`}function ZP(e){const t=e.sections.map(o=>{const{id:n,title:s}=typeof o=="string"?{id:o}:o,a=lb.filter(c=>c.section===n).map(JP).join("");if(!s)return a;const l=`ldp-${n}-setting-group-title`;return`
${s}
${a}
`}).join(""),r=e.toggleKey?` @@ -101,38 +124,38 @@ ${r}
${t}
- `}function OP(){return xa.map(e=>{const t=`ldp-flash-${e.key}`,r=ys[e.key],o=e.type==="color"?``:``;return`