评论历史记录与评论收藏(哔哩哔哩|B站|bilibili)

使用历史列表记录发送过的评论, 可收藏评论, 双击可跳转到评论来源页面. 可自定义发送评论的快捷键 (默认为 Ctrl + Enter)

目前為 2023-11-24 提交的版本,檢視 最新版本

// ==UserScript==
// @name          评论历史记录与评论收藏(哔哩哔哩|B站|bilibili)
// @namespace     https://gf.qytechs.cn/zh-CN/users/1196880-ling2ling4
// @version       2.0.3
// @author        Ling2Ling4
// @description   使用历史列表记录发送过的评论, 可收藏评论, 双击可跳转到评论来源页面. 可自定义发送评论的快捷键 (默认为 Ctrl + Enter)
// @license       AGPL-3.0-or-later
// @icon data:image/png;base64,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
// @match         *://*.bilibili.com/*
// @run-at        document-end
// @grant         GM_setValue
// @grant         GM_getValue
// @grant         GM_registerMenuCommand
// @compatible    chrome
// @compatible    edge
// @compatible    firefox
// ==/UserScript==

(() => {
  "use strict";
  function getBiliPageType(location) {
    const url = location.href;
    return ("www.bilibili.com" !== location.host &&
      "www.bilibili.com" !== location.hostname) ||
      "/" !== location.pathname
      ? url.includes("www.bilibili.com/video")
        ? "视频"
        : url.includes("space.bilibili.com")
        ? "主页"
        : url.includes("t.bilibili.com") ||
          url.includes("www.bilibili.com/opus")
        ? "动态"
        : url.includes("www.bilibili.com/read")
        ? "专栏"
        : url.includes("www.bilibili.com/bangumi")
        ? "番剧"
        : url.includes("live.bilibili.com")
        ? "直播"
        : url.includes("message.bilibili.com")
        ? "消息"
        : "其他"
      : "首页";
  }
  function addCss(cssText, box = document.body, id = "") {
    const style = document.createElement("style");
    return (
      id && (style.id = id),
      box.appendChild(style),
      (style.innerHTML = cssText),
      style
    );
  }
  const base_id = "ll_comment_history_",
    info = {
      pageType: "",
      base_id,
      cssId: base_id + "css",
      settings: {
        isHiddenBtn: {
          name: "是否隐藏按钮",
          value: !1,
          base: !1,
          key: base_id + "isHiddenBtn",
          txt: "是否隐藏评论列表的按钮 (隐藏后鼠标移入按钮区域后按钮会显示出来)\n默认: base\n当前: current",
        },
        position: {
          name: "显示位置",
          value: "4, 4",
          base: "4, 4",
          key: base_id + "position",
          txt: "设置按钮的显示位置 (按钮距左侧 和 顶部的距离), 可以为负值, 中间用 , 分隔\n如: 10,10 表示距离左侧10像素距离顶部10像素\n默认: base",
        },
        listSize: {
          name: "列表宽度与最大高度",
          value: "400, 500",
          base: "400, 500",
          key: base_id + "listSize",
          txt: "设置列表的宽度与列表的最大高度, 中间用 , 分隔\n如: 400,300 表示列表宽度400像素, 列表最大高度300像素\n默认: base",
        },
        scale: {
          name: "缩放倍率",
          value: 1,
          base: 1,
          key: base_id + "scale",
          txt: "设置缩放倍率, 默认: base",
        },
        listMaxLen: {
          name: "列表最大长度",
          value: 200,
          base: 200,
          key: base_id + "listMaxLen",
          txt: "设置历史列表的最大长度, 超出时最早的数据会被删除, 默认: base",
        },
        sendKeys: {
          name: "评论快捷键",
          value: "ctrl+enter",
          base: "ctrl+enter",
          key: base_id + "sendKeys",
          txt: "设置发送消息时的快捷键, 每个键用 + 分隔, 特殊字符请用英文符号 (不支持shift+enter)\n例如: ctrl + enter, 表示按下ctrl和回车键发送消息\n可使用单个按键, 支持 ctrl shift alt win/meta 字母 数字 等的组合键\n默认: base",
        },
        addItemKeys: {
          name: "评论收藏的组合键",
          value: "ctrl",
          base: "ctrl",
          key: base_id + "addItemKeys",
          txt: "设置评论加入评论收藏的组合键, 按下组合键后'双击'评论的文本可将文本添加到评论收藏的列表中, 仅支持 ctrl shift alt win/meta 的组合键\n默认: base",
        },
        isHiddenList: {
          name: "双击列表项后是否收起列表",
          value: !0,
          base: !0,
          key: base_id + "isHiddenList",
          txt: "是否在双击列表的一条评论记录后收起列表\n默认: base\n当前: current",
        },
      },
      history: {
        width: 30,
        height: 30,
        data: {
          saveName: base_id + "list",
          suki_info: { saveName: base_id + "sukiList", callback: {} },
          callback: {},
        },
        color: {
          main: "#addeee",
          bd: "#dfedfe",
          font: "#4f4f4f",
          h_font: "#75beff",
          listBtnObj: {
            bg: "#fff",
            bd: "",
            hover: "#75b3ff",
            hover_bg: "#fff",
            hover_bd: "",
            click: "#75b3ff",
            click_bg: "#fff",
            click_bd: "",
          },
        },
        doms: {
          box: { id: base_id + "box", title: "" },
          btn: { class: "btn", title: "评论记录列表" },
          options: { class: "options", title: "" },
          comment: {
            option: { text: "历史评论", class: "comment" },
            list: { class: "suki-comment" },
          },
          suki_comment: {
            option: { text: "评论收藏", class: "comment" },
            list: { class: "suki-comment" },
          },
        },
      },
      customKeys: {
        isBtnClickEvent: !0,
        curDoms: {},
        curClassList: {},
        classList: {
          focus: "focus",
          视频: {
            focusDom: "reply-box-textarea",
            box: "box-normal",
            textarea: "reply-box-textarea",
            sendBtn: "reply-box-send",
            reply: "reply-content",
            subReply: "reply-content",
            replyParent: "sub-reply-content",
            user: "user-name",
            subUser: "sub-user-name",
            replyUser: "user",
          },
          番剧: {
            focusDom: "reply-box-textarea",
            box: "box-normal",
            textarea: "reply-box-textarea",
            sendBtn: "reply-box-send",
            reply: "reply-content",
            subReply: "reply-content",
            replyParent: "sub-reply-content",
            user: "user-name",
            subUser: "sub-user-name",
            replyUser: "user",
          },
          主页: {
            focusDom: "reply-box-textarea",
            box: "box-normal",
            textarea: "reply-box-textarea",
            sendBtn: "reply-box-send",
            reply: "reply-content",
            subReply: "reply-content",
            replyParent: "sub-reply-content",
            user: "user-name",
            subUser: "sub-user-name",
            replyUser: "user",
          },
          动态: {
            focusDom: "reply-box-textarea",
            box: "box-normal",
            textarea: "reply-box-textarea",
            sendBtn: "reply-box-send",
            reply: "reply-content",
            subReply: "reply-content",
            replyParent: "sub-reply-content",
            user: "user-name",
            subUser: "sub-user-name",
            replyUser: "user",
          },
          专栏: {
            focusDom: "textarea-container",
            box: "textarea-container",
            textarea: "ipt-txt",
            sendBtn: "comment-submit",
            reply: "text",
            subReply: "text-con",
            replyParent: "user",
            user: "name",
            subUser: "name",
            replyUser: { type: "dataset", value: "usercardMid" },
          },
          消息: {
            focusDom: "",
            box: "reply-box",
            textarea: "reply-textarea",
            sendBtn: "send-button",
          },
        },
      },
    };
  function getValue({
    base = null,
    key,
    valType = "string",
    isReSet = !0,
    getVal,
    setVal,
  } = {}) {
    let val = getVal ? getVal(key) : localStorage.getItem(key);
    return (
      null !== base &&
        null == val &&
        ((val = base),
        isReSet &&
          (setVal ? setVal(key, val) : localStorage.setItem(key, val))),
      "string" === valType
        ? val
        : "boolean" === valType || "number" === valType
        ? JSON.parse(val)
        : "object" === valType
        ? JSON.parse(val || {})
        : "array" === valType
        ? JSON.parse(val || [])
        : val
    );
  }
  const settings = info.settings;
  const curInfo = info.history,
    doms = curInfo.doms,
    css_settings = info.settings;
  function boolTxt(val) {
    return val ? "是 (确定)" : "否 (取消)";
  }
  function setIsItem({
    txt,
    base,
    key,
    isChangeTxt = !0,
    isTxtVal = !0,
    getValue = null,
    setValue = null,
  } = {}) {
    let val = JSON.parse(getValue ? getValue(key) : localStorage.getItem(key));
    null == val &&
      ((val = base),
      setValue ? setValue(key, val) : localStorage.setItem(key, val)),
      isChangeTxt &&
        (txt = isTxtVal
          ? txt.replace("base", boolTxt(base)).replace("current", boolTxt(val))
          : txt.replace("base", base).replace("current", val));
    const newVal = confirm(txt);
    return (
      newVal !== val &&
      (setValue ? setValue(key, newVal) : localStorage.setItem(key, newVal), !0)
    );
  }
  function setTextItem({
    txt,
    base,
    key,
    isChangeTxt = !0,
    verification = null,
    getValue = null,
    setValue = null,
  } = {}) {
    let val = getValue ? getValue(key) : localStorage.getItem(key);
    null == val &&
      ((val = base),
      setValue ? setValue(key, base) : localStorage.setItem(key, base)),
      isChangeTxt && (txt = txt.replace("base", base).replace("current", val));
    let newVal = prompt(txt, val);
    return (
      null !== newVal &&
      (!verification ||
        ((newVal = verification(newVal, val)), null !== newVal)) &&
      newVal !== val &&
      (setValue ? setValue(key, newVal) : localStorage.setItem(key, newVal), !0)
    );
  }
  const registerMenu_settings = info.settings;
  function formatDate({
    timestamp,
    isYear = !0,
    isExact = !1,
    delimiter = ".",
    midDelimiter = " ",
    delimiter2 = ":",
  } = {}) {
    if (!timestamp) return -1;
    const date = new Date(timestamp),
      year = isYear ? date.getFullYear() : "",
      month = (date.getMonth() + 1).toString().padStart(2, "0"),
      day = date.getDate().toString().padStart(2, "0");
    let leftTime;
    leftTime =
      3 === delimiter.length
        ? `${isYear ? year + delimiter[0] : ""}${month}${delimiter[1]}${day}${
            delimiter[2]
          }`
        : `${isYear ? year + delimiter : ""}${month}${delimiter}${day}`;
    let rigthTime = "";
    if (isExact) {
      const hour = date.getHours().toString().padStart(2, "0"),
        minute = date.getMinutes().toString().padStart(2, "0"),
        second = date.getSeconds().toString().padStart(2, "0");
      rigthTime =
        3 === delimiter2.length
          ? `${midDelimiter}${hour}${delimiter2[0]}${minute}${delimiter2[1]}${second}${delimiter2[2]}`
          : `${midDelimiter}${hour}${delimiter2}${minute}${delimiter2}${second}`;
    }
    return leftTime + rigthTime;
  }
  let searchBox,
    searchEndTimerId,
    msgBox,
    msgDom,
    msgId,
    useOne,
    msgZIndex,
    msgTimerId,
    msgEndTimerId,
    message_msgBox,
    message_msgDom,
    message_msgId,
    message_useOne,
    message_msgZIndex,
    message_msgTimerId,
    message_msgEndTimerId;
  function createSearch({
    id = "history-search-box",
    box = document.body,
    title = "以'标题='开头表示按标题搜索, '内容='表示按内容搜索, '描述='表示按描述搜索, '日期='表示按日期搜索",
    width = 200,
    height = 30,
    color = "#333",
    bg = "#fff",
    fontSize = 13,
    bd = "1px solid #aaa",
    hover_bdColor = "#cee4ff",
    pd = "0 8px",
    radius = 5,
    transition = 0.5,
    btnText = "搜索",
    btn_class = "",
    btn_fontSize = 13,
    btn_color = "#65aaff",
    btn_bg = "#dfedfe",
    btn_bd = "1px solid #dfedfe",
    btn_pd = "0 10px",
    btn_radius = 6,
    btn_hover = "#65aaff",
    btn_hover_bg = "#cee4ff",
    btn_hover_bd = "1px solid #dfedfe",
    zIndex = 901,
    placeholder = "请输入搜索的内容",
    isBtn = !0,
    isAutoSearch = !0,
    interval = 500,
  } = {}) {
    const ele = document.createElement("div");
    (ele.id = id),
      (ele.isAutoSearch = isAutoSearch),
      (ele.interval = interval),
      (ele.transition = transition),
      (ele.style.cssText = `display: flex;\nopacity: 0;\nposition: absolute;\nleft: -2000px;\ntop: 0;\nz-index: ${zIndex};\ntransition: opacity ${transition}s`);
    const text_css = `width: ${width}px;\nheight: ${height}px;\nline-height: ${height}px;\ncolor: ${color};\nborder: ${bd};\npadding: ${pd};\nborder-radius: ${radius}px;\noutline: ${hover_bdColor};\nbox-sizing: border-box;`;
    ele.innerHTML = `<input class="search-text ll-scroll-style-1" style="${text_css}"></input>${
      isBtn ? "<div class='search-btn'></div>" : ""
    }`;
    const textEle = ele.querySelector(".search-text");
    (ele.title = title),
      (ele.textEle = textEle),
      (textEle.placeholder = placeholder),
      (textEle.style.fontSize = fontSize + "px"),
      (textEle.style.background = bg),
      (textEle.style.fontFamily = "math");
    const btnEle = ele.querySelector(".search-btn");
    return (
      btnEle &&
        ((btnEle.style.cssText = `height: ${height}px;\nline-height: ${height}px;\nfont-size: ${btn_fontSize}px;\ncolor: ${btn_color};\nbackground: ${btn_bg};\nborder: ${btn_bd};\npadding: ${btn_pd};\nborder-radius: ${btn_radius}px;\nbox-sizing: border-box;\nwhite-space: nowrap;\nfont-family: math;\ncursor:pointer;`),
        (btnEle.className += " " + btn_class),
        (btnEle.innerHTML = btnText),
        (btnEle.style.fontSize = btn_fontSize),
        (btnEle.style.color = btn_color),
        (btnEle.style.fontSize = fontSize + "px"),
        (ele.btnEle = btnEle),
        btnEle.addEventListener("mouseenter", () => {
          (btnEle.style.color = btn_hover),
            (btnEle.style.background = btn_hover_bg),
            (btnEle.style.border = btn_hover_bd);
        }),
        btnEle.addEventListener("mouseleave", () => {
          (btnEle.style.color = btn_color),
            (btnEle.style.background = btn_bg),
            (btnEle.style.border = btn_bd);
        })),
      box.appendChild(ele),
      (function bindSearchEvents(ele) {
        const inputEle = ele.textEle,
          searchBtn = ele.btnEle;
        let timerId;
        searchBtn.addEventListener("click", () => {
          searchEle();
        }),
          inputEle.addEventListener("keydown", (e) => {
            (13 !== e.keyCode && "enter" !== e.key.toLowerCase()) ||
              0 == +ele.style.opacity ||
              searchEle();
          }),
          inputEle.addEventListener("input", () => {
            ele.isAutoSearch &&
              (clearTimeout(timerId),
              (timerId = setTimeout(() => {
                searchEle();
              }, ele.interval)));
          });
      })(ele),
      (searchBox = ele),
      ele
    );
  }
  function showSearchBox(isShow = !0, originEle = null) {
    const ele = searchBox;
    if (isShow) {
      let left, top, scrollTop;
      if ((clearTimeout(searchEndTimerId), originEle)) {
        const rect = originEle.getBoundingClientRect();
        (left = rect.left),
          (top = rect.top),
          (scrollTop = document.documentElement.scrollTop);
      }
      const h = parseInt(ele.textEle.style.height);
      left && top
        ? ((ele.style.left = left + "px"),
          (ele.style.top = top + scrollTop - h - 12 + "px"))
        : ((ele.style.left = ""),
          (ele.style.right = "12px"),
          (ele.style.top = "12px")),
        (ele.style.opacity = 1);
    } else
      (ele.style.opacity = 0),
        clearTimeout(searchEndTimerId),
        (searchEndTimerId = setTimeout(() => {
          ele.style.left = "-2000px";
        }, 1e3 * ele.transition)),
        hidcenEle(ele.listEle, "");
  }
  function hidcenEle(listEle, text, searchType = "标题") {
    if (!listEle) return;
    "时间" === searchType && (searchType = "日期"),
      text && console.log("搜索" + searchType + ": " + text);
    const liArr = listEle.querySelectorAll(".item-box"),
      len = liArr.length;
    for (let i = 0; i < len; i++) {
      const item = liArr[i];
      text
        ? ("标题" === searchType &&
            item.querySelector(".item-tt").innerText.includes(text)) ||
          ("描述" === searchType &&
            item.querySelector(".item-tt").title.includes(text)) ||
          ("内容" === searchType &&
            item.querySelector(".hItem").innerText.includes(text)) ||
          ("日期" === searchType &&
            item.querySelector(".item-control").title.includes(text))
          ? (item.style.display = "block")
          : (item.style.display = "none")
        : (item.style.display = "block");
    }
  }
  function searchEle() {
    const textEle = searchBox.textEle,
      listEle = searchBox.listEle;
    if (!listEle) return;
    let text = textEle.value,
      searchType = text.slice(0, 3);
    ["标题=", "描述=", "内容=", "日期=", "时间="].includes(searchType)
      ? ((searchType = searchType.slice(0, 2)),
        (text = text.slice(3, text.length)))
      : (searchType = textEle.searchType ? textEle.searchType : "标题"),
      hidcenEle(listEle, text, searchType);
  }
  function message({
    ele,
    title = "",
    content = "",
    msg = "",
    color,
    fontSize,
    tt_color,
    tt_fontSize,
    bg,
    bd,
    pd,
    radius,
    time = "auto",
    disTime = 0,
    postion = "right-top",
    fn,
  } = {}) {
    useOne && (msgDom = null),
      ele ||
        (ele = msgDom) ||
        (msgId &&
          !useOne &&
          (ele = msgDom = document.querySelector("#" + msgId)),
        ele ||
          (ele = msgDom =
            (function createMsg({
              id = "ll-autoCloseMsg",
              box = document.body,
              isUseOne = !0,
              maxWidth = 224,
              color = "#666",
              fontSize = 14,
              tt_color = "#333",
              tt_fontSize = 16,
              bg = "#fff",
              bd = "2px solid #dfedfe",
              pd = "7px 12px",
              radius = 7,
              zIndex = 1100,
              transition = 0.8,
            } = {}) {
              const ele = document.createElement("div");
              (ele.id = id),
                (ele.className = id),
                (msgId = id),
                (ele.style.cssText = `max-width: ${maxWidth}px;\nbackground: ${bg};\nmargin-bottom: 10px;\nborder: ${bd};\npadding: ${pd};\nbox-sizing: border-box;\nborder-radius: ${radius}px;\nopacity: 0;\ntransition: opacity ${transition}s;\nletter-spacing: 1px;`),
                (ele.innerHTML =
                  '<div class="title" style="margin-bottom:5px;font-weight:bold;"></div><div class="msg"></div>'),
                (ele.transition = transition);
              const ttEle = ele.querySelector(".title");
              (ele.ttEle = ttEle),
                (ttEle.style.color = tt_color),
                (ttEle.style.fontSize = tt_fontSize + "px");
              const msgEle = ele.querySelector(".msg");
              return (
                (ele.msgEle = msgEle),
                (msgEle.style.color = color),
                (msgEle.style.fontSize = fontSize + "px"),
                (useOne = isUseOne),
                (ele.isUseOne = isUseOne),
                (msgDom = ele),
                msgBox ||
                  ((msgBox = document.createElement("div")),
                  (msgBox.style.cssText = `\ndisplay: flex;\nflex-direction: column;\nposition: fixed;\nleft: -2000px;\ntop: 0;\nz-index: ${
                    isUseOne ? msgZIndex : zIndex
                  };`),
                  box.appendChild(msgBox)),
                msgBox.appendChild(ele),
                ele
              );
            })())),
      (msg = content || msg);
    const msgEle = ele.msgEle;
    (msgEle.innerText = msg),
      bd && (ele.style.border = bd),
      pd && (ele.style.padding = pd),
      bg && (ele.style.background = bg),
      radius && (ele.style.borderRadius = radius + "px"),
      color && (msgEle.style.color = color),
      fontSize && (msgEle.style.fontSize = fontSize + "px"),
      (msgBox.style.left = "");
    const placeArr = postion.split(/-|_/);
    if (
      ((msgBox.style[placeArr[0]] = placeArr[0] ? "12px" : ""),
      (msgBox.style[placeArr[1]] = placeArr[1] ? "12px" : ""),
      title)
    ) {
      const ttEle = ele.ttEle;
      (ttEle.innerHTML = title),
        tt_color && (ttEle.style.color = tt_color),
        tt_fontSize && (ttEle.style.fontSize = tt_fontSize + "px");
    }
    "auto" === time
      ? (time = (function getShowTime(text) {
          return 410 * text.length + 1500;
        })(msg))
      : (time *= 1e3),
      (time += disTime),
      useOne || (clearTimeout(msgTimerId), clearTimeout(msgEndTimerId)),
      (ele.style.opacity = 1),
      (msgTimerId = setTimeout(() => {
        (ele.style.opacity = 0),
          (msgEndTimerId = setTimeout(() => {
            (msgBox.style.left = -ele.maxWidth - 100 + "px"),
              fn && fn(),
              useOne && ele.remove();
          }, 1e3 * ele.transition));
      }, time));
  }
  function message_message({
    ele,
    title = "",
    content = "",
    msg = "",
    color,
    fontSize,
    tt_color,
    tt_fontSize,
    bg,
    bd,
    pd,
    radius,
    time = "auto",
    disTime = 0,
    postion = "right-top",
    fn,
  } = {}) {
    message_useOne && (message_msgDom = null),
      ele ||
        (ele = message_msgDom) ||
        (message_msgId &&
          !message_useOne &&
          (ele = message_msgDom = document.querySelector("#" + message_msgId)),
        ele ||
          (ele = message_msgDom =
            (function message_createMsg({
              id = "ll-autoCloseMsg",
              box = document.body,
              isUseOne = !0,
              maxWidth = 224,
              color = "#666",
              fontSize = 14,
              tt_color = "#333",
              tt_fontSize = 16,
              bg = "#fff",
              bd = "2px solid #dfedfe",
              pd = "7px 12px",
              radius = 7,
              zIndex = 1100,
              transition = 0.8,
            } = {}) {
              const ele = document.createElement("div");
              (ele.id = id),
                (ele.className = id),
                (message_msgId = id),
                (ele.style.cssText = `max-width: ${maxWidth}px;\nbackground: ${bg};\nmargin-bottom: 10px;\nborder: ${bd};\npadding: ${pd};\nbox-sizing: border-box;\nborder-radius: ${radius}px;\nopacity: 0;\ntransition: opacity ${transition}s;\nletter-spacing: 1px;`),
                (ele.innerHTML =
                  '<div class="title" style="margin-bottom:5px;font-weight:bold;"></div><div class="msg"></div>'),
                (ele.transition = transition);
              const ttEle = ele.querySelector(".title");
              (ele.ttEle = ttEle),
                (ttEle.style.color = tt_color),
                (ttEle.style.fontSize = tt_fontSize + "px");
              const msgEle = ele.querySelector(".msg");
              return (
                (ele.msgEle = msgEle),
                (msgEle.style.color = color),
                (msgEle.style.fontSize = fontSize + "px"),
                (message_useOne = isUseOne),
                (ele.isUseOne = isUseOne),
                (message_msgDom = ele),
                message_msgBox ||
                  ((message_msgBox = document.createElement("div")),
                  (message_msgBox.style.cssText = `\ndisplay: flex;\nflex-direction: column;\nposition: fixed;\nleft: -2000px;\ntop: 0;\nz-index: ${
                    isUseOne ? message_msgZIndex : zIndex
                  };`),
                  box.appendChild(message_msgBox)),
                message_msgBox.appendChild(ele),
                ele
              );
            })())),
      (msg = content || msg);
    const msgEle = ele.msgEle;
    (msgEle.innerText = msg),
      bd && (ele.style.border = bd),
      pd && (ele.style.padding = pd),
      bg && (ele.style.background = bg),
      radius && (ele.style.borderRadius = radius + "px"),
      color && (msgEle.style.color = color),
      fontSize && (msgEle.style.fontSize = fontSize + "px"),
      (message_msgBox.style.left = "");
    const placeArr = postion.split(/-|_/);
    if (
      ((message_msgBox.style[placeArr[0]] = placeArr[0] ? "12px" : ""),
      (message_msgBox.style[placeArr[1]] = placeArr[1] ? "12px" : ""),
      title)
    ) {
      const ttEle = ele.ttEle;
      (ttEle.innerHTML = title),
        tt_color && (ttEle.style.color = tt_color),
        tt_fontSize && (ttEle.style.fontSize = tt_fontSize + "px");
    }
    "auto" === time
      ? (time = (function message_getShowTime(text) {
          return 410 * text.length + 1500;
        })(msg))
      : (time *= 1e3),
      (time += disTime),
      message_useOne ||
        (clearTimeout(message_msgTimerId), clearTimeout(message_msgEndTimerId)),
      (ele.style.opacity = 1),
      (message_msgTimerId = setTimeout(() => {
        (ele.style.opacity = 0),
          (message_msgEndTimerId = setTimeout(() => {
            (message_msgBox.style.left = -ele.maxWidth - 100 + "px"),
              fn && fn(),
              message_useOne && ele.remove();
          }, 1e3 * ele.transition));
      }, time));
  }
  function createEle({
    className = "",
    id = "",
    title = "",
    css,
    box = document.body,
    type = "div",
  } = {}) {
    const ele = document.createElement(type);
    return (
      id && (ele.id = id),
      className && (ele.className = className),
      title && (ele.title = title),
      css && (ele.style.cssText = css),
      box.appendChild(ele),
      ele
    );
  }
  const edit = {
      isEditing: !1,
      editText: {},
      eleList: {},
      callback: { confirmBefore: null, finished: null },
    },
    eleList = edit.eleList;
  function showEditArea(isShow = !0) {
    (edit.isEditing = isShow),
      (eleList.wrap.style.display = isShow ? "block" : "none");
  }
  function clearEditData() {
    (eleList.title.value = ""),
      (eleList.desc.value = ""),
      (eleList.value.value = "");
  }
  function changeShow(controlObj, isShow = "") {
    for (let key in controlObj) {
      const curStyle = controlObj[key].style;
      curStyle.display =
        "" === isShow
          ? "none" === curStyle.display
            ? "block"
            : "none"
          : isShow
          ? "block"
          : "none";
    }
  }
  function showItemControlEvent(control, info) {
    const listEle = info.listEle,
      moveBox = control.eleList.move_control;
    changeShow(control.move_eleList, !1),
      listEle.addEventListener("click", (e) => {
        const item = e.target;
        if (item.classList.contains("hItem")) {
          if (
            (item === listEle.curClickEle
              ? changeShow(control.move_eleList)
              : changeShow(control.move_eleList, !0),
            (moveBox.style.top =
              item.offsetTop - control.cfg.move_height - 3 + "px"),
            (listEle.oldClickEle = listEle.curClickEle),
            (listEle.curClickEle = item),
            (listEle.curId = item.id),
            control.info.move &&
              control.info.move.isMoving &&
              item !== listEle.oldClickEle)
          ) {
            const move = control.info.move;
            (!move.warnText || confirm(move.warnText)) &&
              (!(function moveItem({ info, ele, toEle, id, toId } = {}) {
                const listEle = info.listEle;
                !ele && id
                  ? (ele = listEle.querySelector(`[id='${id}'`))
                  : ele || id || (ele = listEle.oldClickEle);
                !toEle && toId
                  ? (toEle = listEle.querySelector(`[id='${id}'`))
                  : toEle || toId || (toEle = listEle.curClickEle);
                !id && (id = +ele.id), !toId && (toId = +toEle.id);
                const list_info = listEle.list_info,
                  newDataList = updateDataList(info),
                  dataList = info.dataList,
                  index = dataList.map((item) => +item.id).indexOf(id);
                if (-1 === index)
                  return (
                    console.log("操作失败, 当前项的数据可能在其他页面中已删除"),
                    void message({
                      title: "移动",
                      msg: info.listEle.list_info.errorSyncText,
                    })
                  );
                const data = dataList.splice(index, 1)[0];
                let toIndex = dataList.map((item) => +item.id).indexOf(toId);
                list_info.isAddUp && (toIndex += 1),
                  dataList.splice(toIndex, 0, data),
                  newDataList
                    ? initHisListDom(info)
                    : (listEle.insertBefore(
                        ele.parentElement,
                        toEle.parentElement
                      ),
                      resetNum(listEle));
                (ele = toEle = null),
                  list_info.setValue
                    ? list_info.setValue(
                        list_info.saveName,
                        JSON.stringify(dataList)
                      )
                    : localStorage.setItem(
                        list_info.saveName,
                        JSON.stringify(dataList)
                      );
              })({ info }),
              message({ title: move.text, msg: move.endText }),
              changeShow(control.move_eleList, !1)),
              (move.isMoving = !1);
          }
          if (
            control.info.changePlace &&
            control.info.changePlace.isChangePlaceing &&
            item !== listEle.oldClickEle
          ) {
            const changeP = control.info.changePlace;
            (!changeP.warnText || confirm(changeP.warnText)) &&
              (!(function changePlace({ info, ele, toEle, id, toId } = {}) {
                const listEle = info.listEle;
                !ele && id
                  ? (ele = listEle.querySelector(`[id='${id}'`))
                  : ele || (ele = listEle.oldClickEle);
                !toEle && toId
                  ? (toEle = listEle.querySelector(`[id='${id}'`))
                  : toEle || (toEle = listEle.curClickEle);
                if (
                  (!id && (id = +ele.id),
                  !toId && (toId = +toEle.id),
                  ele && toEle)
                ) {
                  const eleData = getItemData({ info, ele }),
                    toEleData = getItemData({ info, ele: toEle });
                  if (!eleData || !toEleData)
                    return void console.log("数据获取失败");
                  toEleData.id = 1234;
                  const changeInfo = updateItem({
                    info,
                    ele,
                    data: toEleData,
                    isSave: !1,
                  });
                  updateItem({ info, ele: toEle, data: eleData, isSave: !1 }),
                    (info.dataList[changeInfo.index].id = toId),
                    (changeInfo.ele.id = toId),
                    resetNum(listEle);
                  const list_info = listEle.list_info;
                  list_info.setValue
                    ? list_info.setValue(
                        list_info.saveName,
                        JSON.stringify(info.dataList)
                      )
                    : localStorage.setItem(
                        list_info.saveName,
                        JSON.stringify(info.dataList)
                      );
                }
              })({ info }),
              message({ title: move.text, msg: move.endText }),
              changeShow(control.move_eleList, !1)),
              (changeP.isChangePlaceing = !1);
          }
        }
        e.stopPropagation();
      });
  }
  function controlEvents(control, info, searchEle, editInfo) {
    if (!control) return;
    const listEle = info.listEle,
      control_info = control.info;
    if (
      (showItemControlEvent(control, info),
      control_info.add &&
        control_info.add.ele.addEventListener("click", (e) => {
          showEditArea(),
            (editInfo.msg = { noneText: control_info.add.noneText }),
            (editInfo.callback.finished = (data) => {
              addItem({
                title: data.title,
                desc: data.desc,
                value: data.value,
                info,
              }),
                message({
                  title: control_info.add.text,
                  msg: control_info.add.endText,
                });
            }),
            e.stopPropagation();
        }),
      control_info.clear &&
        control_info.clear.ele.addEventListener("click", (e) => {
          if (confirm(control_info.clear.warnText)) {
            confirm(control_info.clear.twoWarnText) &&
              (!(function clearList(info) {
                (info.listEle.innerHTML = ""),
                  (info.dataList = []),
                  bottomText(info);
                const list_info = info.listEle.list_info;
                list_info.setValue
                  ? list_info.setValue(list_info.saveName, "[]")
                  : localStorage.removeItem(list_info.saveName);
              })(info),
              changeShow(control.move_eleList, !1));
          }
          e.stopPropagation();
        }),
      control_info.search)
    ) {
      const search = control_info.search;
      (search.eleList = {}),
        search.ele.addEventListener("click", (e) => {
          let isShow = 0 == +searchEle.style.opacity;
          listEle !== searchEle.listEle && (isShow = !0),
            isShow && message({ title: search.text, msg: search.title }),
            (searchEle.textEle.value = ""),
            (searchEle.listEle = listEle),
            (searchEle.textEle.searchType = search.searchType),
            showSearchBox(isShow, search.ele),
            e.stopPropagation();
        });
      const inputEle = searchEle.textEle;
      searchEle.btnEle.addEventListener("click", () => {
        changeShow(control.move_eleList, !1);
      }),
        inputEle.addEventListener("keydown", (e) => {
          13 === e.keyCode &&
            0 != +searchEle.style.opacity &&
            changeShow(control.move_eleList, !1);
        }),
        inputEle.addEventListener("input", () => {
          searchEle.isAutoSearch && changeShow(control.move_eleList, !1);
        });
    }
    if (control_info.import) {
      const uploadFile = control_info.import;
      uploadFile.ele.addEventListener("click", (e) => {
        if (uploadFile.isUploading)
          return (
            message({ title: uploadFile.text, msg: uploadFile.uploadingText }),
            void console.log(uploadFile.uploadingText)
          );
        message({ title: uploadFile.text, msg: uploadFile.startTipText }),
          (function fileUpload_fileUpload({
            uploadObj,
            startTt = "上传",
            startText = "开始上传",
            endTt = "上传",
            endText = "上传完成",
            errorTt = "文件上传",
            errorMsg = "上传失败",
            startFn,
            finishFn,
            errorFn,
            timeoutFn,
          } = {}) {
            let input = document.createElement("input");
            (input.type = "file"),
              input.click(),
              input.addEventListener("change", (e) => {
                startText &&
                  message_message({ title: startTt, msg: startText });
                const fileObj = e.target.files[0],
                  reader = new FileReader();
                reader.readAsText(fileObj);
                const data = { info: fileObj, data: {} };
                (startFn && null === startFn(data)) ||
                  (uploadObj.timer && clearTimeout(uploadObj.timer),
                  (uploadObj.timer = setTimeout(() => {
                    uploadObj &&
                      uploadObj.isUploading &&
                      (timeoutFn && timeoutFn(),
                      message_message({
                        title: errorTt,
                        msg: "'" + fileObj.name + "'" + errorMsg,
                      }),
                      console.log("文件上传超时"));
                  }, 12e4)),
                  (reader.onload = function (readRes) {
                    try {
                      data.data = readRes.target.result;
                      const msg = "'" + fileObj.name + "'" + endText;
                      endText && message_message({ title: endTt, msg }),
                        console.log("上传成功: ", data.data),
                        finishFn && finishFn(data);
                    } catch (e) {
                      errorFn && errorFn(data),
                        message_message({
                          title: errorTt,
                          msg: "'" + fileObj.name + "'" + errorMsg,
                        });
                    } finally {
                      clearTimeout(uploadObj.timer);
                    }
                  }),
                  (reader.onerror = (e) => {
                    (data.data = e),
                      errorFn && errorFn(data),
                      message_message({
                        title: errorTt,
                        msg: "'" + fileObj.name + "'" + errorMsg,
                      }),
                      console.log(e),
                      clearTimeout(uploadObj.timer);
                  }));
              }),
              input.remove();
          })({
            uploadObj: uploadFile,
            startTt: uploadFile.text,
            startText: "开始上传",
            endTt: uploadFile.text,
            endText: "上传完成",
            errorTt: uploadFile.text,
            errorMsg: "数据导入失败",
            startFn: () => {
              uploadFile.isUploading = !0;
            },
            finishFn: (data) => {
              uploadFile.isUploading = !1;
              if (!confirm(uploadFile.submitText)) return;
              info.dataList = JSON.parse(data.data || null) || [];
              const list_info = listEle.list_info;
              list_info.setValue
                ? list_info.setValue(
                    list_info.saveName,
                    JSON.stringify(info.dataList)
                  )
                : localStorage.setItem(
                    list_info.saveName,
                    JSON.stringify(info.dataList)
                  ),
                initHisListDom(info),
                message({ title: uploadFile.text, msg: uploadFile.endText }),
                console.log(uploadFile.endText);
            },
            errorFn: () => {
              uploadFile.isUploading = !1;
            },
            timeoutFn: () => {
              uploadFile.isUploading = !1;
            },
          }),
          e.stopPropagation();
      });
    }
    if (control_info.out) {
      const outFile = control_info.out;
      outFile.ele.addEventListener("click", (e) => {
        let outName =
          listEle.list_info.outName || listEle.list_info.saveName || "dataList";
        outFile.isTime &&
          (outName =
            formatDate({
              timestamp: new Date().getTime(),
              isExact: !0,
              midDelimiter: "-",
              delimiter2: ".",
            }) +
            " " +
            outName);
        updateDataList(info) && initHisListDom(info),
          (function saveJson({
            data = "",
            fileName = "outData",
            type = "json",
          } = {}) {
            "string" != typeof data &&
              "json" === type &&
              (data = JSON.stringify(data));
            const blob = new Blob(
                [data],
                "json" === type
                  ? { type: "application/json" }
                  : { type: "text/plain" }
              ),
              href = URL.createObjectURL(blob),
              alink = document.createElement("a");
            (alink.style.display = "none"),
              (fileName += "." + type),
              (alink.download = fileName),
              (alink.href = href),
              document.body.appendChild(alink),
              alink.click(),
              document.body.removeChild(alink),
              URL.revokeObjectURL(href);
          })({ data: info.dataList, fileName: outName }),
          message({ title: outFile.text, msg: outFile.startText }),
          e.stopPropagation();
      });
    }
    if ((control_info.skip, control_info.fold)) {
      function setLineH(
        isFold = null,
        listEle = info.listEle,
        fold = control.info.fold
      ) {
        fold.ele.innerText = fold.isFold ? fold.noFoldText : fold.text;
        const textArr = listEle.querySelectorAll(".hItem"),
          len = textArr.length;
        let newH = fold.isFold ? fold.maxHeight : fold.oldMaxH;
        null !== isFold &&
          ((newH = isFold ? fold.maxHeight : fold.oldMaxH),
          (fold.isFold = isFold)),
          (listEle.list_info.liMaxHeight = newH),
          (newH += "px"),
          (listEle.display = "none");
        for (let i = 0; i < len; i++) {
          textArr[i].style.maxHeight = newH;
        }
        listEle.display = "block";
      }
      const fold = control_info.fold,
        list_info = listEle.list_info;
      let isFold;
      (fold.oldMaxH = list_info.liMaxHeight),
        (isFold = list_info.getValue
          ? list_info.getValue(listEle.list_info.list_id + "_" + fold.name)
          : localStorage.getItem(listEle.list_info.list_id + "_" + fold.name)),
        (fold.isFold = null != isFold && JSON.parse(isFold)),
        setLineH(),
        fold.ele.addEventListener("click", (e) => {
          (fold.isFold = !fold.isFold),
            setLineH(),
            list_info.setValue
              ? list_info.setValue(
                  list_info.list_id + "_" + fold.name,
                  JSON.stringify(fold.isFold)
                )
              : localStorage.setItem(
                  list_info.list_id + "_" + fold.name,
                  JSON.stringify(fold.isFold)
                ),
            bottomText(info),
            changeShow(control.move_eleList, !1),
            e.stopPropagation();
        });
    }
    if (control_info.delete) {
      const del = control_info.delete;
      del.ele.addEventListener("click", (e) => {
        confirm(del.warnText) &&
          (!(function delItem({ info, id, ele } = {}) {
            const newDataList = updateDataList(info),
              listEle = info.listEle,
              dataList = info.dataList;
            if (!id && !ele && !(ele = listEle.curClickEle)) return;
            ele ? (id = ele.id) : (ele = listEle.querySelector(`[id='${id}'`));
            const len = dataList.length;
            for (let i = 0; i < len; i++)
              if (+dataList[i].id == +id) {
                const del = dataList.splice(i, 1);
                console.log("删除一项", del[0]);
                break;
              }
            newDataList
              ? initHisListDom(info)
              : (ele.parentElement.remove(),
                resetNum(listEle),
                bottomText(info));
            const list_info = listEle.list_info;
            list_info.setValue
              ? list_info.setValue(list_info.saveName, JSON.stringify(dataList))
              : localStorage.setItem(
                  list_info.saveName,
                  JSON.stringify(dataList)
                );
          })({ info }),
          message({ title: del.text, msg: del.endText }),
          changeShow(control.move_eleList, !1)),
          e.stopPropagation();
      });
    }
    if (control_info.update) {
      const update = control_info.update;
      update.ele.addEventListener("click", (e) => {
        editInfo.msg = { noneText: control_info.add.noneText };
        const itemData = getItemData({ info, ele: info.listEle.curClickEle });
        itemData
          ? (!(function inputEditData({
              title = "",
              desc = "",
              value = "",
              data = {},
            } = {}) {
              (eleList.title.value = data.title || title),
                (eleList.desc.value = data.desc || desc),
                (eleList.value.value = data.value || value);
            })(itemData),
            (editInfo.callback.finished = (data) => {
              (data.id = new Date().getTime()),
                updateItem({ info, data }),
                message({ title: update.text, msg: update.endText }),
                changeShow(control.move_eleList, !1);
            }),
            showEditArea(!0),
            e.stopPropagation())
          : console.log("未获取到当前修改项的数据");
      });
    }
    if (control_info.move) {
      const move = control_info.move;
      move.ele.addEventListener("click", (e) => {
        if (!move.isMoving)
          return (
            (move.isMoving = !0),
            void message({
              title: move.text,
              msg: move.tipText + "\n请在提示存在期间完成该操作",
              fn: () => {
                move.isMoving = !1;
              },
            })
          );
        message({ title: move.text, msg: "已取消" + move.text + "操作" }),
          (move.isMoving = !1),
          e.stopPropagation();
      });
    }
    if (control_info.changePlace) {
      const changeP = control_info.changePlace;
      changeP.ele.addEventListener("click", (e) => {
        if (!changeP.isChangePlaceing)
          return (
            (changeP.isChangePlaceing = !0),
            void message({
              title: changeP.text,
              msg: changeP.tipText + "\n请在提示存在期间完成该操作",
              fn: () => {
                changeP.isChangePlaceing = !1;
              },
            })
          );
        message({ title: changeP.text, msg: "已取消" + changeP.text + "操作" }),
          (changeP.isChangePlaceing = !1),
          e.stopPropagation();
      });
    }
    if ((control_info.desc, control_info.toSuki)) {
      const toSuki = control_info.toSuki;
      toSuki.ele.addEventListener("click", (e) => {
        !(function itemToSuki({ info, ele, id } = {}) {
          if (!id && !ele && !(ele = info.listEle.curClickEle)) return;
          let data = getItemData({ info, ele, id });
          if (!data)
            return (
              console.log(info.listEle.list_info.control.info.toSuki.errorText),
              void message({
                title: "收藏",
                msg: info.listEle.list_info.control.info.toSuki.errorText,
              })
            );
          if (info.callback && info.callback.toSuki) {
            let newData;
            const func = info.callback.toSuki;
            Array.isArray(func)
              ? func.curFn
                ? ((newData = func[curFn](data)), (func.curFn = null))
                : func.forEach((fn) => {
                    newData = fn(data);
                  })
              : (newData = func(data)),
              (data = newData || data);
          }
          addItem({ info: info.suki_info, data });
        })({ info }),
          message({ title: toSuki.text, msg: toSuki.endText }),
          e.stopPropagation();
      });
    }
    control_info.copy &&
      control_info.copy.ele.addEventListener("click", (e) => {
        !(function copyText(text) {
          if (window.clipboardData)
            window.clipboardData.clearData(),
              window.clipboardData.setData("text", text);
          else if (document.execCommand) {
            var ele = document.createElement("SPAN");
            if (
              ((ele.textContent = text),
              document.body.appendChild(ele),
              document.selection)
            )
              (range = document.body.createTextRange()).moveToElementText(ele),
                range.select();
            else if (window.getSelection) {
              var range;
              (range = document.createRange()).selectNode(ele),
                window.getSelection().removeAllRanges(),
                window.getSelection().addRange(range);
            }
            document.execCommand("copy"),
              ele.remove ? ele.remove() : ele.removeNode(!0);
          }
        })(listEle.curClickEle.innerText),
          message({
            title: control_info.copy.text,
            msg: control_info.copy.endText,
          }),
          e.stopPropagation();
      }),
      control_info.toBottom &&
        control_info.toBottom.ele.addEventListener("click", (e) => {
          (info.listEle.parentElement.scrollTop =
            info.listEle.parentElement.scrollHeight),
            e.stopPropagation();
        });
  }
  function getValue_getValue({
    base = null,
    key,
    valType = "string",
    isReSet = !0,
    getVal,
    setVal,
  } = {}) {
    let val = getVal ? getVal(key) : localStorage.getItem(key);
    return (
      null !== base &&
        null == val &&
        ((val = base),
        isReSet &&
          (setVal ? setVal(key, val) : localStorage.setItem(key, val))),
      "string" === valType
        ? val
        : "boolean" === valType || "number" === valType
        ? JSON.parse(val)
        : "object" === valType
        ? JSON.parse(val || {})
        : "array" === valType
        ? JSON.parse(val || [])
        : val
    );
  }
  function setBtnColor(listEle, btnEle, isClicked = "") {
    if (!listEle && !btnEle) return;
    let transformText;
    const btn_info = btnEle.btn_info;
    btn_info.isChangeColor &&
      ("" === isClicked &&
        ((transformText = listEle.parentElement.style.transform),
        (isClicked = "scaleY(1)" === transformText),
        (btnEle.isClicked = isClicked)),
      isClicked
        ? isClicked &&
          ((btnEle.style.color = btn_info.click),
          (btnEle.style.background = btn_info.click_bg),
          (btnEle.style.borderColor = btn_info.click_bd),
          btn_info.isSvg &&
            btnEle.children[0] &&
            (btnEle.children[0].style.fill = btn_info.click))
        : btnEle.isHover
        ? ((btnEle.style.color = btn_info.hover),
          (btnEle.style.background = btn_info.hover_bg),
          btn_info.bd && (btnEle.style.border = btn_info.hover_bd),
          btn_info.isSvg &&
            btnEle.children[0] &&
            (btnEle.children[0].style.fill = btn_info.hover))
        : ((btnEle.style.color = btn_info.color),
          (btnEle.style.background = btn_info.bg),
          btn_info.bd && (btnEle.style.border = btn_info.bd),
          btn_info.isSvg &&
            btnEle.children[0] &&
            (btnEle.children[0].style.fill = btn_info.color)));
  }
  function getTitle({ text, isGetTt = !1, maxLen, addText = "..." } = {}) {
    if (!text) return "";
    let title = text,
      isZs = !1,
      isEnd_l = !1;
    if (isGetTt) {
      "\n" === text[0] && (text = text.slice(1, text.length));
      title = text.split(/(?<=[|\n\r])/)[0].trim();
    }
    return (
      "/" === title[0] &&
        "/" === title[1] &&
        "|" === title[title.length - 1] &&
        ((title = title.slice(2, title.length - 1).trim()), (isZs = !0)),
      "\n\r".includes(title[title.length - 1]) &&
        (title = title.slice(0, title.length - 1)),
      (title = title.replaceAll("\n", " ").replaceAll("\r", " ")),
      maxLen &&
        title.length >= maxLen &&
        (title = title.slice(0, maxLen) + addText),
      "|" === title[title.length - 1] &&
        ((title = title.slice(0, title.length - 1).trim()), (isEnd_l = !0)),
      title.length < 8 &&
        !isZs &&
        !isEnd_l &&
        (title = text
          .trim()
          .replaceAll("\n", " ")
          .replaceAll("\r", " ")
          .slice(0, 8)),
      title
    );
  }
  function getNum(isDesc, isAddUp, len, index) {
    return (isDesc && !isAddUp) || (!isDesc && isAddUp)
      ? len - index
      : index + 1;
  }
  function resetNum(listEle, liArr = []) {
    0 === liArr.length && (liArr = listEle.getElementsByClassName("item-box"));
    const len = liArr.length;
    for (let i = 0; i < len; i++)
      liArr[i].querySelector(".num").innerHTML = getNum(
        listEle.list_info.isDesc,
        !1,
        len,
        i
      );
  }
  function bottomText(info) {
    const listEle = info.listEle,
      dataList = info.dataList,
      list_info = listEle.list_info;
    let bt_box = listEle.querySelector(".bottom_text");
    if (bt_box) {
      let text = list_info.bottomText;
      if (!text) return;
      let isAdd = 50 * dataList.length > list_info.maxHeight - 5;
      isAdd ||
        (isAdd =
          listEle.offsetHeight + list_info.control.offsetHeight >=
          list_info.maxHeight - 5),
        isAdd
          ? (bt_box.innerText = text)
          : bt_box &&
            ((text = list_info.initialText),
            0 === dataList.length
              ? (bt_box.innerHTML = text)
              : bt_box.remove());
    } else if (0 === dataList.length) {
      const text = list_info.initialText;
      text &&
        (listEle.innerHTML = `<div class="bottom_text" title="${list_info.bottomTT}">${text}</div>`);
    } else {
      const text = list_info.bottomText;
      if (!text) return;
      let isAdd = 50 * dataList.length > list_info.maxHeight - 5;
      isAdd ||
        (isAdd =
          listEle.offsetHeight + list_info.control.offsetHeight >=
          list_info.maxHeight - 5),
        isAdd &&
          ((bt_box = document.createElement("div")),
          (bt_box.className = "bottom_text"),
          (bt_box.title = list_info.bottomTT),
          (bt_box.innerText = text),
          listEle.appendChild(bt_box));
    }
  }
  function hiddenBtnList(info, name = "") {
    "btn" === name
      ? (info.btnEle.style.display = "none")
      : ("list" === name ||
          ("显示" !== info.btnEle.btn_info.showMode &&
            (info.btnEle.style.display = "none")),
        (info.listEle.parentElement.style.transform = "scaleY(0)")),
      (info.btnEle.style.borderColor = "#ccc"),
      setBtnColor(info.listEle, info.btnEle),
      showSearchBox(!1);
  }
  function initHisListDom(info) {
    const listEle = info.listEle;
    let curContent,
      dataList = info.dataList;
    listEle.innerHTML = "";
    let curHtml = "";
    const list_info = listEle.list_info;
    dataList ||
      (console.log("本地读取数据"),
      list_info.getValue
        ? (info.dataList =
            JSON.parse(list_info.getValue(list_info.saveName) || null) || [])
        : (info.dataList =
            JSON.parse(localStorage.getItem(list_info.saveName) || null) ||
            []));
    const maxLen = list_info.maxLen;
    list_info.isDelete &&
      dataList.length > maxLen &&
      dataList.splice(0, dataList.length - maxLen);
    const isDesc = list_info.isDesc,
      isAddUp = list_info.isAddUp;
    let htmlItem;
    const len = dataList.length,
      liMaxHeight = list_info.liMaxHeight,
      num_color = list_info.num_color,
      tt_color = list_info.tt_color;
    dataList.forEach((item, i) => {
      (curContent = item.value.replaceAll("\n", "<br>")),
        (htmlItem = `<div class="item-box"><div class="item-control" title="${formatDate(
          {
            timestamp: item.id || new Date().getTime(),
            isExact: !0,
            delimiter2: "时分秒",
          }
        )}" style="color:${num_color}"><span class="num">${getNum(
          isDesc,
          isAddUp,
          len,
          i
        )}</span> <span title="${
          item.desc
        }" class="item-tt" style="color:${tt_color}">${
          item.title || ""
        }</span></div><div id="${
          item.id
        }" class="hItem" style="max-height:${liMaxHeight}px">${curContent}</div></div>`),
        isAddUp ? (curHtml = htmlItem + curHtml) : (curHtml += htmlItem);
    }),
      (listEle.innerHTML = curHtml),
      bottomText(info),
      (info.updateDate = new Date().getTime());
  }
  function addItem({
    info,
    title = "",
    desc = "",
    value,
    id,
    data,
    isUpdateDom = !0,
  } = {}) {
    if (!value && !data) return -1;
    updateDataList(info) && initHisListDom(info);
    const listEle = info.listEle,
      dataList = info.dataList;
    let deleteId,
      curItem,
      isOverLenDel = !1;
    if (
      (data
        ? ((value = data.value),
          (title = data.title || ""),
          (desc = data.desc || ""),
          (data.title = title),
          (data.desc = desc),
          (id = data.id || new Date().getTime()),
          (curItem = { ...data }),
          (curItem.id = id))
        : (curItem = { value, id: id || new Date().getTime(), desc }),
      !curItem.value)
    )
      return -1;
    console.log("添加一项", curItem),
      (curItem.title = getTitle({ text: title || curItem.value, isGetTt: !0 }));
    const list_info = listEle.list_info;
    if (list_info.isDelRepeat)
      for (let i = 0; i < dataList.length; i++) {
        const cur = dataList[i];
        if (
          cur.value === value &&
          (!list_info.isDataStrict ||
            (cur.title === curItem.title && cur.desc === desc))
        ) {
          (deleteId = cur.id), dataList.splice(i, 1);
          break;
        }
      }
    if (
      (dataList.push(curItem),
      list_info.isDelete &&
        dataList.length > list_info.maxLen &&
        (dataList.shift(), (isOverLenDel = !0)),
      list_info.setValue
        ? list_info.setValue(list_info.saveName, JSON.stringify(dataList))
        : localStorage.setItem(list_info.saveName, JSON.stringify(dataList)),
      isUpdateDom)
    ) {
      let liArr;
      (deleteId || isOverLenDel) &&
        (liArr = listEle.getElementsByClassName("item-box")),
        deleteId &&
          listEle.querySelector(`[id='${deleteId}'`).parentElement.remove(),
        isOverLenDel && liArr[liArr.length - 1].remove(),
        (function addLi(info, item) {
          if (!item.value) return;
          const listEle = info.listEle,
            dataList = info.dataList,
            list_info = listEle.list_info,
            content = item.value.replaceAll("\n", "<br>"),
            hItem = document.createElement("div");
          (hItem.className = "item-box"),
            (hItem.innerHTML = `<div class="item-control" title="${formatDate({
              timestamp: item.id || new Date().getTime(),
              isExact: !0,
              delimiter2: "时分秒",
            })}" style="color:${
              list_info.tt_color
            };"><span class="num">${getNum(
              list_info.isDesc,
              list_info.isAddUp,
              dataList.length,
              dataList.length - 1
            )}</span> <span title="${item.desc}" class="item-tt" style="color:${
              list_info.tt_color
            }">${item.title || ""}</span></div><div id="${
              item.id
            }" class="hItem" style="max-height:${
              list_info.liMaxHeight
            }px">${content}</div>`),
            list_info.isAddUp
              ? listEle.insertBefore(hItem, listEle.children[0])
              : listEle.querySelector(".bottom_text")
              ? listEle.insertBefore(
                  hItem,
                  listEle.children[listEle.children.length - 1]
                )
              : listEle.appendChild(hItem);
          resetNum(listEle), bottomText(info);
        })(info, curItem);
    }
    return { deleteId, isOverLenDel };
  }
  function getItemData({ info, id, ele } = {}) {
    if (
      (updateDataList(info) && initHisListDom(info),
      !id && !ele && !(ele = info.listEle.curClickEle))
    )
      return;
    ele && (id = +ele.id);
    const data = info.dataList.find((i) => +i.id == +id);
    return data
      ? { ...data }
      : (console.log("操作失败, 当前项的数据可能在其他页面中已删除"), null);
  }
  function updateItem({
    info,
    id,
    ele,
    newId,
    title = "",
    desc = "",
    value = "",
    data = {},
    isSave = !0,
  } = {}) {
    if (!id && !ele && !(ele = info.listEle.curClickEle)) return;
    data
      ? ((newId = +data.id),
        (title = data.title || ""),
        (desc = data.desc || ""),
        (value = data.value || ""))
      : (data = { id, title, desc, value }),
      ele ? (id = +ele.id) : (ele = info.listEle.querySelector(`[id='${id}'`));
    const newDataList = updateDataList(info);
    newDataList && initHisListDom(info);
    const dataList = info.dataList;
    let index;
    const len = dataList.length;
    for (let i = 0; i < len; i++)
      if (+dataList[i].id == +id) {
        (data.id = dataList[i].id),
          (dataList[i] = data),
          newId && (dataList[i].id = +newId),
          (index = i);
        break;
      }
    if (!newDataList) {
      const tt = ele.parentElement.querySelector(".item-tt");
      (tt.innerHTML = getTitle({ text: title })), (tt.title = desc);
      const content = value.replaceAll("\n", "<br>");
      (ele.innerHTML = content), newId && (ele.id = newId);
    }
    if (isSave) {
      const list_info = info.listEle.list_info;
      list_info.setValue
        ? list_info.setValue(list_info.saveName, JSON.stringify(dataList))
        : localStorage.setItem(list_info.saveName, JSON.stringify(dataList));
    }
    return { index, ele };
  }
  function updateDataList(info) {
    if (!info.listEle.list_info.isDataSync) return !1;
    let curGetValue,
      curSetValue,
      list_info = info.listEle.list_info;
    (curGetValue = list_info.getValue
      ? list_info.getValue
      : localStorage.getItem),
      (curSetValue = list_info.setValue
        ? list_info.setValue
        : localStorage.setItem);
    const time = new Date().getTime(),
      oldUpdateDate = info.updateDate || time,
      updateDate = getValue_getValue({
        key: list_info.list_id + "_updateDate",
        base: time,
        getVal: curGetValue,
        setVal: curSetValue,
      });
    if (((info.updateDate = updateDate), +updateDate != +oldUpdateDate)) {
      let dataList = getValue_getValue({
        key: list_info.saveName,
        base: "[]",
        valType: "array",
        getVal: curGetValue,
        setVal: curSetValue,
      });
      return (info.dataList = dataList), dataList;
    }
    return !1;
  }
  function bindHistoryEvents(info) {
    const textEle = info.textEle,
      btnEle = info.btnEle,
      listEle = info.listEle;
    let mode = btnEle.btn_info.showMode;
    if ("显示" !== mode) {
      let eventName = "click";
      "单击" === mode
        ? (eventName = "click")
        : "双击" === mode && (eventName = "dblclick"),
        textEle &&
          textEle.addEventListener(eventName, function historyBtn(e) {
            if (this !== e.target) return;
            !(function btnShow(isShow) {
              (btnEle.style.display = isShow ? "block" : "none"),
                (listEle.parentElement.style.transform = "scaleY(0)"),
                isShow || showSearchBox(!1),
                setBtnColor(listEle, btnEle);
            })("none" === btnEle.style.display),
              e && e.stopPropagation();
          });
    }
    btnEle.addEventListener("click", function historyList(e) {
      if (
        this !== e.target &&
        "svg" !== e.target.tagName.toLowerCase() &&
        "path" !== e.target.tagName.toLowerCase()
      )
        return;
      const isClicked = "scaleY(0)" === listEle.parentElement.style.transform;
      if (((btnEle.isClicked = isClicked), isClicked)) {
        updateDataList(info) && initHisListDom(info);
      }
      (listEle.parentElement.style.transform = isClicked
        ? "scaleY(1)"
        : "scaleY(0)"),
        setBtnColor(listEle, btnEle, isClicked),
        showSearchBox(!1),
        changeShow(listEle.list_info.control.move_eleList, !1),
        e && e.stopPropagation();
    }),
      listEle.list_info.isOut &&
        listEle.addEventListener("dblclick", function useHistoryText(e) {
          const item = e.target;
          if ("hItem" === item.className) {
            const clickText = item.innerText;
            if (
              (textEle &&
                ((textEle.value = clickText),
                listEle.list_info.isExit &&
                  (function emitEvent(ele, eventType) {
                    try {
                      if (ele.dispatchEvent) {
                        var evt = new Event(eventType, {
                          bubbles: !1,
                          cancelable: !1,
                        });
                        ele.dispatchEvent(evt);
                      } else ele.fireEvent && ele.fireEvent("on" + eventType);
                    } catch (e) {}
                  })(textEle, "input")),
              info.callback && info.callback.clickItem)
            ) {
              const itemId = +item.id,
                data = info.dataList.find((i) => i.id === itemId),
                func = info.callback.clickItem;
              Array.isArray(func)
                ? func.curFn
                  ? (func[curFn](data), (func.curFn = null))
                  : func.forEach((fn) => {
                      fn(data);
                    })
                : func(data);
            }
            listEle.list_info.isClickClose &&
              ((listEle.parentElement.style.transform = "scaleY(0)"),
              setBtnColor(listEle, btnEle),
              showSearchBox(!1),
              changeShow(listEle.list_info.control.move_eleList, !1));
          } else listEle.parentElement.scrollTop = 0;
          e.stopPropagation();
        }),
      listEle.addEventListener("click", function toTop(e) {
        "bottom_text" === e.target.className &&
          (listEle.parentElement.scrollTop = 0);
      }),
      listEle.parentElement.addEventListener("dblclick", (e) => {
        (listEle.parentElement.scrollTop = 0), e.stopPropagation();
      });
  }
  const listCss =
      "\n.ll-history-list {\n  scroll-behavior: smooth;\n}\n.ll-history-list .history-list .item-control {\n  display: flex;\n  gap: 4px;\n  height: 25px;\n  line-height: 25px;\n  font-size: 17px;\n  border-bottom: 1px solid #ccc;\n  overflow: hidden;\n  cursor: default;\n}\n.ll-history-list .history-list .hItem {\n  font-size: 13px;\n  cursor: pointer;\n  padding: 6px 0;\n  overflow-y: auto\n}\n.ll-history-list .history-list .item-tt {\n  font-size: 13px;\n  line-height: 27px;\n  white-space: nowrap;\n  text-overflow: ellipsis;\n  overflow: hidden;\n}\n.ll-history-list .history-list .bottom_text {\n  padding: 8px 0;\n  text-align: center;\n  color: #aaa;\n  cursor: pointer;\n}\n",
    scrollCss =
      "\n.ll-scroll-style-1::-webkit-scrollbar,\n.ll-scroll-style-1 ::-webkit-scrollbar {\n  width: 8px;\n}\n.ll-scroll-1-size-2::-webkit-scrollbar,\n.ll-scroll-style-1 .ll-scroll-1-size-2::-webkit-scrollbar {\n  width: 10px;\n}\n.ll-scroll-1-size-3::-webkit-scrollbar,\n.ll-scroll-style-1 .ll-scroll-1-size-3::-webkit-scrollbar {\n  width: 12px;\n}\n.ll-scroll-style-1::-webkit-scrollbar-thumb,\n.ll-scroll-style-1 ::-webkit-scrollbar-thumb {\n  border-radius: 10px;\n  -webkit-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.05);\n  opacity: 0.2;\n  background: #daedff;\n}\n.ll-scroll-style-1::-webkit-scrollbar-track,\n.ll-scroll-style-1 ::-webkit-scrollbar-track {\n  -webkit-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.08);\n  border-radius: 0;\n  background: #fff;\n  border-radius: 5px;\n}";
  function createSwitchBtn({
    box,
    svg,
    text = ">",
    size = 25,
    lineHeight,
    top = 1,
    right = -28,
    titleText = "显示/隐藏历史记录",
    className = "",
    fontSize = 14,
    fontWeight = 400,
    zIndex = 900,
    color = "#65aaff",
    bg = "#fff",
    bd = "1px solid #b7cffe",
    hover = "#65aaff",
    hover_bg = "#f7fbff",
    hover_bd = "1px solid #b7cffe",
    click = "#65aaff",
    click_bg = "#f7fbff",
    click_bd = "1px solid #b7cffe",
    fontFamily = "initial",
    showMode = "单击",
    isChangeColor = !0,
    isPosition = !0,
    child,
  } = {}) {
    if (!box) return;
    let width = size,
      height = size;
    if ("string" == typeof size && size.includes("x")) {
      const sizeArr = size.split("x");
      (width = sizeArr[0]), (height = sizeArr[1]);
    }
    const btnEle = document.createElement("div");
    (btnEle.innerHTML = svg || text),
      child && btnEle.appendChild(child),
      (btnEle.title = titleText),
      (btnEle.className = className + " ll-history-btn");
    const positionCss = isPosition
      ? `\nposition: absolute;\nz-index: ${zIndex};\ntop: ${top}px;\nright: ${right}px;`
      : "";
    (btnEle.style.cssText =
      `\n${child ? "display: flex;" : ""}\nmin-width: 10px;\nwidth: ${
        "auto" === width ? "auto" : width + "px"
      };\nheight: ${
        "auto" === height ? "auto" : height + "px"
      };\nline-height: ${
        lineHeight || parseInt(height) - 3
      }px;\nfont-size: ${fontSize}px;\nfont-weight: ${fontWeight};\ntext-align: center;\ncolor: ${color};\nbackground: ${bg};\n${
        bd ? "border:" + bd + ";" : ""
      }\nborder-radius: 6px;\nbox-sizing: border-box;\ncursor: pointer;\ndisplay: ${
        "显示" === showMode ? "block" : "none"
      };\nfont-family: ${fontFamily};` + positionCss),
      (btnEle.btn_info = {
        isSvg: !!svg,
        showMode,
        isChangeColor,
        color,
        bg,
        bd,
        hover,
        hover_bg,
        hover_bd,
        click,
        click_bg,
        click_bd,
      });
    const btn_info = btnEle.btn_info;
    return (
      btnEle.addEventListener("mouseenter", () => {
        btn_info.isChangeColor &&
          ((btnEle.style.color = hover),
          (btnEle.style.fill = hover),
          (btnEle.style.background = hover_bg),
          bd && (btnEle.style.border = hover_bd),
          (btnEle.isHover = !0),
          btn_info.isSvg &&
            btnEle.children[0] &&
            (btnEle.children[0].style.fill = btn_info.hover));
      }),
      btnEle.addEventListener("mouseleave", () => {
        btn_info.isChangeColor &&
          (btnEle.isClicked ||
            ((btnEle.style.color = color),
            (btnEle.style.fill = color),
            (btnEle.style.background = bg),
            bd && (btnEle.style.border = bd),
            btn_info.isSvg &&
              btnEle.children[0] &&
              (btnEle.children[0].style.fill = btn_info.color)),
          (btnEle.isHover = !1));
      }),
      box.appendChild(btnEle),
      btnEle
    );
  }
  function createHistoryList({
    list_id = "SD_list_1",
    box,
    width = 350,
    maxHeight = 500,
    liMaxHeight = 220,
    top = 1,
    right = -382,
    fontSize = 12,
    maxLen = 100,
    title = "双击返回顶部",
    cssText = "",
    hoverColor = "#f7fbff",
    num_color = "#b5d6ff",
    tt_color = "#b5d6ff",
    tt_maxLen,
    saveName = "ll-history-list",
    outName = "列表数据",
    controlTitle = "这里是工具栏",
    listTitle = "双击一条记录即可使用",
    bottomTT = "点击返回顶部",
    className = "",
    initialText = "无历史记录",
    bottomText = "没有更多的数据了",
    dataSyncText = "正在同步其他页面的数据, 请稍后再试",
    syncEndText = "数据同步完成, 请重新操作",
    errorSyncText = "操作失败, 当前项的数据可能在其他页面中已删除",
    zIndex = 900,
    color = "#333",
    bg = "#fff",
    bd = "3px solid #dfedfe",
    pd = "6px 5px 6px 10px",
    fontFamily = "math",
    isCenter = !1,
    isDelete = !0,
    isDelRepeat = !0,
    isExit = !1,
    isOut = !0,
    isClickClose = !0,
    isDesc = !0,
    isAddUp = !0,
    isDataStrict = !0,
    isScrollStyle = !0,
    isDataSync = !1,
    controlCfg,
    controlArr = [],
    setValue,
    getValue,
  } = {}) {
    if (!box) return;
    "relative" !== box.style.position &&
      "absolute" !== box.style.position &&
      "fixed" !== box.style.position &&
      (box.style.position = "relative");
    const hList = document.createElement("div");
    (hList.id = list_id || ""),
      (hList.className =
        className + " ll-history-list ll-scroll-style-1 ll-scroll-1-size-2"),
      (hList.title = title),
      (hList.style.scrollBehavior = "smooth"),
      (hList.innerHTML =
        '<div class="list-control"></div><div class="move-control-box"></div><div class="history-list text-list"></div>');
    const control = hList.querySelector(".list-control"),
      moveControlBox = hList.querySelector(".move-control-box"),
      listEle = hList.querySelector(".text-list");
    (control.title = controlTitle), (listEle.title = listTitle);
    const topEle = document.createElement("div");
    (topEle.className = "to-top"),
      (topEle.innerHTML = "^"),
      (listEle.list_info = {
        className,
        saveName,
        outName,
        maxLen,
        maxHeight,
        liMaxHeight,
        num_color,
        tt_color,
        tt_maxLen,
        initialText,
        bottomText,
        dataSyncText,
        syncEndText,
        errorSyncText,
        isDelete,
        isDelRepeat,
        isExit,
        isOut,
        isClickClose,
        isDesc,
        isAddUp,
        isDataStrict,
        isDataSync,
        control,
        bottomTT,
        list_id,
        setValue,
        getValue,
      }),
      (control.eleList = { move_control: moveControlBox }),
      (control.info = {}),
      (control.style.cssText = "display: flex;\nflex-wrap: wrap;"),
      (moveControlBox.style.cssText =
        "display: flex;\nposition: absolute;\nright: 0;\ntop: 0;"),
      (hList.style.cssText = `width: ${width}px;\nmax-height: ${maxHeight}px;\nline-height: ${
        fontSize + 5
      }px;\nfont-size: ${fontSize}px;\ncolor: ${color};\nbackground: ${bg};\nposition: absolute;\nz-index: ${zIndex};\ntop: ${top}px;\nright: ${right}px;\nbox-sizing: border-box;\nborder: ${bd};\nborder-radius: 8px;\npadding: ${pd};\noverflow-y: auto;\ntransition: all 0.4s cubic-bezier(0.32, 0.1, 0.16, 1) 0s;\ntransform-origin: top;\ntransform: scaleY(0);\nfont-family: ${fontFamily};`),
      (listEle.style.cssText = `\n  ${
        isCenter ? "text-align: center" : ""
      };\n  word-break:  break-all;\n  white-space:  pre-wrap`),
      "none" !== cssText &&
        (isScrollStyle
          ? addCss(cssText + listCss + scrollCss, box, "ll-scroll-style-1")
          : addCss(cssText + listCss, box)),
      (control.cfg = {
        name: "cfg",
        height: 24,
        fontSize: 12,
        color: "#65aaff",
        bg: "#dfedfe",
        mg: "0 2px 4px 2px",
        bd: "1px solid #dfedfe",
        pd: "0 5px",
        radius: 6,
        hover: "#65aaff",
        hover_bg: "#cee4ff",
        hover_bd: "1px solid #dfedfe",
        move_height: 24,
        move_fontSize: 12,
        move_mg: "0 4px 0 0",
        move_pd: "0 5px",
        move_radius: 5,
        ...controlCfg,
      });
    const defaControls = {
      add: {
        name: "add",
        text: "添加",
        type: "top",
        title: "添加一项记录至列表顶部",
        class: "control-add",
        noneText: "请填写内容!!",
        endText: "添加成功",
      },
      search: {
        name: "search",
        text: "搜索",
        type: "top",
        searchType: "标题",
        title:
          "搜索所有记录的标题, 若要按描述搜索请先输入'描述=', 按内容搜索输入'内容=', 按日期搜索输入'日期='",
        class: "control-search",
      },
      clear: {
        name: "clear",
        text: "清空",
        type: "top",
        title: "清空列表所有记录",
        class: "control-clear",
        hover_bg: "#fff",
        warnText: "是否清空列表?",
        twoWarnText: "请再次确认是否清空列表?清空数据后将无法复原!",
      },
      import: {
        name: "import",
        text: "导入",
        type: "top",
        title: "导入含数据记录的json文件",
        class: "control-import",
        startTipText:
          "导入数据后当前列表数据将会被覆盖, 建议导入数据前先备份数据",
        submitText:
          "导入数据后当前列表数据将会被覆盖, 建议导入数据前先备份数据, 是否确认导入?",
        uploadingText: "当前已存在上传任务",
        timeoutText: "文件上传超时",
        endText: "导入成功",
        isUploading: !1,
      },
      out: {
        name: "out",
        text: "导出",
        type: "top",
        title: "将列表的所有记录导出为json文件",
        class: "control-out",
        startText: "开始下载",
        isTime: !0,
        isFormat: !1,
      },
      skip: {
        name: "skip",
        text: "跳转",
        type: "top",
        title: "快速跳转到对应名称的记录的位置",
        class: "control-skip",
      },
      fold: {
        name: "fold",
        text: "折叠",
        maxHeight: 45,
        noFoldText: "展开",
        type: "top",
        title: "将每条记录收起, 以节省空间",
        class: "control-fold",
        isFold: !1,
      },
      delete: {
        name: "delete",
        text: "删除",
        type: "move",
        title: "删除此条记录",
        class: "control-delete",
        bg: "#fff",
        hover: "#ff8b8b",
        hover_bg: "#fff",
        hover_bd: "1px solid #ffd4d4",
        warnText: "是否确认删除?",
        endText: "删除成功",
      },
      update: {
        name: "update",
        text: "修改",
        type: "move",
        title: "修改此条记录",
        class: "control-update",
        noneText: "请填写内容!!",
        submitText: "是否确认修改?",
        endText: "修改成功",
      },
      move: {
        name: "move",
        text: "移动",
        type: "move",
        title: "将当前项移动到下次点击的项的的上方",
        class: "control-move",
        tipText: "请选择目标位置的项",
        warnText: "是否将当前项移动到该项之前?",
        endText: "移动完成",
        isMoving: !1,
      },
      changePlace: {
        name: "changePlace",
        text: "换位",
        type: "move",
        title: "将当前项和点击的另一项进行位置交换",
        class: "control-changePlace",
        tipText: "请选择需要交换位置的项",
        warnText: "是否交换两项的位置?",
        endText: "换位成功",
        isChangePlaceing: !1,
      },
      desc: {
        name: "desc",
        text: "描述",
        type: "move",
        title: "当前记录的描述文本",
        class: "control-desc",
      },
      toSuki: {
        name: "toSuki",
        text: "收藏",
        type: "move",
        title: "将当前记录添加到收藏列表中",
        class: "control-toSuki",
        endText: "已添加至收藏",
      },
      copy: {
        name: "copy",
        text: "复制",
        type: "move",
        title: "复制到剪贴板",
        class: "control-copy",
        endText: "已复制到剪贴板",
      },
      toTop: {
        width: 20,
        height: 20,
        name: "toTop",
        text: "^",
        type: "other",
        title: "返回顶部",
        class: "control-toTop",
        bg: "#fff",
        hover_bg: "#fff",
        bd: "1px solid #dfedfe",
        color: "#65aaff",
        hover: "#65aaff",
        hover_bd: "1px solid #65aaff",
        fontSize: 14,
        pd: "3px 0 0 0",
        isCenter: !0,
        css: "position:absolute; bottom:4px; right:4px;",
      },
      toBottom: {
        name: "toBottom",
        text: "底部",
        type: "top",
        title: "滚动到列表底部",
        class: "control-toBottom",
      },
    };
    return (
      controlArr.forEach((item) => {
        control.info[item.name] = { ...defaControls[item.name], ...item };
      }),
      (control.top_eleList = {}),
      (control.move_eleList = {}),
      (control.other_eleList = {}),
      listEle.addEventListener("mouseover", (e) => {
        const item = e.target;
        item.classList.contains("hItem") &&
          (item.style.backgroundColor = hoverColor);
      }),
      listEle.addEventListener("mouseout", (e) => {
        const item = e.target;
        item.classList.contains("hItem") &&
          (item.style.backgroundColor = "#fff");
      }),
      (function addControlDom(control) {
        function createControl({ obj, box, type } = {}) {
          (type = type ? type + "_" : ""), (box = box || obj.box || null);
          const dom = document.createElement("div"),
            cfg = control.cfg;
          (dom.className = obj.class),
            (dom.title = obj.title),
            (dom.innerText = obj.text);
          const width = obj.width || cfg[type + "width"] || cfg.width;
          return (
            (dom.style.cssText = `\nheight: ${
              obj.height || cfg[type + "height"] || cfg.height
            }px;\nline-height: ${
              obj.height || cfg[type + "height"] || cfg.height
            }px;\nwidth: ${width ? width + "px" : "auto"};\nfont-size: ${
              obj.fontSize || cfg[type + "fontSize"] || cfg.fontSize
            }px;\ncolor: ${
              obj.color || cfg[type + "color"] || cfg.color
            };\nbackground: ${obj.bg || cfg[type + "bg"] || cfg.bg};\nmargin: ${
              ("move_" === type ? obj[type + "mg"] : obj.mg) || cfg.mg
            };\nborder: ${
              obj.bd || cfg[type + "bd"] || cfg.bd
            };\nborder-radius: ${
              obj.radius || cfg[type + "radius"] || cfg.radius
            }px;\nbox-sizing: border-box;\npadding: ${
              obj.pd || cfg[type + "pd"] || cfg.pd
            };\ncursor:pointer;\n${
              obj.isCenter ? "text-align: center;" : ""
            }\n${obj.css ? obj.css : ""}`),
            dom.addEventListener("mouseenter", () => {
              (dom.style.color = obj.hover || cfg.hover),
                (dom.style.background = obj.hover_bg || cfg.hover_bg),
                (dom.style.border = obj.hover_bd || cfg.hover_bd);
            }),
            dom.addEventListener("mouseleave", () => {
              (dom.style.color = obj.color || cfg.color),
                (dom.style.background = obj.bg || cfg.bg),
                (dom.style.border = obj.bd || cfg.bd);
            }),
            box ? box.appendChild(dom) : control.appendChild(dom),
            dom
          );
        }
        const info = control.info;
        if (!control.info) return;
        for (let key in info) {
          const item = info[key];
          "move" === item.type
            ? ((item.ele = createControl({
                obj: item,
                box: control.eleList.move_control,
                type: item.type,
              })),
              (item.ele.info = item))
            : (item.ele = createControl({ obj: item })),
            (control[item.type + "_eleList"][key] = item.ele);
        }
      })(control),
      box.appendChild(hList),
      {
        value: listEle,
        list_info: listEle.list_info,
        control,
        control_info: control.info,
      }
    );
  }
  const icons = {
    base: {
      color: "#666",
      width: "100%",
      height: "80%",
      marginTop: "10%",
      html: "",
    },
    lishi: {
      color: "#8a8a8a",
      width: "100%",
      height: "80%",
      marginTop: "10%",
      html: '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700314086069" style="svgStyleFlag" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4255" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M512.5 98.29c-227.84 0-412.54 184.7-412.54 412.54s184.7 412.54 412.54 412.54 412.54-184.7 412.54-412.54S740.34 98.29 512.5 98.29z m249.28 661.82c-32.4 32.4-70.1 57.82-112.08 75.58-43.42 18.37-89.59 27.68-137.21 27.68-47.62 0-93.78-9.31-137.2-27.68-41.97-17.75-79.68-43.18-112.08-75.58-32.4-32.4-57.82-70.1-75.58-112.08-18.37-43.42-27.68-89.59-27.68-137.21 0-47.62 9.31-93.78 27.68-137.21 17.75-41.97 43.18-79.68 75.58-112.08s70.1-57.82 112.08-75.58c43.42-18.37 89.59-27.68 137.21-27.68 47.62 0 93.78 9.31 137.21 27.68 41.97 17.75 79.68 43.18 112.08 75.58s57.82 70.1 75.58 112.08c18.37 43.42 27.68 89.59 27.68 137.21 0 47.62-9.31 93.78-27.68 137.21-17.77 41.97-43.19 79.68-75.59 112.08z" p-id="4256"></path><path d="M738.68 674.81L542 497.48V248.27c0-16.57-13.43-30-30-30s-30 13.43-30 30v262.55c0 8.5 3.6 16.59 9.91 22.28L698.5 719.37a29.906 29.906 0 0 0 20.08 7.72c8.2 0 16.37-3.34 22.29-9.91 11.1-12.3 10.12-31.27-2.19-42.37z" p-id="4257"></path></svg>',
    },
    shoucang: {
      color: "#fe9850",
      width: "100%",
      height: "80%",
      marginTop: "10%",
      html: '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700314090785" style="svgStyleFlag" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4405" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M949.888 457.258667c26.069333-29.824 13.866667-67.52-24.789333-76.309334L681.728 325.546667l-127.786667-214.677334c-20.266667-34.069333-59.925333-34.090667-80.213333 0l-127.786667 214.677334-243.370666 55.381333c-38.442667 8.746667-50.858667 46.506667-24.789334 76.309333l164.394667 188.053334-22.613333 248.917333c-3.584 39.466667 28.458667 62.805333 64.896 47.146667l237.781333-102.037334a21.333333 21.333333 0 0 0-16.810667-39.210666L267.626667 902.186667c-6.698667 2.88-6.229333 3.221333-5.568-4.096l24.277333-267.093334-176.426667-201.813333c-4.757333-5.461333-4.906667-5.034667 2.133334-6.634667l261.205333-59.434666 137.152-230.4c3.733333-6.293333 3.136-6.293333 6.869333 0l137.173334 230.4 261.205333 59.434666c7.125333 1.621333 6.954667 1.088 2.133333 6.613334l-176.426666 201.813333 24.256 267.093333a21.333333 21.333333 0 1 0 42.496-3.84l-22.613334-248.917333 164.394667-188.053333z" p-id="4406"></path></svg>',
    },
  };
  const commentHistory_curInfo = info.history,
    commentHistory_doms = commentHistory_curInfo.doms,
    svg = (function getIconHTML({
      name = "",
      svg,
      color,
      width,
      height,
      marginTop,
      css,
    } = {}) {
      let icon;
      if (
        (svg
          ? ((icon = { ...icons.base }), (icon.html = svg))
          : (icon = icons[name]),
        icon)
      )
        return (
          css ||
            (css = `\n    fill:${
              color || icon.color || icons.base.fill
            };\n    width:${
              width || icon.width || icons.base.width
            };\n    height:${
              height || icon.height || icons.base.height
            };\n    margin-top:${
              marginTop || icon.marginTop || icons.base.marginTop
            };`),
          icon.html.replace("svgStyleFlag", css)
        );
    })({
      svg: '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1700396681111" style="svgStyleFlag" class="" viewBox="0 0 1129 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15893" xmlns:xlink="http://www.w3.org/1999/xlink" width="220.5078125" height="200"><path d="M669.489367 1016.496894c-85.292857 2.785872-189.356466-2.386815-292.381021-29.349537C148.937907 927.424287-6.152335 732.202431 0.187406 497.45884 6.73797 255.283749 172.038056 65.520695 404.560478 15.774058 576.109953-20.939216 737.517347 5.669626 884.799618 103.822669c122.465423 81.618517 190.493403 199.45337 219.790235 340.855193 24.922259 120.206608 25.04273 240.84992-6.166565 360.265943-36.434687 139.368889-127.359522 201.350774-265.990532 211.026032-47.427587 3.312929-95.284349 0.527057-162.93586 0.527057" fill="#ADDEEE" p-id="15894"></path><path d="M389.795357 745.070147c-21.594272-42.932545-21.669566-91.391657-33.761756-136.816428-5.391039-20.231454-13.831478-27.903895-30.65212-35.674219-29.417301-13.605596-58.277429-28.890245-85.73709-46.079827-29.010715-18.145814-27.949072-26.74437 3.056929-42.480782 107.090422-54.339561 218.374711-99.222216 329.576176-144.112401 69.435975-28.024365 139.820652-53.729681 210.145095-79.434996 13.138774-4.796217 30.441298-15.322295 41.426668-3.91528 10.089374 10.488431 4.39716 28.536364 0.639997 43.128309-20.63804 80.135229-54.866618 155.316123-86.723439 231.174663-25.148141 59.873658-54.550384 117.98544-83.064159 176.405926-20.841334 42.691605-25.012612 44.235128-68.299038 22.414975-31.096354-15.676177-60.747066-34.168342-91.037776-51.410631-6.159036 2.763284-12.129837 1.355289-18.017815-0.873408-41.637491-15.774058-41.276081-15.623471-59.331542 26.87237-6.490329 15.314766-7.604677 35.011633-28.22013 40.801729" fill="#FDFEFE" p-id="15895"></path><path d="M389.795357 745.070147c11.858779-26.99284 25.931197-53.277918 34.921281-81.204401 7.785383-24.18438 16.173116-22.324622 32.654936-8.606086 11.24137 9.366553 25.223435 15.457824 37.99327 23.009796-11.72325 28.58154-75.256188 68.788448-105.569487 66.800691" fill="#0294C9" p-id="15896"></path></svg>',
    });
  const pageType = getBiliPageType(window.location);
  console.log("当前页面:", pageType),
    "直播" !== pageType &&
      "其他" !== pageType &&
      ((document.comment_list_info = info),
      (info.pageType = pageType),
      (function setZIndex(val) {
        msgZIndex = val;
      })(12e3),
      (info.edit = (function createEditEle({
        id,
        box,
        placeholder = {
          title: "请输入标题",
          desc: "请输入描述",
          value: "请输入内容",
        },
        zIndex = 2e3,
      } = {}) {
        return (
          addCss(
            `.ll-edit-wrap {\n  position: fixed;\n  left: 0;\n  top: 0;\n  width: 100%;\n  height: 100%;\n  z-index: ${zIndex};\n  background: rgba(0, 0, 0, 0.12);\n}\n.ll-edit-wrap .edit-box {\n  position: relative;\n  width: 480px;\n  top: calc(50% - 250px);\n  margin: auto;\n  color: #333;\n  background: #fff;\n  font-size: 16px;\n  font-family: math;\n  border: 3px solid #dfedfe;\n  border-radius: 10px;\n  box-sizing: border-box;\n  padding: 20px;\n}\n.ll-edit-wrap .edit-box > div {\n  margin-bottom: 15px;\n}\n.ll-edit-wrap .edit-box .edit-item {\n  display: flex;\n}\n.ll-edit-wrap .edit-box textarea {\n  width: 100%;\n  line-height: 18px;\n  border-radius: 6px;\n  padding: 5px 7px;\n  outline-color: #cee4ff;\n  border: 1px solid #aaa;\n  box-sizing: border-box;\n  font-size: 13px;\n  font-family: math;\n  /* 保留空格 */\n  white-space: pre-wrap;\n  /* 允许词内换行 */\n  word-break: break-all;\n  letter-spacing: 1px;\n}\n.ll-edit-wrap .edit-box textarea::placeholder {\n  color: #bbb;\n}\n.ll-edit-wrap .edit-box .title {\n  width: 15%;\n  font-weight: bold;\n  font-size: 18px;\n}\n.ll-edit-wrap .edit-box .content-box .title {\n  width: 100%;\n  margin-bottom: 8px;\n}\n.ll-edit-wrap .edit-box .name-box textarea {\n  height: 30px;\n}\n.ll-edit-wrap .edit-box .desc-box textarea {\n  height: 100px;\n}\n.ll-edit-wrap .edit-box .content-box textarea {\n  width: 100%;\n  height: 200px;\n}\n.ll-edit-wrap .edit-box .btn-box {\n  justify-content: flex-end;\n  margin-bottom: 0;\n}\n.ll-edit-wrap .edit-box .btn-box button {\n  font-size: 16px;\n  color: #65aaff;\n  background: #dfedfe;\n  outline: none;\n  border: none;\n  border-radius: 6px;\n  padding: 8px 16px;\n  box-sizing: border-box;\n  cursor: pointer;\n}\n.ll-edit-wrap .edit-box .btn-box .cancel-btn {\n  color: #888;\n  background: #f4f4f4;\n  margin-right: 20px;\n}\n.ll-edit-wrap .edit-box .btn-box .cancel-btn:hover {\n  color: #666;\n  background: #eee;\n}\n.ll-edit-wrap .edit-box .btn-box .confirm-btn:hover {\n  background: #cee4ff;\n}`
          ),
          (eleList.wrap = createEle({ className: "ll-edit-wrap", box })),
          (eleList.wrap.id = id),
          (eleList.wrap.innerHTML =
            '<div class="edit-box">\n  <div class="edit-item name-box">\n    <div class="name title">标 题</div>\n    <textarea class="edit-name" placeholder="" title="拖动右下角可调节宽高"></textarea>\n  </div>\n  <div class="edit-item desc-box">\n    <div class="desc title">描 述</div>\n    <textarea class="edit-desc" placeholder="" title="拖动右下角可调节宽高"></textarea>\n  </div>\n  <div class="content content-box">\n    <div class="desc title">内 容</div>\n    <textarea class="edit-content" placeholder="" title="拖动右下角可调节宽高"></textarea>\n  </div>\n  <div class="edit-item btn-box">\n    <button class="cancel-btn">取 消</button>\n    <button class="confirm-btn">确 认</button>\n  </div>\n</div>'),
          (eleList.wrap.style.display = "none"),
          (eleList.box = eleList.wrap.children[0]),
          (eleList.box.className =
            eleList.box.className + " ll-scroll-style-1"),
          (eleList.title = eleList.box.querySelector(".edit-name")),
          (eleList.desc = eleList.box.querySelector(".edit-desc")),
          (eleList.value = eleList.box.querySelector(".edit-content")),
          (eleList.cancel = eleList.box.querySelector(".cancel-btn")),
          (eleList.confirm = eleList.box.querySelector(".confirm-btn")),
          (eleList.title.placeholder = placeholder.title),
          (eleList.desc.placeholder = placeholder.desc),
          (eleList.value.placeholder = placeholder.value),
          (function bindEvents() {
            function cancelEdit(e) {
              ("ll-edit-wrap" !== e.target.className &&
                "cancel-btn" !== e.target.className) ||
                (showEditArea(!1), clearEditData());
            }
            function confirmEdit() {
              const data = (function getEditData() {
                return {
                  title: eleList.title.value,
                  desc: eleList.desc.value,
                  value: eleList.value.value,
                };
              })();
              if (edit.callback.confirmBefore) {
                let result;
                const func = edit.callback.confirmBefore;
                if (
                  (Array.isArray(func)
                    ? func.curFn
                      ? ((result = func[curFn](data)), (func.curFn = null))
                      : func.forEach((fn) => {
                          result = fn(data);
                        })
                    : (result = func(data)),
                  !1 === result)
                )
                  return;
              }
              if (eleList.value.value) {
                if (
                  (showEditArea(!1), clearEditData(), edit.callback.finished)
                ) {
                  const func = edit.callback.finished;
                  Array.isArray(func)
                    ? func.curFn
                      ? (func[curFn](data), (func.curFn = null))
                      : func.forEach((fn) => {
                          fn(data);
                        })
                    : func(data);
                }
              } else alert(edit.msg.noneText || "请填写内容!!");
            }
            eleList.wrap.addEventListener("click", cancelEdit),
              eleList.cancel.addEventListener("click", cancelEdit),
              eleList.confirm.addEventListener("click", confirmEdit);
          })(),
          edit
        );
      })({
        placeholder: {
          title: "请输入标题",
          desc: "请输入描述\n鼠标对准标题时将显示描述信息\n鼠标对准序号时将显示日期",
          value: "请 输 入 内 容",
        },
        zIndex: 12e3,
      })),
      (function getData() {
        (settings.isHiddenBtn.value = getValue({
          base: settings.isHiddenBtn.base,
          key: settings.isHiddenBtn.key,
          valType: "boolean",
          getVal: GM_getValue,
          setVal: GM_setValue,
        })),
          (settings.position.value = getValue({
            base: settings.position.base,
            key: settings.position.key,
            getVal: GM_getValue,
            setVal: GM_setValue,
          })),
          (settings.listSize.value = getValue({
            base: settings.listSize.base,
            key: settings.listSize.key,
            getVal: GM_getValue,
            setVal: GM_setValue,
          })),
          (settings.scale.value = getValue({
            base: settings.scale.base,
            key: settings.scale.key,
            valType: "number",
            getVal: GM_getValue,
            setVal: GM_setValue,
          })),
          (settings.listMaxLen.value = getValue({
            base: settings.listMaxLen.base,
            key: settings.listMaxLen.key,
            valType: "number",
            getVal: GM_getValue,
            setVal: GM_setValue,
          })),
          (settings.sendKeys.value = getValue({
            base: settings.sendKeys.base,
            key: settings.sendKeys.key,
            getVal: GM_getValue,
            setVal: GM_setValue,
          })),
          (settings.addItemKeys.value = getValue({
            base: settings.addItemKeys.base,
            key: settings.addItemKeys.key,
            getVal: GM_getValue,
            setVal: GM_setValue,
          })),
          (settings.isHiddenList.value = getValue({
            base: settings.isHiddenList.base,
            key: settings.isHiddenList.key,
            valType: "boolean",
            getVal: GM_getValue,
            setVal: GM_setValue,
          }));
      })(),
      addCss(
        (function getCss() {
          return `\n#${doms.box.id} {\n  opacity: ${
            +css_settings.isHiddenBtn.value ? 0 : 1
          };\n  transform: scale(${
            css_settings.scale.value
          });\n  transform-origin: left top;\n  transition: ease 1s 3s all;\n  display:flex;\n  position:fixed;\n  z-index:11000;\n  left:${css_settings.position.value
            .split(/,|,/)[0]
            .trim()}px;\n  top:${css_settings.position.value
            .split(/,|,/)[1]
            .trim()}px;\n  font-family:math;\n  gap:${Math.floor(
            curInfo.height / 4
          )}px;\n}\n#${
            doms.box.id
          }:hover {\n  opacity: 1;\n  transition: ease 1s all;\n}\n#${
            doms.box.id
          } .${doms.btn.class} {\n  width:${curInfo.width}px;\n  height:${
            curInfo.height
          }px;\n  background:#fff;\n  border:1px solid #ccc;\n  border-radius:6px;\n  box-sizing:border-box;\n  cursor:pointer;\n}\n#${
            doms.box.id
          } .${doms.btn.class}:hover {\n  border:1px solid ${
            curInfo.color.main
          };\n}\n#${doms.box.id} .${
            doms.options.class
          } {\n  display:flex;\n  height:${curInfo.height}px;\n  line-height:${
            curInfo.height + 1
          }px;\n  font-size:${
            curInfo.height - 9
          }px;\n  background:#fff;\n  border:2px solid ${
            curInfo.color.bd
          };\n  border-radius:${Math.floor(
            curInfo.height / 6
          )}px;\n  box-sizing:border-box;\n  padding:0 ${Math.floor(
            curInfo.height / 2
          )}px;\n  gap:${Math.floor(
            curInfo.height / 2
          )}px;\n  transition:all 0.5s;\n  transform:scaleX(0);\n  transform-origin:left top;\n}\n#${
            doms.box.id
          } .${doms.btn.class}.opened {\n  border:1px solid ${
            curInfo.color.main
          };\n}\n#${doms.box.id} .${
            doms.options.class
          }.opened {\n  transform:scaleX(1);\n}\n.ll-scroll-style-1::-webkit-scrollbar,\n.ll-scroll-style-1 ::-webkit-scrollbar {\n  width: 8px;\n}\n.ll-scroll-1-size-2::-webkit-scrollbar,\n.ll-scroll-style-1 .ll-scroll-1-size-2::-webkit-scrollbar {\n  width: 10px;\n}\n.ll-scroll-1-size-3::-webkit-scrollbar,\n.ll-scroll-style-1 .ll-scroll-1-size-3::-webkit-scrollbar {\n  width: 12px;\n}\n.ll-scroll-style-1::-webkit-scrollbar-thumb,\n.ll-scroll-style-1 ::-webkit-scrollbar-thumb {\n  border-radius: 10px;\n  -webkit-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.05);\n  opacity: 0.2;\n  background: #daedff;\n}\n.ll-scroll-style-1::-webkit-scrollbar-track,\n.ll-scroll-style-1 ::-webkit-scrollbar-track {\n  -webkit-box-shadow: inset 0 0 8px rgba(0, 0, 0, 0.08);\n  border-radius: 0;\n  background: #fff;\n  border-radius: 5px;\n}\n`;
        })()
      ),
      (function registerMenu() {
        GM_registerMenuCommand("基础设置", () => {
          const f1 = setIsItem({
              txt: registerMenu_settings.isHiddenBtn.txt,
              base: registerMenu_settings.isHiddenBtn.base,
              key: registerMenu_settings.isHiddenBtn.key,
              setValue: GM_setValue,
              getValue: GM_getValue,
            }),
            f2 = setTextItem({
              txt: registerMenu_settings.position.txt,
              base: registerMenu_settings.position.base,
              key: registerMenu_settings.position.key,
              verification: (newVal) =>
                newVal.includes(",") || newVal.includes(",")
                  ? newVal
                  : registerMenu_settings.position.base,
              setValue: GM_setValue,
              getValue: GM_getValue,
            }),
            f3 = setTextItem({
              txt: registerMenu_settings.listSize.txt,
              base: registerMenu_settings.listSize.base,
              key: registerMenu_settings.listSize.key,
              verification: (newVal) =>
                newVal.split(/,|,/).every((i) => +i.trim())
                  ? newVal
                  : registerMenu_settings.listSize.base,
              setValue: GM_setValue,
              getValue: GM_getValue,
            }),
            f4 = setTextItem({
              txt: registerMenu_settings.scale.txt,
              base: registerMenu_settings.scale.base,
              key: registerMenu_settings.scale.key,
              verification: (newVal) =>
                +newVal ? newVal : registerMenu_settings.scale.base,
              setValue: GM_setValue,
              getValue: GM_getValue,
            });
          (f1 || f2 || f3 || f4) && history.go(0);
        }),
          GM_registerMenuCommand("其他设置", () => {
            const f1 = setTextItem({
                txt: registerMenu_settings.listMaxLen.txt,
                base: registerMenu_settings.listMaxLen.base,
                key: registerMenu_settings.listMaxLen.key,
                verification: (newVal) =>
                  +newVal ? newVal : registerMenu_settings.listMaxLen.base,
                setValue: GM_setValue,
                getValue: GM_getValue,
              }),
              f2 = setTextItem({
                txt: registerMenu_settings.sendKeys.txt,
                base: registerMenu_settings.sendKeys.base,
                key: registerMenu_settings.sendKeys.key,
                verification: (newVal) =>
                  newVal.replaceAll(" ", "").toLowerCase(),
                setValue: GM_setValue,
                getValue: GM_getValue,
              }),
              f3 = setTextItem({
                txt: registerMenu_settings.addItemKeys.txt,
                base: registerMenu_settings.addItemKeys.base,
                key: registerMenu_settings.addItemKeys.key,
                verification: (newVal) =>
                  newVal.replaceAll(" ", "").toLowerCase(),
                setValue: GM_setValue,
                getValue: GM_getValue,
              }),
              f5 = setIsItem({
                txt: registerMenu_settings.isHiddenList.txt,
                base: registerMenu_settings.isHiddenList.base,
                key: registerMenu_settings.isHiddenList.key,
                setValue: GM_setValue,
                getValue: GM_getValue,
              });
            (f1 || f2 || f3 || f4 || f5) && history.go(0);
          });
      })(),
      "首页" !== pageType &&
        (function main() {
          const pageType = info.pageType,
            curInfo = info.customKeys,
            settings = info.settings,
            classList = curInfo.classList;
          function genericGetTextarea(textareaClass, box = null) {
            if (box) return box.querySelector(`.${textareaClass}`);
            {
              const focus = document.activeElement;
              return focus.classList.contains(textareaClass) ? focus : null;
            }
          }
          function getTextarea(classObj, box = null) {
            let textarea;
            return (
              classObj.focusDom &&
                (textarea =
                  classObj.focusDom === classObj.box
                    ? (box =
                        box ||
                        document.querySelector(
                          `.${classObj.box}.${classList.focus}`
                        ) ||
                        document).querySelector(`.${classObj.textarea}`)
                    : box
                    ? box.querySelector(
                        `.${classObj.textarea}.${classList.focus}`
                      )
                    : document.querySelector(
                        `.${classObj.textarea}.${classList.focus}`
                      )),
              (textarea =
                textarea || genericGetTextarea(classObj.textarea, box)),
              { box, textarea }
            );
          }
          function getContainer(dom, boxClass) {
            for (let i = 0; i < 2; i++)
              if ((dom = dom.parentElement).classList.contains(boxClass))
                return dom;
            return dom;
          }
          function getBtn(box, btnClass) {
            let btn = box.querySelector(`.${btnClass}`);
            if (btn) return btn;
            if (((btn = box.querySelector("button")), btn)) return btn;
            {
              const divArr = box.querySelectorAll("div");
              for (let i = 0; i < divArr.length; i++) {
                const div = divArr[i],
                  className = div.className;
                if (
                  ["send", "submit", "btn", "button"].some((item) =>
                    className.includes(item)
                  )
                )
                  return div;
              }
            }
          }
          function getSendDoms(classObj, textarea = null, btn = null) {
            let box;
            if (!textarea && !btn) {
              const result = getTextarea(classObj);
              return (
                (box = result.box),
                (textarea = result.textarea)
                  ? ((box = box || getContainer(textarea, classObj.box)),
                    { box, textarea, btn: getBtn(box, classObj.btn) })
                  : {}
              );
            }
            return !textarea && btn
              ? ((box = getContainer(btn, classObj.box)),
                {
                  box,
                  textarea: (textarea = getTextarea(classObj, box).textarea),
                  btn,
                })
              : textarea && !btn
              ? ((box = getContainer(textarea, classObj.box)),
                { box, textarea, btn: getBtn(box, classObj.btn) })
              : void 0;
          }
          function verifyKeys(e, key, keys, canShiftEnter = !0) {
            if (!keys) return console.log("未设置快捷键"), !1;
            let keyArr = keys.split("+");
            if (key && key !== keyArr[keyArr.length - 1]) return;
            const keyObj = {
              control: e.ctrlKey,
              ctrl: e.ctrlKey,
              shift: e.shiftKey,
              alt: e.altKey,
              meta: e.metaKey,
              win: e.metaKey,
              window: e.metaKey,
            };
            if (
              !canShiftEnter &&
              "enter" === key &&
              keyObj.shift &&
              !keyObj.control &&
              !keyObj.ctrl &&
              !keyObj.alt &&
              !keyObj.meta &&
              !keyObj.win &&
              !keyObj.window
            )
              return !1;
            for (let i = 0; i < keyArr.length; i++) {
              const item = keyArr[i];
              if (void 0 !== keyObj[item] && !keyObj[item]) return !1;
            }
            return !0;
          }
          function getCommentInfo(allData = {}) {
            const location = window.location,
              host = location.hostname,
              path = location.pathname.split("/"),
              pageType = getBiliPageType(location),
              data = {
                id: new Date().getTime(),
                pageType,
                url: location.href,
                ...allData.data,
              },
              longTime = formatDate({
                timestamp: data.id,
                isExact: !0,
                delimiter2: "时分秒",
              }),
              shortTime = formatDate({ timestamp: data.id }),
              pageTitle = document.head.querySelector("title").innerText;
            let listTitle;
            if ("视频" === pageType) {
              const bv = path.find((i) => "BV" === i.slice(0, 2)) || "",
                h1 = document.querySelector("h1");
              (data.bv = bv),
                (listTitle = h1
                  ? h1.innerText
                  : pageTitle.split("_哔哩哔哩")[0]);
            } else if ("主页" === pageType)
              listTitle = pageTitle.split("-哔哩哔哩")[0];
            else if ("动态" === pageType)
              listTitle = pageTitle.split("的动态")[0] + "的动态";
            else if ("专栏" === pageType) {
              const h1 = document.querySelector("h1");
              listTitle = h1 ? h1.innerText : host;
            } else
              listTitle =
                "番剧" === pageType
                  ? pageTitle.split("-番剧")[0]
                  : "消息" === pageType
                  ? "消息中心"
                  : host;
            return (
              (data.title = `${shortTime} [${pageType}] ${listTitle}`),
              (data.desc = `评论的相关信息:\n${
                data.user ? "收藏日期" : "评论日期"
              }: ${longTime}\n来源: ${data.pageType}`),
              "视频" === pageType
                ? ((data.desc += "\n视频标题: " + listTitle),
                  (data.desc += "\n视频ID: " + data.bv))
                : "主页" === pageType
                ? (data.desc += "\n主页名称: " + listTitle)
                : "动态" === pageType
                ? (data.desc += "\n动态名称: " + listTitle)
                : "专栏" === pageType
                ? (data.desc += "\n专栏名称: " + listTitle)
                : "番剧" === pageType &&
                  (data.desc += "\n番剧名称: " + listTitle),
              (data.desc += `\n评论用户: ${data.user ? data.user : "自己"}`),
              data.uid && (data.desc += `\nUID: ${data.uid}`),
              allData.replyUser &&
                ((data.desc += `\n回复用户: ${allData.replyUser}`),
                allData.replyUid &&
                  (data.desc += `\nUID: ${allData.replyUid}`)),
              (data.desc += "\n地址: " + data.url),
              data
            );
          }
          function addComment({ info, doms, replyDom, isSub }) {
            let data,
              allData = { data: {} };
            if (replyDom) {
              const curClass = curInfo.curClassList;
              let userDom,
                replyBox = replyDom.parentElement;
              if (
                ("专栏" === pageType
                  ? (userDom =
                      isSub || replyBox.classList.contains(curClass.replyParent)
                        ? replyBox.querySelector("." + curClass.subUser)
                        : replyBox.querySelector("." + curClass.user))
                  : isSub || replyBox.classList.contains(curClass.replyParent)
                  ? ((replyBox = replyBox.parentElement),
                    (userDom = replyBox.querySelector("." + curClass.subUser)))
                  : ((replyBox = replyBox.parentElement.parentElement),
                    (userDom = replyBox.querySelector("." + curClass.user))),
                userDom)
              ) {
                const location = window.location;
                let curUrl = location.href;
                (allData.data.user = userDom.innerText),
                  (allData.data.uid =
                    userDom.dataset.userId || userDom.dataset.usercardMid),
                  (allData.data.url = curUrl);
                const rootId = userDom.dataset.rootReplyId;
                if (rootId) {
                  if (location.hash) {
                    const urlArr = curUrl.split("#reply");
                    1 === urlArr.length
                      ? (curUrl += `#reply${rootId}`)
                      : (curUrl = urlArr[0] + "#reply" + rootId);
                  } else curUrl += `#reply${rootId}`;
                  allData.data.url = curUrl;
                }
              } else console.log("评论用户的数据获取失败");
              const subAllData = (function getText(dom) {
                const nodeArr = dom.childNodes,
                  allData = { data: {} };
                let text = "";
                for (let i = 0; i < nodeArr.length; i++) {
                  const node = nodeArr[i];
                  "IMG" === node.tagName
                    ? (text += node.alt)
                    : (node.classList &&
                        node.classList.contains(
                          curInfo.curClassList.replyUser
                        ) &&
                        ((allData.replyUser = node.textContent.replace(
                          "@",
                          ""
                        )),
                        (allData.replyUid = node.dataset
                          ? node.dataset.userId
                          : "")),
                      node.dataset &&
                        "string" != typeof curInfo.replyUser &&
                        node.dataset[curInfo.curClassList.replyUser.value] &&
                        ((allData.replyUser = node.textContent.replace(
                          "@",
                          ""
                        )),
                        (allData.replyUid =
                          node.dataset[curInfo.curClassList.replyUser.value])),
                      (text += node.textContent));
                }
                return (allData.data.value = text), allData;
              })(replyDom);
              (allData.replyUser = subAllData.replyUser),
                (allData.replyUid = subAllData.replyUid),
                (allData.data.value = subAllData.data.value),
                (data = getCommentInfo(allData));
            } else
              data = getCommentInfo({ data: { value: doms.textarea.value } });
            addItem({ info, data });
          }
          function dblClickHandle(e) {
            let isSub = !1;
            const curClass = curInfo.curClassList;
            let flag = e.target.classList.contains(curClass.reply);
            flag ||
              curClass.reply === curClass.subReply ||
              ((flag = e.target.classList.contains(curClass.subReply)),
              (isSub = flag));
            let replyDom = flag ? e.target : null;
            if (
              (replyDom ||
                ((flag = e.target.parentElement.classList.contains(
                  curClass.reply
                )),
                flag ||
                  curClass.reply === curClass.subReply ||
                  ((flag = e.target.parentElement.classList.contains(
                    curClass.subReply
                  )),
                  (isSub = flag)),
                (replyDom = flag ? e.target.parentElement : null)),
              flag)
            ) {
              if (!verifyKeys(e, null, settings.addItemKeys.value)) return;
              message({ title: "收藏", msg: "已添加评论到收藏列表" }),
                addComment({
                  info: info.history.data.suki_info,
                  replyDom,
                  isSub,
                });
            }
          }
          function handleKeyDown(e) {
            const key = (function getKeyDown(e) {
              const keyCode = e.keyCode || e.which || e.charCode;
              let key = e.key || String.fromCharCode(keyCode);
              return (key = key.toLowerCase()), console.log("按下", key), key;
            })(e);
            if (!key) return;
            if (!verifyKeys(e, key, settings.sendKeys.value, !1)) return;
            const doms = getSendDoms(curInfo.curClassList),
              btn = doms.btn;
            btn &&
              ((curInfo.curSendBtn = btn),
              document.activeElement.blur(),
              doms.textarea.blur(),
              (curInfo.isBtnClickEvent = !1),
              btn.click(),
              addComment({ info: info.history.data, doms }),
              (curInfo.isBtnClickEvent = !0));
          }
          function clickBtn() {
            curInfo.isBtnClickEvent &&
              addComment({ info: info.history.data, doms: curInfo.curDoms });
          }
          function clickHandle(e) {
            let textarea,
              flag = "TEXTAREA" === e.target.tagName;
            if (
              (flag ||
                ((textarea = genericGetTextarea(curInfo.curClassList.textarea)),
                (flag = flag || textarea)),
              flag)
            ) {
              if (e.target === curInfo.curTextarea) return;
              let doms = curInfo.curDoms;
              if (
                ((curInfo.curTextarea = textarea || e.target),
                (curInfo.curDoms = getSendDoms(
                  curInfo.curClassList,
                  curInfo.curTextarea
                )),
                (doms = curInfo.curDoms),
                !doms.btn)
              )
                return void (curInfo.curTextarea = null);
              (curInfo.curSendBtn = doms.btn),
                doms.btn.addEventListener("click", clickBtn, !0);
            }
          }
          function magClickHandle(e) {
            if ("BUTTON" === e.target.tagName) {
              const btn = e.target,
                doms = getSendDoms(curInfo.curClassList, null, btn);
              if (!doms.textarea) return;
              (curInfo.curDoms = doms),
                (curInfo.curSendBtn = btn),
                addComment({ info: info.history.data, doms });
            }
          }
          !(function main() {
            curInfo.curClassList = classList[pageType];
            const clickFn = "消息" === pageType ? magClickHandle : clickHandle;
            document.addEventListener("click", clickFn, !0),
              document.addEventListener("dblclick", dblClickHandle, !0),
              document.addEventListener("keydown", handleKeyDown);
          })();
        })(),
      (function commentHistory_main() {
        !(function commentHistory_getData() {
          const dataList =
              JSON.parse(
                GM_getValue(commentHistory_curInfo.data.saveName) || null
              ) || [],
            suki_dataList =
              JSON.parse(
                GM_getValue(commentHistory_curInfo.data.suki_info.saveName) ||
                  null
              ) || [];
          (commentHistory_curInfo.data.dataList = dataList),
            (commentHistory_curInfo.data.suki_info.dataList = suki_dataList);
        })(),
          (function createDoms() {
            const box = createEle({
                id: commentHistory_doms.box.id,
                title: commentHistory_doms.box.title,
              }),
              btn = createEle({
                className: commentHistory_doms.btn.class,
                title: commentHistory_doms.btn.title,
                box,
              }),
              options = createEle({
                className: commentHistory_doms.options.class,
                title: commentHistory_doms.options.title,
                box,
              });
            (btn.innerHTML = svg),
              (commentHistory_doms.box.ele = box),
              (commentHistory_doms.btn.ele = btn),
              (commentHistory_doms.options.ele = options);
          })(),
          (info.searchEle = createSearch({
            box: commentHistory_doms.box.ele,
            zIndex: 12e3,
          })),
          (function createHisBtnList() {
            const settings = info.settings,
              colorObj = commentHistory_curInfo.color.listBtnObj,
              listBtn = createSwitchBtn({
                titleText: `按下${settings.sendKeys.value}即可发送评论`,
                color: commentHistory_curInfo.color.font,
                size: "autoxauto",
                text: commentHistory_doms.comment.option.text,
                box: commentHistory_doms.options.ele,
                ...colorObj,
                showMode: "显示",
                isPosition: !1,
              }),
              suki_listBtn = createSwitchBtn({
                titleText: `按下${settings.addItemKeys.value}后双击页面中的一条评论即可加入收藏`,
                color: commentHistory_curInfo.color.font,
                size: "autoxauto",
                text: commentHistory_doms.suki_comment.option.text,
                box: commentHistory_doms.options.ele,
                ...colorObj,
                showMode: "显示",
                isPosition: !1,
              });
            (listBtn.style.lineHeight =
              commentHistory_curInfo.height - 3 + "px"),
              (suki_listBtn.style.lineHeight =
                commentHistory_curInfo.height - 3 + "px");
            const wh = settings.listSize.value.split(/,|,/),
              w =
                +wh[0].trim() || settings.listSize.base.split(/,|,/)[0].trim(),
              h =
                +wh[1].trim() || settings.listSize.base.split(/,|,/)[1].trim();
            let commentListInfo = createHistoryList({
                list_id: "ll_comment_list",
                box: commentHistory_doms.options.ele,
                width: w,
                maxHeight: h,
                right: -430,
                top: 36,
                right: -241,
                saveName: commentHistory_curInfo.data.saveName,
                outName: commentHistory_doms.comment.option.text,
                className: "autoImg-hList",
                maxLen: settings.listMaxLen.value,
                listTitle: "双击跳转到评论来源的页面",
                initialText: "暂无评论记录",
                isScrollStyle: !1,
                isDataSync: !0,
                isClickClose: settings.isHiddenList.value,
                setValue: GM_setValue,
                getValue: GM_getValue,
                controlArr: [
                  { name: "add" },
                  {
                    name: "search",
                    title:
                      "搜索所有评论的内容, 若要按标题搜索请先输入'标题=', 按描述搜索输入'描述=', 按日期搜索输入'日期='",
                  },
                  { name: "clear" },
                  { name: "out" },
                  { name: "import" },
                  { name: "fold" },
                  { name: "update" },
                  { name: "move", warnText: "" },
                  { name: "toSuki" },
                  { name: "copy" },
                  { name: "delete" },
                  { name: "toBottom" },
                ],
              }),
              suki_commentListInfo = createHistoryList({
                list_id: "ll_comment_cukiList",
                box: commentHistory_doms.options.ele,
                width: w,
                maxHeight: h,
                right: -460,
                top: 36,
                right: -315,
                cssText: "none",
                saveName: commentHistory_curInfo.data.suki_info.saveName,
                outName: commentHistory_doms.suki_comment.option.text,
                className: "suki_autoImg-hList",
                maxLen: settings.listMaxLen.value,
                listTitle: "双击跳转到评论来源的页面",
                initialText: "暂无收藏评论",
                isDesc: !1,
                isAddUp: !1,
                isDelete: !1,
                isScrollStyle: !1,
                isDataSync: !0,
                isClickClose: settings.isHiddenList.value,
                setValue: GM_setValue,
                getValue: GM_getValue,
                controlArr: [
                  { name: "add" },
                  {
                    name: "search",
                    title:
                      "搜索所有评论的内容, 若要按标题搜索请先输入'标题=', 按描述搜索输入'描述=', 按日期搜索输入'日期='",
                  },
                  { name: "clear" },
                  { name: "out" },
                  { name: "import" },
                  { name: "fold" },
                  { name: "update" },
                  { name: "move", warnText: "" },
                  { name: "toSuki" },
                  { name: "copy" },
                  { name: "delete" },
                  { name: "toBottom" },
                ],
              });
            (commentHistory_curInfo.data.btnEle = listBtn),
              (commentHistory_curInfo.data.listEle = commentListInfo.value),
              (commentHistory_curInfo.data.suki_info.btnEle = suki_listBtn),
              (commentHistory_curInfo.data.suki_info.listEle =
                suki_commentListInfo.value),
              initHisListDom(commentHistory_curInfo.data),
              initHisListDom(commentHistory_curInfo.data.suki_info),
              bindHistoryEvents(commentHistory_curInfo.data),
              bindHistoryEvents(commentHistory_curInfo.data.suki_info),
              controlEvents(
                commentListInfo.control,
                commentHistory_curInfo.data,
                info.searchEle,
                info.edit
              ),
              controlEvents(
                suki_commentListInfo.control,
                commentHistory_curInfo.data.suki_info,
                info.searchEle,
                info.edit
              );
          })(),
          (function setToSukiCallback() {
            info.history.data.callback.toSuki = (data) => {
              const sukiDate = formatDate({
                timestamp: new Date().getTime(),
                isExact: !0,
                delimiter2: "时分秒",
              });
              return (
                data.desc && data.desc.includes("评论的相关信息:")
                  ? (data.desc = data.desc.replace(
                      "评论的相关信息:",
                      `评论的相关信息:\n收藏日期: ${sukiDate}`
                    ))
                  : (data.desc += `\n收藏日期: ${sukiDate}`),
                data
              );
            };
          })(),
          (function commentHistory_bindEvents() {
            (commentHistory_curInfo.data.listEle.parentElement.style.opacity = 0),
              (commentHistory_curInfo.data.suki_info.listEle.parentElement.style.opacity = 0),
              commentHistory_doms.btn.ele.addEventListener("click", () => {
                const isClose =
                  commentHistory_doms.options.ele.classList.contains("opened");
                commentHistory_doms.btn.ele.classList.toggle("opened"),
                  commentHistory_doms.options.ele.classList.toggle("opened"),
                  hiddenBtnList(commentHistory_curInfo.data),
                  hiddenBtnList(commentHistory_curInfo.data.suki_info),
                  isClose
                    ? (changeShow(
                        commentHistory_curInfo.data.listEle.list_info.control
                          .move_eleList,
                        !1
                      ),
                      changeShow(
                        commentHistory_curInfo.data.suki_info.listEle.list_info
                          .control.move_eleList,
                        !1
                      ),
                      (commentHistory_curInfo.data.listEle.parentElement.style.opacity = 0),
                      (commentHistory_curInfo.data.suki_info.listEle.parentElement.style.opacity = 0))
                    : ((commentHistory_curInfo.data.listEle.parentElement.style.opacity = 1),
                      (commentHistory_curInfo.data.suki_info.listEle.parentElement.style.opacity = 1));
              }),
              commentHistory_curInfo.data.btnEle.addEventListener(
                "click",
                () => {
                  hiddenBtnList(commentHistory_curInfo.data.suki_info);
                }
              ),
              commentHistory_curInfo.data.suki_info.btnEle.addEventListener(
                "click",
                () => {
                  hiddenBtnList(commentHistory_curInfo.data);
                }
              ),
              (commentHistory_curInfo.data.callback.clickItem = (data) => {
                data.url && window.open(data.url);
              }),
              (commentHistory_curInfo.data.suki_info.callback.clickItem = (
                data
              ) => {
                data.url && window.open(data.url);
              });
          })();
      })());
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址