Greasy Fork

NGA Filter

troll must die

目前为 2021-03-15 提交的版本。查看 最新版本

// ==UserScript==
// @name        NGA Filter
// @namespace   https://greasyfork.org/users/263018
// @version     1.1.0
// @author      snyssss
// @description troll must die

// @match       *bbs.nga.cn/thread.php?fid=*
// @match       *bbs.nga.cn/read.php?tid=*
// @match       *bbs.nga.cn/nuke.php?*
// @match       *ngabbs.com/thread.php?fid=*
// @match       *ngabbs.com/read.php?tid=*
// @match       *ngabbs.com/nuke.php?*

// @grant       GM_addStyle
// @grant       GM_setValue
// @grant       GM_getValue

// @noframes
// ==/UserScript==

((n, self) => {
  if (n === undefined) return;

  const key = "NGAFilter";

  // 数据
  const data = (() => {
    const d = {
      tags: {},
      users: {},
      options: {
        filterMode: 0,
        keyword: "",
      },
    };
    const v = GM_getValue(key);
    if (typeof v !== "object") {
      return d;
    }
    return Object.assign(d, v);
  })();

  // 保存数据
  const saveData = () => {
    GM_setValue(key, data);
  };

  // 增加标记
  const addTag = (name) => {
    const tag = Object.values(data.tags).find((item) => item.name === name);

    if (tag) return tag.id;

    const id =
      Math.max(...Object.values(data.tags).map((item) => item.id), 0) + 1;

    const hash = (() => {
      let h = 5381;
      for (var i = 0; i < name.length; i++) {
        h = ((h << 5) + h + name.charCodeAt(i)) & 0xffffffff;
      }
      return h;
    })();

    const hex = Math.abs(hash).toString(16) + "000000";

    const hsv = [
      `0x${hex.substr(2, 2)}` / 255,
      `0x${hex.substr(2, 2)}` / 255 / 2 + 0.25,
      `0x${hex.substr(4, 2)}` / 255 / 2 + 0.25,
    ];

    const rgb = n.hsvToRgb(hsv[0], hsv[1], hsv[2]);

    const color = ["#", ...rgb].reduce((a, b) => {
      return a + ("0" + b.toString(16)).slice(-2);
    });

    data.tags[id] = {
      id,
      name,
      color,
      enabled: true,
    };

    saveData();

    return id;
  };

  // 增加用户
  const addUser = (id, name = null, tags = [], isEnabled = true) => {
    if (data.users[id]) return data.users[id];

    data.users[id] = {
      id,
      name,
      tags,
      enabled: isEnabled,
    };

    saveData();

    return data.users[id];
  };

  // 旧版本数据迁移
  {
    const dataKey = "troll_data";
    const modeKey = "troll_mode";
    const keywordKey = "troll_keyword";

    if (localStorage.getItem(dataKey)) {
      let trollMap = (function () {
        try {
          return JSON.parse(localStorage.getItem(dataKey)) || {};
        } catch (e) {}

        return {};
      })();

      let filterMode = ~~localStorage.getItem(modeKey);

      let filterKeyword = localStorage.getItem(keywordKey) || "";

      // 整理标签
      [...new Set(Object.values(trollMap).flat())].forEach((item) =>
        addTag(item)
      );

      // 整理用户
      Object.keys(trollMap).forEach((item) => {
        addUser(
          item,
          null,
          (typeof trollMap[item] === "object"
            ? trollMap[item]
            : []
          ).map((tag) => addTag(tag))
        );
      });

      data.options.filterMode = filterMode ? 0 : 1;
      data.options.keyword = filterKeyword;

      localStorage.removeItem(dataKey);
      localStorage.removeItem(modeKey);
      localStorage.removeItem(keywordKey);

      saveData();
    }
  }

  // 编辑用户标记
  const editUser = (() => {
    let window;
    return (uid, name, callback) => {
      if (window === undefined) {
        window = n.createCommmonWindow();
      }

      const user = data.users[uid];

      const content = document.createElement("div");

      const size = Math.floor((screen.width * 0.8) / 200);

      const items = Object.values(data.tags).map(
        (tag, index) => `
          <td class="c1">
            <label for="s-tag-${index}" style="display: block; cursor: pointer;">
              <b class="block_txt nobr" style="background:${
                tag.color
              }; color:#fff; margin: 0.1em 0.2em;">${tag.name}</b>
            </label>
          </td>
          <td class="c2" width="1">
              <input id="s-tag-${index}" type="checkbox" value="${tag.id}" ${
          user && user.tags.find((item) => item === tag.id) && "checked"
        }/>
          </td>
        `
      );

      const rows = [...new Array(Math.floor(items.length / size))].map(
        (item, index) =>
          `
          <tr class="row${(index % 2) + 1}">
            ${items.slice(size * index, size * (index + 1)).join("")}
          </tr>
          `
      );

      content.className = "w100";
      content.innerHTML = `
        <div class="filter-table-wrapper" style="width: 80vw;">
          <table class="filter-table forumbox">
            <tbody>
              ${rows.join("")}
            </tbody>
          </table>
        </div>
        <div style="margin: 10px 0;">
            <input placeholder="一次性添加多个标记用&quot;|&quot;隔开,不会添加重名标记" style="width: -webkit-fill-available;" />
        </div>
        <div style="margin: 10px 0;">
            <button>${user && user.enabled === false ? "启用" : "禁用"}</button>
            <div class="right_">
                <button>删除</button>
                <button>保存</button>
            </div>
        </div>
    `;

      const actions = content.getElementsByTagName("button");

      actions[0].onclick = () => {
        actions[0].innerText =
          actions[0].innerText === "禁用" ? "启用" : "禁用";
      };

      actions[1].onclick = () => {
        if (confirm("是否确认?")) {
          delete data.users[uid];

          saveData();

          callback && callback();

          window._.hide();
        }
      };

      actions[2].onclick = () => {
        if (confirm("是否确认?")) {
          const values = [...content.getElementsByTagName("input")];
          const newTags = values[values.length - 1].value
            .split("|")
            .filter((item) => item.length)
            .map((item) => addTag(item));
          const tags = [
            ...new Set(
              values
                .filter((item) => item.type === "checkbox" && item.checked)
                .map((item) => ~~item.value)
                .concat(newTags)
            ),
          ].sort();

          if (user) {
            user.tags = tags;
            user.enabled = actions[0].innerText === "禁用";
          } else {
            addUser(uid, name, tags, actions[0].innerText === "禁用");
          }

          saveData();

          callback && callback();

          window._.hide();
        }
      };

      if (user === undefined) {
        actions[1].style = "display: none;";
      }

      window._.addContent(null);
      window._.addTitle(`编辑标记 - ${name ? name : "#" + uid}`);
      window._.addContent(content);
      window._.show();
    };
  })();

  // 过滤
  const reFilter = () => {
    const tPage = location.pathname === "/thread.php";
    const pPage = location.pathname === "/read.php";
    const uPage = location.pathname === "/nuke.php";

    if (tPage) {
      const tData = n.topicArg.data;

      Object.values(tData).forEach((item) => {
        if (item.containerC) return;

        const uid =
          item[2].search.match(/uid=(\S+)/) &&
          item[2].search.match(/uid=(\S+)/)[1];

        const user = data.users[uid];

        const tags = user ? user.tags.map((tag) => data.tags[tag]) : [];

        const isBlock =
          (user &&
            user.enabled &&
            (tags.length === 0 || tags.filter((tag) => tag.enabled).length)) ||
          (data.options.keyword.length &&
            item[1].innerText.search(data.options.keyword) >= 0);

        item.contentC = item[1];

        item.contentB = item.contentB || item.contentC.innerHTML;

        item.containerC =
          item.containerC || item.contentC.parentNode.parentNode;

        item.containerC.style =
          isBlock && data.options.filterMode === 0 ? "display: none;" : "";

        item.contentC.style =
          isBlock && data.options.filterMode === 1
            ? "text-decoration: line-through;"
            : "";
      });
    } else if (pPage) {
      const pData = n.postArg.data;

      Object.values(pData).forEach((item) => {
        if (~~item.pAid === self) return;
        if (item.containerC) return;

        if (typeof item.i === "number") {
          item.actionC =
            item.actionC ||
            (() => {
              const ele = item.uInfoC.querySelector('[name="uid"]');

              ele.onclick = null;

              return ele;
            })();

          item.tagC =
            item.tagC ||
            (() => {
              const tc = document.createElement("div");

              tc.className = "filter-tags";

              item.uInfoC.appendChild(tc);

              return tc;
            })();
        }

        item.pName =
          item.pName ||
          item.uInfoC.getElementsByClassName("author")[0].innerText;

        item.reFilter =
          item.reFilter ||
          (() => {
            const user = data.users[item.pAid];

            const tags = user ? user.tags.map((tag) => data.tags[tag]) : [];

            const isBlock =
              user &&
              user.enabled &&
              (tags.length === 0 || tags.filter((tag) => tag.enabled).length);

            item.avatarC =
              item.avatarC ||
              (() => {
                const tc = document.createElement("div");

                const avatar = document.getElementById(`posteravatar${item.i}`);

                if (avatar) {
                  avatar.parentNode.insertBefore(tc, avatar.nextSibling);

                  tc.appendChild(avatar);
                }

                return tc;
              })();

            item.contentB = item.contentB || item.contentC.innerHTML;

            item.containerC =
              item.containerC ||
              (() => {
                let temp = item.contentC;

                while (
                  temp.className !== "forumbox postbox" &&
                  temp.className !== "comment_c left"
                ) {
                  temp = temp.parentNode;
                }

                return temp;
              })();

            item.containerC.style.display =
              isBlock && data.options.filterMode === 0 ? "none" : "";

            item.contentC.innerHTML =
              isBlock && data.options.filterMode === 1
                ? `
                    <div class="lessernuke" style="background: #81C7D4; border-color: #66BAB7;">
                        <span class="crimson">Troll must die.</span>
                        <a href="javascript:void(0)" onclick="[...document.getElementsByName('troll_${user.id}')].forEach(item => item.style.display = '')">点击查看</a>
                        <div style="display: none;" name="troll_${user.id}">
                            ${item.contentB}
                        </div>
                    </div>`
                : item.contentB;

            item.avatarC.style.display = isBlock ? "none" : "";

            if (item.actionC) {
              item.actionC.style =
                user && user.enabled
                  ? "background: #cb4042;"
                  : "background: #aaa;";
            }

            if (item.tagC) {
              item.tagC.style.display = tags.length ? "" : "none";
              item.tagC.innerHTML = tags
                .map(
                  (tag) =>
                    `<b class="block_txt nobr" style="background:${tag.color}; color:#fff; margin: 0.1em 0.2em;">${tag.name}</b>`
                )
                .join("");
            }
          });

        if (item.actionC) {
          item.actionC.onclick =
            item.actionC.onclick ||
            ((e) => {
              if (item.pAid < 0) return;

              const user = data.users[item.pAid];

              if (e.ctrlKey === false) {
                editUser(item.pAid, item.pName, item.reFilter);
              } else {
                if (user) {
                  if (user.tags.length) {
                    user.enabled = !user.enabled;
                    user.name = item.pName;
                  } else {
                    delete data.users[user.id];
                  }
                } else {
                  addUser(item.pAid, item.pName);
                }

                saveData();
                item.reFilter();
              }
            });
        }

        item.reFilter();
      });
    } else if (uPage) {
      const container = document.getElementById("ucp_block");

      if (container.firstChild) {
        const uid = container.innerText.match(/用户ID\s*:\s*(\S+)/)[1];

        const name = container.innerText.match(/用户名\s*:\s*(\S+)/)[1];

        container.tagC =
          container.tagC ||
          (() => {
            const c = document.createElement("span");

            c.innerHTML = `
                    <h2 class="catetitle">:: ${name} 的标记 ::</h2>
                    <div class="cateblock" style="text-align: left; line-height: 1.8em;">
                        <div class="contentBlock" style="padding: 5px 10px;">
                            <span>
                                <ul class="actions" style="padding: 0px; margin: 0px;">
                                    <li style="padding-right: 5px;">
                                        <span>
                                            <a href="javascript: void(0);">[编辑 ${name} 的标记]</a>
                                        </span>
                                    </li>
                                    <div class="clear"></div>
                                </ul>
                            </span>
                            <div class="filter-tags"></div>
                            <div class="clear"></div>
                        </div>
                    </div>
                `;

            c.getElementsByTagName("a")[0].onclick = () => {
              editUser(uid, name, container.refresh);
            };

            container.firstChild.insertBefore(
              c,
              container.firstChild.childNodes[1]
            );

            return c.getElementsByClassName("filter-tags")[0];
          })();

        container.refresh = () => {
          container.tagC.innerHTML = data.users[uid].tags
            .map(
              (tag) =>
                `<b class="block_txt nobr" style="background:${data.tags[tag].color}; color:#fff; margin: 0.1em 0.2em;">${data.tags[tag].name}</b>`
            )
            .join("");
        };

        container.refresh();
      }
    }
  };

  // STYLE
  GM_addStyle(`
    .filter-table-wrapper {
      max-height: 80vh;
      overflow-y: auto;
    }
    .filter-table {
      margin: 0;
    }
    .filter-table th,
    .filter-table td {
      position: relative;
      white-space: nowrap;
    }
    .filter-table th {
      position: sticky;
      top: 2px;
      z-index: 1;
    }
    .filter-table input:not([type]), .filter-table input[type="text"] {
      margin: 0;
      box-sizing: border-box;
      height: 100%;
      width: 100%;
    }
    .filter-input-wrapper {
      position: absolute;
      top: 6px;
      right: 6px;
      bottom: 6px;
      left: 6px;
    }
    .filter-text-ellipsis {
      display: flex;
    }
    .filter-text-ellipsis > * {
      flex: 1;
      width: 1px;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .filter-button-group {
      margin: -.1em -.2em;
    }
    .filter-tags {
      margin: 2px -0.2em 0;
      text-align: left;
    }
  `);

  // UI
  const u = (() => {
    const modules = {};

    const tabContainer = (() => {
      const c = document.createElement("div");

      c.className = "w100";
      c.innerHTML = `
          <div class="right_" style="margin-bottom: 5px;">
              <table class="stdbtn" cellspacing="0">
                  <tbody>
                      <tr></tr>
                  </tbody>
              </table>
          </div>
          <div class="clear"></div>
          `;

      return c;
    })();

    const tabPanelContainer = (() => {
      const c = document.createElement("div");

      c.style = "width: 80vw;";

      return c;
    })();

    const content = (() => {
      const c = document.createElement("div");

      c.append(tabContainer);
      c.append(tabPanelContainer);

      return c;
    })();

    const addModule = (() => {
      const tc = tabContainer.getElementsByTagName("tr")[0];
      const cc = tabPanelContainer;

      return (module) => {
        const tabBox = document.createElement("td");

        tabBox.innerHTML = `<a href="javascript:void(0)" class="nobr silver">${module.name}</a>`;

        const tab = tabBox.childNodes[0];

        const toggle = () => {
          Object.values(modules).forEach((item) => {
            if (item.tab === tab) {
              item.tab.className = "nobr";
              item.content.style = "display: block";
              item.refresh();
            } else {
              item.tab.className = "nobr silver";
              item.content.style = "display: none";
            }
          });
        };

        tc.append(tabBox);
        cc.append(module.content);

        tab.onclick = toggle;

        modules[module.name] = {
          ...module,
          tab,
          toggle,
        };

        return modules[module.name];
      };
    })();

    return {
      content,
      modules,
      addModule,
    };
  })();

  // 屏蔽列表
  const blockModule = (() => {
    const content = (() => {
      const c = document.createElement("div");

      c.style = "display: none";
      c.innerHTML = `
        <div class="filter-table-wrapper">
          <table class="filter-table forumbox">
            <thead>
              <tr class="block_txt_c0">
                <th class="c1" width="1">昵称</th>
                <th class="c2">标记</th>
                <th class="c3" width="1">操作</th>
              </tr>
            </thead>
            <tbody></tbody>
          </table>
        </div>
      `;

      return c;
    })();

    const refresh = (() => {
      const container = content.getElementsByTagName("tbody")[0];

      const func = () => {
        container.innerHTML = "";

        Object.values(data.users).forEach((item) => {
          const tc = document.createElement("tr");

          tc.className = `row${
            (container.querySelectorAll("TR").length % 2) + 1
          }`;

          tc.refresh = () => {
            if (data.users[item.id]) {
              tc.innerHTML = `
                <td class="c1">
                    <a href="/nuke.php?func=ucp&uid=${
                      item.id
                    }" class="b nobr">[${
                item.name ? "@" + item.name : "#" + item.id
              }]</a>
                </td>
                <td class="c2">
                    ${item.tags
                      .map((tag) => {
                        if (data.tags[tag]) {
                          return `<b class="block_txt nobr" style="background:${data.tags[tag].color}; color:#fff; margin: 0.1em 0.2em;">${data.tags[tag].name}</b>`;
                        }
                      })
                      .join("")}
                </td>
                <td class="c3">
                    <div class="filter-table-button-group">
                      <button>编辑</button>
                      <button>${item.enabled ? "禁用" : "启用"}</button>
                      <button>删除</button>
                    </div>
                </td>
              `;

              const actions = tc.getElementsByTagName("button");

              actions[0].onclick = () => {
                editUser(item.id, item.name, tc.refresh);
              };

              actions[1].onclick = () => {
                data.users[item.id].enabled = !data.users[item.id].enabled;
                actions[1].innerHTML = data.users[item.id].enabled
                  ? "禁用"
                  : "启用";

                saveData();
                reFilter();
              };

              actions[2].onclick = () => {
                if (confirm("是否确认?")) {
                  delete data.users[item.id];
                  container.removeChild(tc);

                  saveData();
                  reFilter();
                }
              };
            } else {
              tc.remove();
            }
          };

          tc.refresh();

          container.appendChild(tc);
        });
      };

      return func;
    })();

    return {
      name: "屏蔽列表",
      content,
      refresh,
    };
  })();

  // 标记设置
  const tagModule = (() => {
    const content = (() => {
      const c = document.createElement("div");

      c.style = "display: none";
      c.innerHTML = `
        <div class="filter-table-wrapper">
          <table class="filter-table forumbox">
            <thead>
              <tr class="block_txt_c0">
                <th class="c1" width="1">标记</th>
                <th class="c2">列表</th>
                <th class="c3" width="1">操作</th>
              </tr>
            </thead>
            <tbody></tbody>
          </table>
        </div>
      `;

      return c;
    })();

    const refresh = (() => {
      const container = content.getElementsByTagName("tbody")[0];

      const func = () => {
        container.innerHTML = "";

        Object.values(data.tags).forEach((item) => {
          const tc = document.createElement("tr");

          tc.className = `row${
            (container.querySelectorAll("TR").length % 2) + 1
          }`;

          tc.innerHTML = `
            <td class="c1">
                <b class="block_txt nobr" style="background:${
                  item.color
                }; color:#fff; margin: 0.1em 0.2em;">${item.name}</b>
            </td>
            <td class="c2">
                <button>${
                  Object.values(data.users).filter((user) =>
                    user.tags.find((tag) => tag === item.id)
                  ).length
                }
                </button>
                <div style="white-space: normal; display: none;">
                    ${Object.values(data.users)
                      .filter((user) =>
                        user.tags.find((tag) => tag === item.id)
                      )
                      .map(
                        (user) =>
                          `<a href="/nuke.php?func=ucp&uid=${
                            user.id
                          }" class="b nobr">[${
                            user.name ? "@" + user.name : "#" + user.id
                          }]</a>`
                      )
                      .join("")}
                </div>
            </td>
            <td class="c3">
                <div class="filter-table-button-group">
                  <button>${item.enabled ? "禁用" : "启用"}</button>
                  <button>删除</button>
                </div>
            </td>
          `;

          const actions = tc.getElementsByTagName("button");

          actions[0].onclick = (() => {
            let hide = true;
            return () => {
              hide = !hide;
              actions[0].nextElementSibling.style.display = hide
                ? "none"
                : "block";
            };
          })();

          actions[1].onclick = () => {
            data.tags[item.id].enabled = !data.tags[item.id].enabled;
            actions[1].innerHTML = data.tags[item.id].enabled ? "禁用" : "启用";

            saveData();
            reFilter();
          };

          actions[2].onclick = () => {
            if (confirm("是否确认?")) {
              delete data.tags[item.id];

              Object.values(data.users).forEach((user) => {
                const index = user.tags.findIndex((tag) => tag === item.id);
                if (index >= 0) {
                  user.tags.splice(index, 1);
                }
              });

              container.removeChild(tc);

              saveData();
              reFilter();
            }
          };

          container.appendChild(tc);
        });
      };

      return func;
    })();

    return {
      name: "标记设置",
      content,
      refresh,
    };
  })();

  // 通用设置
  const commonModule = (() => {
    const content = (() => {
      const c = document.createElement("div");

      c.style = "display: none";

      return c;
    })();

    const refresh = (() => {
      const container = content;

      const func = () => {
        container.innerHTML = "";

        // 屏蔽关键词
        {
          const tc = document.createElement("div");

          tc.innerHTML += `
            <div>过滤关键词,用"|"隔开</div>
            <div>
                <textarea rows="3" style="box-sizing: border-box; width: 100%;">${data.options.keyword}</textarea>
                <button>确认</button>
            </div>
          `;

          const actions = tc.getElementsByTagName("button");

          actions[0].onclick = () => {
            const v = actions[0].previousElementSibling.value;

            data.options.keyword = v;

            saveData();
            reFilter();
          };

          container.appendChild(tc);
        }

        // 过滤方式
        {
          const tc = document.createElement("div");

          tc.innerHTML += `
            <br/>
            <div>过滤方式</div>
            <div>
                <input type="radio" name="filterType" ${
                  data.options.filterMode === 0 && "checked"
                }>
                <span>隐藏</span>
                <input type="radio" name="filterType" ${
                  data.options.filterMode === 1 && "checked"
                }>
                <span>标记</span>
                <button>确认</button>
            </div>
          `;

          const actions = tc.getElementsByTagName("button");

          actions[0].onclick = () => {
            const values = document.getElementsByName("filterType");

            for (let i = 0, length = values.length; i < length; i++) {
              if (values[i].checked) {
                data.options.filterMode = i;
                break;
              }
            }

            saveData();
            reFilter();
          };

          container.appendChild(tc);
        }

        // 删除没有标记的用户
        {
          const tc = document.createElement("div");

          tc.innerHTML += `
            <br/>
            <div>
                <button>删除没有标记的用户</button>
            </div>
          `;

          const actions = tc.getElementsByTagName("button");

          actions[0].onclick = () => {
            if (confirm("是否确认?")) {
              Object.values(data.users).forEach((item) => {
                if (item.tags.length === 0) {
                  delete data.users[item.id];
                }
              });

              saveData();
              reFilter();
            }
          };

          container.appendChild(tc);
        }

        // 删除没有用户的标记
        {
          const tc = document.createElement("div");

          tc.innerHTML += `
            <br/>
            <div>
                <button>删除没有用户的标记</button>
            </div>
          `;

          const actions = tc.getElementsByTagName("button");

          actions[0].onclick = () => {
            if (confirm("是否确认?")) {
              Object.values(data.tags).forEach((item) => {
                if (
                  Object.values(data.users).filter((user) =>
                    user.tags.find((tag) => tag === item.id)
                  ).length === 0
                ) {
                  delete data.tags[item.id];
                }
              });

              saveData();
              reFilter();
            }
          };

          container.appendChild(tc);
        }
      };

      return func;
    })();

    return {
      name: "通用设置",
      content,
      refresh,
    };
  })();

  u.addModule(blockModule).toggle();
  u.addModule(tagModule);
  u.addModule(commonModule);

  // 增加菜单项
  (() => {
    const title = "屏蔽/标记";
    let window;

    n.mainMenu.addItemOnTheFly(title, null, () => {
      if (window === undefined) {
        window = n.createCommmonWindow();
      }

      window._.addContent(null);
      window._.addTitle(title);
      window._.addContent(u.content);
      window._.show();
    });
  })();

  // 执行过滤
  (() => {
    const hookFunction = (object, functionName, callback) => {
      ((originalFunction) => {
        object[functionName] = function () {
          const returnValue = originalFunction.apply(this, arguments);

          callback.apply(this, [returnValue, originalFunction, arguments]);

          return returnValue;
        };
      })(object[functionName]);
    };

    const initialized = {
      topicArg: false,
      postArg: false,
    };

    hookFunction(n, "eval", () => {
      if (Object.values(initialized).findIndex((item) => item === false) < 0) {
        return;
      }

      if (n.topicArg && initialized.topicArg === false) {
        hookFunction(
          n.topicArg,
          "add",
          (returnValue, originalFunction, arguments) => reFilter()
        );

        initialized.topicArg = true;
      }

      if (n.postArg && initialized.postArg === false) {
        hookFunction(
          n.postArg,
          "proc",
          (returnValue, originalFunction, arguments) => reFilter()
        );

        initialized.postArg = true;
      }
    });

    if (n.ucp) {
      hookFunction(n.ucp, "_echo", (returnValue, originalFunction, arguments) =>
        reFilter()
      );
    }

    reFilter();
  })();
})(commonui, __CURRENT_UID);