您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
sis001第一会所综合社区,帖子图片预览,板块收纳,搜索优化
// ==UserScript== // @name sis001-预览 // @version 1.3.0 // @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",BORDER_LIGHT:"#e3e6ea",BORDER_NORMAL:"#e9ecef",TEXT_PRIMARY:"#2c3e50",TEXT_SECONDARY:"#666", TEXT_LIGHT:"#999",TEXT_ERROR:"#333"},t={SM:"6px",XL:"12px",ROUND:"50%",PILL:"999px"},n={MD:"8px",LG:"10px",XL:"12px",XXL:"16px"},i={ LIGHT:"0 2px 6px rgba(0,0,0,0.08)",NORMAL:"0 3px 12px rgba(0,0,0,0.08)"},a={GRADIENT:"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)", WHITE_ALPHA:"rgba(255,255,255,0.9)",LIGHT_ALPHA:"rgba(248,249,250,0.6)"},r={select(e){return document.querySelector(e)},selectAll(e){ return document.querySelectorAll(e)},create(e,t={},n={}){const i=document.createElement(e);return Object.entries(t).forEach(([e,t])=>{ i.setAttribute(e,t)}),Object.entries(n).forEach(([e,t])=>{i.style[e]=t}),i},addStyle(e,t){const n=document.createElement("style");return t&&(n.id=t), n.textContent=e,document.head.appendChild(n),n}},o={resolve(e,t){try{return new URL(t,e).href}catch(n){return void 0,t}},isHttp(e){ return/^https?:\/\//i.test(e)}},s={applyButtonStyle(t,options={}){ const{primary:n=!1}=options,i=["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"],a=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=[...i,a].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:${i.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}` ;r.addStyle(n,"sis-toggle-styles").setAttribute("data-sis-toggle-style","1")}},c={createOverlay(){return r.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 r.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=r.create("div",{},{padding:"12px 16px",borderBottom:"1px solid #e9ecef", fontWeight:"600",display:"flex",justifyContent:"space-between",alignItems:"center"});n.textContent=e;const i=r.create("button") ;return i.textContent="×",s.applyButtonStyle(i),i.onclick=t,n.appendChild(i),n},createFooter(e,t,n="保存并刷新"){const i=r.create("div",{},{ padding:"12px 16px",borderTop:"1px solid #e9ecef",display:"flex",justifyContent:"flex-end",gap:"10px"}),a=r.create("button");a.textContent="取消", s.applyButtonStyle(a),a.onclick=e;const o=r.create("button");return o.textContent=n,s.applyButtonStyle(o),o.onclick=t,i.appendChild(a), i.appendChild(o),i}},l={waitForDOMContentLoaded(){return"loading"===document.readyState?new Promise(e=>{ document.addEventListener("DOMContentLoaded",()=>e(),{once:!0})}):Promise.resolve()},waitForWindowLoad(){ return"complete"!==document.readyState?new Promise(e=>{window.addEventListener("load",()=>e(),{once:!0})}):Promise.resolve()}},d=class{static init(){ this.setupMagnetLinks()}static setupMagnetLinks(){r.select(".t_msgfont")&&r.selectAll(".t_msgfont").forEach(e=>{this.processPost(e)})} static processPost(e){if(this.processed.has(e))return;const t=/([a-fA-F0-9]{40})/g ;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(r.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 ' ;r.addStyle(e).setAttribute("data-sis-ad-remover","1")}static removeRulesTable(){ const e=document.querySelector('table[summary="Rules and Recommend"]');e&&e.remove()}static removePublicMessages(){ const e=document.querySelector(".maintable#pmprompt");e&&e.remove();const t=document.querySelector(".box#pmprompt");t&&t.remove()} static removeTopicsByType(e){document.querySelectorAll("thead.separation").forEach(t=>{const n=t.querySelectorAll("font");let i=!1;if(n.forEach(t=>{ e.some(e=>t.textContent?.includes(e))&&(i=!0)}),i){t.remove();let e=t.nextElementSibling ;for(;e&&"TBODY"===e.tagName&&e.id&&e.id.startsWith("stickthread_");){const t=e;e=e.nextElementSibling,t.remove()}}})}static removeStickyTopics(){ this.removeTopicsByType(["固定主題"])}static removeImportantTopics(){this.removeTopicsByType(["重要主題"])}static removeAdministrativeThreads(){ document.querySelectorAll('tbody[id^="stickthread_"], tbody[id^="normalthread_"]').forEach(e=>{ e.querySelectorAll('em a[href*="typeid=528"]').length>0&&(e.classList.add("sis-hide-admin"),setTimeout(()=>{e.remove()},10))})}static refresh(){ this.removeRulesTable(),this.removePublicMessages(),this.removeStickyTopics(),this.removeImportantTopics(),this.removeAdministrativeThreads()}} class PostLayoutManager{static async transformPostLayout(e,t,n,i){const a=this.getTableColumnCount(e);e.innerHTML="" ;const o=r.create("tr"),s=r.create("td",{colspan:String(a)},{padding:"4px !important",border:"none !important",background:"transparent !important" }),c=this.createPostContainer(),l=this.createTitleSection(t,n),d=this.createImageSection();c.appendChild(l),c.appendChild(d),s.appendChild(c), o.appendChild(s),e.appendChild(o),await i(d)}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;if(e.querySelectorAll("th, td").forEach(e=>{ const n=parseInt(e.getAttribute("colspan")||"1");t+=n}),t>0)return t}}return 6}static createPostContainer(){return r.create("div",{ class:"new-post-layout"},{background:a.GRADIENT,border:`1px solid ${e.BORDER_LIGHT}`,borderRadius:t.XL,boxShadow:i.NORMAL,overflow:"hidden"})} static createTitleSection(t,i){const o=r.create("div",{},{padding:`${n.XL} ${n.XXL}`,background:a.WHITE_ALPHA, borderBottom:`1px solid ${e.BORDER_NORMAL}`}),s=r.create("a",{href:t},{fontWeight:"500",color:e.TEXT_PRIMARY,fontSize:"15px",lineHeight:"1.3", textDecoration:"none",display:"block",wordBreak:"break-word"});return s.textContent=i||"无标题",o.appendChild(s),o}static createImageSection(){ const t=r.create("div",{},{padding:`${n.MD} ${n.XXL}`,background:a.LIGHT_ALPHA,display:"flex",gap:n.LG,minHeight:"60px",flexWrap:"nowrap", alignItems:"center",overflow:"auto"}),i=r.create("div",{},{color:e.TEXT_SECONDARY,fontSize:"14px"});return i.textContent="正在加载图片预览...", t.appendChild(i),t}}class Storage{static get(e,t=null){try{const n=GM_getValue(e);if(null==n)return t;try{return JSON.parse(n)}catch{return n} }catch(n){return void 0,t}}static set(e,t){try{const n=JSON.stringify(t);return GM_setValue(e,n),!0}catch(n){return void 0,!1}}static delete(e){try{ return GM_deleteValue(e),!0}catch(t){return void 0,!1}}static listKeys(){try{return GM_listValues()}catch(e){return void 0,[]}} static migrateFromLocalStorage(e,t=!0){try{const n=localStorage.getItem(e);if(null!==n){try{const t=JSON.parse(n);this.set(e,t)}catch{GM_setValue(e,n) }return t&&localStorage.removeItem(e),!0}return!1}catch(n){return void 0,!1}}}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",searchLastSelection:"sis_search_last_selection",searchFavAuto:"sis_search_fav_auto", previewMaxImages:"sis_preview_max_images"},g={MAX_IMAGES_PER_POST:4};class Config{static getMaxImagesPerPost(){return g.MAX_IMAGES_PER_POST} static getCollectedBoardNames(){try{const e=Storage.get(h.collectNames,"");if(!e)return[];const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){ return void 0,[]}}static setCollectedBoardNames(e){try{Storage.set(h.collectNames,JSON.stringify(e||[]))}catch(t){void 0}} static getFavoriteBoardNames(){try{const e=Storage.get(h.favoriteNames,"");if(!e)return[];const t=JSON.parse(e);return Array.isArray(t)?t:[]}catch(e){ return void 0,[]}}static setFavoriteBoardNames(e){try{Storage.set(h.favoriteNames,JSON.stringify(e||[]))}catch(t){void 0}}static getCollectionOpen(){ try{return"1"===(Storage.get(h.collectionOpen,"0")??"0")}catch(e){return void 0,!1}}static setCollectionOpen(e){try{ Storage.set(h.collectionOpen,e?"1":"0")}catch(t){void 0}}static getFavoriteOpen(){try{return"1"===(Storage.get(h.favoriteOpen,"0")??"0")}catch(e){ return void 0,!1}}static setFavoriteOpen(e){try{Storage.set(h.favoriteOpen,e?"1":"0")}catch(t){void 0}}static getSearchFavForums(){try{ const e=Storage.get(h.searchFavForums,"");return e?JSON.parse(e):[]}catch(e){return void 0,[]}}static setSearchFavForums(e){try{ Storage.set(h.searchFavForums,JSON.stringify(e||[]))}catch(t){void 0}}static getSearchFavAuto(){try{ return"1"===(Storage.get(h.searchFavAuto,"0")??"0")}catch(e){return void 0,!1}}static setSearchFavAuto(e){try{Storage.set(h.searchFavAuto,e?"1":"0") }catch(t){void 0}}static getSearchLastSelection(){try{const e=Storage.get(h.searchLastSelection,"");return e?JSON.parse(e):[]}catch(e){return void 0, []}}static setSearchLastSelection(e){try{Storage.set(h.searchLastSelection,JSON.stringify(e||[]))}catch(t){void 0}}}class ImageExtractor{ static extractAndGroupImages(e){const t=e.querySelector(".t_msgfont")||e.querySelector(".postmessage");if(!t)return{images:[],domainGroups:new Map} ;const n=t.cloneNode(!0);this.cleanContentClone(n) ;const i=Array.from(n.querySelectorAll("img")),a=i.filter(e=>this.isValidContentImage(e)),r=this.groupImagesByDomain(a);this.applyImageLimits(r) ;const o=Array.from(r.keys()),s=o[0]||"",c=r.get(s)||[];return this.logExtractionResults(c,i,o),{images:c,domainGroups:r}}static cleanContentClone(e){ e.querySelectorAll(".quote").forEach(e=>e.remove()),e.querySelectorAll(".ad_pip, .ad_thread3_0, .ad_thread4_0").forEach(e=>e.remove()), e.querySelectorAll(".postratings, .comment_digg").forEach(e=>e.remove())}static isValidContentImage(e){ const t=e.getAttribute("onclick")||"",n=e.getAttribute("onload")||"",i=e.getAttribute("src")||e.src||"" ;if(!i||i.length<=10||i.includes("data:"))return!1;if(!/\.(jpg|jpeg|png|gif|webp)(\?|$)/i.test(i))return!1 ;if(i.includes("images/green001/")||i.includes("images/attachicons/")||i.includes("images/joinvip.gif")||i.includes("/ad_")||i.includes("advertisement"))return!1 ;if(i.includes("images/smilies/")&&this.isSmallImage(e))return!1 ;if(i.includes("images/common/")&&(i.match(/\/(she|mengmengda|yang|\d{5}SIS\d+)\.gif$/)||this.isSmallImage(e)))return!1 ;const a=t.includes("zoom(this"),r=n.includes("attachimg(this");return a&&r}static groupImagesByDomain(e){const t=new Map;return e.forEach(e=>{ const n=this.getImageSource(e),i=this.extractDomain(n);t.has(i)||t.set(i,[]),t.get(i).push(e)}),t}static applyImageLimits(e){ const t=Config.getMaxImagesPerPost();Array.from(e.keys()).forEach(n=>{const i=e.get(n)||[];e.set(n,i.slice(0,t))})}static logExtractionResults(e,t,n){ e.length>0?void 0:t.length>5&&(void 0, ("localhost"===window.location.hostname||window.location.hostname.includes("dev"))&&t.slice(0,3).forEach((e,t)=>{e.getAttribute("src")||e.src, e.getAttribute("onclick"),e.getAttribute("onload")}))}static isSmallImage(e){const t=e.getAttribute("width"),n=e.getAttribute("height");if(t||n){ const e=parseInt(t||"0",10),i=parseInt(n||"0",10);if(e>0&&e<=100||i>0&&i<=100)return!0}const i=e.style;if(i.width||i.height){ const e=parseInt(i.width,10),t=parseInt(i.height,10);if(e>0&&e<=100||t>0&&t<=100)return!0} if(e.naturalWidth>0&&e.naturalHeight>0&&(e.naturalWidth<=100||e.naturalHeight<=100))return!0;const a=e.getAttribute("src")||"" ;return[/\/meemo\d{3}\.gif$/i,/\/\w{2,6}\.gif$/i,/\/emoji_\w+\.gif$/i,/\/smiley_\w+\.gif$/i].some(e=>e.test(a))}static extractDomain(e){try{ return new URL(e).hostname}catch{return"unknown"}}static getImageSource(e){return e.getAttribute("src")||e.src||""}}const u=class{static get(e){ const t=this.cache.get(e);return t?Date.now()-t.timestamp>this.maxAge?(this.cache.delete(e),null):t:null}static set(e,t,n){ if(this.cache.size>=this.maxSize){const e=this.cache.keys().next().value;e&&this.cache.delete(e)}this.cache.set(e,{urls:t,domainGroups:n, timestamp:Date.now(),extractedCount:t.length})}static cleanup(){const e=Date.now(),t=[];this.cache.forEach((n,i)=>{ e-n.timestamp>this.maxAge&&t.push(i)}),t.forEach(e=>this.cache.delete(e)),t.length>0}static getStats(){return{size:this.cache.size, maxSize:this.maxSize}}static clear(){this.cache.clear()}};u.cache=new Map,u.maxSize=200,u.maxAge=18e5;let m=u;class ImageLoader{ static async loadImagesForPost(e,t,n,i=0){const a=2,r=m.get(e);if(r&&0===i)return void 0,t.innerHTML="", 0===r.urls.length?(this.showSimpleNoImageMessage(t),void 0):(n&&n(r.urls,r.domainGroups),void 0);try{const i=await fetch(e) ;if(!i.ok)throw new Error(`请求失败,状态码: ${i.status}`);const a=await i.text();if(a.includes("<b>Parse error</b>"))throw new Error("服务器返回PHP解析错误") ;const r=(new DOMParser).parseFromString(a,"text/html"),{images:s,domainGroups:c}=ImageExtractor.extractAndGroupImages(r);if(t.innerHTML="", 0===s.length)return this.showSimpleNoImageMessage(t),m.set(e,[],new Map),void 0;const l=s.map(t=>o.resolve(e,ImageExtractor.getImageSource(t))) ;return m.set(e,l,c),n&&n(l,c),void 0}catch(s){const r=s instanceof Error?s.message:"未知错误";0===i||r.includes("Parse error")||r.includes("500"),0 ;const o=i<a,c=0===i?"重试":`重试 (${i}/${a})`;return this.showStaticFailureMessage(t,r.includes("403")||r.includes("权限")?"访问受限":"加载失败",o?()=>{ setTimeout(()=>{this.loadImagesForPost(e,t,n,i+1)},Math.min(1e3+1e3*i,3e3))}:void 0,c),void 0}}static showStaticFailureMessage(t,n,i,a="重试"){ t.innerHTML="", t.style.cssText="\n padding: 8px 20px;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n height: auto;\n min-height: 30px;\n max-height: 30px;\n gap: 10px;\n " ;const o=r.create("div",{},{color:e.TEXT_LIGHT,fontSize:"13px",fontStyle:"italic",lineHeight:"1.2"});if(o.textContent=n,t.appendChild(o),i){ const n=r.create("button") ;n.textContent=a,n.style.cssText=`\n padding: 2px 8px;\n font-size: 11px;\n margin-left: 8px;\n cursor: pointer;\n border: 1px solid ${e.TEXT_LIGHT};\n background: transparent;\n border-radius: 3px;\n color: ${e.TEXT_LIGHT};\n `, n.onclick=e=>{e.stopPropagation(),i()},t.appendChild(n)}}static showSimpleNoImageMessage(t){t.innerHTML="", t.style.cssText="\n padding: 8px 20px;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n height: auto;\n min-height: 30px;\n max-height: 30px;\n " ;const n=r.create("div",{},{color:e.TEXT_LIGHT,fontSize:"13px",fontStyle:"italic",textAlign:"center",lineHeight:"1.2"});n.textContent="帖子内无图片内容", t.appendChild(n)}}const f=class{static init(){this.overlay||(this.overlay=document.createElement("div"), this.overlay.style.cssText="\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.95);\n z-index: 999999;\n display: none;\n align-items: center;\n justify-content: center;\n ", this.img=document.createElement("img"), this.img.style.cssText="\n max-width: 85%;\n max-height: 85%;\n object-fit: contain;\n border-radius: 4px;\n ", this.counter=document.createElement("div"), this.counter.style.cssText="\n position: absolute;\n top: 20px;\n left: 50%;\n transform: translateX(-50%);\n color: white;\n background: rgba(0, 0, 0, 0.6);\n padding: 8px 16px;\n border-radius: 20px;\n font-size: 14px;\n ", this.prevBtn=this.createNavButton("‹","left"),this.nextBtn=this.createNavButton("›","right"),this.overlay.appendChild(this.img), this.overlay.appendChild(this.counter),this.overlay.appendChild(this.prevBtn),this.overlay.appendChild(this.nextBtn), document.body.appendChild(this.overlay),this.setupEvents())}static createNavButton(e,t){const n=document.createElement("button") ;return n.innerHTML="‹"===e?'<svg viewBox="0 0 24 24" fill="white" width="30" height="30"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></svg>':'<svg viewBox="0 0 24 24" fill="white" width="30" height="30"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>', n.style.cssText=`\n position: fixed;\n ${t}: 16px;\n top: 50%;\n transform: translateY(-50%);\n width: 40px;\n height: 40px;\n background: rgba(255, 255, 255, 0.2);\n border-radius: 50%;\n border: none;\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n cursor: pointer;\n user-select: none;\n z-index: 10002;\n `, n}static setupEvents(){this.overlay.onclick=e=>{e.target===this.overlay&&this.close()},this.prevBtn.onclick=e=>{e.stopPropagation(),this.prev()}, this.nextBtn.onclick=e=>{e.stopPropagation(),this.next()},document.addEventListener("keydown",e=>{ "flex"===this.overlay?.style.display&&("Escape"===e.key?this.close():"ArrowLeft"===e.key?this.prev():"ArrowRight"===e.key&&this.next())})} static show(e,t=0){this.init(),this.images=e,this.currentIndex=t,this.updateImage(),this.overlay.style.display="flex"}static close(){ this.overlay&&(this.overlay.style.display="none")}static prev(){this.currentIndex=(this.currentIndex-1+this.images.length)%this.images.length, this.updateImage()}static next(){this.currentIndex=(this.currentIndex+1)%this.images.length,this.updateImage()}static updateImage(){ const e=this.images[this.currentIndex];this.img.style.display="none",this.img.src="", this.counter.textContent=`${this.currentIndex+1} / ${this.images.length}`,this.images.length<=1?(this.prevBtn.style.display="none", this.nextBtn.style.display="none",this.counter.style.display="none"):(this.prevBtn.style.display="flex",this.nextBtn.style.display="flex", this.counter.style.display="block"),this.img.onload=()=>{this.img.style.display="block"},this.img.onerror=()=>{this.img.alt="图片加载失败"},this.img.src=e}} ;f.overlay=null,f.img=null,f.counter=null,f.prevBtn=null,f.nextBtn=null,f.images=[],f.currentIndex=0;let x=f;const y=class{ static injectStyles(options={}){if(this.injected)return;const e={...this.defaultOptions,...options},t=document.createElement("style") ;t.textContent=`\n .shared-img-grid {\n display: flex;\n flex-wrap: nowrap;\n align-items: flex-start;\n gap: ${e.gap}px;\n width: 100%;\n }\n \n .shared-img-item {\n overflow: hidden;\n border-radius: ${e.borderRadius}px;\n position: relative;\n cursor: ${e.cursor};\n min-height: ${e.minHeight}px;\n max-height: ${e.maxHeight}px;\n height: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n background: ${e.backgroundColor};\n }\n \n .shared-img-item-single {\n overflow: hidden;\n border-radius: ${e.borderRadius}px;\n position: relative;\n cursor: ${e.cursor};\n min-height: ${e.minHeight}px;\n max-height: ${e.maxHeight}px;\n height: auto;\n display: flex;\n align-items: center;\n justify-content: center;\n background: ${e.backgroundColor};\n }\n \n .shared-img {\n max-width: 100%;\n max-height: ${e.maxHeight}px;\n width: auto;\n height: auto;\n object-fit: contain;\n }\n `, document.head.appendChild(t),this.injected=!0}static createGrid(){const e=document.createElement("div");return e.className="shared-img-grid",e} static createImageItem(e,t=!1,n){const i=document.createElement("div");i.className=t?"shared-img-item-single":"shared-img-item" ;const a=document.createElement("img");return a.className="shared-img",a.src=e,a.loading="lazy",n&&i.addEventListener("click",t=>{t.preventDefault(), t.stopPropagation(),n(e)}),i.appendChild(a),i}static setGridWidth(e,t,n=8){const i=`calc((100% - ${(t-1)*n}px) / ${t})` ;Array.from(e.children).forEach(e=>{e.style.width=i,e.style.flex="0 0 auto"})}static create(e,t,options={}){this.injectStyles(options) ;const n=this.createGrid(),i=1===e.length;e.forEach((e,a)=>{const r=this.createImageItem(e,i,e=>{t&&t(e,a)});n.appendChild(r)}) ;const a=options.gap||this.defaultOptions.gap;return this.setGridWidth(n,e.length,a),n}};y.injected=!1,y.defaultOptions={minHeight:200,maxHeight:400, gap:8,backgroundColor:"#f5f5f5",borderRadius:4,cursor:"pointer"};let v=y;class ImageRenderer{static renderImages(e,t,n,i){e.innerHTML="" ;const a=Array.from(i.keys());if(0===a.length||0===t.length)return this.showGlobalFailure(e),void 0;const r=a[0],s=i.get(r)||[] ;if(0===s.length)return this.showGlobalFailure(e),void 0;const c=s.map(e=>o.resolve(n,ImageExtractor.getImageSource(e))) ;e.style.cssText="\n padding: 16px 20px;\n background: rgba(248, 250, 252, 0.7);\n ";const l=v.create(c,(e,i)=>{ const a=t.map(e=>o.resolve(n||location.href,e));x.show(a,i)},{minHeight:150,maxHeight:280,gap:12,backgroundColor:"#f5f5f5",borderRadius:4}) ;l.style.marginBottom="0",e.appendChild(l)}static showGlobalFailure(t){t.innerHTML="", t.style.cssText="\n padding: 8px 20px;\n background: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n height: auto;\n min-height: 30px;\n max-height: 30px;\n " ;const n=r.create("div",{},{fontSize:"12px",color:e.TEXT_SECONDARY,textAlign:"center",fontStyle:"italic"});n.textContent="帖子内可能无图",t.appendChild(n)}} class ImagePreview{static async init(){await this.displayThreadImages()}static async displayThreadImages(){ if(r.select(".postmessage")||r.select("#postlist")||r.select(".plhin")||r.select(".t_msgfont"))return ;const e=window.location.href.includes("/search.php"),t=window.location.href.includes("/tag.php");let n=[];if(e||t){const e=r.selectAll("tbody") ;n=Array.from(e).filter(e=>{const t=e.querySelector('a[href*="thread-"], a[href*="viewthread.php"]'),n=e.querySelector(".icon");return t&&n})}else{ const e=r.selectAll('tbody[id^="normalthread_"]');n=Array.from(e)}const i=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 i=t.textContent?.trim()||"";if(!i){const t=e.querySelector('span[id^="thread_"]');t&&(i=t.textContent?.trim()||"")} await PostLayoutManager.transformPostLayout(e,n,i,async e=>{await ImageLoader.loadImagesForPost(n,e,(t,i)=>{ImageRenderer.renderImages(e,t,n,i)})})}) ;await Promise.all(i.map(e=>e()))}}class BoardManager{static init(){this.normalizeExclusiveLists(),this.setupBoardCollectionCollapse(), this.setupBoardFavoriteSection()}static normalizeExclusiveLists(){ const e=new Set(Config.getFavoriteBoardNames()),t=new Set(Config.getCollectedBoardNames());let n=!1;e.forEach(e=>{t.has(e)&&(t.delete(e),n=!0)}), n&&Config.setCollectedBoardNames(Array.from(t))}static findBoardElementsMap(){const e=new Map;return r.selectAll("div.mainbox.forumlist").forEach(t=>{ const n=t.querySelector("h3 > a"),i=n?.textContent?.trim()||"";i&&!e.has(i)&&e.set(i,t)}),e}static moveBoardsToContainer(e,t){ const n=this.findBoardElementsMap(),i=[];return e.forEach(e=>{const a=n.get(e);a&&(t.appendChild(a),i.push(e))}),i} static setupBoardCollectionCollapse(){this.setupBoardSection({containerId:"board-collection-container",title:"板块收纳区", getBoardNames:()=>Config.getCollectedBoardNames(),getOpenState:()=>Config.getCollectionOpen(),setOpenState:e=>Config.setCollectionOpen(e), onSettings:()=>this.openBoardCollectSettings(),insertMethod:e=>this.insertContainer(e),emptyMessage:'未选择任何板块,可点击右侧"设置"进行选择。'})} static setupBoardFavoriteSection(){this.setupBoardSection({containerId:"board-favorite-container",title:"板块收藏区", getBoardNames:()=>Config.getFavoriteBoardNames(),getOpenState:()=>Config.getFavoriteOpen(),setOpenState:e=>Config.setFavoriteOpen(e), onSettings:()=>this.openBoardFavoriteSettings(),insertMethod:e=>this.insertFavoriteContainer(e),emptyMessage:'未选择任何收藏板块,可点击右侧"设置"进行选择。'})} static setupBoardSection(config){if(r.select(`#${config.containerId}`))return ;const e=new Set(config.getBoardNames()),t=Array.from(r.selectAll("div.mainbox.forumlist"));if(0===t.length)return;const n=t.filter(t=>{ const n=t.querySelector("h3 > a"),i=n?.textContent?.trim()||"";return i&&e.has(i) }),i=this.createBoardContainer(config.containerId,config.title,n.length),{content:a}=this.setupContainerElements(i,{isOpen:config.getOpenState(), onToggle:config.setOpenState,onSettings:config.onSettings,title:config.title,count:n.length});if(config.insertMethod(i), 0===n.length)this.showEmptyMessage(a,config.emptyMessage);else{const e=n.map(e=>{const t=e.querySelector("h3 > a");return t?.textContent?.trim()||""}) ;this.moveBoardsToContainer(e,a)}}static createBoardContainer(e,t,n){return r.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=r.create("div",{},{padding:"10px 14px",background:options.isOpen?"#f0f0f0":"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)", border:options.isOpen?"2px solid #d0d0d0":"none",borderBottom:"1px solid #e9ecef",cursor:"pointer",userSelect:"none",display:"flex", alignItems:"center",justifyContent:"space-between"}),n=r.create("span",{},{fontWeight:"600",color:"#2c3e50",fontSize:"14px"}) ;n.textContent=`${options.title}(共 ${options.count} 个)`;const i=r.create("span",{},{fontSize:"12px",color:"#666"}) ;i.textContent=options.isOpen?"[点击收起]":"[点击展开]";const a=r.create("button");a.textContent="设置",a.title="选择需要管理的板块",s.applyButtonStyle(a), a.addEventListener("click",e=>{e.stopPropagation(),options.onSettings()});const o=r.create("div",{},{display:"flex",alignItems:"center",gap:"10px"}) ;o.appendChild(i),o.appendChild(a),t.appendChild(n),t.appendChild(o);const c=r.create("div",{},{padding:"10px",background:"#fafafa", border:"2px solid #d0d0d0",borderTop:"none",display:options.isOpen?"":"none"});return t.addEventListener("click",()=>{const e="none"===c.style.display ;c.style.display=e?"":"none",i.textContent=e?"[点击收起]":"[点击展开]",t.style.background=e?"#f0f0f0":"linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%)", t.style.border=e?"2px solid #d0d0d0":"none",t.style.borderBottom="1px solid #e9ecef",options.onToggle(e)}),e.appendChild(t),e.appendChild(c),{ header:t,content:c,toggleHint:i}}static insertContainer(e){ const t=r.select('table.portalbox[summary="HeadBox"]')||r.select("#hottags")?.closest("table")||r.select("#hottags");if(t?.parentNode){ const n=t.parentNode;t.nextSibling?n.insertBefore(e,t.nextSibling):n.appendChild(e)}else document.body.appendChild(e)} static insertFavoriteContainer(e){const t=r.select("#board-collection-container");if(t?.parentNode){const n=t.parentNode ;t.nextSibling?n.insertBefore(e,t.nextSibling):n.appendChild(e)}else this.insertContainer(e)}static showEmptyMessage(e,t){const n=r.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(r.selectAll("div.mainbox.forumlist > h3 > a")).map(e=>e.textContent?.trim()||"").filter(Boolean);return Array.from(new Set(e))} static openBoardSettings(e,t,n,i,a){const o=c.createOverlay(),s=c.createPanel("520px"),l=c.createHeader(n,()=>o.remove()),d=r.create("div",{},{ padding:"12px 16px"}),p=r.create("div",{},{color:"#666",marginBottom:"8px"});p.textContent=i,d.appendChild(p);const h=r.create("div",{},{ display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px"}),g=new Set(t);e.forEach(e=>{const t=r.create("label",{},{display:"flex",alignItems:"center", gap:"6px",padding:"6px",border:"1px solid #eee",borderRadius:"6px"}),n=r.create("input",{type:"checkbox"});n.checked=g.has(e),n.onchange=()=>{ n.checked?g.add(e):g.delete(e)};const i=r.create("span");i.textContent=e,t.appendChild(n),t.appendChild(i),h.appendChild(t)}),d.appendChild(h) ;const u=c.createFooter(()=>o.remove(),()=>a(Array.from(g)));s.appendChild(l),s.appendChild(d),s.appendChild(u),o.appendChild(s), document.body.appendChild(o)}}class SearchOptimizer{static init(){this.setupSearchFavorites()}static setupSearchFavorites(){ if(!/\/search\.php(\?|$)/.test(location.pathname+location.search))return;const e=r.select("#srchfid") ;e&&"SELECT"===e.tagName&&e.multiple&&(this.createSearchTools(e),this.setupTopGrouping(e),this.setupAutoRemember(e))}static createSearchTools(e){ const t=r.create("div",{},{margin:"6px 0",display:"flex",gap:"12px",alignItems:"center"}),n=r.create("button",{type:"button"},{height:"30px"}) ;n.textContent="置顶设置",s.applyButtonStyle(n),n.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),this.openSearchFavSettings(e)}), s.ensureToggleStyles();const{switchWrap:i}=this.createToggleSwitch();t.appendChild(n),t.appendChild(i),e.parentNode?.insertBefore(t,e)} static createToggleSwitch(){const e=r.create("label",{class:"sis-toggle"}),t=r.create("input",{type:"checkbox",class:"sis-input"}) ;t.checked=Config.getSearchFavAuto();const n=r.create("span",{class:"sis-text"});n.textContent="多选记忆";const i=r.create("span",{class:"sis-switch"}) ;return e.appendChild(t),e.appendChild(n),e.appendChild(i),t.addEventListener("change",()=>{if(Config.setSearchFavAuto(t.checked),t.checked){ const e=r.select("#srchfid");if(e){const t=Array.from(e.selectedOptions).map(e=>e.value).filter(Boolean);t.length>0&&Config.setSearchLastSelection(t)} }}),{switchWrap:e,switchInput:t}}static setupTopGrouping(e){const t=Config.getSearchFavForums();if(0===t.length)return;const n=r.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);t&&n.appendChild(t)})}static setupAutoRemember(e){if(!Config.getSearchFavAuto())return ;const t=Config.getSearchLastSelection();t.length>0&&Array.from(e.options).forEach(e=>{e.selected=t.includes(e.value)}), e.addEventListener("change",()=>{const t=Array.from(e.selectedOptions).map(e=>e.value).filter(Boolean);Config.setSearchLastSelection(t)})} static openSearchFavSettings(e){ const t=Array.from(e.querySelectorAll("option")).filter(e=>e.value),n=c.createOverlay(),i=c.createPanel("1100px"),a=c.createHeader("置顶设置",()=>n.remove()),{body:r,favSet:o}=this.createPanelBody(e,t),s=c.createFooter(()=>n.remove(),()=>{ Config.setSearchFavForums(Array.from(o)),location.reload()});i.appendChild(a),i.appendChild(r),i.appendChild(s),n.appendChild(i), document.body.appendChild(n)}static createPanelBody(e,t){const n=r.create("div",{},{padding:"12px 16px",display:"grid", gridTemplateColumns:"repeat(auto-fit,minmax(260px,1fr))",gap:"12px"}),i=new Set(Config.getSearchFavForums()) ;return this.organizeOptions(e,t).forEach(e=>{const t=this.createGroupCard(e,i);n.appendChild(t)}),{body:n,favSet:i}}static organizeOptions(e,t){ const n=[];Array.from(e.querySelectorAll("optgroup")).forEach(e=>{const options=Array.from(e.querySelectorAll("option")).filter(e=>e.value) ;options.length>0&&n.push({label:e.label||"分组",options:options})}) ;const i=Array.from(e.children).filter(e=>"OPTION"===e.tagName&&e.value&&"all"!==e.value);return i.length>0&&n.unshift({label:"其他",options:i}),n} static createGroupCard(e,t){const n=r.create("div",{},{border:"1px solid #e9ecef",borderRadius:"8px",overflow:"hidden",background:"#fff" }),i=r.create("div",{},{padding:"8px 10px",background:"#f8f9fa",borderBottom:"1px solid #e9ecef",fontWeight:"600",color:"#2c3e50",fontSize:"12px"}) ;i.textContent=e.label;const a=r.create("div",{},{padding:"8px 10px",display:"flex",flexDirection:"column",gap:"6px"});return e.options.forEach(e=>{ const n=r.create("label",{},{display:"flex",alignItems:"center",gap:"6px",padding:"6px",border:"1px solid #eee",borderRadius:"6px" }),i=r.create("input",{type:"checkbox"});i.checked=t.has(e.value),i.onchange=()=>{i.checked?t.add(e.value):t.delete(e.value)};const o=r.create("span") ;o.textContent=e.textContent?.trim()||"",n.appendChild(i),n.appendChild(o),a.appendChild(n)}),n.appendChild(i),n.appendChild(a),n}}async function S(){ try{b(),AdRemover.init(),"loading"===document.readyState&&await l.waitForDOMContentLoaded(),p.init(),await l.waitForWindowLoad(), await ImagePreview.init(),BoardManager.init(),SearchOptimizer.init(),setInterval(()=>{m.cleanup()},3e5)}catch(e){void 0}}function b(){ 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}}}S()})();