// ==UserScript==
// @name sis001-预览
// @version 1.1.9
// @namespace https://sleazyfork.org/zh-CN/users/1461640-%E6%98%9F%E5%AE%BF%E8%80%81%E9%AD%94
// @author 星宿老魔
// @description sis001第一会所综合社区,帖子图片预览,板块收纳,搜索优化
// @match https://sis001.com/*
// @match https://*.sis001.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=sis001.com
// @license MIT
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @run-at document-start
// ==/UserScript==
(function(){"use strict";const e={ACCENT:"#00599F",BG_LIGHT:"#f8f9fa",BORDER_LIGHT:"#e3e6ea",BORDER_NORMAL:"#e9ecef",
TEXT_PRIMARY:"#2c3e50",TEXT_SECONDARY:"#666",TEXT_MUTED:"#6c757d",TEXT_LIGHT:"#999",TEXT_ERROR:"#333"};const t={
SM:"6px",MD:"8px",XL:"12px",ROUND:"50%",PILL:"999px"};const n={MD:"8px",LG:"10px",XL:"12px",XXL:"16px"};const o={
LIGHT:"0 2px 6px rgba(0,0,0,0.08)",NORMAL:"0 3px 12px rgba(0,0,0,0.08)",IMAGE:"0 2px 8px rgba(0,0,0,0.12)"};const r={
GRADIENT:"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)",WHITE_ALPHA:"rgba(255,255,255,0.9)",
LIGHT_ALPHA:"rgba(248,249,250,0.6)"};const a={select(e){return document.querySelector(e)},selectAll(e){
return document.querySelectorAll(e)},create(e,t={},n={}){const o=document.createElement(e)
;Object.entries(t).forEach(([e,t])=>{o.setAttribute(e,t)});Object.entries(n).forEach(([e,t])=>{o.style[e]=t});return o},
addStyle(e,t){const n=document.createElement("style");if(t)n.id=t;n.textContent=e;document.head.appendChild(n);return n}
};async function runWithConcurrency(e,t,n=8){const o=[...e];const r=new Set;const a=[];async function runNext(){
if(0===o.length)return;const e=o.shift();const s=t(e).then(e=>{a.push(e)}).finally(()=>{r.delete(s)});r.add(s)
;if(r.size>=n)await Promise.race(Array.from(r));return runNext()}await runNext();await Promise.all(Array.from(r))
;return a}const s={resolve(e,t){try{return new URL(t,e).href}catch(n){console.warn("[URL] 解析 URL 失败:",n);return t}},
isHttp(e){return/^https?:\/\//i.test(e)}};const i={applyButtonStyle(t,options={}){const{primary:n=false}=options
;const o=["display:inline-flex","align-items:center","justify-content:center","height:28px","padding:0 12px","border-radius:6px","font-size:12px","line-height:1","cursor:pointer","user-select:none","white-space:nowrap","box-sizing:border-box"]
;const r=n?`background:${e.ACCENT};color:#fff;border:1px solid ${e.ACCENT}`:`background:#fff;color:${e.TEXT_PRIMARY};border:1px solid ${e.BORDER_LIGHT}`
;t.style.cssText=[...o,r].join(";")},ensureToggleStyles(){
if(document.querySelector('style[data-sis-toggle-style="1"]'))return
;const n=`.sis-toggle{display:inline-flex;align-items:center;gap:${t.SM};cursor:pointer;user-select:none;height:28px;padding:0 12px;border:1px solid ${e.BORDER_LIGHT};border-radius:${t.SM};background:#fff;box-shadow:${o.LIGHT};vertical-align:middle;box-sizing:border-box}.sis-toggle .sis-input{position:absolute;opacity:0;width:0;height:0}.sis-toggle .sis-switch{position:relative;width:30px;height:16px;background:#e5e7eb;border-radius:${t.PILL};box-shadow:inset 0 0 0 1px #d1d5db;flex:0 0 30px}.sis-toggle .sis-switch::before{content:"";position:absolute;top:2px;left:2px;width:12px;height:12px;background:#fff;border-radius:${t.ROUND};box-shadow:0 1px 2px rgba(0,0,0,.2)}.sis-toggle .sis-input:checked + .sis-text + .sis-switch{background:${e.ACCENT}}.sis-toggle .sis-input:checked + .sis-text + .sis-switch::before{transform:translateX(14px)}.sis-toggle .sis-text{color:${e.TEXT_ERROR};font-size:12px}`
;a.addStyle(n,"sis-toggle-styles").setAttribute("data-sis-toggle-style","1")}};const c={createOverlay(){
return a.create("div",{},{position:"fixed",inset:"0",background:"rgba(0,0,0,0.4)",zIndex:"10001",display:"flex",
alignItems:"center",justifyContent:"center"})},createPanel(e="480px"){return a.create("div",{},{width:e,maxWidth:"92vw",
maxHeight:"80vh",overflow:"auto",background:"#fff",borderRadius:"10px",boxShadow:"0 10px 30px rgba(0,0,0,.2)"})},
createHeader(e,t){const n=a.create("div",{},{padding:"12px 16px",borderBottom:"1px solid #e9ecef",fontWeight:"600",
display:"flex",justifyContent:"space-between",alignItems:"center"});n.textContent=e;const o=a.create("button")
;o.textContent="×";i.applyButtonStyle(o);o.onclick=t;n.appendChild(o);return n},createFooter(e,t,n="保存并刷新"){
const o=a.create("div",{},{padding:"12px 16px",borderTop:"1px solid #e9ecef",display:"flex",justifyContent:"flex-end",
gap:"10px"});const r=a.create("button");r.textContent="取消";i.applyButtonStyle(r);r.onclick=e;const s=a.create("button")
;s.textContent=n;i.applyButtonStyle(s);s.onclick=t;o.appendChild(r);o.appendChild(s);return o}};const l={
waitForDOMContentLoaded(){if("loading"===document.readyState)return new Promise(e=>{
document.addEventListener("DOMContentLoaded",()=>e(),{once:true})});return Promise.resolve()},waitForWindowLoad(){
if("complete"!==document.readyState)return new Promise(e=>{window.addEventListener("load",()=>e(),{once:true})})
;return Promise.resolve()}};const d=class _MagnetConverter{static init(){this.setupMagnetLinks()}
static setupMagnetLinks(){if(!a.select(".t_msgfont"))return;const e=a.selectAll(".t_msgfont");e.forEach(e=>{
this.processPost(e)})}static processPost(e){if(this.processed.has(e))return;const t=/([a-fA-F0-9]{40})/g
;if(t.test(e.innerHTML))e.innerHTML=e.innerHTML.replace(t,e=>`magnet:?xt=urn:btih:${e}`);this.processed.add(e)}
static refresh(){this.setupMagnetLinks()}};d.processed=new WeakSet;let p=d;class AdRemover{static init(){
this.injectHidingCSS();this.removeRulesTable();this.removePublicMessages();this.removeStickyTopics()
;this.removeImportantTopics();this.removeAdministrativeThreads();setTimeout(()=>{this.removeRulesTable()
;this.removePublicMessages();this.removeStickyTopics();this.removeImportantTopics();this.removeAdministrativeThreads()
},1e3)}static injectHidingCSS(){if(a.select('style[data-sis-ad-remover="1"]'))return
;const e=`\n /* 立即隐藏本版规则表格 */\n table[summary="Rules and Recommend"] { display: none !important; }\n \n /* 立即隐藏公共消息 */\n .maintable#pmprompt,\n .box#pmprompt { display: none !important; }\n \n /* 立即隐藏固定主题和重要主题区块 */\n thead.separation { display: none !important; }\n tbody[id^="stickthread_"] { display: none !important; }\n \n /* 立即隐藏版务相关帖子(备用CSS) */\n .sis-hide-admin { display: none !important; }\n `
;a.addStyle(e).setAttribute("data-sis-ad-remover","1")}static removeRulesTable(){
const e=document.querySelector('table[summary="Rules and Recommend"]');if(e)e.remove()}static removePublicMessages(){
const e=document.querySelector(".maintable#pmprompt");if(e)e.remove();const t=document.querySelector(".box#pmprompt")
;if(t)t.remove()}static removeTopicsByType(e){const t=document.querySelectorAll("thead.separation");t.forEach(t=>{
const n=t.querySelectorAll("font");let o=false;n.forEach(t=>{if(e.some(e=>t.textContent?.includes(e)))o=true});if(o){
t.remove();let e=t.nextElementSibling;while(e)if("TBODY"===e.tagName&&e.id&&e.id.startsWith("stickthread_")){const t=e
;e=e.nextElementSibling;t.remove()}else break}})}static removeStickyTopics(){this.removeTopicsByType(["固定主題"])}
static removeImportantTopics(){this.removeTopicsByType(["重要主題"])}static removeAdministrativeThreads(){
const e=document.querySelectorAll('tbody[id^="stickthread_"], tbody[id^="normalthread_"]');e.forEach(e=>{
const t=e.querySelectorAll('em a[href*="typeid=528"]');if(t.length>0){e.classList.add("sis-hide-admin");setTimeout(()=>{
e.remove()},10)}})}static refresh(){this.removeRulesTable();this.removePublicMessages();this.removeStickyTopics()
;this.removeImportantTopics();this.removeAdministrativeThreads()}}const h={collectNames:"sis_board_collect_names",
favoriteNames:"sis_board_favorite_names",collectionOpen:"sis_board_collection_open",
favoriteOpen:"sis_board_favorite_open",searchFavForums:"sis_search_fav_forums",searchFavAuto:"sis_search_fav_auto",
previewMaxImages:"sis_preview_max_images",previewConcurrency:"sis_preview_concurrency"};const u={
MAX_PREVIEW_CONCURRENCY:9,MAX_IMAGES_PER_POST:3};class Config{static getMaxPreviewConcurrency(){
const e=parseInt(GM_getValue(h.previewConcurrency,"")||"",10)
;return Number.isFinite(e)&&e>=1&&e<=100?e:u.MAX_PREVIEW_CONCURRENCY}static setMaxPreviewConcurrency(e){try{
GM_setValue(h.previewConcurrency,String(e))}catch(t){console.warn("[Config] 保存预览并发数失败:",t)}}
static getMaxImagesPerPost(){const e=parseInt(GM_getValue(h.previewMaxImages,"")||"",10)
;return Number.isFinite(e)&&e>=1&&e<=20?e:u.MAX_IMAGES_PER_POST}static setMaxImagesPerPost(e){try{
GM_setValue(h.previewMaxImages,String(e))}catch(t){console.warn("[Config] 保存图片数量配置失败:",t)}}
static getCollectedBoardNames(){try{const e=GM_getValue(h.collectNames,"");if(!e)return[];const t=JSON.parse(e)
;return Array.isArray(t)?t:[]}catch(e){console.warn("[Config] 获取收纳板块列表失败:",e);return[]}}
static setCollectedBoardNames(e){try{GM_setValue(h.collectNames,JSON.stringify(e||[]))}catch(t){
console.warn("[Config] 保存收纳板块列表失败:",t)}}static getFavoriteBoardNames(){try{const e=GM_getValue(h.favoriteNames,"")
;if(!e)return[];const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){console.warn("[Config] 获取收藏板块列表失败:",e)
;return[]}}static setFavoriteBoardNames(e){try{GM_setValue(h.favoriteNames,JSON.stringify(e||[]))}catch(t){
console.warn("[Config] 保存收藏板块列表失败:",t)}}static getCollectionOpen(){try{return"1"===GM_getValue(h.collectionOpen,"0")
}catch(e){console.warn("[Config] 获取收纳区状态失败:",e);return false}}static setCollectionOpen(e){try{
GM_setValue(h.collectionOpen,e?"1":"0")}catch(t){console.warn("[Config] 保存收纳区状态失败:",t)}}static getFavoriteOpen(){try{
return"1"===GM_getValue(h.favoriteOpen,"0")}catch(e){console.warn("[Config] 获取收藏区状态失败:",e);return false}}
static setFavoriteOpen(e){try{GM_setValue(h.favoriteOpen,e?"1":"0")}catch(t){console.warn("[Config] 保存收藏区状态失败:",t)}}
static getSearchFavForums(){try{const e=GM_getValue(h.searchFavForums,"");return e?JSON.parse(e):[]}catch(e){
console.warn("[Config] 获取搜索收藏论坛失败:",e);return[]}}static setSearchFavForums(e){try{
GM_setValue(h.searchFavForums,JSON.stringify(e||[]))}catch(t){console.warn("[Config] 保存搜索收藏论坛失败:",t)}}
static getSearchFavAuto(){try{return"1"===GM_getValue(h.searchFavAuto,"0")}catch(e){
console.warn("[Config] 获取搜索自动记忆状态失败:",e);return false}}static setSearchFavAuto(e){try{
GM_setValue(h.searchFavAuto,e?"1":"0")}catch(t){console.warn("[Config] 保存搜索自动记忆状态失败:",t)}}}
const g=class _PreviewImageExtractor{static extractValidImages(e){const t=Array.from(e.querySelectorAll("img"))
;const n=t.filter(e=>{const t=this.getImageSource(e);return this.isValidImageSource(t,e)});const o=n.sort((e,t)=>{
const n=this.getImageSource(e);const o=this.getImageSource(t);const r=this.VALID_DOMAINS.some(e=>n.includes(e))
;const a=this.VALID_DOMAINS.some(e=>o.includes(e));if(r&&!a)return-1;if(!r&&a)return 1;return 0})
;return o.slice(0,Config.getMaxImagesPerPost())}static getImageSource(e){return e.src||e.getAttribute("src")||""}
static isValidImageSource(e,t){if(!e)return false;if(e.includes("attachments/"))return true
;const n=t.getAttribute("onclick")||"";if(!n.includes("zoom(this)"))return false;if(s.isHttp(e)){
const t=this.VALID_DOMAINS.some(t=>e.includes(t));if(t)return true;return true}return false}static addValidDomain(e){
if(!this.VALID_DOMAINS.includes(e))this.VALID_DOMAINS.push(e)}static getValidDomains(){return[...this.VALID_DOMAINS]}}
;g.VALID_DOMAINS=["imagebam.com","imgccc.com","blr844.com","img.blr844.com","imx.to","img.sis.la","imagetwist.com","imgbox.com"]
;let f=g;class ImageViewer{static show(e,t,n){const o=this.createViewerOverlay()
;const{container:r,img:a,info:i,prevBtn:c,nextBtn:l}=this.createViewerElements();let d=t;const updateImage=()=>{
const t=f.getImageSource(e[d]);const o=s.resolve(n||location.href,t);this.updateImageSize(a,o)
;i.textContent=`${d+1} / ${e.length}`};c.addEventListener("click",()=>{d=(d-1+e.length)%e.length;updateImage()})
;l.addEventListener("click",()=>{d=(d+1)%e.length;updateImage()});const handleKeydown=e=>{
if("ArrowLeft"===e.key)c.click();else if("ArrowRight"===e.key)l.click();else if("Escape"===e.key){o.remove()
;document.removeEventListener("keydown",handleKeydown)}};o.addEventListener("click",e=>{if(e.target===o){o.remove()
;document.removeEventListener("keydown",handleKeydown)}});r.appendChild(i);r.appendChild(c);r.appendChild(l)
;r.appendChild(a);o.appendChild(r);document.body.appendChild(o);document.addEventListener("keydown",handleKeydown)
;updateImage()}static createViewerOverlay(){return a.create("div",{},{position:"fixed",top:"0",left:"0",width:"100%",
height:"100%",background:"rgba(0,0,0,0.9)",zIndex:"10000",display:"flex",alignItems:"center",justifyContent:"center"})}
static createViewerElements(){const e=a.create("div",{},{position:"relative",maxWidth:"90%",maxHeight:"90%",
textAlign:"center"});const t=a.create("img",{},{objectFit:"contain",borderRadius:"8px",
boxShadow:"0 4px 20px rgba(0,0,0,0.5)"});const n=a.create("div",{},{position:"absolute",top:"-40px",left:"50%",
transform:"translateX(-50%)",color:"white",fontSize:"16px",fontWeight:"bold",background:"rgba(0,0,0,0.7)",
padding:"8px 16px",borderRadius:"20px"});const o={position:"absolute",top:"50%",transform:"translateY(-50%)",
background:"rgba(255,255,255,0.2)",color:"white",border:"none",fontSize:"24px",width:"44px",height:"44px",
borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer"}
;const r=a.create("button",{},{...o,left:"-60px"});r.innerHTML="❮";const s=a.create("button",{},{...o,
right:"-60px"});s.innerHTML="❯";return{container:e,img:t,info:n,prevBtn:r,nextBtn:s}}static updateImageSize(e,t){
e.style.width="";e.style.height="";e.style.maxWidth="";e.style.maxHeight="";e.style.display="none";e.onload=()=>{
e.style.display="block";const t=.9*window.innerWidth;const n=.9*window.innerHeight;const o=e.naturalWidth
;const r=e.naturalHeight;if(o<300&&r<300){const a=2*o;const s=2*r;if(a<=t&&s<=n){e.style.width=a+"px"
;e.style.height=s+"px"}else this.scaleImageToFit(e,a,s,t,n)}else if(o>t||r>n)this.scaleImageToFit(e,o,r,t,n);else{
e.style.width=o+"px";e.style.height=r+"px"}};e.onerror=()=>{e.style.display="block";e.style.maxWidth="90%"
;e.style.maxHeight="90%"};e.src=t}static scaleImageToFit(e,t,n,o,r){const a=o/t;const s=r/n;const i=Math.min(a,s)
;const c=t*i;const l=n*i;e.style.width=c+"px";e.style.height=l+"px"}}const m=class _CacheManager{static getCache(){try{
return JSON.parse(GM_getValue(this.CACHE_KEY,"{}"))}catch(e){console.warn("[CacheManager] 解析缓存失败:",e);return{}}}
static setCache(e){try{GM_setValue(this.CACHE_KEY,JSON.stringify(e))}catch(t){console.warn("[CacheManager] 保存缓存失败:",t)}}
static getCacheEntry(e){const t=this.getCache();const n=t[e];if(!n)return null
;if(Date.now()-n.ts>this.TTL_MS)return null;return Array.isArray(n.urls)?n.urls:null}static saveCacheEntry(e,t,n){
const o=this.getCache();o[e]={ts:Date.now(),urls:t.slice(0,n)};this.limitCacheSize(o);this.setCache(o)}
static limitCacheSize(e){const t=Object.keys(e);if(t.length<=this.MAX_ENTRIES)return
;t.sort((t,n)=>(e[t].ts||0)-(e[n].ts||0));for(let n=0;n<t.length-this.MAX_ENTRIES;n++)delete e[t[n]]}
static clearCache(){try{GM_deleteValue(this.CACHE_KEY);console.log("[CacheManager] 已清除预览缓存")}catch(e){
console.warn("[CacheManager] 清除缓存失败:",e)}}static clearExpiredCache(){const e=this.getCache();const t=Date.now()
;let n=false;Object.keys(e).forEach(o=>{if(t-e[o].ts>this.TTL_MS){delete e[o];n=true}});if(n)this.setCache(e)}
static filterCachedUrls(e,t){return e.filter(e=>{if(e.includes("attachments/"))return true
;return t.some(t=>e.includes(t))})}};m.CACHE_KEY="sis_preview_cache_v1";m.TTL_MS=15*60*1e3;m.MAX_ENTRIES=200;let C=m
;const x=class _ImageLoader{static createImageWithRetry(e,t={},options={}){const n=a.create("img",{},{width:"100%",
height:"100%",objectFit:"cover",display:"block",opacity:"0",...t})
;const{maxRetries:o=this.DEFAULT_MAX_RETRIES,retryDelay:r=this.DEFAULT_RETRY_DELAY,onLoad:s,onError:i,onAllRetrisFailed:c}=options
;let l=0;const loadWithRetry=()=>{n.onload=()=>{n.style.opacity="1";if(s)s(n)};n.onerror=()=>{if(l<o){l++;if(i)i(n)
;setTimeout(()=>{n.src=e+"?retry="+l},r*l)}else if(c)c(n);else this.showDefaultError(n)};n.src=e};setTimeout(()=>{
loadWithRetry()},100*Math.random());return n}static showDefaultError(t){const n=t.parentElement;if(!n)return
;n.innerHTML="";n.style.display="flex";n.style.alignItems="center";n.style.justifyContent="center"
;n.style.background=e.BG_LIGHT;n.style.color=e.TEXT_MUTED;n.style.fontSize="12px";n.textContent="加载失败"}
static preloadImage(e){return new Promise((t,n)=>{const o=new Image;o.onload=()=>t(o);o.onerror=n;o.src=e})}
static async preloadImages(e,t=3){const n=[];const o=[...e];const r=new Set;const processNext=async()=>{
if(0===o.length)return;const e=o.shift();const a=_ImageLoader.preloadImage(e).then(e=>{n.push(e)
}).catch(()=>{}).finally(()=>r.delete(a));r.add(a);if(r.size>=t)await Promise.race(Array.from(r));return processNext()}
;await processNext();await Promise.all(Array.from(r));return n}};x.DEFAULT_MAX_RETRIES=2;x.DEFAULT_RETRY_DELAY=1e3
;let y=x;class ImagePreview{static async init(){await this.displayThreadImages()}static async displayThreadImages(){
if(a.select(".postmessage")||a.select("#postlist")||a.select(".plhin"))return
;const e=window.location.href.includes("/search.php");const t=window.location.href.includes("/tag.php");let n=[]
;if(e||t){const e=a.selectAll("tbody");n=Array.from(e).filter(e=>{
const t=e.querySelector('a[href*="thread-"], a[href*="viewthread.php"]');const n=e.querySelector(".icon");return t&&n})
}else{const e=a.selectAll('tbody[id^="normalthread_"]');n=Array.from(e)}const o=n.map(e=>async()=>{
if(e.id&&e.id.startsWith("stickthread_"))return;if(e.querySelector(".new-post-layout"))return
;const t=e.querySelector('a[href*="thread-"], a[href*="viewthread.php"]');if(!t)return;const n=t.href
;let o=t.textContent?.trim()||"";if(!o){const t=e.querySelector('span[id^="thread_"]');if(t)o=t.textContent?.trim()||""}
await this.transformPostLayout(e,n,o)});await runWithConcurrency(o,e=>e(),Config.getMaxPreviewConcurrency())}
static async transformPostLayout(e,t,n){const o=this.getTableColumnCount(e);e.innerHTML="";const r=a.create("tr")
;const s=a.create("td",{colspan:String(o)},{padding:"4px !important",border:"none !important",
background:"transparent !important"});const i=this.createPostContainer();const c=this.createTitleSection(t,n)
;const l=this.createImageSection();i.appendChild(c);i.appendChild(l);s.appendChild(i);r.appendChild(s);e.appendChild(r)
;await this.loadImagesForPost(t,l)}static getTableColumnCount(e){const t=e.closest("table");if(t){
const e=t.querySelector("thead tr")||t.querySelector("tr:first-child");if(e){let t=0
;const n=e.querySelectorAll("th, td");n.forEach(e=>{const n=parseInt(e.getAttribute("colspan")||"1");t+=n})
;if(t>0)return t}}return 6}static createPostContainer(){const n=a.create("div",{class:"new-post-layout"},{
background:r.GRADIENT,border:`1px solid ${e.BORDER_LIGHT}`,borderRadius:t.XL,boxShadow:o.NORMAL,overflow:"hidden"})
;return n}static createTitleSection(t,o){const s=a.create("div",{},{padding:`${n.XL} ${n.XXL}`,background:r.WHITE_ALPHA,
borderBottom:`1px solid ${e.BORDER_NORMAL}`});const i=a.create("a",{href:t},{fontWeight:"500",color:e.TEXT_PRIMARY,
fontSize:"15px",lineHeight:"1.3",textDecoration:"none",display:"block",wordBreak:"break-word"});i.textContent=o||"无标题"
;s.appendChild(i);return s}static createImageSection(){const t=a.create("div",{},{padding:`${n.MD} ${n.XXL}`,
background:r.LIGHT_ALPHA,display:"flex",gap:n.LG,height:"184px",flexWrap:"nowrap",alignItems:"stretch",overflow:"auto"})
;const o=a.create("div",{},{color:e.TEXT_SECONDARY,fontSize:"14px"});o.textContent="正在加载图片预览...";t.appendChild(o)
;return t}static async loadImagesForPost(e,t){try{const n=C.getCacheEntry(e);if(n&&n.length>0){
const o=this.filterCachedImageUrls(n);if(o.length>0){this.renderCachedImages(t,o,e);return}else C.clearCache()}
const o=await fetch(e);const r=await o.text();const a=new DOMParser;const i=a.parseFromString(r,"text/html")
;const c=f.extractValidImages(i);t.innerHTML="";if(0===c.length){this.showNoImagesMessage(t);return}
const l=c.map(t=>s.resolve(e,f.getImageSource(t)));C.saveCacheEntry(e,l,Config.getMaxImagesPerPost())
;this.renderImages(t,c,l,e)}catch(n){console.warn("[ImagePreview] 加载图片失败:",n);this.showNoImagesMessage(t)}}
static filterCachedImageUrls(e){const t=f.getValidDomains();return C.filterCachedUrls(e,t)}
static renderCachedImages(e,t,n){e.innerHTML="";t.slice(0,Config.getMaxImagesPerPost()).forEach((o,r)=>{
const a=this.createImageContainer();const s=this.createLoadingPlaceholder();const i=y.createImageWithRetry(o,{},{
onLoad:()=>{s.remove()}});this.setupImageInteraction(a,t,r,n);a.appendChild(s);a.appendChild(i);e.appendChild(a)})}
static renderImages(e,t,n,o){t.forEach((t,r)=>{const a=this.createImageContainer()
;const s=this.createLoadingPlaceholder();const i=y.createImageWithRetry(n[r],{},{onLoad:()=>{s.remove()}})
;this.setupImageInteraction(a,n,r,o);a.appendChild(s);a.appendChild(i);e.appendChild(a)})}static createImageContainer(){
return a.create("div",{},{position:"relative",flex:"1",minWidth:"120px",cursor:"pointer",borderRadius:t.MD,
overflow:"hidden",boxShadow:o.IMAGE,height:"184px",backgroundColor:e.BG_LIGHT})}static createLoadingPlaceholder(){
const t=a.create("div",{},{position:"absolute",top:"0",left:"0",width:"100%",height:"100%",display:"flex",
alignItems:"center",justifyContent:"center",backgroundColor:e.BG_LIGHT,color:e.TEXT_MUTED,fontSize:"12px",zIndex:"1"})
;t.textContent="加载中...";return t}static setupImageInteraction(e,t,n,o){e.addEventListener("click",()=>{
const e=t.map(e=>{const t=a.create("img",{src:e});return t});ImageViewer.show(e,n,o)})}static showNoImagesMessage(t){
const n=a.create("div",{},{color:e.TEXT_LIGHT,fontSize:"14px",fontStyle:"italic"});n.textContent="暂无图片预览"
;t.appendChild(n)}}class BoardManager{static init(){this.normalizeExclusiveLists();this.setupBoardCollectionCollapse()
;this.setupBoardFavoriteSection()}static normalizeExclusiveLists(){const e=new Set(Config.getFavoriteBoardNames())
;const t=new Set(Config.getCollectedBoardNames());let n=false;e.forEach(e=>{if(t.has(e)){t.delete(e);n=true}})
;if(n)Config.setCollectedBoardNames(Array.from(t))}static findBoardElementsMap(){const e=new Map
;const t=a.selectAll("div.mainbox.forumlist");t.forEach(t=>{const n=t.querySelector("h3 > a")
;const o=n?.textContent?.trim()||"";if(o&&!e.has(o))e.set(o,t)});return e}static moveBoardsToContainer(e,t){
const n=this.findBoardElementsMap();const o=[];e.forEach(e=>{const r=n.get(e);if(r){t.appendChild(r);o.push(e)}})
;return o}static setupBoardCollectionCollapse(){if(a.select("#board-collection-container"))return
;const e=new Set(Config.getCollectedBoardNames());const t=Array.from(a.selectAll("div.mainbox.forumlist"))
;if(0===t.length)return;const n=t.filter(t=>{const n=t.querySelector("h3 > a");const o=n?.textContent?.trim()||""
;return o&&e.has(o)});const o=this.createBoardContainer("board-collection-container","板块收纳区",n.length)
;const{content:r}=this.setupContainerElements(o,{isOpen:Config.getCollectionOpen(),
onToggle:e=>Config.setCollectionOpen(e),onSettings:()=>this.openBoardCollectSettings(),title:"板块收纳区",count:n.length})
;this.insertContainer(o);if(0===n.length)this.showEmptyMessage(r,'未选择任何板块,可点击右侧"设置"进行选择。');else{const e=n.map(e=>{
const t=e.querySelector("h3 > a");return t?.textContent?.trim()||""});this.moveBoardsToContainer(e,r)}}
static setupBoardFavoriteSection(){if(a.select("#board-favorite-container"))return
;const e=new Set(Config.getFavoriteBoardNames());const t=Array.from(a.selectAll("div.mainbox.forumlist"))
;if(0===t.length)return;const n=t.filter(t=>{const n=t.querySelector("h3 > a");const o=n?.textContent?.trim()||""
;return o&&e.has(o)});const o=this.createBoardContainer("board-favorite-container","板块收藏区",n.length)
;const{content:r}=this.setupContainerElements(o,{isOpen:Config.getFavoriteOpen(),onToggle:e=>Config.setFavoriteOpen(e),
onSettings:()=>this.openBoardFavoriteSettings(),title:"板块收藏区",count:n.length});this.insertFavoriteContainer(o)
;if(0===n.length)this.showEmptyMessage(r,'未选择任何收藏板块,可点击右侧"设置"进行选择。');else{const e=n.map(e=>{
const t=e.querySelector("h3 > a");return t?.textContent?.trim()||""});this.moveBoardsToContainer(e,r)}}
static createBoardContainer(e,t,n){return a.create("div",{id:e},{margin:"12px 0",border:"1px solid #e3e6ea",
borderRadius:"10px",boxShadow:"0 3px 12px rgba(0,0,0,0.08)",overflow:"hidden",background:"#fff"})}
static setupContainerElements(e,options){const t=a.create("div",{},{padding:"10px 14px",
background:options.isOpen?"#e9ecef":"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)",
borderBottom:"1px solid #e9ecef",cursor:"pointer",userSelect:"none",display:"flex",alignItems:"center",
justifyContent:"space-between"});const n=a.create("span",{},{fontWeight:"600",color:"#2c3e50",fontSize:"14px"})
;n.textContent=`${options.title}(共 ${options.count} 个)`;const o=a.create("span",{},{fontSize:"12px",color:"#666"})
;o.textContent=options.isOpen?"[点击收起]":"[点击展开]";const r=a.create("button");r.textContent="设置";r.title="选择需要管理的板块"
;i.applyButtonStyle(r);r.addEventListener("click",e=>{e.stopPropagation();options.onSettings()})
;const s=a.create("div",{},{display:"flex",alignItems:"center",gap:"10px"});s.appendChild(o);s.appendChild(r)
;t.appendChild(n);t.appendChild(s);const c=a.create("div",{},{padding:"10px",background:"rgba(248,249,250,0.6)",
display:options.isOpen?"":"none"});t.addEventListener("click",()=>{const e="none"===c.style.display
;c.style.display=e?"":"none";o.textContent=e?"[点击收起]":"[点击展开]"
;t.style.background=e?"#e9ecef":"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)";options.onToggle(e)})
;e.appendChild(t);e.appendChild(c);return{header:t,content:c,toggleHint:o}}static insertContainer(e){
const t=a.select('table.portalbox[summary="HeadBox"]')||a.select("#hottags")?.closest("table")||a.select("#hottags")
;if(t?.parentNode){const n=t.parentNode;if(t.nextSibling)n.insertBefore(e,t.nextSibling);else n.appendChild(e)
}else document.body.appendChild(e)}static insertFavoriteContainer(e){const t=a.select("#board-collection-container")
;if(t?.parentNode){const n=t.parentNode;if(t.nextSibling)n.insertBefore(e,t.nextSibling);else n.appendChild(e)
}else this.insertContainer(e)}static showEmptyMessage(e,t){const n=a.create("div",{},{color:"#666",fontSize:"12px"})
;n.textContent=t;e.appendChild(n)}static openBoardCollectSettings(){const e=this.getAllBoardNames()
;this.openBoardSettings(e,Config.getCollectedBoardNames(),"板块收纳设置","勾选需要收纳到顶部的板块:",e=>{
const t=new Set(Config.getFavoriteBoardNames());e.forEach(e=>t.delete(e));Config.setFavoriteBoardNames(Array.from(t))
;Config.setCollectedBoardNames(e);location.reload()})}static openBoardFavoriteSettings(){const e=this.getAllBoardNames()
;this.openBoardSettings(e,Config.getFavoriteBoardNames(),"板块收藏设置",'勾选需要加入"板块收藏区"的板块:',e=>{
const t=new Set(Config.getCollectedBoardNames());e.forEach(e=>t.delete(e));Config.setCollectedBoardNames(Array.from(t))
;Config.setFavoriteBoardNames(e);location.reload()})}static getAllBoardNames(){
const e=Array.from(a.selectAll("div.mainbox.forumlist > h3 > a")).map(e=>e.textContent?.trim()||"").filter(Boolean)
;return Array.from(new Set(e))}static openBoardSettings(e,t,n,o,r){const s=c.createOverlay()
;const i=c.createPanel("520px");const l=c.createHeader(n,()=>s.remove());const d=a.create("div",{},{padding:"12px 16px"
});const p=a.create("div",{},{color:"#666",marginBottom:"8px"});p.textContent=o;d.appendChild(p)
;const h=a.create("div",{},{display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px"});const u=new Set(t);e.forEach(e=>{
const t=a.create("label",{},{display:"flex",alignItems:"center",gap:"6px",padding:"6px",border:"1px solid #eee",
borderRadius:"6px"});const n=a.create("input",{type:"checkbox"});n.checked=u.has(e);n.onchange=()=>{
if(n.checked)u.add(e);else u.delete(e)};const o=a.create("span");o.textContent=e;t.appendChild(n);t.appendChild(o)
;h.appendChild(t)});d.appendChild(h);const g=c.createFooter(()=>s.remove(),()=>r(Array.from(u)));i.appendChild(l)
;i.appendChild(d);i.appendChild(g);s.appendChild(i);document.body.appendChild(s)}}class SearchOptimizer{static init(){
this.setupSearchFavorites()}static setupSearchFavorites(){
if(!/\/search\.php(\?|$)/.test(location.pathname+location.search))return;const e=a.select("#srchfid")
;if(!e||"SELECT"!==e.tagName||!e.multiple)return;this.createSearchTools(e);this.setupTopGrouping(e)
;this.setupAutoRemember(e)}static createSearchTools(e){const t=a.create("div",{},{margin:"6px 0",display:"flex",
gap:"12px",alignItems:"center"});const n=a.create("button",{type:"button"},{height:"30px"});n.textContent="置顶设置"
;i.applyButtonStyle(n);n.addEventListener("click",t=>{t.preventDefault();t.stopPropagation()
;this.openSearchFavSettings(e)});i.ensureToggleStyles();const{switchWrap:o}=this.createToggleSwitch();t.appendChild(n)
;t.appendChild(o);e.parentNode?.insertBefore(t,e)}static createToggleSwitch(){const e=a.create("label",{
class:"sis-toggle"});const t=a.create("input",{type:"checkbox",class:"sis-input"});t.checked=Config.getSearchFavAuto()
;const n=a.create("span",{class:"sis-text"});n.textContent="多选记忆";const o=a.create("span",{class:"sis-switch"})
;e.appendChild(t);e.appendChild(n);e.appendChild(o);t.addEventListener("change",()=>{Config.setSearchFavAuto(t.checked)
;if(t.checked){const e=a.select("#srchfid");if(e){const t=Array.from(e.selectedOptions).map(e=>e.value).filter(Boolean)
;if(t.length>0)Config.setSearchFavForums(t)}}});return{switchWrap:e,switchInput:t}}static setupTopGrouping(e){
const t=Config.getSearchFavForums();if(0===t.length)return;const n=a.create("optgroup",{label:"常用置顶"})
;e.insertBefore(n,e.firstChild);const options=Array.from(e.querySelectorAll("option"));t.forEach(e=>{
const t=options.find(t=>t.value===e);if(t)n.appendChild(t)});if(Config.getSearchFavAuto()){
Array.from(e.options).forEach(e=>e.selected=false);Array.from(n.querySelectorAll("option")).forEach(e=>e.selected=true)}
}static setupAutoRemember(e){if(!Config.getSearchFavAuto())return;e.addEventListener("change",()=>{
const t=Array.from(e.selectedOptions).map(e=>e.value).filter(Boolean);Config.setSearchFavForums(t)})}
static openSearchFavSettings(e){const t=Array.from(e.querySelectorAll("option")).filter(e=>e.value)
;const n=c.createOverlay();const o=c.createPanel("1100px");const r=c.createHeader("置顶设置",()=>n.remove())
;const{body:a,favSet:s}=this.createPanelBody(e,t);const i=c.createFooter(()=>n.remove(),()=>{
Config.setSearchFavForums(Array.from(s));location.reload()});o.appendChild(r);o.appendChild(a);o.appendChild(i)
;n.appendChild(o);document.body.appendChild(n)}static createPanelBody(e,t){const n=a.create("div",{},{
padding:"12px 16px",display:"grid",gridTemplateColumns:"repeat(auto-fit,minmax(260px,1fr))",gap:"12px"})
;const o=new Set(Config.getSearchFavForums());const r=this.organizeOptions(e,t);r.forEach(e=>{
const t=this.createGroupCard(e,o);n.appendChild(t)});return{body:n,favSet:o}}static organizeOptions(e,t){const n=[]
;const o=Array.from(e.querySelectorAll("optgroup"));o.forEach(e=>{
const options=Array.from(e.querySelectorAll("option")).filter(e=>e.value);if(options.length>0)n.push({
label:e.label||"分组",options:options})})
;const r=Array.from(e.children).filter(e=>"OPTION"===e.tagName&&e.value&&"all"!==e.value);if(r.length>0)n.unshift({
label:"其他",options:r});return n}static createGroupCard(e,t){const n=a.create("div",{},{border:"1px solid #e9ecef",
borderRadius:"8px",overflow:"hidden",background:"#fff"});const o=a.create("div",{},{padding:"8px 10px",
background:"#f8f9fa",borderBottom:"1px solid #e9ecef",fontWeight:"600",color:"#2c3e50",fontSize:"12px"})
;o.textContent=e.label;const r=a.create("div",{},{padding:"8px 10px",display:"flex",flexDirection:"column",gap:"6px"})
;e.options.forEach(e=>{const n=a.create("label",{},{display:"flex",alignItems:"center",gap:"6px",padding:"6px",
border:"1px solid #eee",borderRadius:"6px"});const o=a.create("input",{type:"checkbox"});o.checked=t.has(e.value)
;o.onchange=()=>{if(o.checked)t.add(e.value);else t.delete(e.value)};const s=a.create("span")
;s.textContent=e.textContent?.trim()||"";n.appendChild(o);n.appendChild(s);r.appendChild(n)});n.appendChild(o)
;n.appendChild(r);return n}}class SettingsPanel{static init(){this.hideVirtualSoccerEarly()
;this.injectScriptConfigMenuButton()}static hideVirtualSoccerEarly(){
if(a.select('style[data-sis-hide-soccer="1"]'))return
;const e=`\n a[href="z_soccer.php"], \n a[href*="z_soccer"] {\n display: none !important;\n }\n `
;a.addStyle(e,"sis-hide-soccer").setAttribute("data-sis-hide-soccer","1")}static injectScriptConfigMenuButton(){
const e=document.querySelector('a[href="z_soccer.php"]');if(e){e.textContent="脚本配置";e.href="javascript:void(0)"
;const t=e.cloneNode(true);t.addEventListener("click",e=>{e.preventDefault();this.openScriptSettingsPanel()})
;e.parentNode?.replaceChild(t,e);t.style.display="";const n=t.closest("li");if(n)n.id="sis-script-settings"}else{
const e=document.querySelectorAll('a[href*="z_soccer"]');if(e.length>0){const t=e[0];t.textContent="脚本配置"
;t.href="javascript:void(0)";const n=t.cloneNode(true);n.addEventListener("click",e=>{e.preventDefault()
;this.openScriptSettingsPanel()});t.parentNode?.replaceChild(n,t);n.style.display="";const o=n.closest("li")
;if(o)o.id="sis-script-settings"}}}static openScriptSettingsPanel(){const e=c.createOverlay()
;const t=c.createPanel("480px");const n=this.createPanelBody();const o=c.createHeader("脚本配置",()=>e.remove())
;const r=c.createFooter(()=>e.remove(),()=>this.saveSettings(n));t.appendChild(o);t.appendChild(n);t.appendChild(r)
;e.appendChild(t);document.body.appendChild(e)}static createPanelBody(){const e=a.create("div",{},{padding:"12px 16px",
display:"flex",flexDirection:"column",gap:"12px"});const t=this.createSelectRow("预览图数量",[{value:"3",text:"3张"},{
value:"4",text:"4张"},{value:"5",text:"5张"}],String(Config.getMaxImagesPerPost()))
;const n=this.createSelectRow("加载并发上限",[{value:"6",text:"6个(推荐)"},{value:"10",text:"10个(平衡)"},{value:"15",text:"15个(快速)"
}],String(Config.getMaxPreviewConcurrency()));const o=a.create("div",{},{color:"#777",fontSize:"12px"})
;o.textContent="提示:并发过大会增加服务器负载,推荐使用默认档位。";e.appendChild(t);e.appendChild(n);e.appendChild(o);return e}
static createSelectRow(e,options,t){const n=a.create("label",{},{display:"flex",alignItems:"center",
justifyContent:"space-between",gap:"12px",padding:"8px 10px",border:"1px solid #e9ecef",borderRadius:"8px"})
;const o=a.create("span",{},{fontSize:"13px",color:"#2c3e50"});o.textContent=e;const r=a.create("select",{},{
width:"120px",padding:"6px 8px",border:"1px solid #e3e6ea",borderRadius:"6px",background:"#fff",fontSize:"12px"})
;options.forEach(e=>{const n=a.create("option",{value:e.value});n.textContent=e.text;if(e.value===t)n.selected=true
;r.appendChild(n)});n.__select=r;n.appendChild(o);n.appendChild(r);return n}static saveSettings(e){
const t=Array.from(e.children).filter(e=>e.__select);if(t.length>=2){const e=t[0].__select;const n=t[1].__select
;const o=parseInt(e.value,10);const r=parseInt(n.value,10);Config.setMaxImagesPerPost(o)
;Config.setMaxPreviewConcurrency(r);location.reload()}}}async function initScript(){try{autoRedirectToDesktop()
;AdRemover.init();if("loading"===document.readyState)await l.waitForDOMContentLoaded();p.init()
;await l.waitForWindowLoad();await ImagePreview.init();BoardManager.init();SearchOptimizer.init();SettingsPanel.init()
}catch(e){console.error("[SIS001 Preview] 初始化失败:",e)}}function autoRedirectToDesktop(){
const e=document.querySelectorAll("a");for(let t=0;t<e.length;t++){const n=e[t]
;if(n.textContent&&n.textContent.includes("电脑版")){window.location.href=n.href;break}}}initScript()})();