@shenzi#soushuba_tid_tmp

搜书吧 缓存tid

// ==UserScript==
// @name         @shenzi#soushuba_tid_tmp
// @name:zh-CN   @神紫#小说网站 搜书吧 缓存tid
// @namespace    http://tampermonkey.net/
// @version      1.0.5.20250328h
// @description  搜书吧 缓存tid
// @author       神紫
// @match        *://vsdf.n.rkggs5f4e5asf.com/*
// @match        *://v.asf.nupt4j5yt4.com/*
// @match        *://s.dg.b4yh4tyj46.com/*
// @match        *://p6.36.nu6kiu4yuk5.com/*
// @match        *://u0.k1.2ijtyj454.com/*
// @match        *://52n.mf.56sdfwef45.com/*
// @match        *://62df.th.9ef56erg.com/*
// @match        *://upq.asd6.sa5f6dff3f12.com/*
// @match        *://q1.v.agrth45tge.com/*
// @match        *://b6d.vb.2bhrg1e54.com/*
// @match        *://cc96.c3.c3sdefwewer.com/*
// @match        *://33ty.hk.sdvs4df4e5f4.com/*
// @match        *://sxsy77.com/*
// @match        *://sxsy122.com/*
// @match        *://sxsy19.com/*
// @icon         https://b6d.vb.2bhrg1e54.com/favicon.ico
// @icon         https://sxsy19.com/favicon.ico
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_deleteValue
// @grant        GM_listValues
// @grant        GM_setClipboard
// @grant        GM_registerMenuCommand
// @license      MIT
// ==/UserScript==

"use strict";

(function () {
  class DecimalBase64To {
    static base64Code = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+/";
    static decToB64(decimal) {
      if (decimal === 0) return this.base64Code[0];
      const base64Arr = [];
      while (decimal > 0) {
        const remainder = decimal % 64;
        base64Arr.push(this.base64Code[remainder]);
        decimal = Math.floor((decimal - remainder) / 64);
      }
      return base64Arr.reverse().join("");
    }
    static b64ToDec(base64) {
      let decimal = 0;
      for (let i = 0; i < base64.length; i++) {
        const value = this.base64Code.indexOf(base64[i]);
        if (value === -1) return NaN;
        decimal = decimal * 64 + value;
      }
      return decimal;
    }
  }
  class DataTmp {
    data_key;
    max_exist_time_get_data_tmp;
    black_flag;
    last_time_get_data_tmp = (() => -1)();
    data = "";
    constructor(data_key) {
      let black_flag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "|";
      let max_exist_time_get_data_tmp = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 30 * 1000;
      this.data_key = data_key;
      this.black_flag = black_flag;
      this.max_exist_time_get_data_tmp = max_exist_time_get_data_tmp;
    }
    init() {
      this.data = GM_getValue(this.data_key, this.black_flag);
      this.last_time_get_data_tmp = Date.now();
    }
    _add(value) {
      this.data += `${value}${this.black_flag}`;
    }
    _del(value) {
      this.data = this.data.replace(`${this.black_flag}${value}${this.black_flag}`, this.black_flag);
    }
    _save() {
      GM_setValue(this.data_key, this.data);
    }
    exist(value) {
      return this.data.indexOf(`${this.black_flag}${value}${this.black_flag}`) !== -1;
    }
    init_tmp() {
      if (Date.now() - this.last_time_get_data_tmp >= this.max_exist_time_get_data_tmp) {
        this.init();
      }
    }
    add_unsave(value) {
      this.init_tmp();
      this._add(value);
    }
    add_save(value) {
      this.init();
      if (!this.exist(value)) {
        this._add(value);
        this._save();
      }
    }
    del_save(value) {
      this.init();
      if (this.exist(value)) {
        this._del(value);
        this._save();
      }
    }
    load(values) {
      this.init();
      let updated = false;
      for (const value of values) {
        if (!this.exist(value)) {
          if (!updated) updated = true;
          this._add(value);
        }
      }
      if (updated) {
        this._save();
      }
    }
    dumps_fmt_dump(dumps) {
      return dumps.split(this.black_flag).map(dt => dt.trim()).filter(dt => dt.length !== 0);
    }
    fmt_data() {
      this.init();
      return this.dumps_fmt_dump(this.data);
    }
    dump() {
      return this.fmt_data();
    }
    dumps() {
      this.init();
      return this.data;
    }
    optimize_sorted() {
      const dts = this.fmt_data();
      if (dts.length === 0) return;
      const data = dts.sort().join(this.black_flag);
      GM_setValue(this.data_key, `${this.black_flag}${data}${this.black_flag}`);
    }
  }
  class ImExData {
    static im_init = false;
    static im_open;
    static dm_init = false;
    static dm_open;
    static dts_exp_fail(dts) {
      const fails = [];
      dts.forEach(dat => {
        if (isNaN(DecimalBase64To.b64ToDec(dat))) {
          fails.push(dat);
        }
      });
      return fails;
    }
    static load_im_dm_style() {
      const style = document.createElement("style");
      style.innerText = `
#confirm-dialog {
  border: none;
  border-radius: 8px;
  padding: 20px;
  min-width: 20em;
  width: 30em;
  max-width: 80%;
}

#confirm-dialog[data-state="init"] #confirm-content { border-color: #1f1f1f; }
#confirm-dialog[data-state="succeed"] #confirm-content { border-color: #7fff00; }
#confirm-dialog[data-state="fail"] #confirm-content { border-color: #ff0000; }

#confirm-content {
  min-width: 97%;
  max-width: 97%;
  min-height: 10em;
  height: 20em;
  max-height: 80vh;
}

#confirm-error { color: #ff0000; font-weight: bold; }
`;
      document.body.appendChild(style);
    }
    static load_im_element(data_key, data_ban_key, black_flag) {
      const confirmDialog = document.createElement("dialog");
      const confirmContent = document.createElement("textarea");
      const confirmError = document.createElement("p");
      const confirmPaste = document.createElement("button");
      const confirmSubmit = document.createElement("button");
      const confirmClose = document.createElement("button");
      confirmContent.placeholder = "请输入要导入的数据";
      confirmPaste.innerText = "导入剪切板的数据";
      confirmSubmit.innerText = "确定";
      confirmClose.innerText = "取消";
      confirmDialog.id = "confirm-dialog";
      confirmContent.id = "confirm-content";
      confirmError.id = "confirm-error";
      confirmPaste.id = "confirm-paste";
      confirmSubmit.id = "confirm-submit";
      confirmClose.id = "confirm-close";
      function msgOut(state, errorinfo, content) {
        confirmDialog.dataset.state = state;
        confirmError.innerText = errorinfo;
        confirmContent.value = content;
      }
      function initOut() {
        msgOut("init", "", "");
      }
      function infoOut(content) {
        msgOut("succeed", "", content);
      }
      function errorOut(errorinfo) {
        let content = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
        msgOut("fail", errorinfo, content);
      }
      const initObj = () => {
        option_dbpack = null;
        initOut();
      };
      this.im_open = () => {
        confirmDialog.showModal();
        initObj();
      };
      const checkdata = () => {
        const importedData = confirmContent.value.trim();
        if (importedData.length === 0) return errorOut("无数据");
        let idbpack;
        try {
          idbpack = this.im_dbpack(importedData, this.allowKeys, black_flag);
        } catch (e) {
          return errorOut(e.message);
        }
        let dt = new DataTmp(data_key, black_flag);
        const i10 = this.allowKeyCore in idbpack;
        const i20 = this.allowKeyBan in idbpack;
        const importedCoreData = i10 ? dt.dumps_fmt_dump(idbpack[this.allowKeyCore]) : [];
        const importedBanData = i20 ? dt.dumps_fmt_dump(idbpack[this.allowKeyBan]) : [];
        dt = null;
        const fails = this.dts_exp_fail(importedCoreData);
        if (fails.length !== 0) return errorOut("↑↑↑❌浏览数据加载出错❌↑↑↑", importedCoreData.join(black_flag));
        const failBans = this.dts_exp_fail(importedBanData);
        if (failBans.length !== 0) return errorOut("↑↑↑❌封禁数据加载出错❌↑↑↑", importedBanData.join(black_flag));
        option_dbpack = idbpack;
        if (!i10) return infoOut(`封禁数据:\n${importedBanData.join(black_flag)}`);
        if (!i20) return infoOut(`浏览数据:\n${importedCoreData.join(black_flag)}`);
        return infoOut(`浏览数据:\n${importedCoreData.join(black_flag)}\n${`${'-'.repeat(10)}\n`.repeat(3)}封禁数据:\n${importedBanData.join(black_flag)}`);
      };
      let option_dbpack;
      confirmContent.addEventListener("change", checkdata);
      confirmPaste.addEventListener("click", () => {
        navigator.clipboard.readText().then(text => {
          confirmContent.value = text;
          checkdata();
        }).catch(err => {
          alert(`无法从剪切板读取数据: ${err}`);
        });
      });
      confirmSubmit.addEventListener("click", () => {
        if (confirmDialog.dataset?.state !== "succeed") return;
        if (option_dbpack === null) return;
        let dt = new DataTmp(data_key, black_flag);
        const i10 = this.allowKeyCore in option_dbpack;
        const i20 = this.allowKeyBan in option_dbpack;
        const importedCoreData = i10 ? dt.dumps_fmt_dump(option_dbpack[this.allowKeyCore]) : [];
        const importedBanData = i20 ? dt.dumps_fmt_dump(option_dbpack[this.allowKeyBan]) : [];
        if (i10) dt.load(importedCoreData);
        if (i20) new DataTmp(data_ban_key, black_flag).load(importedBanData);
        dt = null;
        initObj();
        confirmDialog.close();
      });
      confirmClose.addEventListener("click", () => {
        if (confirmDialog === null) return;
        initObj();
        confirmDialog.close();
      });
      confirmDialog.appendChild(confirmContent);
      confirmDialog.appendChild(confirmError);
      confirmDialog.appendChild(confirmPaste);
      confirmDialog.appendChild(confirmSubmit);
      confirmDialog.appendChild(confirmClose);
      document.body.appendChild(confirmDialog);
    }
    static add_dm_options(select, options, currOption) {
      const optionEls = [];
      for (const option of options) {
        if (option === currOption) continue;
        const thisOption = option;
        const optionEl = document.createElement("option");
        optionEl.className = "option-other-web";
        optionEl.value = optionEl.innerText = thisOption;
        select.appendChild(optionEl);
        optionEls.push(optionEl);
      }
      return optionEls;
    }
    static remove_dm_options(select, options) {
      for (const option of options) {
        select.removeChild(option);
      }
      options.splice(0, options.length);
    }
    static load_dm_element(ksDt, ksBanDt, data_key, data_ban_key, black_flag) {
      const confirmDialog = document.createElement("dialog");
      const confirmTitle = document.createElement("select");
      const confirmOptionVoid = document.createElement("option");
      const confirmContent = document.createElement("textarea");
      const confirmError = document.createElement("p");
      const confirmSubmit = document.createElement("button");
      const confirmClose = document.createElement("button");
      confirmOptionVoid.innerText = "请选择网站";
      confirmOptionVoid.value = "null";
      confirmOptionVoid.selected = true;
      confirmContent.readOnly = true;
      confirmContent.placeholder = "请选择上方‘其他网站的数据’,\n以便装以‘该网站’的数据到‘本网站’。";
      confirmSubmit.innerText = "确定";
      confirmClose.innerText = "取消";
      confirmDialog.id = "confirm-dialog";
      confirmTitle.id = "confirm-selects";
      confirmContent.id = "confirm-content";
      confirmError.id = "confirm-error";
      confirmSubmit.id = "confirm-submit";
      confirmClose.id = "confirm-close";
      function msgOut(state, errorinfo, content) {
        confirmDialog.dataset.state = state;
        confirmError.innerText = errorinfo;
        confirmContent.value = content;
      }
      function initOut() {
        msgOut("init", "", "");
      }
      function infoOut(content) {
        msgOut("succeed", "", content);
      }
      function errorOut(errorinfo) {
        let content = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
        msgOut("fail", errorinfo, content);
      }
      const initObj = () => {
        optionHt = null;
        if (options !== null) this.remove_dm_options(confirmTitle, options);
        initOut();
        confirmOptionVoid.selected = true;
      };
      this.dm_open = () => {
        confirmDialog.showModal();
        initObj();
        options = this.add_dm_options(confirmTitle, ksDt.read_fmt_hts(), all_tid_dt.unfmt_host(data_key));
      };
      let optionHt;
      let options = null;
      confirmTitle.addEventListener("change", () => {
        const {
          selectedOptions
        } = confirmTitle;
        if (selectedOptions.length === 0) return errorOut("异常程式-无选择");else if (selectedOptions.length > 1) return errorOut("异常程式-多重选择");
        const selectedOption = selectedOptions[0];
        const optionHt2 = selectedOption.value;
        const importedData = new DataTmp(ksDt.fmt_key(optionHt2), black_flag).dump();
        const importedBanData = new DataTmp(ksBanDt.fmt_key(optionHt2), black_flag).dump();
        const i10 = importedData.length === 0;
        const i20 = importedBanData.length === 0;
        if (i10 && i20) return errorOut("网站数据为空");
        const fails = this.dts_exp_fail(importedData);
        if (fails.length !== 0) return errorOut("↑↑↑❌浏览数据加载出错❌↑↑↑", importedData.join(black_flag));
        const failBans = this.dts_exp_fail(importedBanData);
        if (failBans.length !== 0) return errorOut("↑↑↑❌封禁数据加载出错❌↑↑↑", importedBanData.join(black_flag));
        optionHt = optionHt2;
        if (i10) return infoOut(`封禁数据:\n${importedBanData.join(black_flag)}`);
        if (i20) return infoOut(`浏览数据:\n${importedData.join(black_flag)}`);
        return infoOut(`浏览数据:\n${importedData.join(black_flag)}\n${`${'-'.repeat(10)}\n`.repeat(3)}封禁数据:\n${importedBanData.join(black_flag)}`);
      });
      confirmSubmit.addEventListener("click", () => {
        if (confirmDialog.dataset?.state !== "succeed") return;
        if (optionHt === null) return;
        const data_key2 = ksDt.fmt_key(optionHt);
        const data_ban_key2 = ksBanDt.fmt_key(optionHt);
        const dump_key2 = new DataTmp(data_key2, black_flag).dump();
        const dump_ban_key2 = new DataTmp(data_ban_key2, black_flag).dump();
        if (dump_key2.length !== 0) new DataTmp(data_key, black_flag).load(dump_key2);
        if (dump_ban_key2.length !== 0) new DataTmp(data_ban_key, black_flag).load(dump_ban_key2);
        ksDt.delete_key(data_key2);
        ksBanDt.delete_key(data_ban_key2);
        initObj();
        confirmDialog.close();
      });
      confirmClose.addEventListener("click", () => {
        if (confirmDialog === null) return;
        initObj();
        confirmDialog.close();
      });
      confirmTitle.appendChild(confirmOptionVoid);
      confirmDialog.appendChild(confirmTitle);
      confirmDialog.appendChild(confirmContent);
      confirmDialog.appendChild(confirmError);
      confirmDialog.appendChild(confirmSubmit);
      confirmDialog.appendChild(confirmClose);
      document.body.appendChild(confirmDialog);
    }
    static optimize_sorted_base(ksDt, black_flag) {
      const keys = ksDt.read_keys();
      for (const key of keys) {
        let dt = new DataTmp(key, black_flag);
        dt.optimize_sorted();
        dt = null;
      }
    }
    static ex_dbpack_start(k, black_flag) {
      return `${k}${black_flag.repeat(2)}>>${k}>>>${black_flag.repeat(2)}`;
    }
    static ex_dbpack_end(k, black_flag) {
      return `${black_flag.repeat(2)}<<${k}<<<${black_flag.repeat(2)}`;
    }
    static ex_dbpack_split(black_flag) {
      return `${black_flag.repeat(2)}<>><><${black_flag.repeat(2)}`;
    }
    static allowKeyCore = "core";
    static allowKeyBan = "ban";
    static allowKeys = [this.allowKeyCore, this.allowKeyBan];
    static im_dbpack(dbpack, keys, black_flag) {
      const dbpacks = dbpack.split(this.ex_dbpack_split(black_flag));
      const eobj = {};
      for (const dbpack of dbpacks) {
        const [k] = dbpack.split(black_flag, 1);
        if (k in eobj) throw new Error("数据key值重复");
        if (!keys.includes(k)) throw new Error(`${k}[k]不属于keys: ${JSON.stringify(keys)}`);
        const dbpack_start = this.ex_dbpack_start(k, black_flag);
        if (!dbpack.startsWith(dbpack_start)) throw new Error(`${dbpack_start}这个头部数据未能匹配到这个数据:${dbpack}`);
        const dbpack_end = this.ex_dbpack_end(k, black_flag);
        if (!dbpack.endsWith(dbpack_end)) throw new Error(`${dbpack_end}这个尾部数据未能匹配到这个数据:${dbpack}`);
        eobj[k] = dbpack.substring(dbpack_start.length, dbpack.length - dbpack_end.length);
      }
      return eobj;
    }
    static ex_dbpack(mp, black_flag) {
      return mp.map(_ref => {
        let [k, v] = _ref;
        return `${this.ex_dbpack_start(k, black_flag)}${v}${this.ex_dbpack_end(k, black_flag)}`;
      }).join(this.ex_dbpack_split(black_flag));
    }
    static im(data_key, data_ban_key, black_flag) {
      if (!this.im_init) {
        this.im_init = true;
        if (!this.dm_init) this.load_im_dm_style();
        this.load_im_element(data_key, data_ban_key, black_flag);
      }
      this.im_open?.();
    }
    static ex(data_key, data_ban_key, black_flag) {
      const dbpack = this.ex_dbpack([[this.allowKeyCore, new DataTmp(data_key, black_flag).dumps()], [this.allowKeyBan, new DataTmp(data_ban_key, black_flag).dumps()]], black_flag);
      if (dbpack === "") {
        alert("写入剪贴板失败: tid数据为空");
      } else {
        try {
          GM_setClipboard(dbpack);
          alert("写入剪贴板成功!");
        } catch (error) {
          alert("写入剪贴板失败: " + error);
        }
      }
    }
    static data_migration(ksDt, ksBanDt, data_key, data_ban_key, black_flag) {
      if (!this.dm_init) {
        this.dm_init = true;
        if (!this.im_init) this.load_im_dm_style();
        this.load_dm_element(ksDt, ksBanDt, data_key, data_ban_key, black_flag);
      }
      this.dm_open?.();
    }
    static optimize_sorted(ksDt, ksBanDt, black_flag) {
      this.optimize_sorted_base(ksDt, black_flag);
      this.optimize_sorted_base(ksBanDt, black_flag);
    }
  }
  class KeysDt {
    mkey;
    constructor(mkey) {
      this.mkey = `#${mkey}`;
    }
    unfmt_host(key) {
      return key.substring(0, key.length - this.mkey.length);
    }
    fmt_key(host) {
      return `${host}${this.mkey}`;
    }
    check_key(key) {
      return key.endsWith(this.mkey);
    }
    delete_key(key) {
      this.check_key(key) ? GM_deleteValue(key) : undefined;
    }
    read_keys() {
      return GM_listValues().filter(key => this.check_key(key));
    }
    read_fmt_hts() {
      return this.read_keys().map(key => this.unfmt_host(key));
    }
  }
  function rCodeE(rCode) {
    let min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 4;
    let max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 6;
    const rcl = rCode.length;
    const rl = Math.floor(Math.random() * (max - min + 1)) + min;
    return new Array(rl).fill("").map(() => rCode[Math.floor(Math.random() * rcl)]).join("");
  }
  function reset_gmdata(key, handle) {
    const rf = rCodeE(".0123456789");
    let userInput = prompt(`您正在进行一个危险的操作[${handle}],请输入这段字符串=> ${rf} <=以确保该操作是由您本人的发动的!`);
    if (userInput === null) {
      alert("❌操作已取消。❌");
    } else if (userInput === rf) {
      alert(`✔️输入正确,请确认此消息(Enter),操作[${handle}]将会运行。✔️`);
      GM_deleteValue(key);
    } else {
      alert("❌输入错误,操作已取消。❌");
    }
  }
  const all_tid_dt = new KeysDt("tid_datas");
  const all_tid_ban_dt = new KeysDt("tid_ban_datas");
  const tid_tmp_key = all_tid_dt.fmt_key(window.location.host);
  const tid_ban_tmp_key = all_tid_ban_dt.fmt_key(window.location.host);
  const tid_split = "|";
  GM_registerMenuCommand("重置tid浏览数据", () => reset_gmdata(tid_tmp_key, "重置tid浏览数据"));
  GM_registerMenuCommand("重置tid封禁数据", () => reset_gmdata(tid_ban_tmp_key, "重置tid封禁数据"));
  GM_registerMenuCommand("导出tid数据到剪切板", () => ImExData.ex(tid_tmp_key, tid_ban_tmp_key, tid_split));
  GM_registerMenuCommand("导入tid数据从剪切板", () => ImExData.im(tid_tmp_key, tid_ban_tmp_key, tid_split));
  GM_registerMenuCommand("迁移tid数据从缓存中", () => ImExData.data_migration(all_tid_dt, all_tid_ban_dt, tid_tmp_key, tid_ban_tmp_key, tid_split));
  GM_registerMenuCommand("tid数据顺序优化", () => ImExData.optimize_sorted(all_tid_dt, all_tid_ban_dt, tid_split));
  let ApplicationNames;
  (function (ApplicationNames) {
    ApplicationNames["soushuba"] = "\u641C\u4E66\u5427";
    ApplicationNames["sxsy"] = "\u5C1A\u9999\u4E66\u82D1";
  })(ApplicationNames || (ApplicationNames = {}));
  function getApplicationName() {
    const applicationNameMeta = document.querySelector('meta[name="application-name"]');
    if (applicationNameMeta === null) return null;
    let applicationName = applicationNameMeta.getAttribute('content');
    if (applicationName === null) return null;
    applicationName = applicationName.trim();
    const appName = Object.values(ApplicationNames).find(name => name === applicationName);
    return appName ? appName : null;
  }
  function load_tid_style() {
    const style = document.createElement("style");
    style.innerHTML = `
#threadlisttableid tr[data-fidxexist="hide"] { display: none; }

#delform tr[data-banstate="init"][data-fidxexist="exist"]:hover td,
#delform tr[data-banstate="init"][data-fidxexist="exist"]:hover th,
#threadlisttableid tr[data-banstate="init"][data-fidxexist="exist"]:hover td,
#threadlisttableid tr[data-banstate="init"][data-fidxexist="exist"]:hover th { background: #0096fa; }

#delform tr[data-banstate="init"][data-fidxexist="exist"] th > a,
#threadlisttableid tr[data-banstate="init"][data-fidxexist="exist"] a.s.xst,
#threadlist ul li[data-banstate="init"][data-fidxexist="exist"] h3 a { color: snow; background: #0096fa; }

#threadlist ul li[data-fidxexist="exist"] h3 a strong font { color: snow; background: red; }

#delform tr[data-banstate="init"] td.icn,
#delform tr[data-banstate="ban"],
#threadlisttableid tr[data-banstate="init"] td.icn,
#threadlisttableid tr[data-banstate="ban"],
#threadlist ul li[data-banstate="init"] h3 span.uv,
#threadlist ul li[data-banstate="ban"] { position: relative; }

#delform tr[data-banstate="init"] td.icn:after,
#delform tr[data-banstate="ban"]:after,
#threadlisttableid tr[data-banstate="init"] td.icn:after,
#threadlisttableid tr[data-banstate="ban"]:after,
#threadlist ul li[data-banstate="init"] h3 span.uv:after,
#threadlist ul li[data-banstate="ban"]:after {
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 65001;
  width: 100%;
  height: 100%;
  cursor: pointer;
  pointer-events: all;
}

#delform tr[data-banstate="init"] td.icn:after:active,
#threadlisttableid tr[data-banstate="init"] td.icn:after:active,
#threadlist ul li[data-banstate="init"] h3 span.uv:after:active {
  text-shadow: 2px 2px 6px black;
}

#delform tr[data-banstate="init"] td.icn:after,
#threadlisttableid tr[data-banstate="init"] td.icn:after,
#threadlist ul li[data-banstate="init"] h3 span.uv:after {
  content: "❌";
  background-color: #ffffff;
}
#delform tr[data-banstate="init"] td.icn:after,
#threadlisttableid tr[data-banstate="init"] td.icn:after {
  font-size: 1.5em;
}
#threadlist ul li[data-banstate="init"] h3 span.uv:after {
  font-size: 1.2em;
  top: 2.0em;
}
#delform tr[data-banstate="ban"] td.by,
#threadlisttableid tr[data-banstate="ban"] td.by { display: none; }
#delform tr[data-banstate="ban"]:after,
#threadlisttableid tr[data-banstate="ban"]:after,
#threadlist ul li[data-banstate="ban"]:after {
  content: "UI屏蔽中,点击解除屏蔽";
  background-color: rgba(255, 0, 0, 0.5);
  font-size: 2.0em;
  color: aliceblue;
  font-weight: bold;
  letter-spacing: 0.3em;
}
`;
    document.head.appendChild(style);
  }
  function load_replycoins_style() {
    const style = document.createElement("style");
    style.innerHTML = `
.post-btn-time {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.3em;
}
.post-btn-time .time-u30,
.post-btn-time .time-u45,
.post-btn-time .time-u60 {
  background: #0096fa;
}
.post-btn-time.run .time-u30,
.post-btn-time.run .time-u45,
.post-btn-time.run .time-u60 {
  background: red;
}
.post-btn-time.run.u30 .time-u30,
.post-btn-time.run.u45 .time-u30,
.post-btn-time.run.u45 .time-u45,
.post-btn-time.run.u60 .time-u30,
.post-btn-time.run.u60 .time-u45,
.post-btn-time.run.u60 .time-u60 {
  background: green;
}
.post-btn {
  font-size: 1.2em;
  font-weight: bold;
  background: #0096fa;
  color: azure;
  border: 0;
  border-radius: 0.3em;
  padding: 0.3em 0.6em;
  cursor: pointer;
}`;
    document.head.appendChild(style);
  }
  function keyJump() {
    function pageJump(className) {
      const elements = document.getElementsByClassName(className);
      if (elements.length === 0) return;
      const element = elements[0];
      if (!(element instanceof HTMLAnchorElement)) return;
      element.click();
    }
    document.body.addEventListener("keydown", _ref2 => {
      let {
        altKey,
        ctrlKey,
        key,
        shiftKey
      } = _ref2;
      if (!ctrlKey && !shiftKey && !altKey) {
        if (key === "ArrowLeft" || key === "a") {
          pageJump("prev");
        } else if (key === "ArrowRight" || key === "d") {
          pageJump("nxt");
        }
      }
    });
  }
  function keyJumpHome() {
    function pageJump(className) {
      const elements = document.getElementsByClassName(className);
      if (elements.length === 0) return;
      const element = elements[0];
      if (!(element instanceof HTMLAnchorElement)) return;
      element.click();
    }
    function pageJumpX(className) {
      const spanf = document.getElementsByClassName(className);
      if (spanf.length === 0) return;
      const span = spanf[0];
      if (!(span instanceof HTMLSpanElement)) return;
      const af = span.getElementsByTagName("a");
      if (af.length === 0) return;
      const a = af[0];
      a.click();
    }
    document.body.addEventListener("keydown", _ref3 => {
      let {
        altKey,
        ctrlKey,
        key,
        shiftKey
      } = _ref3;
      if (!ctrlKey && !shiftKey && !altKey) {
        if (key === "ArrowLeft" || key === "a") {
          pageJumpX("pgb");
        } else if (key === "ArrowRight" || key === "d") {
          pageJump("nxt");
        }
      }
    });
  }
  function newthread_mark_a4(element, tid_s10, dt, banDt) {
    const tid_i10 = parseInt(tid_s10, 10);
    if (isNaN(tid_i10) || !isFinite(tid_i10)) return;
    const tid_b64 = DecimalBase64To.decToB64(tid_i10);
    const dataset = element.dataset;
    dataset.tid = tid_b64;
    dataset.fidxexist = dt.exist(tid_b64) ? "exist" : "init";
    dataset.banstate = banDt.exist(tid_b64) ? "ban" : "init";
  }
  function newthread_mark_a3(element, a0, dt, banDt) {
    const {
      href
    } = a0;
    if (href.trim().length === 0) return;
    const m = href.match(tid_pattern_a2);
    if (m === null) return;
    const tid = DecimalBase64To.decToB64(parseInt(m[0], 10));
    const dataset = element.dataset;
    dataset.tid = tid;
    dataset.fidxexist = dt.exist(tid) ? "exist" : "init";
    dataset.banstate = banDt.exist(tid) ? "ban" : "init";
  }
  function target_find_a(target) {
    if (target === null) return null;
    if (!(target instanceof Element)) return null;
    if (target instanceof HTMLAnchorElement) return target;
    const a = target.closest("a");
    if (a === null) return undefined;
    return a;
  }
  function newthread_mark_forumdisplay(tbody, dt, banDt) {
    let soushuba_remove_guanggao = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
    const trf = tbody.getElementsByTagName("tr");
    if (trf.length === 0) return;
    const tr = trf[0];
    const thf = tr.getElementsByTagName("th");
    if (thf.length === 0) return;
    const th = thf[0];
    const af = th.getElementsByTagName("a");
    if (af.length === 0) return;
    const {
      id: cid
    } = af[0];
    if (cid.trim().length === 0) return;
    const m = cid.match(tid_from_id_pattern);
    if (m === null) {
      if (soushuba_remove_guanggao) {
        if (cid.match(tid_bad_from_id_pattern) === null) return;
        tr.dataset.fidxexist = "hide";
        return;
      } else {
        return;
      }
    }
    const tid_s10 = m.groups?.tid;
    if (tid_s10 === undefined) return;
    newthread_mark_a4(tr, tid_s10, dt, banDt);
  }
  function newthread_mark_home(tr, dt, banDt) {
    const icnf = tr.getElementsByClassName("icn");
    if (icnf.length === 0) return;
    const icn = icnf[0];
    if (!(icn instanceof HTMLTableCellElement)) return;
    const af = icn.getElementsByTagName("a");
    if (af.length === 0) return;
    const {
      href
    } = af[0];
    if (href.length === 0) return;
    const m = href.match(tid_from_url_pattern);
    if (m === null) return;
    const tid_s10 = m.groups?.tid;
    if (tid_s10 === undefined) return;
    newthread_mark_a4(tr, tid_s10, dt, banDt);
  }
  function newthread_mark_search(li, dt, banDt) {
    const h3f = li.getElementsByTagName("h3");
    if (h3f.length === 0) return;
    const h3 = h3f[0];
    const af = h3.getElementsByTagName("a");
    if (af.length === 0) return;
    const a0 = af[0];
    newthread_mark_a3(li, a0, dt, banDt);
    const span = document.createElement("span");
    span.className = "uv";
    h3.insertAdjacentElement("afterbegin", span);
  }
  function newthread_mark_listen_forumdisplay(xbody, dt, banDt) {
    let BUTTONS;
    (function (BUTTONS) {
      BUTTONS[BUTTONS["LEFT"] = 0] = "LEFT";
      BUTTONS[BUTTONS["CENTER"] = 1] = "CENTER";
    })(BUTTONS || (BUTTONS = {}));
    function click(xbody, target, button, dt, banDt) {
      let ex_handle = true;
      let ban_handle = true;
      const a = target_find_a(target);
      if (a === null) throw new Error("target不是标签HTMLElement的子集。");
      if (a === undefined) {
        if (button === BUTTONS.CENTER) {
          throw new Error("target父元素a未查询到 && target不是元素a。");
        } else {
          ex_handle = false;
        }
      } else {
        if (!xbody.contains(a)) throw new Error("xbody并不包含子元素a。");
      }
      const tr = target.closest("tr");
      if (tr === null) throw new Error("target父元素tr未查询到。");
      if (!xbody.contains(tr)) throw new Error("xbody并不包含子元素tr。");
      const dataset = tr.dataset;
      const tid = dataset?.tid;
      if (tid === undefined) throw new Error("元素tr的dataset的tid属性并不存在。");
      const banstate = dataset?.banstate;
      if (banstate === undefined) throw new Error("元素tr的dataset的banstate属性并不存在。");
      const fidxexist = dataset?.fidxexist;
      if (fidxexist === undefined) throw new Error("元素tr的dataset的fidxexist属性并不存在。");
      if (ex_handle) {
        const {
          href
        } = a;
        if (tid_find.test(href)) {
          dataset.fidxexist = "exist";
          dt.add_unsave(tid);
          return;
        }
      }
      if (ban_handle) {
        if (banstate === "init") {
          const td = target.closest("td");
          if (td === null) return;
          if (!td.classList.contains("icn")) return;
          if (isNaN(DecimalBase64To.b64ToDec(tid))) return;
          if (!banDt.exist(tid)) banDt.add_save(tid);
          dataset.banstate = "ban";
          return;
        } else if (banstate === "ban") {
          if (isNaN(DecimalBase64To.b64ToDec(tid))) return;
          if (banDt.exist(tid)) banDt.del_save(tid);
          dataset.banstate = "init";
          return;
        } else {
          throw new Error("程式错误。");
        }
      }
    }
    xbody.addEventListener("mousedown", _ref4 => {
      let {
        target,
        button
      } = _ref4;
      let fbutton;
      if (button === 0) {
        fbutton = BUTTONS.LEFT;
      } else if (button === 1) {
        fbutton = BUTTONS.CENTER;
      } else {
        return;
      }
      try {
        return click(xbody, target, fbutton, dt, banDt);
      } catch (err) {}
    });
  }
  function forumdisplay() {
    let soushuba_remove_guanggao = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    const dt = new DataTmp(tid_tmp_key, tid_split);
    dt.init();
    const banDt = new DataTmp(tid_ban_tmp_key, tid_split);
    banDt.init();
    load_tid_style();
    const threadlisttableid = document.getElementById("threadlisttableid");
    if (threadlisttableid === null) return;
    if (!(threadlisttableid instanceof HTMLTableElement)) return;
    const xbody = threadlisttableid;
    const tbodys = xbody.getElementsByTagName("tbody");
    for (const tbody of tbodys) {
      newthread_mark_forumdisplay(tbody, dt, banDt, soushuba_remove_guanggao);
    }
    newthread_mark_listen_forumdisplay(xbody, dt, banDt);
    const observer = new MutationObserver(function (mutations, observer) {
      for (const mutation of mutations) {
        if (mutation.type !== "childList") return;
        const {
          addedNodes
        } = mutation;
        if (addedNodes.length === 0) continue;
        for (const addedNode of addedNodes) {
          if (!(addedNode instanceof HTMLTableSectionElement)) continue;
          newthread_mark_forumdisplay(addedNode, dt, banDt);
        }
      }
    });
    const config = {
      attributes: false,
      characterData: false,
      childList: true,
      subtree: false
    };
    observer.observe(xbody, config);
  }
  function homephp() {
    const dt = new DataTmp(tid_tmp_key, tid_split);
    dt.init();
    const banDt = new DataTmp(tid_ban_tmp_key, tid_split);
    banDt.init();
    load_tid_style();
    const delform = document.getElementById("delform");
    if (delform === null) return;
    if (!(delform instanceof HTMLFormElement)) return;
    let tablef = delform.getElementsByTagName("table");
    if (tablef.length === 0) return;
    const table = tablef[0];
    let tbodyf = table.getElementsByTagName("tbody");
    if (tbodyf.length === 0) return;
    const tbody = tbodyf[0];
    const xbody = tbody;
    const trs = xbody.getElementsByTagName("tr");
    for (const tr of trs) {
      newthread_mark_home(tr, dt, banDt);
    }
    newthread_mark_listen_forumdisplay(xbody, dt, banDt);
  }
  function searchphp() {
    const dt = new DataTmp(tid_tmp_key, tid_split);
    dt.init();
    const banDt = new DataTmp(tid_ban_tmp_key, tid_split);
    banDt.init();
    load_tid_style();
    const threadlist = document.getElementById("threadlist");
    if (threadlist === null) return;
    if (!(threadlist instanceof HTMLDivElement)) return;
    const ulf = threadlist.getElementsByTagName("ul");
    if (ulf.length === 0) return;
    const ul = ulf[0];
    const xbody = ul;
    const lis = xbody.getElementsByTagName("li");
    for (const li of lis) {
      newthread_mark_search(li, dt, banDt);
    }
    function click_a(a) {
      const li = a.closest("li[data-banstate] h3");
      if (li === null) return "li error";
      const dataset = li.dataset;
      if (dataset?.fidxexist === undefined) return "li error";
      const tid = dataset?.tid;
      if (tid === undefined) return "li error";
      const href = a.href;
      if (!tid_find.test(href)) return "href is null";
      dataset.fidxexist = "exist";
      dt.add_unsave(tid);
      return "final";
    }
    function run_a(target) {
      const a = target_find_a(target);
      return a === null ? "element is null" : a === undefined ? "element unfind a" : click_a(a);
    }
    function run_ban(target, li) {
      const dataset = li.dataset;
      const banstate = dataset?.banstate;
      if (banstate === "init") {
        const span = target.closest("li[data-banstate] h3 span.uv");
        if (span === null) return;
        const tid = dataset?.tid;
        if (tid === undefined) return;
        if (isNaN(DecimalBase64To.b64ToDec(tid))) return;
        if (!banDt.exist(tid)) banDt.add_save(tid);
        dataset.banstate = "ban";
        return;
      } else if (banstate === "ban") {
        const tid = dataset?.tid;
        if (tid === undefined) return;
        if (isNaN(DecimalBase64To.b64ToDec(tid))) return;
        if (banDt.exist(tid)) banDt.del_save(tid);
        dataset.banstate = "init";
        return;
      }
    }
    xbody.addEventListener("mousedown", _ref5 => {
      let {
        target,
        button
      } = _ref5;
      if (button === 0) {
        const res1 = run_a(target);
        if (res1 === "final") return;
        if (res1 === "element is null") return;
        let li;
        if (res1 === "element unfind a") {
          li = target.closest("li[data-banstate]");
          if (li === null) return null;
        } else if (res1 === "li error") {
          return;
        } else if (res1 === "href is null") {
          li = target.closest("li[data-banstate]");
          if (li === null) return null;
        } else {
          return;
        }
        li.closest("li[data-banstate]");
        run_ban(target, li);
      } else if (button === 1) {
        run_a(target);
      }
    });
  }
  function viewthread(get_tid) {
    if (get_tid === null || get_tid === undefined) return;
    const tid_b10 = parseInt(get_tid, 10);
    if (isNaN(tid_b10) || !isFinite(tid_b10)) return;
    const tid_b64 = DecimalBase64To.decToB64(tid_b10);
    let dt = new DataTmp(tid_tmp_key, tid_split);
    dt.add_save(tid_b64);
    dt = null;
  }
  function viewthread_replycoins() {
    const fastpostsubmit = document.getElementById("fastpostsubmit");
    if (fastpostsubmit === null || !(fastpostsubmit instanceof HTMLButtonElement)) throw new Error("fastpostsubmit");
    const fastpostmessage = document.getElementById("fastpostmessage");
    if (fastpostmessage === null || !(fastpostmessage instanceof HTMLTextAreaElement)) throw new Error("fastpostmessage");
    const pgses = document.getElementsByClassName("pgs");
    if (pgses.length !== 2) throw new Error("pgs");
    const pgs1 = pgses[0];
    if (!(pgs1 instanceof HTMLDivElement)) throw new Error("pgs1");
    const pgs2 = pgses[1];
    if (!(pgs2 instanceof HTMLDivElement)) throw new Error("pgs2");
    load_replycoins_style();
    function initElement(top) {
      const div = document.createElement("div");
      const pbtn = document.createElement("button");
      const timer = document.createElement("span");
      const time = document.createElement("span");
      const time30u = document.createElement("span");
      const time45u = document.createElement("span");
      const time60u = document.createElement("span");
      pbtn.className = "post-btn";
      pbtn.innerHTML = "快速回复(CTRL+D)";
      timer.className = "post-btn-timer";
      timer.innerHTML = "时间(s): ";
      time.className = "post-btn-time";
      time.innerHTML = "未启动";
      time30u.className = "time-u30";
      time30u.innerHTML = "30s↑";
      time45u.className = "time-u45";
      time45u.innerHTML = "45s↑";
      time60u.className = "time-u60";
      time60u.innerHTML = "60s↑";
      div.className = "post-btn-time";
      div.appendChild(pbtn);
      div.appendChild(timer);
      div.appendChild(time);
      div.appendChild(time30u);
      div.appendChild(time45u);
      div.appendChild(time60u);
      top.appendChild(div);
      function run() {
        const {
          classList
        } = div;
        if (classList.contains("run")) {
          if (classList.contains("u30")) {
            classList.remove("u30");
          } else if (classList.contains("u45")) {
            classList.remove("u45");
          } else if (classList.contains("u60")) {
            classList.remove("u60");
          }
        } else {
          classList.add("run");
        }
      }
      function update(s) {
        time.innerHTML = s.toString(10);
        if (s === 30) {
          div.classList.add("u30");
        } else if (s === 45) {
          div.classList.remove("u30");
          div.classList.add("u45");
        } else if (s === 60) {
          div.classList.remove("u45");
          div.classList.add("u60");
        }
      }
      return [pbtn, update, run];
    }
    const [pbtn1, update1, run1] = initElement(pgs1);
    const [pbtn2, update2, run2] = initElement(pgs2);
    function choice() {
      for (var _len = arguments.length, array = new Array(_len), _key = 0; _key < _len; _key++) {
        array[_key] = arguments[_key];
      }
      const randomIndex = Math.floor(Math.random() * array.length);
      return array[randomIndex];
    }
    function linkc() {
      for (var _len2 = arguments.length, array = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        array[_key2] = arguments[_key2];
      }
      return array.join("");
    }
    const values = [() => linkc(choice("👍🏻", "👍", "⭐️", "(* ̄▽ ̄)b", ""), choice("感谢", "谢谢"), choice("👍🏻", "👍", "⭐️", "(* ̄▽ ̄)b", ""), choice("楼主", "lz", "大佬", "dl"), choice(linkc(choice("的", ""), "分享"), linkc("分享", choice("的", ""), choice("帖子", "文件", "书"))), choice("👍🏻", "👍", "⭐️", "(* ̄▽ ̄)b", "  !  !  !", ""))];
    function postdata(fastpostmessage, fastpostsubmit) {
      fastpostmessage.value = choice(...values)();
      fastpostsubmit.click();
      startTimeCount();
    }
    window.addEventListener("keypress", ev => {
      const {
        key,
        ctrlKey,
        shiftKey,
        altKey
      } = ev;
      if (ctrlKey && !shiftKey && !altKey) {
        if (key === "d") {
          ev.preventDefault();
          ev.stopPropagation();
        }
      }
    });
    window.addEventListener("keydown", ev => {
      const {
        key,
        ctrlKey,
        shiftKey,
        altKey
      } = ev;
      if (ctrlKey && !shiftKey && !altKey) {
        if (key === "d") {
          postdata(fastpostmessage, fastpostsubmit);
          ev.preventDefault();
          ev.stopPropagation();
        }
      }
    });
    pbtn1.addEventListener("click", () => {
      postdata(fastpostmessage, fastpostsubmit);
    });
    pbtn2.addEventListener("click", () => {
      postdata(fastpostmessage, fastpostsubmit);
    });
    let timer;
    function startTimeCount() {
      if (timer !== undefined) {
        clearInterval(timer);
        timer = undefined;
      }
      let countdownTime = 0;
      run1();
      run2();
      const updateCountdown = () => {
        countdownTime++;
        update1(countdownTime);
        update2(countdownTime);
      };
      timer = setInterval(updateCountdown, 1000);
    }
  }
  const {
    pathname: pn,
    search
  } = window.location;
  const tid_pattern_a2 = /(?<=(?:^|\/)thread-)[1-9]\d*(?=-[1-9]\d*-[1-9]\d*[.]html)|(?<=[?&]tid=)[1-9]\d*(?=&|$)/;
  const tid_from_url_pattern = /[?&]tid=(?<tid>[1-9]\d*)(?:&|$)/;
  const tid_from_id_pattern = /^content_(?<tid>[1-9]\d*)$/;
  const tid_bad_from_id_pattern = /^content_adver&aid=[1-9]\d*$/;
  const tid_find = /(^|\/)thread-[1-9]\d*-[1-9]\d*-[1-9]\d*[.]html|[?&]tid=[1-9]\d*(&|$)/;
  if (pn === "/forum.php") {
    const urlSearch = new URLSearchParams(search);
    const mod = urlSearch.get("mod");
    if (mod === null) {
      return;
    } else if (mod === "viewthread") {
      const applicationName = getApplicationName();
      if (applicationName === ApplicationNames.soushuba || applicationName === ApplicationNames.sxsy) {
        const get_tid = urlSearch.get("tid");
        viewthread(get_tid);
        viewthread_replycoins();
      }
    } else if (mod === "forumdisplay") {
      const applicationName = getApplicationName();
      if (applicationName === ApplicationNames.soushuba) {
        forumdisplay(true);
        keyJump();
      } else if (applicationName === ApplicationNames.sxsy) {
        forumdisplay();
        keyJump();
      }
    }
  } else if (pn === "/search.php") {
    const urlSearch = new URLSearchParams(search);
    const mod = urlSearch.get("mod");
    if (mod === null) {
      return;
    } else if (mod === "forum") {
      searchphp();
      keyJump();
    }
  } else if (pn === "/home.php") {
    const urlSearch = new URLSearchParams(search);
    const mod = urlSearch.get("mod");
    if (mod === null) {
      return;
    } else if (mod === "space") {
      const do_ = urlSearch.get("do");
      if (do_ === null) return;
      const uid = urlSearch.get("uid");
      if (uid === null) return;
      homephp();
      keyJumpHome();
    }
  }
})();