2048-预览

为2048核基地论坛帖子添加图片、链接预览

// ==UserScript==
// @name         2048-预览
// @version      1.1.8
// @namespace    https://sleazyfork.org/zh-CN/users/1461640-%E6%98%9F%E5%AE%BF%E8%80%81%E9%AD%94
// @author       星宿老魔
// @description  为2048核基地论坛帖子添加图片、链接预览
// @match        https://hjd2048.com/2048/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=hjd2048.com
// @license      MIT
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-start
// ==/UserScript==

(function(){"use strict";const o={name:"2048-预览",version:"1.1.7",currentDomain:"hjd2048.com",defaults:{MAX_PREVIEW_IMAGES:3,CONCURRENT_LIMIT:9,EXCLUDED_FORUMS:["56","102"]},get(l){try{return GM_getValue(l,this.defaults[l])}catch(e){return console.warn(`[${this.name}] 获取配置失败:`,e),this.defaults[l]}},set(l,e){try{GM_setValue(l,e)}catch(t){console.warn(`[${this.name}] 保存配置失败:`,t)}},getAll(){const l={};for(const e in this.defaults)l[e]=this.get(e);return l.EXCLUDED_FORUMS=this.get("EXCLUDED_FORUMS"),l},selectors:{threadRows:"tr.tr3.t_one",threadLinks:'a[target="_self"], a[target="_blank"]',contentSelectors:["#read_tpc",".tpc_content",".f14.cc",'div[id="read_tpc"]',".t_f"],searchLink:'#nav-pc a[href="/search.php"]',navSearch:"#nav-s",searchResultTable:".t table",searchResultRows:'tr[id^="search_"]',searchResultHeader:".t table .h",previewRows:"tr.imagePreviewTr",imgSelectors:["#read_tpc img",".tpc_content img",".f14.cc img",'div[id="read_tpc"] img'],magnetTextarea:"textarea[readonly], textarea#copytext",magnetLink:'a[href^="magnet:?xt=urn:btih:"]',ed2kLink:'a[href^="ed2k://"]',btLink:'a[href*="bt.ivcbt.com/list.php?name="], a[href*="bt.bxmho.cn/list.php?name="]'},regex:{threadUrl:/read\.php\?tid=/,searchUrl:/search\.php/,searchRowId:/^search_(\d+)_(\d+)$/,magnetHash:/([A-F0-9]{40})/i,fileSize:/【影片容量】:([^<]+)<br|【影片大小】:([^<]+)/i,thunder:/thunder:\/\/[A-Za-z0-9+\/=]+/i,ed2k:/ed2k:\/\/\|file\|[^|]+\|\d+\|[A-F0-9]{32}\|\//i,magnetLink:/magnet:\?xt=urn:btih:[a-zA-Z0-9]+/,copyText:/magnet:\?xt=urn:btih:/},filters:{badImagePatterns:[/^(none|empty|blank|default)\./,/^(icon|logo|banner|ad)_/,/\.(ico|cur)$/,/^(loading|wait|spinner)/],badImageClasses:["icon","emoji","smiley"],minImageSize:{width:100,height:100}},btSites:[{name:"bxmho",pattern:/(?:\/\/bt\.bxmho\.cn\/list\.php\?name=|userscript\.html\?name=)([0-9a-z]+)/i,url:"https://bt.bxmho.cn/list.php",method:"GET",getHash:l=>{const e=l.match(/([0-9a-z]+)$/i);return e?e[1]:""}},{name:"82bt",pattern:/\/\/www\.82bt\.com\/(?:cao\.php|dlink\.php)\?hash=([0-9a-z]+)/i,url:"https://www.82bt.com/downt-m.php",method:"POST",paramName:"code",referer:"https://www.82bt.com",getHash:l=>{const e=l.match(/hash=([0-9a-z]+)/i);return e?e[1]:""}}]},u={copyToClipboard(l,e){navigator.clipboard.writeText(l).then(()=>{this.showClickTip("已复制",e)}).catch(()=>{this.fallbackCopyTextToClipboard(l,e)})},fallbackCopyTextToClipboard(l,e){const t=document.createElement("textarea");t.value=l,t.style.position="fixed",t.style.top="-1000px",t.style.left="-1000px",document.body.appendChild(t),t.focus(),t.select();try{document.execCommand("copy"),this.showClickTip("已复制",e)}catch(n){console.error("复制失败:",n),this.showClickTip("复制失败",e)}document.body.removeChild(t)},showClickTip(l,e){const t=e;let n=document.querySelector(".click-tip");n&&n.remove(),n=document.createElement("div"),n.className="click-tip",n.textContent=l,document.body.appendChild(n),n.style.left=`${t.clientX}px`,n.style.top=`${t.clientY}px`,setTimeout(()=>{n.style.opacity="1"},10),setTimeout(()=>{n.style.opacity="0",setTimeout(()=>{n.parentElement&&n.remove()},200)},1e3)},removeRules(){try{const l=document.querySelector(".collapse-header");if(l){const e=l.closest("div, section, .rule-container, .collapse-container");e&&e.remove()}}catch(l){console.error("移除版规时出错:",l)}},isContentPage(){return o.regex.threadUrl.test(window.location.href)},async asyncPool(l,e,t){const n=[],i=[];for(const a of e){const r=Promise.resolve().then(()=>t(a,e));if(n.push(r),l<=e.length){const s=r.then(()=>{const c=i.indexOf(s);c!==-1&&i.splice(c,1)});i.push(s),i.length>=l&&await Promise.race(i)}}return Promise.all(n)},debounce(l,e,t){let n=null;return function(...i){const a=()=>{n=null,t||l.apply(this,i)},r=t&&!n;n&&clearTimeout(n),n=setTimeout(a,e),r&&l.apply(this,i)}},waitForElement(l,e=5e3){return new Promise(t=>{const n=document.querySelector(l);if(n){t(n);return}const i=new MutationObserver(()=>{const a=document.querySelector(l);a&&(i.disconnect(),t(a))});i.observe(document.body,{childList:!0,subtree:!0}),setTimeout(()=>{i.disconnect(),t(null)},e)})},safeQuerySelector(l,e=document){try{return e.querySelector(l)}catch{return null}},safeQuerySelectorAll(l,e=document){try{return Array.from(e.querySelectorAll(l))}catch{return[]}}},I=class I{static getForumById(e){return this.FORUM_SECTIONS.find(t=>t.id===e)}static getChildForums(e){return this.FORUM_SECTIONS.filter(t=>t.parent===e)}static getMainCategories(){return this.FORUM_SECTIONS.filter(e=>e.level===2&&e.parent==="1")}static getSexInfoForumIds(){return this.FORUM_SECTIONS.filter(e=>e.name.includes("性息")||e.parent==="218").map(e=>e.id)}static getDisplayName(e){return`${" ".repeat(Math.max(0,e.level-2))}${e.name}`}static getForumTree(){const e=[];return this.getMainCategories().forEach(n=>{e.push(n),this.getChildForums(n.id).forEach(a=>{e.push(a);const r=this.getChildForums(a.id);e.push(...r)})}),e}};I.FORUM_SECTIONS=[{id:"all",name:"全部版块分类",level:0},{id:"1",name:"总板块",level:1},{id:"2",name:"新片速递",level:2,parent:"1"},{id:"3",name:"最新合集",level:3,parent:"2"},{id:"4",name:"亞洲無碼",level:3,parent:"2"},{id:"5",name:"日本騎兵",level:3,parent:"2"},{id:"13",name:"歐美新片",level:3,parent:"2"},{id:"15",name:"國內原創",level:3,parent:"2"},{id:"16",name:"中字原創",level:3,parent:"2"},{id:"18",name:"三級寫真",level:3,parent:"2"},{id:"343",name:"实时BT",level:3,parent:"2"},{id:"326",name:"本站高清影院",level:3,parent:"2"},{id:"7",name:"图片专区",level:2,parent:"1"},{id:"23",name:"網友自拍",level:3,parent:"7"},{id:"24",name:"亞洲激情",level:3,parent:"7"},{id:"25",name:"歐美激情",level:3,parent:"7"},{id:"26",name:"熟女专图",level:3,parent:"7"},{id:"27",name:"高跟絲襪",level:3,parent:"7"},{id:"28",name:"卡通漫畫",level:3,parent:"7"},{id:"345",name:"图你所图",level:3,parent:"7"},{id:"135",name:"原創达人",level:3,parent:"7"},{id:"273",name:"美图秀秀",level:2,parent:"1"},{id:"21",name:"唯美清純",level:3,parent:"273"},{id:"275",name:"亞洲正妹",level:3,parent:"273"},{id:"276",name:"素人正妹",level:3,parent:"273"},{id:"277",name:"角色扮演",level:3,parent:"273"},{id:"278",name:"A I 智能",level:3,parent:"273"},{id:"320",name:"优质图片",level:3,parent:"273"},{id:"333",name:"明星合成",level:3,parent:"273"},{id:"29",name:"动态图片",level:3,parent:"273"},{id:"92",name:"精品收录",level:2,parent:"1"},{id:"295",name:"原创首发",level:3,parent:"92"},{id:"94",name:"稀有首發",level:3,parent:"92"},{id:"329",name:"藏精阁 — 2017-2024",level:4,parent:"94"},{id:"283",name:"网络见闻",level:3,parent:"92"},{id:"111",name:"主播實錄",level:3,parent:"92"},{id:"99",name:"國產主播",level:4,parent:"111"},{id:"324",name:"自购主播区",level:4,parent:"111"},{id:"323",name:"国产主播2区",level:4,parent:"111"},{id:"322",name:"国产主播3区",level:4,parent:"111"},{id:"131",name:"名站同步",level:3,parent:"92"},{id:"314",name:"真实街拍",level:3,parent:"92"},{id:"341",name:"原档115",level:3,parent:"92"},{id:"213",name:"国产主播同步",level:4,parent:"341"},{id:"342",name:"VR視頻2023-2025",level:4,parent:"341"},{id:"290",name:"日本4K超清",level:4,parent:"341"},{id:"303",name:"高清有碼",level:4,parent:"341"},{id:"302",name:"AI視界",level:4,parent:"341"},{id:"304",name:"外掛字幕",level:4,parent:"341"},{id:"306",name:"FC2視頻",level:4,parent:"341"},{id:"307",name:"S-cute / Mywife",level:4,parent:"341"},{id:"305",name:"亞洲SM",level:4,parent:"341"},{id:"321",name:"补档申请",level:3,parent:"92"},{id:"75",name:"免空網盤",level:2,parent:"1"},{id:"72",name:"网盘二区",level:3,parent:"75"},{id:"272",name:"网盘三区",level:3,parent:"75"},{id:"195",name:"优质 B T",level:3,parent:"75"},{id:"280",name:"国产精选",level:3,parent:"75"},{id:"76",name:"多挂原创",level:3,parent:"75"},{id:"55",name:"有声小说",level:3,parent:"75"},{id:"180",name:"实用漫画",level:3,parent:"75"},{id:"113",name:"原档收藏",level:3,parent:"75"},{id:"116",name:"有碼.HD",level:4,parent:"113"},{id:"114",name:"亞洲SM.HD",level:4,parent:"113"},{id:"96",name:"日韓VR/3D",level:4,parent:"113"},{id:"119",name:"S-cute / Mywife / G-area",level:4,parent:"113"},{id:"41",name:"綜合資源",level:2,parent:"1"},{id:"43",name:"E D 2 K",level:3,parent:"41"},{id:"315",name:"原档字幕",level:3,parent:"41"},{id:"318",name:"磁链迅雷",level:3,parent:"41"},{id:"316",name:"包罗万象",level:3,parent:"41"},{id:"271",name:"聚合1区",level:4,parent:"316"},{id:"281",name:"聚合2区",level:4,parent:"316"},{id:"284",name:"聚合3区",level:4,parent:"316"},{id:"313",name:"远古资源",level:4,parent:"316"},{id:"319",name:"聚合5区",level:4,parent:"316"},{id:"325",name:"聚合6区 WK",level:4,parent:"316"},{id:"327",name:"聚合7区",level:4,parent:"316"},{id:"332",name:"司机社",level:4,parent:"316"},{id:"335",name:"套图学院",level:4,parent:"316"},{id:"334",name:"游戏下载",level:4,parent:"316"},{id:"340",name:"韩国主播",level:4,parent:"316"},{id:"344",name:"美足踩踏",level:4,parent:"316"},{id:"346",name:"套图百晓生",level:4,parent:"316"},{id:"348",name:"街拍精品",level:4,parent:"316"},{id:"67",name:"正片大片",level:3,parent:"41"},{id:"66",name:"H-GAME",level:3,parent:"41"},{id:"291",name:"快播影院",level:3,parent:"41"},{id:"293",name:"快播1号",level:4,parent:"291"},{id:"294",name:"快播2号",level:4,parent:"291"},{id:"296",name:"快播3号",level:4,parent:"291"},{id:"299",name:"快播4号",level:4,parent:"291"},{id:"300",name:"快播5号",level:4,parent:"291"},{id:"301",name:"快播6号",level:4,parent:"291"},{id:"308",name:"快播7号",level:4,parent:"291"},{id:"309",name:"快播频道",level:4,parent:"291"},{id:"311",name:"快播10号",level:4,parent:"291"},{id:"312",name:"快播11号",level:4,parent:"291"},{id:"331",name:"本站破解资源",level:3,parent:"41"},{id:"102",name:"文学欣赏",level:2,parent:"1"},{id:"328",name:"在线速听",level:3,parent:"102"},{id:"48",name:"综合小说",level:3,parent:"102"},{id:"49",name:"激情都市",level:4,parent:"48"},{id:"51",name:"青春校园",level:4,parent:"48"},{id:"52",name:"武侠虚幻",level:4,parent:"48"},{id:"105",name:"另类其他",level:4,parent:"48"},{id:"103",name:"人妻意淫",level:3,parent:"102"},{id:"50",name:"乱伦迷情",level:3,parent:"102"},{id:"54",name:"长篇连载",level:3,parent:"102"},{id:"100",name:"文学作者",level:3,parent:"102"},{id:"109",name:"TXT小说打包",level:3,parent:"102"},{id:"297",name:"2008-2024大集合",level:4,parent:"109"},{id:"110",name:"TXT小说綜合一区",level:4,parent:"109"},{id:"189",name:"TXT小说綜合二区",level:4,parent:"109"},{id:"193",name:"同人小说",level:4,parent:"109"},{id:"336",name:"耽美小说",level:4,parent:"109"},{id:"192",name:"言情小说",level:4,parent:"109"},{id:"338",name:"常规小说",level:4,parent:"109"},{id:"190",name:"都市校园",level:4,parent:"109"},{id:"191",name:"武侠小说",level:4,parent:"109"},{id:"93",name:"TXT小说網盤區",level:4,parent:"109"},{id:"56",name:"网友互动",level:2,parent:"1"},{id:"57",name:"聚友客栈",level:3,parent:"56"},{id:"61",name:"求片专版",level:3,parent:"56"},{id:"206",name:"重金求片区(米粒悬赏)限侠客以上",level:4,parent:"61"},{id:"218",name:"成人信息",level:3,parent:"56"},{id:"220",name:"北京性息",level:4,parent:"218"},{id:"237",name:"上海性息",level:4,parent:"218"},{id:"238",name:"广州性息",level:4,parent:"218"},{id:"239",name:"深圳性息",level:4,parent:"218"},{id:"287",name:"赚米专区",level:3,parent:"56"},{id:"136",name:"坛友自售",level:3,parent:"56"},{id:"289",name:"破解软件",level:3,parent:"56"},{id:"339",name:"包养情报",level:3,parent:"56"},{id:"128",name:"问题建议/举报申诉",level:3,parent:"56"},{id:"292",name:"解禁忏悔区/丢失找回",level:4,parent:"128"}];let g=I;const k=class k{static init(){this.initialized||(this.removeSearchButton(),this.addSettingsButton(),this.initialized=!0)}static removeSearchButton(){try{const e=document.getElementById("td_ID141");if(e){const n=e.closest("li");if(n){n.remove();return}}document.querySelectorAll('a[href="/search.php"]').forEach(n=>{const i=n.closest("li");i&&i.remove()})}catch(e){console.warn(`[${o.name}] 移除搜索按钮时出错:`,e)}}static addSettingsButton(){const e=document.getElementById("nav-pc");if(e){const t=document.createElement("li"),n=document.createElement("a");n.href="javascript:;",n.textContent="预览图设置",n.onclick=()=>!1,t.appendChild(n),e.appendChild(t);const i=this.createSettingsPanel();n.addEventListener("click",c=>{c.preventDefault(),i.show()});const a=document.createElement("li"),r=document.createElement("a");r.href="javascript:;",r.textContent="搜索过滤",r.onclick=()=>!1,a.appendChild(r),e.appendChild(a);const s=this.createSearchFilterPanel();r.addEventListener("click",c=>{c.preventDefault(),s.show()})}else this.addFallbackSettingsButton()}static addFallbackSettingsButton(){const e=document.getElementById("nav-s");if(e){const t=document.createElement("a");t.href="javascript:;",t.textContent="预览图设置",t.style.color="#fff",t.style.marginRight="15px",t.className="fr",e.insertBefore(t,e.firstChild);const n=this.createSettingsPanel();t.addEventListener("click",i=>{i.preventDefault(),n.show()})}}static createSettingsPanel(){document.body.insertAdjacentHTML("beforeend",`
      <dialog id="preview-settings-panel" class="compact-panel script-container">
        <header>
          <span>预览图设置</span>
          <button id="close-settings-btn" class="close-x">×</button>
        </header>
        <main class="settings-grid">
          <div class="setting-group">
            <label class="group-title">预览图数量</label>
            <label class="radio-item"><input type="radio" name="MAX_PREVIEW_IMAGES" value="3" checked>少量 (3张)</label>
            <label class="radio-item"><input type="radio" name="MAX_PREVIEW_IMAGES" value="4">适中 (4张)</label>
            <label class="radio-item"><input type="radio" name="MAX_PREVIEW_IMAGES" value="5">较多 (5张)</label>
          </div>
          <div class="setting-group">
            <label class="group-title">加载速度</label>
            <label class="radio-item"><input type="radio" name="CONCURRENT_LIMIT" value="6">稳定 (6个并发)</label>
            <label class="radio-item"><input type="radio" name="CONCURRENT_LIMIT" value="9" checked>平衡 (9个并发)</label>
            <label class="radio-item"><input type="radio" name="CONCURRENT_LIMIT" value="12">快速 (12个并发)</label>
          </div>
        </main>
        <footer>
          <button id="save-settings-btn">保存</button>
        </footer>
      </dialog>
      <div id="preview-settings-overlay" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.5); z-index:10000;"></div>
    `);const t=document.getElementById("preview-settings-panel"),n=document.getElementById("preview-settings-overlay");return this.loadBasicSettings(),setTimeout(()=>{n&&this.setupBasicEventListeners(t,n)},50),{show:()=>{t.style.display="block",n.style.display="block"}}}static createSearchFilterPanel(){document.body.insertAdjacentHTML("beforeend",`
      <dialog id="search-filter-panel" class="compact-search-panel script-container">
        <header>
          <span>搜索过滤设置</span>
          <button id="search-close-settings-btn" class="close-x">×</button>
        </header>
        <main id="search-forum-list" class="forum-tree"></main>
        <footer>
          <div class="filter-controls">
            <button id="search-clear-all-filters" class="secondary">清除</button>
            <button id="search-select-all-forums" class="secondary">全选</button>
          </div>
          <button id="search-save-settings-btn">保存</button>
        </footer>
      </dialog>
      <div id="search-filter-overlay" style="display:none; position:fixed; inset:0; background:rgba(0,0,0,0.5); z-index:10000;"></div>
    `);const t=document.getElementById("search-filter-panel"),n=document.getElementById("search-filter-overlay");return this.generateSearchForumList(),this.loadSearchFilterSettings(),setTimeout(()=>{n&&this.setupSearchFilterEventListeners(t,n)},50),{show:()=>{t.style.display="block",n.style.display="block"}}}static loadBasicSettings(){const e=o.getAll();for(const t in e){if(t==="EXCLUDED_FORUMS")continue;const n=document.querySelector(`[name="${t}"][value="${e[t]}"]`);n&&(n.checked=!0)}}static setupBasicEventListeners(e,t){const n=document.getElementById("save-settings-btn");n&&n.addEventListener("click",r=>{r.preventDefault(),r.stopPropagation(),this.saveBasicSettings()});const i=()=>{e.style.display="none",t.style.display="none"},a=document.getElementById("close-settings-btn");a&&a.addEventListener("click",i),t.addEventListener("click",i)}static saveBasicSettings(){try{document.querySelectorAll('#preview-settings-panel input[type="radio"]:checked').forEach(t=>{const n=t,i=isNaN(Number(n.value))?n.value:Number(n.value);o.set(n.name,i)}),this.showMessage("保存成功!","success"),setTimeout(()=>{const t=document.getElementById("preview-settings-panel"),n=document.getElementById("preview-settings-overlay");t&&(t.style.display="none"),n&&(n.style.display="none")},1e3)}catch(e){console.error("保存设置失败:",e),this.showMessage("保存失败!","error")}}static generateSearchForumList(){const e=document.getElementById("search-forum-list");if(!e)return;const t=g.getForumTree();t.filter(i=>i.level===2).forEach(i=>{const a=document.createElement("div");a.className="forum-group";const r=document.createElement("div");r.className="forum-group-title";const s=document.createElement("input");s.type="checkbox",s.id=`search-forum-${i.id}`,s.value=i.id,s.className="forum-checkbox main-checkbox";const c=document.createElement("label");c.className="main-forum-label",c.htmlFor=`search-forum-${i.id}`,c.textContent=g.getDisplayName(i),r.appendChild(s),r.appendChild(c),a.appendChild(r);const p=t.filter(d=>d.level===3&&d.parent===i.id);if(p.length>0){const d=document.createElement("div");d.className="sub-forums-grid",p.forEach(h=>{const E=document.createElement("label");E.className="sub-forum-item";const f=document.createElement("input");f.type="checkbox",f.id=`search-forum-${h.id}`,f.value=h.id,f.className="forum-checkbox sub-checkbox",f.dataset.parent=i.id;const A=document.createElement("span");A.textContent=g.getDisplayName(h),E.appendChild(f),E.appendChild(A),d.appendChild(E)}),a.appendChild(d)}e.appendChild(a),s.addEventListener("change",()=>{this.handleSearchFilterParentToggle(i.id,s.checked)})})}static loadSearchFilterSettings(){(o.get("EXCLUDED_FORUMS")||[]).forEach(t=>{const n=document.getElementById(`search-forum-${t}`);n&&(n.checked=!0)})}static setupSearchFilterEventListeners(e,t){const n=document.getElementById("search-save-settings-btn");n&&n.addEventListener("click",()=>this.saveSearchFilterSettings());const i=()=>{e.style.display="none",t.style.display="none"},a=document.getElementById("search-close-settings-btn");a&&a.addEventListener("click",i),t.addEventListener("click",i);const r=document.getElementById("search-clear-all-filters"),s=document.getElementById("search-select-all-forums");r&&r.addEventListener("click",()=>this.clearAllSearchFilters()),s&&s.addEventListener("click",()=>this.selectAllSearchForums())}static saveSearchFilterSettings(){const e=document.querySelectorAll(".compact-search-panel .forum-checkbox:checked"),t=Array.from(e).map(n=>n.value);o.set("EXCLUDED_FORUMS",t),this.showMessage("过滤设置已保存!","success"),setTimeout(()=>{const n=document.getElementById("search-filter-panel"),i=document.getElementById("search-filter-overlay");n&&(n.style.display="none"),i&&(i.style.display="none")},1e3)}static handleSearchFilterParentToggle(e,t){document.querySelectorAll(`[data-parent="${e}"]`).forEach(i=>{i.checked=t})}static clearAllSearchFilters(){document.querySelectorAll(".compact-search-panel .forum-checkbox").forEach(t=>t.checked=!1)}static selectAllSearchForums(){document.querySelectorAll(".compact-search-panel .forum-checkbox").forEach(t=>t.checked=!0)}static showMessage(e,t){const n=document.querySelector(".quick-message");n&&n.remove();const i=document.createElement("div");i.className="quick-message",i.textContent=e,i.style.background=t==="success"?"#10b981":"#ef4444",document.body.appendChild(i),setTimeout(()=>i.classList.add("show"),10),setTimeout(()=>{i.classList.remove("show"),setTimeout(()=>i.remove(),300)},2e3)}};k.initialized=!1;let w=k;const m=class m{static init(){this.createLightbox(),this.setupEventListeners()}static createLightbox(){if(this.lightbox)return;this.lightbox=document.createElement("div"),this.lightbox.className="lightbox",this.lightboxContent=document.createElement("div"),this.lightboxContent.className="lightbox-content",this.lightboxImg=document.createElement("img"),this.lightboxImg.className="lightbox-image";const e=document.createElement("div");e.className="lightbox-close",e.innerHTML="×";const t=document.createElement("div");t.className="lightbox-prev",t.innerHTML="‹";const n=document.createElement("div");n.className="lightbox-next",n.innerHTML="›",this.loadingText=document.createElement("div"),this.loadingText.className="lightbox-loading",this.loadingText.textContent="加载中...",this.lightboxContent.appendChild(this.loadingText),this.lightboxContent.appendChild(this.lightboxImg),this.lightbox.appendChild(this.lightboxContent),this.lightbox.appendChild(e),this.lightbox.appendChild(t),this.lightbox.appendChild(n),document.body.appendChild(this.lightbox),this.closeBtn=e,this.prevBtn=t,this.nextBtn=n}static setupEventListeners(){!this.closeBtn||!this.prevBtn||!this.nextBtn||!this.lightbox||(this.closeBtn.addEventListener("click",()=>this.closeLightbox()),this.prevBtn.addEventListener("click",e=>{e.stopPropagation(),this.currentIndex=(this.currentIndex-1+this.currentImages.length)%this.currentImages.length,this.updateLightboxImage()}),this.nextBtn.addEventListener("click",e=>{e.stopPropagation(),this.currentIndex=(this.currentIndex+1)%this.currentImages.length,this.updateLightboxImage()}),this.lightbox.addEventListener("click",e=>{e.target===this.lightbox&&this.closeLightbox()}),document.addEventListener("keydown",e=>{this.lightbox?.classList.contains("active")&&(e.key==="Escape"?this.closeLightbox():e.key==="ArrowLeft"?this.prevBtn?.click():e.key==="ArrowRight"&&this.nextBtn?.click())}))}static updateLightboxImage(){if(!this.lightboxImg||!this.loadingText||!this.lightboxContent)return;const e=this.currentImages[this.currentIndex];this.loadingText.textContent="加载中...",this.loadingText.style.display="block",this.lightboxImg.style.display="none",this.lightboxImg.style.width="",this.lightboxImg.style.height="",this.lightboxImg.style.maxWidth="",this.lightboxImg.style.maxHeight="",this.lightboxContent.classList.remove("landscape","portrait"),this.lightboxImg.src=e,this.lightboxImg.onload=()=>{if(!this.lightboxImg||!this.loadingText||!this.lightboxContent)return;this.loadingText.style.display="none",this.lightboxImg.style.display="block";const t=window.innerWidth*.9,n=window.innerHeight*.9,i=this.lightboxImg.naturalWidth,a=this.lightboxImg.naturalHeight;if(i<300&&a<300){const r=i*2,s=a*2;r<=t&&s<=n?(this.lightboxImg.style.width=r+"px",this.lightboxImg.style.height=s+"px"):this.scaleImageToFit(r,s,t,n)}else i>t||a>n?this.scaleImageToFit(i,a,t,n):(this.lightboxImg.style.width=i+"px",this.lightboxImg.style.height=a+"px")},this.lightboxImg.onerror=()=>{this.loadingText&&(this.loadingText.textContent="图片加载失败")}}static scaleImageToFit(e,t,n,i){if(!this.lightboxImg)return;const a=n/e,r=i/t,s=Math.min(a,r),c=e*s,p=t*s;this.lightboxImg.style.width=c+"px",this.lightboxImg.style.height=p+"px"}static showLightbox(e,t){this.lightbox&&(this.currentImages=e,this.currentIndex=t,this.updateLightboxImage(),this.lightbox.classList.add("active"))}static closeLightbox(){this.lightbox&&this.lightbox.classList.remove("active")}};m.lightbox=null,m.lightboxImg=null,m.lightboxContent=null,m.loadingText=null,m.currentImages=[],m.currentIndex=0,m.closeBtn=null,m.prevBtn=null,m.nextBtn=null;let v=m;const T=class T{static injectStyles(){if(this.styleInjected||document.getElementById("ultra-minimal-styles"))return;const e=document.createElement("style");e.id="ultra-minimal-styles",e.textContent='.click-tip{position:fixed;background:rgba(0,0,0,0.8);color:#fff;padding:6px 12px;border-radius:4px;font-size:13px;z-index:10000}.thread-title-highlighted{background:#e8f4fd!important;border-radius:4px 4px 0 0}.preview-container{margin:0 0 10px 0;border:1px solid #dee2e6;border-top:none;border-radius:0 0 4px 4px;padding:16px;background:#f8f9fa}.preview-images{display:flex;gap:12px;margin-bottom:16px}.preview-image-wrapper{height:200px;flex:0 0 auto;border-radius:4px;cursor:pointer;overflow:hidden}.preview-image{width:100%;height:100%;object-fit:cover}.preview-magnet{font-size:13px;word-break:break-all;cursor:pointer;padding:10px 12px;background:#f0f9ff;border:1px solid #e0f2fe;border-radius:4px;margin-bottom:10px}.lightbox{position:fixed;inset:0;background:rgba(0,0,0,0.9);display:flex;align-items:center;justify-content:center;z-index:9999;opacity:0;visibility:hidden}.lightbox.active{opacity:1;visibility:visible}.lightbox-image{border-radius:8px;display:block;object-fit:contain}.lightbox-prev,.lightbox-next,.lightbox-close{position:absolute;color:#fff;cursor:pointer;background:rgba(0,0,0,0.5);border-radius:50%;display:flex;align-items:center;justify-content:center}.lightbox-prev,.lightbox-next{top:50%;transform:translateY(-50%);font-size:36px;width:60px;height:60px}.lightbox-close{top:20px;right:20px;font-size:24px;width:40px;height:40px}.lightbox-prev{left:20px}.lightbox-next{right:20px}.compact-panel{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:10001;background:#fff;border:1px solid #ddd;border-radius:6px;font-family:system-ui,sans-serif;width:360px;box-shadow:0 4px 12px rgba(0,0,0,0.15)}.compact-panel header{position:relative;padding:12px 16px;border-bottom:1px solid #eee;background:#fafafa;border-radius:6px 6px 0 0;font-size:14px;font-weight:500;color:#333}.settings-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;padding:16px}.setting-group{display:flex;flex-direction:column;gap:6px}.group-title{font-size:13px;font-weight:500;color:#666;margin-bottom:2px}.radio-item{display:flex;align-items:center;gap:6px;padding:4px 8px;border-radius:4px;cursor:pointer;font-size:13px;color:#333}.radio-item input[type="radio"]{margin:0}.compact-panel footer{padding:12px 16px;border-top:1px solid #eee;text-align:right}.compact-panel button{padding:6px 16px;border:1px solid #ddd;border-radius:4px;background:#fff;color:#333;cursor:pointer;font-size:13px}.compact-panel #save-settings-btn{background:#007bff;border-color:#007bff;color:#fff}.settings-panel{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:10001;background:#fff;border:1px solid #dee2e6;border-radius:8px;font-family:system-ui,sans-serif;width:480px;max-height:80vh;overflow-y:auto}.settings-panel-wide{width:800px}.settings-panel header{position:relative;padding:20px 24px 16px;border-bottom:1px solid #dee2e6;background:#f8f9fa;border-radius:8px 8px 0 0}.settings-panel h2{margin:0;font-size:16px;font-weight:600;text-align:center;color:#333}.settings-panel p{margin:8px 0 0;font-size:13px;color:#6b7280;text-align:center}.close-x{position:absolute;top:16px;right:16px;width:20px;height:20px;border:none;background:none;color:#999;font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;line-height:1}.settings-panel main{padding:24px}.settings-panel fieldset{border:1px solid #e5e7eb;border-radius:6px;padding:20px;margin-bottom:24px;background:#fafbfc}.settings-panel legend{font-size:14px;font-weight:600;color:#374151;padding:0 8px;background:#fff}.settings-panel label{display:flex;align-items:center;padding:12px 16px;margin-bottom:8px;border:1px solid #e5e7eb;border-radius:6px;cursor:pointer}.settings-panel label:last-child{margin-bottom:0}.settings-panel input[type="radio"]{margin-right:12px}.settings-panel footer{padding:16px 24px;background:#f8f9fa;border-top:1px solid #dee2e6;border-radius:0 0 8px 8px;display:flex;justify-content:space-between;align-items:center}.compact-search-panel{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:10001;background:#fff;border:1px solid #ddd;border-radius:6px;font-family:system-ui,sans-serif;width:680px;max-height:75vh;overflow:hidden;box-shadow:0 4px 12px rgba(0,0,0,0.15)}.compact-search-panel header{position:relative;padding:12px 16px;border-bottom:1px solid #eee;background:#fafafa;border-radius:6px 6px 0 0;font-size:14px;font-weight:500;color:#333}.forum-tree{padding:16px;max-height:400px;overflow-y:auto}.forum-group{margin-bottom:16px;border:1px solid #e5e7eb;border-radius:6px;overflow:hidden}.forum-group:last-child{margin-bottom:0}.forum-group-title{padding:8px 12px;background:#f8f9fa;border-bottom:1px solid #e5e7eb;display:flex;align-items:center;gap:8px;font-weight:500;color:#374151}.main-forum-label{cursor:pointer;font-size:13px;user-select:none}.sub-forums-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:1px;background:#e5e7eb}.sub-forum-item{display:flex;align-items:center;gap:6px;padding:6px 10px;background:#fff;cursor:pointer;font-size:12px;color:#4b5563}.filter-controls{display:flex;gap:8px}.compact-search-panel footer{padding:12px 16px;border-top:1px solid #eee;display:flex;justify-content:space-between;align-items:center}.compact-search-panel button{padding:6px 12px;border:1px solid #ddd;border-radius:4px;background:#fff;color:#333;cursor:pointer;font-size:12px}.compact-search-panel #search-save-settings-btn{background:#007bff;border-color:#007bff;color:#fff}.forum-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:6px;max-height:350px;overflow-y:auto;border:1px solid #dee2e6;border-radius:6px;padding:10px}.forum-item{display:flex;align-items:center;gap:6px;padding:6px;border:1px solid #f1f5f9;border-radius:4px;cursor:pointer}.forum-item:has(.level-2){grid-column:1/-1;background:#eff6ff;font-weight:600}.settings-panel button{padding:10px 20px;border-radius:6px;font-size:14px;cursor:pointer;border:1px solid;min-width:80px;font-weight:500}.settings-panel button:not(.secondary){background:#3b82f6;border-color:#3b82f6;color:#fff}.settings-panel button.secondary{background:#f8f9fa;border-color:#d1d5db;color:#374151}.quick-message{position:fixed;top:20px;right:20px;padding:10px 14px;background:#28a745;color:#fff;border-radius:4px;font-size:13px;z-index:10003}.quick-message.show{display:block}.flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:0.5rem}.mb-3{margin-bottom:0.75rem}.p-3{padding:0.75rem}.text-center{text-align:center}.cursor-pointer{cursor:pointer}',document.head.appendChild(e),this.styleInjected=!0}static setImageGridWidth(e,t){let n;t===1?n="50%":n=`calc((100% - ${(t-1)*12}px) / ${t})`,Array.from(e.children).forEach(i=>{i.style.width=n,i.style.flex="0 0 auto"})}};T.styleInjected=!1;let y=T;class x{static removeAds(){document.querySelectorAll(o.selectors.threadRows).forEach(t=>{const n=t.querySelector("td.tal");n&&n.innerHTML.includes("headtopic_3.gif")&&t.remove()}),this.removeAdButtons()}static removeGlobalAds(){this.removeAdButtons()}static removeAdButtons(){["td_ID144","td_ID86","td_ID139"].forEach(t=>{const n=document.getElementById(t);if(n){const i=n.closest("li");i?i.remove():n.remove()}})}}class S{static extractImages(e){const t=o.get("MAX_PREVIEW_IMAGES");let n=[];for(const s of o.selectors.imgSelectors)if(n=Array.from(e.querySelectorAll(s)),n.length>0)break;let a=n.filter(s=>{const c=s.getAttribute("style")||"";return!(c.includes("display: none")||c.includes("display:none"))}).map(s=>({src:s.getAttribute("data-original")||s.getAttribute("src")||"",img:s})).filter(s=>{if(!s.src||!s.src.startsWith("http")||s.src.includes("loading.")||s.src.includes("placeholder."))return!1;const p=s.src.toLowerCase().split("/").pop()||"";return!(o.filters.badImagePatterns.some(d=>d.test(p))||s.img.width&&s.img.height&&(s.img.width<o.filters.minImageSize.width||s.img.height<o.filters.minImageSize.height))});return a.sort((s,c)=>{const p=/\.(jpg|jpeg|png)$/i.test(s.src),d=/\.(jpg|jpeg|png)$/i.test(c.src);return p&&!d?-1:!p&&d?1:0}),a.map(s=>s.src).slice(0,t)}static extractFileSize(e){let t="";for(const n of o.selectors.contentSelectors){const i=e.querySelector(n);if(i){let r=i.innerHTML.match(o.regex.fileSize);if(r&&(r[1]||r[2])){t=(r[1]||r[2]).trim();break}}}return t}static extractMagnet(e){let t="",n=e.querySelector(o.selectors.magnetTextarea);if(n)t=n.value.trim();else{let i=e.querySelector(o.selectors.magnetLink);if(i)t=i.getAttribute("href")||"";else{const r=e.body.innerHTML.match(o.regex.magnetHash);r&&r[1]&&(t=`magnet:?xt=urn:btih:${r[1]}`)}}return t}}class B{static async extractFromPage(e){try{for(const t of o.btSites){const n=e.match(t.pattern);if(n){const i=t.getHash(n[0]),a=await this.fetchFromBtSite(t,i);if(a)return this.cleanMagnetLink(a)}}return null}catch(t){return console.error(`[${o.name}] 外链磁力获取失败:`,t),null}}static cleanMagnetLink(e){const t=e.match(/magnet:\?xt=urn:btih:([a-f0-9]{40})/i);return t?`magnet:?xt=urn:btih:${t[1]}`:e}static async fetchFromBtSite(e,t){try{return new Promise(n=>{const i={method:e.method,url:e.method==="GET"?`${e.url}?name=${t}`:e.url,headers:{Accept:"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8",DNT:"1",Connection:"keep-alive","Upgrade-Insecure-Requests":"1"},onload:a=>{if(a.status>=200&&a.status<300)try{const r=new DOMParser().parseFromString(a.responseText,"text/html"),s=r.querySelector("#magnetInput");if(s){const d=s.value||s.getAttribute("value");if(d){const h=d.replace(/&amp;/g,"&");n(h);return}}const c=r.querySelector(".magnet-box input");if(c){const d=c.getAttribute("value")||c.value;if(d){const h=d.replace(/&amp;/g,"&");n(h);return}}const p=a.responseText.match(/magnet:\?xt=urn:btih:[a-f0-9]{40}[^"'\s]*/i);if(p){const d=p[0].replace(/&amp;/g,"&");n(d);return}n(null)}catch(r){console.error(`[${o.name}] ${e.name}HTML解析失败:`,r),n(null)}else n(null)},onerror:()=>n(null),ontimeout:()=>n(null)};if(e.method==="POST"){i.headers["Content-Type"]="application/x-www-form-urlencoded",i.headers.Referer=e.referer,i.headers.Origin=e.referer;const a={};a[e.paramName]=t,i.data=new URLSearchParams(a).toString()}GM_xmlhttpRequest(i)})}catch(n){return console.error(`[${o.name}] 获取${e.name}站点链接失败:`,n),null}}}class R{static buildPreviewUI(e,t){const{imgSrcs:n,fileSize:i,magnet:a}=t;if(e.nextElementSibling&&e.nextElementSibling.classList.contains("imagePreviewTr"))return;if(e.classList.add("thread-title-highlighted"),i){const p=e.querySelector("td:nth-child(2)");if(p){const d=document.createElement("span");d.style.cssText="margin-left: 8px; color: #ff6b35; font-weight: 600; font-size: 13px;",d.textContent=`[${i}]`,p.appendChild(d)}}const r=document.createElement("tr");r.className="imagePreviewTr";const s=document.createElement("td");s.colSpan=e.children.length;const c=document.createElement("div");c.className="preview-container",c.style.borderTop="none",n.length&&c.appendChild(this.createImageSection(n)),a&&c.appendChild(this.createInfoSection(i,a)),s.appendChild(c),r.appendChild(s),e.parentNode.insertBefore(r,e.nextSibling)}static createImageSection(e){const t=document.createElement("div");return t.className="preview-images",e.forEach((n,i)=>{if(n&&n.startsWith("http")){const a=document.createElement("div");a.className="preview-image-wrapper";const r=document.createElement("img");r.src=n,r.className="preview-image",r.onerror=()=>{a.style.display="none"},a.addEventListener("click",()=>v.showLightbox(e,i)),a.appendChild(r),t.appendChild(a)}}),t.children.length>0&&y.setImageGridWidth(t,t.children.length),t}static createInfoSection(e,t){const n=document.createElement("div");return n.className="preview-magnet",n.textContent=t,n.title="点击链接可复制",n.onclick=function(i){u.copyText(t)},n}}class F{static async processThreadLink(e){const t=e.href;if(!t||!o.regex.threadUrl.test(t))return;const n=e.closest("tr");if(!(!n||n.querySelector('img[src*="headtopic"]')))try{const a=await(await fetch(t)).text(),s=new DOMParser().parseFromString(a,"text/html");let c=S.extractMagnet(s);c||(c=await B.extractFromPage(a)||"");const p={imgSrcs:S.extractImages(s),fileSize:S.extractFileSize(s),magnet:c||""};if(!p.imgSrcs.length&&!p.fileSize&&!p.magnet)return;R.buildPreviewUI(n,p)}catch(i){console.error(`[${o.name}] 预览加载失败:`,i)}}}const b=class b{static init(){this.initialized||this.isSearchResultPage()&&(this.filterSearchResults(),this.updateResultStats(),this.initialized=!0)}static isSearchResultPage(){if(!window.location.href.includes("search.php"))return!1;const e=document.querySelector(".t table"),t=document.querySelectorAll('tr[id^="search_"]');return!!(e&&t.length>0)}static extractForumId(e){const t=e.getAttribute("id");if(t&&t.startsWith("search_")){const n=t.split("_");if(n.length>=2)return n[1]}return null}static getExcludedForums(){return o.get("EXCLUDED_FORUMS")||[]}static filterSearchResults(){const e=this.getExcludedForums();if(e.length===0)return;const t=document.querySelectorAll('tr[id^="search_"]');this.totalCount=t.length;let n=0;t.forEach(i=>{const a=this.extractForumId(i);if(a&&e.includes(a)){i.style.display="none";const r=i.nextElementSibling;r&&r.classList.contains("imagePreviewTr")&&(r.style.display="none"),n++}}),this.filteredCount=n}static updateResultStats(){if(this.filteredCount===0)return;const e=document.querySelector(".t table .h");if(e){const t=e.textContent||"主题列表",n=this.totalCount-this.filteredCount;e.textContent=`${t} (显示 ${n}/${this.totalCount} 条结果,已过滤 ${this.filteredCount} 条)`,e.setAttribute("title",`已根据设置隐藏${this.filteredCount}条不相关结果`)}}static reapplyFilter(){if(!this.isSearchResultPage())return;document.querySelectorAll('tr[id^="search_"], tr.imagePreviewTr').forEach(t=>{t.style.display=""}),this.filteredCount=0,this.filterSearchResults(),this.updateResultStats()}static getFilterStats(){return{total:this.totalCount,filtered:this.filteredCount,visible:this.totalCount-this.filteredCount}}static clearAllFilters(){o.set("EXCLUDED_FORUMS",[]),this.reapplyFilter()}static applyPresetExcludeSexInfo(){const e=g.getSexInfoForumIds(),t=this.getExcludedForums(),n=[...new Set([...t,...e])];o.set("EXCLUDED_FORUMS",n),this.reapplyFilter()}static addExcludedForum(e){const t=this.getExcludedForums();t.includes(e)||(t.push(e),o.set("EXCLUDED_FORUMS",t),this.reapplyFilter())}static removeExcludedForum(e){const n=this.getExcludedForums().filter(i=>i!==e);o.set("EXCLUDED_FORUMS",n),this.reapplyFilter()}static toggleForumExclusion(e){this.getExcludedForums().includes(e)?this.removeExcludedForum(e):this.addExcludedForum(e)}};b.initialized=!1,b.filteredCount=0,b.totalCount=0;let C=b;class L{static async displayThreadImages(){const e=o.get("CONCURRENT_LIMIT");if(u.isContentPage())return;u.removeRules(),v.init();const t=u.safeQuerySelectorAll(o.selectors.threadLinks);t.length&&await u.asyncPool(e,t,F.processThreadLink)}static isSearchPage(){return o.regex.searchUrl.test(window.location.href)&&document.querySelector(o.selectors.searchResultTable)!==null}static async main(){try{if(w.init(),y.injectStyles(),u.isContentPage())return;this.isSearchPage()?(C.init(),await this.displayThreadImages()):(x.removeAds(),await this.displayThreadImages())}catch(e){console.error(`[${o.name}] 初始化失败:`,e)}}}x.removeGlobalAds(),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{x.removeGlobalAds(),L.main()}):(x.removeGlobalAds(),L.main()),window.addEventListener("load",()=>{x.removeGlobalAds()})})();