Greasy Fork is available in English.

哔哩哔哩屏蔽增强器

对B站视频或评论进行屏蔽,支持关键词模糊正则等,支持时长播放弹幕过滤等,如视频、评论、动态、直播间的评论等,详情可看下面支持的屏蔽类型

// ==UserScript==
// @name        哔哩哔哩屏蔽增强器
// @namespace   http://tampermonkey.net/
// @license     Apache-2.0
// @version     2.4
// @author      byhgz
// @description 对B站视频或评论进行屏蔽,支持关键词模糊正则等,支持时长播放弹幕过滤等,如视频、评论、动态、直播间的评论等,详情可看下面支持的屏蔽类型
// @icon        https://static.hdslb.com/images/favicon.ico
// @noframes
// @run-at      document-start
// @grant       GM_setValue
// @grant       GM_getValue
// @grant       GM_deleteValue
// @grant       GM_addStyle
// @grant       GM_unregisterMenuCommand
// @grant       GM_registerMenuCommand
// @grant       GM_openInTab
// @exclude     *://message.bilibili.com/pages/nav/header_sync
// @exclude     *://message.bilibili.com/pages/nav/index_new_pc_sync
// @exclude     *://live.bilibili.com/blackboard/dropdown-menu.html
// @exclude     *://live.bilibili.com/p/html/live-web-mng/*
// @exclude     *://www.bilibili.com/correspond/*
// @match       *://search.bilibili.com/*
// @match       *://www.bilibili.com/v/food/*
// @match       *://message.bilibili.com/*
// @match       *://www.bilibili.com/read/*
// @match       *://www.bilibili.com/v/topic/detail/?topic_id=*
// @match       *://www.bilibili.com/v/kichiku/*
// @match       *://t.bilibili.com/*
// @match       *://space.bilibili.com/*
// @match       *://www.bilibili.com/video/*
// @match       *://live.bilibili.com/?spm_id_from=*
// @match       *://live.bilibili.com/p/eden/area-tags?*
// @match       *://live.bilibili.com/*
// @match       *://www.bilibili.com/opus/*
// @match       *://www.bilibili.com/*
// @require     https://cdn.jsdelivr.net/npm/vue@2
// @require     https://unpkg.com/element-ui/lib/index.js
// @require     https://cdn.jsdelivr.net/npm/[email protected]/dist/dexie.min.js
// @require     https://update.greasyfork.org/scripts/517928/gz_ui_css-v1.js
// @source      https://gitee.com/hangexi/BiBiBSPUserVideoMonkeyScript
// homepage     https://scriptcat.org/zh-CN/script-show-page/1029
// ==/UserScript==
"use strict";
(function (Vue, Dexie) {
    'use strict';
    var gmUtil = {
        setData(key, content) {
            GM_setValue(key, content);
        },
        getData(key, defaultValue) {
            return GM_getValue(key, defaultValue);
        },
        delData(key) {
            if (!this.isData(key)) {
                return false;
            }
            GM_deleteValue(key);
            return true;
        },
        isData(key) {
            return this.getData(key) !== undefined;
        },
        addStyle(style) {
            GM_addStyle(style);
        },
        addGMMenu(text, func, shortcutKey = null) {
            return GM_registerMenuCommand(text, func, shortcutKey);
        },
        openInTab(url, options = {active: true, insert: true, setParent: true}) {
            GM_openInTab(url, options);
        }
    };
    class EventEmitter {
        #regularEvents = {
            events: {},
            futures: {}
        }
        #callbackEvents = {
            events: {},
            callbackInterval: 1500
        }
        on(eventName, callback) {
            const events = this.#regularEvents.events;
            if (events[eventName]) {
                events[eventName].push(callback);
                return
            }
            events[eventName] = [];
            events[eventName].push(callback);
            const futureEvents = this.#regularEvents.futures;
            if (futureEvents[eventName]) {
                for (const futureEvent of futureEvents[eventName]) {
                    callback(...futureEvent);
                }
                delete futureEvents[eventName];
            }
        }
        once(eventName, callback) {
            const onceCallback = (...args) => {
                callback(...args);
                this.#removeCallback(eventName, onceCallback);
            };
            this.on(eventName, onceCallback);
        }
        handler(eventName, callback) {
            const handlerEvents = this.#callbackEvents.events;
            if (handlerEvents[eventName]) {
                throw new Error('该事件名已经存在,请更换事件名')
            }
            handlerEvents[eventName] = callback;
        }
        invoke(eventName, ...data) {
            return new Promise(resolve => {
                const handlerEvents = this.#callbackEvents.events;
                if (handlerEvents[eventName]) {
                    resolve(handlerEvents[eventName](...data));
                    return
                }
                const i1 = setInterval(() => {
                    if (handlerEvents[eventName]) {
                        clearInterval(i1);
                        resolve(handlerEvents[eventName](...data));
                    }
                }, this.#callbackEvents.callbackInterval);
            })
        }
        send(eventName, ...data) {
            const ordinaryEvents = this.#regularEvents;
            const events = ordinaryEvents.events;
            const event = events[eventName];
            if (event) {
                for (const callback of event) {
                    callback(...data);
                }
                return;
            }
            const futures = ordinaryEvents.futures;
            if (futures[eventName]) {
                futures[eventName].push(data);
                return;
            }
            futures[eventName] = [];
            futures[eventName].push(data);
        }
        #removeCallback(eventName, callback) {
            const events = this.#regularEvents.events;
            if (events[eventName]) {
                events[eventName] = events[eventName].filter(cb => cb !== callback);
            }
            const handlerEvents = this.#callbackEvents.events;
            if (handlerEvents[eventName]) {
                handlerEvents[eventName] = handlerEvents[eventName].filter(cb => cb !== callback);
            }
        }
        off(eventName) {
            const events = this.#regularEvents.events;
            if (events[eventName]) {
                delete events[eventName];
                return true
            }
            const handlerEvents = this.#callbackEvents.events;
            if (handlerEvents[eventName]) {
                delete handlerEvents[eventName];
                return true
            }
            return false
        }
        setInvokeInterval(interval) {
            this.#callbackEvents.callbackInterval = interval;
        }
        getEvents() {
            return {
                regularEvents: this.#regularEvents,
                callbackEvents: this.#callbackEvents
            }
        }
    }
    const eventEmitter = new EventEmitter();
    const group_url = 'http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=tFU0xLt1uO5u5CXI2ktQRLh_XGAHBl7C&authKey=KAf4rICQYjfYUi66WelJAGhYtbJLILVWumOm%2BO9nM5fNaaVuF9Iiw3dJoPsVRUak&noverify=0&group_code=876295632';
    const scriptCat_js_url = 'https://scriptcat.org/zh-CN/script-show-page/1029';
    var globalValue = {
        group_url,
        scriptCat_js_url
    };
    gmUtil.addGMMenu('主面板', () => {
        eventEmitter.send('主面板开关');
    }, 'Q');
    gmUtil.addGMMenu('脚本猫脚本更新页', () => {
        gmUtil.openInTab(globalValue.scriptCat_js_url);
    }, 'E');
    gmUtil.addGMMenu('gf脚本更新页', () => {
        gmUtil.openInTab('https://greasyfork.org/zh-CN/scripts/461382');
    }, 'W');
    gmUtil.addGMMenu('加入or反馈', () => {
        gmUtil.openInTab(globalValue.group_url);
    }, "T");
    const start = () => {
        let loop = false;
        let msg;
        if (!Vue) {
            loop = true;
            msg = 'Vue is not defined,Vue未定义,请检查是否引入了Vue';
        }
        if (!Dexie) {
            loop = true;
            msg = 'Dexie is not defined,Dexie未定义,请检查是否引入了Dexie';
        }
        if (loop) {
            if (confirm('外部库验证失败:' + msg + `\n请联系作者核查问题\n可通过点击确定按钮跳转。
        \n脚本主页信息中,有相关解决文档
        \n或通过脚本信息底下联系方式联系作者解决`)) {
                gmUtil.openInTab(globalValue.scriptCat_js_url);
                gmUtil.openInTab(globalValue.group_url);
            }
            throw new Error(`外部库验证失败:${msg}`)
        }
    };
    start();
    const setBorderColor = (color) => {
        gmUtil.setData("borderColor", color);
    };
    const defBorderColor = "rgb(0, 243, 255)";
    const getBorderColor = () => {
        return gmUtil.getData("borderColor", defBorderColor)
    };
    const setOutputInformationFontColor = (color) => {
        gmUtil.setData("output_information_font_color", color);
    };
    const defOutputInformationFontColor = "rgb(119,128,248)";
    const getOutputInformationFontColor = () => {
        return gmUtil.getData("output_information_font_color", defOutputInformationFontColor)
    };
    const setHighlightInformationColor = (color) => {
        gmUtil.setData("highlight_information_color", color);
    };
    const defHighlightInformationColor = "rgb(234, 93, 93)";
    const getHighlightInformationColor = () => {
        return gmUtil.getData("highlight_information_color", defHighlightInformationColor);
    };
    const setDefaultColorInfo = () => {
        setBorderColor(defBorderColor);
        setOutputInformationFontColor(defOutputInformationFontColor);
        setHighlightInformationColor(defHighlightInformationColor);
    };
    const setBOnlyTheHomepageIsBlocked = (bool) => {
        gmUtil.setData("bOnlyTheHomepageIsBlocked", bool === true);
    };
    const getBOnlyTheHomepageIsBlocked = () => {
        return gmUtil.getData("bOnlyTheHomepageIsBlocked", false);
    };
    const getAdaptationBAppCommerce = () => {
        return gmUtil.getData("adaptation-b-app-recommend", false) === true;
    };
    const setAdaptationBAppCommerce = (bool) => {
        gmUtil.setData("adaptation-b-app-recommend", bool === true);
    };
    const isShowRightTopMainButSwitch = () => {
        return gmUtil.getData("showRightTopMainButSwitch", false) === true;
    };
    const setShowRightTopMainButSwitch = (bool) => {
        gmUtil.setData("showRightTopMainButSwitch", bool === true);
    };
    const isFirstFullDisplay = () => {
        return gmUtil.getData('isFirstFullDisplay', true) === true
    };
    const setFirstFullDisplay = (bool) => {
        gmUtil.setData('isFirstFullDisplay', bool === true);
    };
    const isHalfHiddenIntervalAfterInitialDisplay = () => {
        return gmUtil.getData('is_half_hidden_interval_after_initial_display', true) === true
    };
    const setHalfHiddenIntervalAfterInitialDisplay = (bool) => {
        gmUtil.setData('is_half_hidden_interval_after_initial_display', bool === true);
    };
    const isCompatible_BEWLY_BEWLY = () => {
        return gmUtil.getData("compatible_BEWLY_BEWLY", false) === true;
    };
    const setCompatible_BEWLY_BEWLY = (bool) => {
        gmUtil.setData("compatible_BEWLY_BEWLY", bool === true);
    };
    const setDiscardOldCommentAreas = (bool) => {
        gmUtil.setData("discardOldCommentAreas", bool === true);
    };
    const isDiscardOldCommentAreas = () => {
        return gmUtil.getData("discardOldCommentAreas", false) === true;
    };
    const isDelPlayerPageRightVideoList = () => {
        return gmUtil.getData("isDelPlayerPageRightVideoList", false) === true
    };
    const bFuzzyAndRegularMatchingWordsToLowercase$1 = () => {
        return gmUtil.getData("bFuzzyAndRegularMatchingWordsToLowercase", true) === true
    };
    const setFuzzyAndRegularMatchingWordsToLowercase = (bool) => {
        gmUtil.setData("bFuzzyAndRegularMatchingWordsToLowercase", bool === true);
    };
    var localMKData = {
        setBorderColor,
        getBorderColor,
        setOutputInformationFontColor,
        getOutputInformationFontColor,
        setHighlightInformationColor,
        getHighlightInformationColor,
        setBOnlyTheHomepageIsBlocked,
        getBOnlyTheHomepageIsBlocked,
        getAdaptationBAppCommerce,
        setAdaptationBAppCommerce,
        setDefaultColorInfo,
        isCompatible_BEWLY_BEWLY,
        setCompatible_BEWLY_BEWLY,
        setDiscardOldCommentAreas,
        isDiscardOldCommentAreas,
        isShowRightTopMainButSwitch,
        setShowRightTopMainButSwitch,
        isFirstFullDisplay,
        setFirstFullDisplay,
        isHalfHiddenIntervalAfterInitialDisplay,
        setHalfHiddenIntervalAfterInitialDisplay,
        isDelPlayerPageRightVideoList,
        bFuzzyAndRegularMatchingWordsToLowercase: bFuzzyAndRegularMatchingWordsToLowercase$1,
        setFuzzyAndRegularMatchingWordsToLowercase
    };
    const panel_settings_vue = {
        template: `
      <div>
      <el-card shadow="never">
        <template #header>
          <span>颜色设置</span>
        </template>
        <div class="el-horizontal-center">
          选择器
          <el-color-picker v-model="input_color"/>
        </div>
        <button gz_type @click="setBorderColorBut">设置边框色</button>
        <button gz_type @click="setDefFontColorForOutputInformationBut">设置输出信息默认字体色</button>
        <button gz_type @click="setTheFontColorForOutputInformationBut">设置输出信息高亮字体色</button>
        <el-tooltip content="刷新页面生效">
          <el-button @click="setDefInfoBut">恢复默认</el-button>
        </el-tooltip>
      </el-card>
      <el-card shadow="never">
        <template #header>
          <span>外部主面板显隐按钮设置</span>
        </template>
        <el-switch v-model="showRightTopMainButSwitch" active-text="显示按钮"></el-switch>
        <el-tooltip content="页面每次加载完之后是否完整展示按钮,否则半隐藏">
          <el-switch v-model="isFirstFullDisplay" active-text="初次完整显示"></el-switch>
        </el-tooltip>
        <el-tooltip content="页面每次加载完之后如完整展示按钮时,间隔10秒后半隐藏处理">
          <el-switch v-model="isHalfHiddenIntervalAfterInitialDisplay"
                     active-text="初次显示后间隔半隐藏"/>
        </el-tooltip>
      </el-card>
      <el-card shadow="never">
        <template #header>
          <span>说明</span>
        </template>
        <div>按键盘tab键上的~键为展开关闭主面板</div>
      </el-card>
      <el-card shadow="never">
        <template #header>
          <span>devTools</span>
        </template>
        <el-input v-model.trim="devToolsInputVal" @keyup.enter.native="changeDevToolsInput"></el-input>
      </el-card>
      </div>`,
        data() {
            return {
                input_color: null,
                showRightTopMainButSwitch: localMKData.isShowRightTopMainButSwitch(),
                isFirstFullDisplay: localMKData.isFirstFullDisplay(),
                isHalfHiddenIntervalAfterInitialDisplay: localMKData.isHalfHiddenIntervalAfterInitialDisplay(),
                devToolsInputVal: ''
            }
        },
        methods: {
            setBorderColorBut() {
                this.$confirm('是否设置面板边框颜色', '提示').then(() => {
                    localMKData.setBorderColor(this.input_color);
                    this.$alert("已设置面板边框颜色,刷新生效");
                });
            },
            setDefFontColorForOutputInformationBut() {
                this.$confirm("是否设置输出信息默认字体颜色", "提示").then(() => {
                    localMKData.setOutputInformationFontColor(this.input_color);
                    this.$alert("已设置输出信息默认字体颜色,刷新生效");
                });
            },
            setTheFontColorForOutputInformationBut() {
                this.$confirm('是要设置输出信息高亮字体颜色吗?').then(() => {
                    localMKData.setHighlightInformationColor(this.input_color);
                    this.$alert("已设置输出信息高亮字体颜色,刷新生效");
                });
            },
            setDefInfoBut() {
                localMKData.setDefaultColorInfo();
                this.$alert("已恢复默认颜色,刷新生效");
            },
            changeDevToolsInput() {
                debugger
                if (this.devToolsInputVal === 'show-dev') {
                    gmUtil.setData('dev-', true);
                    eventEmitter.send('debugger-dev-show', true);
                    this.devToolsInputVal = '';
                }
                if (this.devToolsInputVal === 'stop-dev') {
                    gmUtil.setData('open-dev', false);
                    eventEmitter.send('debugger-dev-show', false);
                    this.devToolsInputVal = '';
                }
            }
        },
        watch: {
            showRightTopMainButSwitch(newVal) {
                localMKData.setShowRightTopMainButSwitch(newVal);
                eventEmitter.send('显隐主面板开关', newVal);
            },
            isFirstFullDisplay(newVal) {
                localMKData.setFirstFullDisplay(newVal);
            },
            isHalfHiddenIntervalAfterInitialDisplay(newBool) {
                localMKData.setHalfHiddenIntervalAfterInitialDisplay(newBool);
            }
        }
    };
    const ruleKeyListData = [
        {
            key: "name",
            name: "用户名黑名单(模糊匹配)",
            oldKey: "userNameKeyArr",
            oldName: "用户名黑名单模式(模糊匹配)"
        },
        {
            key: "precise_name",
            name: "用户名黑名单(精确匹配)",
            oldKey: "userNameArr",
            oldName: "用户名黑名单模式(精确匹配)"
        }, {
            key: "nameCanonical",
            name: "用户名黑名单(正则匹配)"
        },
        {
            key: "precise_uid",
            name: "用户uid黑名单(精确匹配)",
            oldKey: "userUIDArr",
            oldName: "用户uid黑名单模式(精确匹配)"
        },
        {
            key: "precise_uid_white",
            name: "用户uid白名单(精确匹配)",
            oldKey: "userWhiteUIDArr",
            oldName: "用户uid白名单模式(精确匹配)"
        }, {
            key: "title",
            name: "标题黑名单(模糊匹配)",
            oldKey: "titleKeyArr",
            oldName: "标题黑名单模式(模糊匹配)"
        }, {
            key: "titleCanonical",
            name: "标题黑名单(正则匹配)",
            oldKey: "titleKeyCanonicalArr",
            oldName: "标题黑名单模式(正则匹配)"
        }, {
            key: "commentOn",
            name: "评论关键词黑名单(模糊匹配)",
            oldKey: "commentOnKeyArr",
            oldName: "评论关键词黑名单模式(模糊匹配)"
        }, {
            key: "commentOnCanonical",
            name: "评论关键词黑名单(正则匹配)",
            oldKey: "contentOnKeyCanonicalArr",
            oldName: "评论关键词黑名单模式(正则匹配)"
        }, {
            key: "contentOn",
            name: "评论内容黑名单(模糊匹配)",
            oldKey: "contentOnKeyArr",
            oldName: "评论内容黑名单模式(模糊匹配)"
        }, {
            key: "precise_fanCard",
            name: "粉丝牌黑名单(精确匹配)",
            oldKey: "fanCardArr",
            oldName: "粉丝牌黑名单模式(精确匹配)"
        }, {
            key: "dynamic",
            name: "动态关键词黑名单(模糊匹配)",
            oldKey: "dynamicArr",
            oldName: "动态关键词内容黑名单模式(模糊匹配)"
        }, {
            key: "precise_tag",
            name: "话题tag标签黑名单(精确匹配)",
        }
        , {
            key: "tag",
            name: "话题tag标签黑名单(模糊匹配)",
        }, {
            key: "tagCanonical",
            name: "话题tag标签黑名单(正则匹配)"
        }, {
            key: "precise_partition",
            name: "直播分区黑名单(精确匹配)"
        }, {
            key: 'videoTag',
            name: '视频tag黑名单(模糊匹配)',
        }, {
            key: 'precise_videoTag',
            name: '视频tag黑名单(精确匹配)',
        }, {
            key: 'videoTagCanonical',
            name: '视频tag黑名单(正则匹配)',
        },
        {
            key: 'hotSearchKey',
            name: '热搜关键词(模糊匹配)',
        },
        {
            key: 'hotSearchKeyCanonical',
            name: '热搜关键词(正则匹配)'
        }
    ];
    const otherKeyListData = [
        {
            name: '最小播放量',
            value: 'nMinimumPlay',
            associated: 'nMaximumPlayback',
            defVal: -1
        },
        {
            name: '最大播放量',
            value: 'nMaximumPlayback',
            associated: 'nMinimumPlay',
            bLarge: true,
            defVal: -1
        },
        {
            name: '最小弹幕数',
            value: 'nMinimumBarrage',
            associated: 'nMaximumBarrage',
            defVal: -1
        },
        {
            name: '最大弹幕数',
            value: 'nMaximumBarrage',
            associated: 'nMinimumBarrage',
            bLarge: true,
            defVal: -1
        },
        {
            name: '最小时长',
            value: 'nMinimumDuration',
            associated: 'nMaximumDuration',
            defVal: -1
        },
        {
            name: '最大时长',
            value: 'nMaximumDuration',
            associated: 'nMinimumDuration',
            bLarge: true,
            defVal: -1
        },
        {
            name: '最小用户等级过滤',
            value: 'nMinimumLevel',
            associated: 'nMaximumLevel',
            defVal: -1
        },
        {
            name: '最大用户等级过滤',
            value: 'nMaximumLevel',
            associated: 'nMinimumLevel',
            bLarge: true,
            defVal: -1
        }
    ];
    const getRuleKeyListData = () => {
        return ruleKeyListData;
    };
    const getNameArr = () => {
        return gmUtil.getData("name", []);
    };
    const getPreciseNameArr = () => {
        return gmUtil.getData("precise_name", []);
    };
    const getNameCanonical = () => {
        return gmUtil.getData("nameCanonical", []);
    };
    const getPreciseUidArr = () => {
        return gmUtil.getData("precise_uid", []);
    };
    const getPreciseUidWhiteArr = () => {
        return gmUtil.getData("precise_uid_white", []);
    };
    const getTitleArr = () => {
        return gmUtil.getData("title", []);
    };
    const getTitleCanonicalArr = () => {
        return gmUtil.getData("titleCanonical", []);
    };
    const getCommentOnArr = () => {
        return gmUtil.getData("commentOn", []);
    };
    const getCommentOnCanonicalArr = () => {
        return gmUtil.getData("commentOnCanonical", []);
    };
    const getPreciseTagArr = () => {
        return gmUtil.getData("precise_tag", []);
    };
    const getTagArr = () => {
        return gmUtil.getData("tag", []);
    };
    const getTagCanonicalArr = () => {
        return gmUtil.getData("tagCanonical", []);
    };
    const getPreciseFanCardArr = () => {
        return gmUtil.getData("precise_fanCard", []);
    };
    const getPrecisePartitionArr = () => {
        return gmUtil.getData("precise_partition", []);
    };
    const getVideoTagArr = () => {
        return gmUtil.getData("videoTag", []);
    };
    const getPreciseVideoTagArr = () => {
        return gmUtil.getData("precise_videoTag", []);
    };
    const getVideoTagCanonicalArr = () => {
        return gmUtil.getData("videoTagCanonical", []);
    };
    const getHotSearchKeyArr = () => {
        return gmUtil.getData("hotSearchKey", []);
    };
    const getHotSearchKeyCanonicalArr = () => {
        return gmUtil.getData("hotSearchKeyCanonical", []);
    };
    const clearKeyItem = (ruleKey) => {
        gmUtil.delData(ruleKey);
    };
    var ruleKeyListData$1 = {
        getNameArr,
        getPreciseNameArr,
        getNameCanonical,
        getPreciseUidArr,
        getPreciseUidWhiteArr,
        getTitleArr,
        getTitleCanonicalArr,
        getCommentOnArr,
        getCommentOnCanonicalArr,
        getRuleKeyListData,
        getPreciseTagArr,
        getTagArr,
        getTagCanonicalArr,
        getPreciseFanCardArr,
        getPrecisePartitionArr,
        getVideoTagArr,
        getPreciseVideoTagArr,
        getVideoTagCanonicalArr,
        getHotSearchKeyArr,
        getHotSearchKeyCanonicalArr,
        otherKeyListData,
        clearKeyItem
    };
    const verificationInputValue = (ruleValue, type) => {
        if (ruleValue === null) return {status: false, res: '内容不能为空'};
        if (type === "precise_uid" || type === "precise_uid_white") {
            ruleValue = parseInt(ruleValue);
            if (isNaN(ruleValue)) {
                return {
                    status: false,
                    res: '请输入数字!'
                };
            }
        } else {
            ruleValue.trim();
        }
        if (ruleValue === '') {
            return {status: false, res: '内容不能为空'};
        }
        return {status: true, res: ruleValue};
    };
    const addRule = (ruleValue, type) => {
        const verificationRes = verificationInputValue(ruleValue, type);
        if (!verificationRes.status) {
            return verificationRes
        }
        const arr = gmUtil.getData(type, []);
        if (arr.includes(verificationRes.res)) {
            return {status: false, res: '已存在此内容'};
        }
        arr.push(verificationRes.res);
        gmUtil.setData(type, arr);
        return {status: true, res: '添加成功'};
    };
    const showAddRuleInput = async (type) => {
        let ruleValue;
        try {
            const {value} = await eventEmitter.invoke('el-prompt', '请输入要添加的规则内容', 'tip');
            ruleValue = value;
        } catch (e) {
            return
        }
        const {res, status} = addRule(ruleValue, type);
        eventEmitter.send('el-msg', res);
        status && eventEmitter.send('刷新规则信息');
        status && eventEmitter.send('通知屏蔽');
    };
    const delRule = (type, value) => {
        const verificationRes = verificationInputValue(value, type);
        if (!verificationRes.status) {
            return verificationRes
        }
        const {res} = verificationRes;
        const arr = gmUtil.getData(type, []);
        const indexOf = arr.indexOf(res);
        if (indexOf === -1) {
            return {status: false, res: '不存在此内容'};
        }
        arr.splice(indexOf, 1);
        gmUtil.setData(type, arr);
        return {status: true, res: "移除成功"}
    };
    const showDelRuleInput = async (type) => {
        let ruleValue;
        try {
            const {value} = await eventEmitter.invoke('el-prompt', '请输入要删除的规则内容', '删除指定规则');
            ruleValue = value;
        } catch (e) {
            return
        }
        const {status, res} = delRule(type, ruleValue);
        eventEmitter.send('el-msg', res);
        status && eventEmitter.send('刷新规则信息');
    };
    const getRuleContent = (space = 0) => {
        const ruleMap = {};
        for (let ruleKeyListDatum of ruleKeyListData$1.getRuleKeyListData()) {
            const key = ruleKeyListDatum.key;
            ruleMap[key] = gmUtil.getData(key, []);
        }
        return JSON.stringify(ruleMap, null, space);
    };
    const verificationRuleMap = (keyArr, content) => {
        let parse;
        try {
            parse = JSON.parse(content);
        } catch (e) {
            alert('规则内容有误');
            return false;
        }
        const newRule = {};
        for (const key in parse) {
            if (!Array.isArray(parse[key])) {
                continue;
            }
            if (parse[key].length === 0) {
                continue;
            }
            newRule[key] = parse[key];
        }
        if (Object.keys(newRule).length === 0) {
            alert('规则内容为空');
            return false;
        }
        return newRule;
    };
    const overwriteImportRules = (keyArr, content) => {
        const map = verificationRuleMap(keyArr, content);
        if (map === false) return false;
        for (let key of Object.keys(map)) {
            gmUtil.setData(key, map[key]);
        }
        return true;
    };
    const appendImportRules = (keyArr, content) => {
        const map = verificationRuleMap(keyArr, content);
        if (map === false) return false;
        for (let key of Object.keys(map)) {
            const arr = gmUtil.getData(key, []);
            for (let item of map[key]) {
                if (!arr.includes(item)) {
                    arr.push(item);
                }
            }
            gmUtil.setData(key, arr);
        }
        return true;
    };
    const getNewRuleKeyList = () => {
        return ruleKeyListData$1.getRuleKeyListData();
    };
    const overwriteImportRulesV1 = (content) => {
        let parse;
        try {
            parse = JSON.parse(content);
        } catch (e) {
            alert('规则内容有误');
            return false;
        }
        for (let ruleKeyListDatum of ruleKeyListData$1.getRuleKeyListData()) {
            const name = ruleKeyListDatum.oldName;
            const jsonRuleList = parse[name];
            if (!jsonRuleList) {
                continue;
            }
            if (jsonRuleList.length === 0) {
                continue;
            }
            gmUtil.setData(ruleKeyListDatum.key, jsonRuleList);
        }
        return true;
    };
    const addRulePreciseUid = (uid, isTip = true) => {
        const results = addRule(uid, "precise_uid");
        if (isTip) {
            eventEmitter.send('el-alert', results.res);
            return null
        }
        return results;
    };
    const delRUlePreciseUid = (uid, isTip = true) => {
        const results = delRule('precise_uid', uid);
        if (isTip) {
            eventEmitter.send('el-alert', results.res);
            return null
        }
        return results
    };
    const addRulePreciseName = (name, tip = true) => {
        const results = addRule(name, "precise_name");
        if (tip) {
            eventEmitter.send('el-msg', results.res);
        }
        return results;
    };
    const findRuleItemValue = (type, value) => {
        return gmUtil.getData(type, []).find(item => item === value) || null
    };
    var ruleUtil = {
        addRule,
        showAddRuleInput,
        showDelRuleInput,
        getRuleContent,
        overwriteImportRules,
        appendImportRules,
        overwriteImportRulesV1,
        getNewRuleKeyList,
        addRulePreciseUid,
        addRulePreciseName,
        delRUlePreciseUid,
        findRuleItemValue
    };
    const rule_set_value_dialog = {
        template: `
      <div>
      <el-dialog :visible="show" width="30%" title="修改单项规则值"
                 :close-on-click-modal="false" :modal="false">
        {{ ruleName }}-{{ ruleType }}
        <el-form>
          <el-form-item label="要修改的值">
            <el-input type="text" v-model="oldVal" clearable/>
          </el-form-item>
          <el-form-item label="修改后的值">
            <el-input v-model="newVal" clearable/>
          </el-form-item>
        </el-form>
        <template #footer class="dialog-footer">
          <el-button @click="show=false">取消</el-button>
          <el-button @click="okBut">确定</el-button>
        </template>
      </el-dialog>
      </div>`,
        data() {
            return {
                show: false,
                ruleType: "",
                ruleName: "",
                oldVal: '',
                newVal: ''
            }
        },
        methods: {
            okBut() {
                let tempOldVal = this.oldVal.trim();
                let tempNewVal = this.newVal.trim();
                if (tempOldVal.length === 0 || tempNewVal.length === 0) {
                    this.$alert("请输入要修改的值或新值");
                    return
                }
                if (tempNewVal === tempOldVal) {
                    this.$alert("新值不能和旧值相同");
                    return;
                }
                const tempRuleType = this.ruleType;
                if (tempRuleType === 'precise_uid' || tempRuleType === 'precise_uid_white') {
                    tempOldVal = parseInt(tempOldVal);
                    tempNewVal = parseInt(tempNewVal);
                    if (isNaN(tempOldVal) || isNaN(tempNewVal)) {
                        this.$alert("请输入整数数字");
                        return
                    }
                }
                if (!ruleUtil.findRuleItemValue(tempRuleType, tempOldVal)) {
                    this.$alert("要修改的值不存在");
                    return;
                }
                if (ruleUtil.findRuleItemValue(tempRuleType, tempNewVal)) {
                    this.$alert("新值已存在");
                    return;
                }
                const ruleArr = gmUtil.getData(tempRuleType, []);
                const indexOf = ruleArr.indexOf(tempOldVal);
                ruleArr[indexOf] = tempNewVal;
                gmUtil.setData(tempRuleType, ruleArr);
                this.$alert(`已将旧值【${tempOldVal}】修改成【${tempNewVal}】`);
                this.show = false;
            }
        },
        watch: {
            show(newVal) {
                if (newVal === false) this.oldVal = this.newVal = '';
            }
        },
        created() {
            eventEmitter.on('修改规则对话框', (type, name) => {
                this.show = true;
                this.ruleType = type;
                this.ruleName = name;
            });
        }
    };
    const basic_rules_vue = {
        components: {rule_set_value_dialog},
        template: `
      <div>
      <el-card shadow="never">
        <template #header>
          <span>使用说明</span>
        </template>
        <div>1. 大部分情况下模糊匹配比精确匹配好用</div>
        <div>2. 如果可以的话,请优先考虑根据uid精确屏蔽,而非使用用户名相关屏蔽,因用户名可以随意更改</div>
        <div>如果用户要添加自己的正则匹配相关的规则时,建议先去该网址进行测试再添加,避免浪费时间
          <el-link href="https://www.jyshare.com/front-end/854/" target="_blank"
                   type="primary">>>>正则表达式在线测试<<<
          </el-link>
        </div>
        <div>
          如果更新脚本之后规则全没了,请点击下面的【旧规则自动转新规则】按钮,进行转换,如不行请通过关于和问题反馈选项卡中的反馈渠道联系作者
        </div>
      </el-card>
      <el-card>
        <el-select v-model="selectVal" filterable>
          <el-option v-for="item in ruleInfoArr" :value="item.type" :key="item.type" :label="item.name"></el-option>
        </el-select>
        <el-divider/>
        <el-button-group>
          <el-button @click="operationBut('add')">添加{{ selectText }}</el-button>
          <el-button @click="operationBut('del')">移除{{ selectText }}</el-button>
          <el-button @click="setRuleBut">修改{{ selectText }}</el-button>
          <el-button @click="operationBut('find-item-all')">查询{{ selectText }}的内容</el-button>
        </el-button-group>
        <el-divider/>
        <el-button-group>
          <el-button @click="clearItemRuleBut" type="danger">清空{{ selectText }}项</el-button>
          <el-button type="danger" @click="operationBut('del_all')">全部移除</el-button>
        </el-button-group>
      </el-card>
      <rule_set_value_dialog/>
      </div>`,
        data() {
            return {
                selectVal: 'name',
                selectText: "",
                ruleActions: [
                    {
                        type: "uid",
                        name: "uid(精确)",
                    }
                ],
                ruleKeyArr: [],
                ruleInfoArr: [],
            }
        },
        methods: {
            setRuleBut() {
                const type = this.selectVal;
                const {name} = this.ruleInfoArr.find(item => item.type === type);
                eventEmitter.send('修改规则对话框', type, name);
            },
            operationBut(model) {
                const type = this.selectVal;
                if (model === "add") {
                    ruleUtil.showAddRuleInput(type);
                }
                if (model === "del") {
                    ruleUtil.showDelRuleInput(type);
                }
                if (model === "del_all") {
                    this.$confirm('确定要删除所有规则吗?').then(() => {
                        for (let x of this.ruleKeyArr) {
                            gmUtil.delData(x);
                        }
                        this.$alert("删除全部规则成功");
                        eventEmitter.send('刷新规则信息');
                    });
                }
                if (model === 'find-item-all') {
                    const ruleData = gmUtil.getData(type, []);
                    eventEmitter.send('展示内容对话框', JSON.stringify(ruleData, null, 4));
                }
            },
            clearItemRuleBut() {
                const type = this.selectVal;
                const find = this.ruleInfoArr.find(item => item.type === type);
                this.$confirm(`是要清空${find.name}的规则内容吗?`, 'tip').then(() => {
                    ruleKeyListData$1.clearKeyItem(type);
                    this.$alert(`已清空${find.name}的规则内容`);
                });
            }
        },
        watch: {
            selectVal(newVal) {
                console.log(newVal);
                const find = this.ruleInfoArr.find(item => item.type === newVal);
                this.selectText = find.name;
            }
        },
        created() {
            for (let newRuleKeyListElement of ruleUtil.getNewRuleKeyList()) {
                this.ruleKeyArr.push(newRuleKeyListElement.key);
                this.ruleInfoArr.push({
                    type: newRuleKeyListElement.key,
                    name: newRuleKeyListElement.name,
                });
            }
            const find = this.ruleInfoArr.find(item => item.type === this.selectVal);
            this.selectText = find.name;
        }
    };
    const oldToNewRule = () => {
        const listData = ruleKeyListData$1.getRuleKeyListData().filter(item => item.oldKey);
        for (let data of listData) {
            const oldKeyDataArr = gmUtil.getData(data.oldKey, []);
            if (oldKeyDataArr.length === 0) {
                continue
            }
            const newKeyDataArr = gmUtil.getData(data.key, []);
            if (newKeyDataArr.length === 0) {
                gmUtil.setData(data.key, oldKeyDataArr);
                gmUtil.delData(data.oldKey);
                continue
            }
            for (let v of oldKeyDataArr) {
                const isExist = newKeyDataArr.find(item => item === v);
                if (!isExist) {
                    newKeyDataArr.push(v);
                }
            }
            gmUtil.setData(data.key, newKeyDataArr);
        }
    };
    var ruleConversion = {
        oldToNewRule
    };
    const wait = (milliseconds = 1000) => {
        return new Promise(resolve => setTimeout(resolve, milliseconds));
    };
    const fileDownload = (content, fileName) => {
        const element = document.createElement('a');
        element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(content));
        element.setAttribute('download', fileName);
        element.style.display = 'none';
        document.body.appendChild(element);
        element.click();
        document.body.removeChild(element);
    };
    const handleFileReader = (event) => {
        return new Promise((resolve, reject) => {
            const file = event.target.files[0];
            if (!file) {
                reject('未读取到文件');
                return;
            }
            let reader = new FileReader();
            reader.onload = (e) => {
                const fileContent = e.target.result;
                resolve({file, content: fileContent});
                reader = null;
            };
            reader.readAsText(file);
        });
    };
    const isIterable = (obj) => {
        return obj != null && typeof obj[Symbol.iterator] === 'function';
    };
    const toTimeString = () => {
        return new Date().toLocaleString();
    };
    function smoothScroll(toTop = false, duration = 1000) {
        return new Promise((resolve) => {
            const start = window.scrollY;
            const end = toTop ? 0 : document.documentElement.scrollHeight - window.innerHeight;
            const change = end - start;
            const startTime = performance.now();
            function animateScroll(currentTime) {
                const elapsedTime = currentTime - startTime;
                const progress = Math.min(elapsedTime / duration, 1);
                const easeInOutQuad = progress < 0.5 ? 2 * progress * progress : -1 + (4 - 2 * progress) * progress;
                window.scrollTo(0, start + change * easeInOutQuad);
                if (progress < 1) {
                    requestAnimationFrame(animateScroll);
                } else {
                    resolve();
                }
            }
            requestAnimationFrame(animateScroll);
        });
    }
    function debounce(func, wait = 1000) {
        let timeout;
        return function (...args) {
            const context = this;
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(context, args), wait);
        };
    }
    function debounceAsync(asyncFunc, wait = 1000) {
        let timeout;
        let pendingPromise;
        return async function (...args) {
            const context = this;
            if (pendingPromise) {
                clearTimeout(timeout);
                await pendingPromise;
            }
            pendingPromise = new Promise((resolve) => {
                timeout = setTimeout(() => {
                    pendingPromise = null; // 清除引用
                    resolve(asyncFunc.apply(context, args));
                }, wait);
            });
            return pendingPromise;
        };
    }
    function throttle(func, limit) {
        let inThrottle;
        return function (...args) {
            const context = this;
            if (!inThrottle) {
                func.apply(context, args);
                inThrottle = true;
                setTimeout(() => inThrottle = false, limit);
            }
        };
    }
    function throttleAsync(asyncFunc, limit) {
        let isThrottled = false;
        let pendingArgs = null;
        let pendingContext = null;
        let timeoutId;
        let pendingPromiseResolve;
        const throttled = async function (...args) {
            const context = this;
            if (isThrottled) {
                return new Promise((resolve) => {
                    pendingArgs = args;
                    pendingContext = context;
                    pendingPromiseResolve = resolve;
                });
            }
            isThrottled = true;
            try {
                return await asyncFunc.apply(context, args);
            } finally {
                timeoutId = setTimeout(() => {
                    isThrottled = false;
                    if (pendingArgs) {
                        throttled.apply(pendingContext, pendingArgs).then(pendingPromiseResolve);
                        pendingArgs = null;
                        pendingContext = null;
                        pendingPromiseResolve = null;
                    }
                }, limit);
            }
        };
        throttled.cancel = () => {
            clearTimeout(timeoutId);
            isThrottled = false;
            pendingArgs = null;
            pendingContext = null;
            pendingPromiseResolve = null;
        };
        return throttled;
    }
    const parseUrl = (urlString) => {
        const url = new URL(urlString);
        const pathSegments = url.pathname.split('/').filter(segment => segment !== '');
        const searchParams = new URLSearchParams(url.search.slice(1));
        const queryParams = {};
        for (const [key, value] of searchParams.entries()) {
            queryParams[key] = value;
        }
        return {
            protocol: url.protocol,
            hostname: url.hostname,
            port: url.port,
            pathname: url.pathname,
            pathSegments,
            search: url.search,
            queryParams,
            hash: url.hash
        };
    };
    const getLocalStorage = (key, isList = false, defaultValue = null) => {
        const item = localStorage.getItem(key);
        if (item === null) {
            return defaultValue
        }
        if (isList) {
            try {
                return JSON.parse(item)
            } catch (e) {
                console.error(`读取localStorage时尝试转换${key}的值失败`, e);
                return defaultValue
            }
        }
        return item
    };
    var defUtil = {
        wait,
        fileDownload,
        toTimeString,
        smoothScroll,
        debounce,
        debounceAsync,
        throttle,
        throttleAsync,
        parseUrl,
        handleFileReader,
        isIterable,
        getLocalStorage
    };
    var rule_export_import_vue = {
        template: `
      <div>
      <el-card shadow="never">
        <template #header>
          <span>导出规则</span>
        </template>
        <button gz_type @click="ruleOutToFIleBut">导出到文件</button>
        <button gz_type @click="outToInputBut">导出到编辑框</button>
        <button gz_type @click="ruleOutToConsoleBut">导出到控制台</button>
      </el-card>
      <el-card shadow="never">
        <template #header>
          <el-row>
            <el-col :span="12">
              <div class="el-horizontal-left">导入规则</div>
            </el-col>
            <el-col :span="12">
              <div class="el-horizontal-right">
                <el-button v-for="item in ruleReference" @click="xtipAlertBut(item.content,item.title)">
                  {{ item.title }}
                </el-button>
              </div>
            </el-col>
          </el-row>
        </template>
        <div>规则内容请在下面编辑框中导入</div>
        <div>旧版本的需要使用下面的v1旧版本导入规则</div>
        <div>旧版本的只能覆盖导入</div>
        <div>v1之后的版本可以选择覆盖和追加</div>
        <div>旧规则转新规则,用于2.0之前版本升上来旧规则内容丢失问题</div>
        <el-divider/>
        <div>
          <button gz_type @click="inputFIleRuleBut">读取外部规则文件</button>
          <button gz_type @click="overwriteImportRulesBut">覆盖导入规则</button>
          <button gz_type @click="appendImportRulesBut">追加导入规则</button>
          <button gz_type @click="overwriteImportRulesV1But">v1旧版本覆盖导入规则</button>
          <button gz_type @click="ruleOldToNewBut">旧规则自动转新规则</button>
        </div>
        <el-divider/>
        <div>
          <el-input autosize
                    :autosize="{ minRows: 10, maxRows: 50}"
                    type="textarea" v-model="ruleContentImport" placeholder="要导入的规则内容"></el-input>
        </div>
      </el-card>
      <input ref="file" type="file" accept="application/json" @change="handleFileUpload"
             style="display: none">
      </div>`,
        data() {
            return {
                ruleContentImport: "",
                ruleReference: [
                    {
                        title: "旧版本规则参考",
                        content: ` {"用户名黑名单模式(精确匹配)":["账号已注销"],"BV号黑名单模式(精确匹配)":[],
                        "用户名黑名单模式(模糊匹配)":["bili_","_bili"],"用户uid黑名单模式(精确匹配)":[442010132,76525078,225219967,3493283164588093],
                        "用户uid白名单模式(精确匹配)":[344490740,1861980711],"标题黑名单模式(模糊匹配)":["激励计划","蚌不住","手游激励","游戏活动打卡"],
                        "标题黑名单模式(正则匹配)":["感觉.*不如","不要笑.*挑战"],"评论关键词黑名单模式(模糊匹配)":["感觉不如","差不多的了"],
                        "评论关键词黑名单模式(正则匹配)":["这不.+吗","玩.*的","不要笑.*挑战"],"粉丝牌黑名单模式(精确匹配)":[],
                        "专栏关键词内容黑名单模式(模糊匹配)":[],"动态关键词内容黑名单模式(模糊匹配)":["拼多多","京东红包","京东618红包","618活动"]}`
                    },
                    {
                        title: "新版本规则参考",
                        content: "待补充"
                    }
                ],
            }
        },
        methods: {
            overwriteImportRulesBut() {
                this.$confirm('是否要覆盖导入规则?').then(() => {
                    const trim = this.ruleContentImport.trim();
                    debugger
                    if (ruleUtil.overwriteImportRules(this.ruleKeyArr, trim)) {
                        this.$alert('已覆盖导入成功!');
                        eventEmitter.send('刷新规则信息');
                    }
                });
            },
            appendImportRulesBut() {
                this.$confirm('是否要追加导入规则?').then(() => {
                    const trim = this.ruleContentImport.trim();
                    if (ruleUtil.appendImportRules(this.ruleKeyArr, trim)) {
                        this.$message('已追加导入成功!');
                        eventEmitter.send('刷新规则信息');
                    }
                });
            },
            overwriteImportRulesV1But() {
                this.$confirm('旧版本-是否导入规则?').then(() => {
                    const trim = this.ruleContentImport.trim();
                    if (ruleUtil.overwriteImportRulesV1(trim)) {
                        this.$message('已导入成功!');
                        eventEmitter.send('刷新规则信息');
                    }
                });
            },
            xtipAlertBut(content, title) {
                this.$alert(content, title);
            },
            ruleOldToNewBut() {
                ruleConversion.oldToNewRule();
                eventEmitter.send('刷新规则信息');
                this.$message('已转换成功!');
            },
            handleFileUpload(event) {
                defUtil.handleFileReader(event).then(data => {
                    const {content} = data;
                    try {
                        JSON.parse(content);
                    } catch (e) {
                        this.$message('文件内容有误');
                        return;
                    }
                    this.ruleContentImport = content;
                    this.$message('读取到内容,请按需覆盖或追加');
                });
            },
            inputFIleRuleBut() {
                this.$refs.file.click();
            },
            outToInputBut() {
                this.ruleContentImport = ruleUtil.getRuleContent(2);
                this.$message('已导出到输入框中');
            },
            ruleOutToFIleBut() {
                const ruleContent = ruleUtil.getRuleContent(4);
                let fileName = "b站屏蔽器规则-" + defUtil.toTimeString();
                const s = prompt("保存为", fileName);
                if (s === null) return;
                if (!(s.includes(" ") || s === "" || s.length === 0)) fileName = s;
                defUtil.fileDownload(ruleContent, fileName + ".json");
            },
            ruleOutToConsoleBut() {
                console.log(ruleUtil.getRuleContent());
                this.$message('已导出到控制台上,F12打开控制台查看');
            },
        },
    };
    var other_parameter_filter = {
        template: `
      <div>
      <div style="display: flex">
        <div style="width: 70vw">
          <el-card>
            <template #header>
              <span>使用说明</span>
            </template>
            <ol>
              <li>如设置时长相关单位为秒</li>
              <li>如设置播放量和弹幕量相关单位为个</li>
              <li>设置最小播放量则小于该值的视频会屏蔽</li>
              <li>设置最大播放量则大于该值的视频会屏蔽</li>
              <li>设置最小弹幕量则小于该值的视频会屏蔽</li>
              <li>设置最大弹幕量则大于该值的视频会屏蔽</li>
              <li>设置最小时长则小于该值的视频会屏蔽</li>
              <li>设置最大时长则大于该值的视频会屏蔽</li>
              <li>设置最小用户等级则小于该值的会屏蔽,低于该值的会屏蔽掉</li>
              <li>设置最大用户等级则大于该值的会屏蔽,高于该值的会屏蔽掉</li>
              <li>取消相关限制条件则不做限制处理</li>
              <li>右侧信息关键条件-1则为未做任何限制处理</li>
              <li>最后因为设置限制条件冲突或限制太多,视频未能限制的情况下,请按需设置限制条件</li>
            </ol>
          </el-card>
          <input gz_type type="number" :min="inputMin" :max="inputMax" v-model="num">
          <el-select v-model="selectValue" filterable>
            <el-option :value="item.value" v-for="item in selectList" :label="item.name"></el-option>
          </el-select>
          <div>
            <button @click="okVideoSelectBut" gz_type>设置</button>
            <button @click="cancelBut" gz_type>取消</button>
            <button gz_type @click="allCancelBut">全部取消</button>
          </div>
        </div>
        <div>
          <el-button @click="updateInfoBut">刷新</el-button>
          <div v-for="item in selectList" style="padding: 5px">
            {{ item.name }}{{ item.defVal }}
            {{ item.name.includes('时长') ? '秒' : '' }}
          </div>
        </div>
      </div>
      </div>`,
        data() {
            return {
                num: 0,
                selectList: ruleKeyListData$1.otherKeyListData,
                selectValue: 'nMinimumPlay',
                inputMax: "",
                inputMin: 0
            }
        },
        methods: {
            okVideoSelectBut() {
                const find = this.selectList.find(item => item.value === this.selectValue);
                const associatedVal = gmUtil.getData(find.associated, -1);
                const associatedFind = this.selectList.find(item => item.value === find.associated);
                if (this.num > associatedVal && associatedVal !== -1) {
                    if (associatedFind.bLarge) {
                        this.$alert(`要设置的${find.name}值不能大于${associatedFind.name}的值`);
                        return
                    }
                    console.log('正常修改');
                }
                this.$alert(`已设置${find.name},值为${this.num}`);
                gmUtil.setData(this.selectValue, this.num);
                this.updateInfo();
            },
            cancelBut() {
                gmUtil.setData(this.selectValue, -1);
                const find = this.selectList.find(item => item.value === this.selectValue);
                this.$alert(`已取消${find.name}的限制`);
                this.updateInfo();
            },
            allCancelBut() {
                for (let item of this.selectList) {
                    gmUtil.setData(item.value, -1);
                }
                this.updateInfo();
            },
            updateInfo() {
                for (let item of this.selectList) {
                    item.defVal = gmUtil.getData(item.value, -1);
                }
            },
            updateInfoBut() {
                this.updateInfo();
                this.$alert('已刷新');
            },
        },
        watch: {
            selectValue(newVal) {
                const find = this.selectList.find(item => item.value === newVal);
                if (find.name.includes('用户等级')) {
                    this.inputMin = 3;
                    this.inputMax = 6;
                    if (this.num > 6) {
                        this.num = 6;
                    }
                    if (this.num < 3) {
                        this.num = 3;
                    }
                } else {
                    this.inputMin = 0;
                    this.inputMax = '';
                }
            }
        },
        created() {
            this.updateInfo();
        }
    };
    var rule_information_vue = {
        template: `
      <div>
      <h2>规则信息</h2>
      <button gz_type @click="refreshInfoBut">刷新信息</button>
      <div v-for="item in ruleInfoArr"
           style="padding: 5px">
        {{ item.name }}{{ item.len }}个
      </div>
      </div>`,
        data() {
            return {
                ruleInfoArr: [],
            }
        },
        methods: {
            refreshInfoBut() {
                for (let x of this.ruleInfoArr) {
                    x.len = gmUtil.getData(x.type, []).length;
                }
                this.$notify({
                    title: 'tip',
                    message: '刷新规则信息成功',
                    type: 'success',
                });
            },
        },
        created() {
            for (let newRuleKeyListElement of ruleUtil.getNewRuleKeyList()) {
                this.ruleInfoArr.push({
                    type: newRuleKeyListElement.key,
                    name: newRuleKeyListElement.name,
                    len: 0
                });
            }
            this.refreshInfoBut();
            eventEmitter.on('刷新规则信息', () => {
                this.refreshInfoBut();
            });
        }
    };
    var conditional_processing_vue = {
        template: `
      <div>
      <el-switch v-model="bOnlyTheHomepageIsBlocked" active-text="仅首页屏蔽生效屏蔽"/>
      <el-tooltip content="模糊和正则匹配时,将匹配词转小写与规则值匹配。修改后刷新页面生效">
        <el-switch v-model="bFuzzyAndRegularMatchingWordsToLowercase" active-text="模糊和正则匹配词转小写"></el-switch>
      </el-tooltip>
      </div>`,
        data() {
            return {
                bOnlyTheHomepageIsBlocked: localMKData.getBOnlyTheHomepageIsBlocked(),
                bFuzzyAndRegularMatchingWordsToLowercase: localMKData.bFuzzyAndRegularMatchingWordsToLowercase(),
            }
        },
        methods: {},
        watch: {
            bOnlyTheHomepageIsBlocked(newVal) {
                localMKData.setBOnlyTheHomepageIsBlocked(newVal);
            },
            bFuzzyAndRegularMatchingWordsToLowercase(newVal) {
                localMKData.setFuzzyAndRegularMatchingWordsToLowercase(newVal);
            }
        },
        created() {
        }
    };
    var ruleManagementVue = {
        components: {
            rule_export_import_vue,
            other_parameter_filter,
            rule_information_vue,
            conditional_processing_vue,
            basic_rules_vue
        },
        template: `
      <div>
      <el-tabs type="border-card" tab-position="left">
        <el-tab-pane label="基础规则">
          <basic_rules_vue/>
        </el-tab-pane>
        <el-tab-pane label="其他规则">
          <other_parameter_filter/>
        </el-tab-pane>
        <el-tab-pane label="高级规则">待补充</el-tab-pane>
        <el-tab-pane label="导出导入">
          <rule_export_import_vue/>
        </el-tab-pane>
        <el-tab-pane label="条件处理">
          <conditional_processing_vue/>
        </el-tab-pane>
        <el-tab-pane label="规则信息">
          <rule_information_vue/>
        </el-tab-pane>
      </el-tabs>
      </div>`,
        data() {
            return {}
        }
    };
    const compatible_setting_vue = {
        template: `
      <div>
      <div>
        <el-checkbox v-model="adaptationBAppRecommend">首页屏蔽适配Bilibili-Gate脚本(bilibili-app-recommend)
        </el-checkbox>
      </div>
      <div>
        <el-tooltip content="使用之后需刷新对应页面才可生效,勾选即评论区使用新版获取方式,不再使用旧版方式"
                    placement="top">
          <el-checkbox v-model="discardOldCommentAreasV">弃用旧版评论区处理</el-checkbox>
        </el-tooltip>
      </div>
      <div>
        <el-checkbox v-model="compatible_BEWLY_BEWLY">兼容BewlyBewly插件</el-checkbox>
      </div>
      </div>`,
        data() {
            return {
                adaptationBAppRecommend: localMKData.getAdaptationBAppCommerce(),
                compatible_BEWLY_BEWLY: localMKData.isCompatible_BEWLY_BEWLY(),
                discardOldCommentAreasV: localMKData.isDiscardOldCommentAreas()
            }
        },
        watch: {
            adaptationBAppRecommend(newVal) {
                localMKData.setAdaptationBAppCommerce(newVal);
            },
            compatible_BEWLY_BEWLY(newVal) {
                localMKData.setCompatible_BEWLY_BEWLY(newVal);
            },
            discardOldCommentAreasV(newVal) {
                localMKData.setDiscardOldCommentAreas(newVal);
            }
        }
    };
    const mk_db = new Dexie('mk-db');
    mk_db.version(1).stores({
        videoInfos: 'bv,tags,userInfo,videoInfo',
    });
    const addVideoData = async (bv, data) => {
        const {tags, userInfo, videoInfo} = data;
        try {
            await mk_db.videoInfos.add({
                bv, tags, userInfo, videoInfo
            });
        } catch (e) {
            console.log(`添加视频数据失败`, data, e);
            return false
        }
        return true
    };
    const bulkImportVideoInfos = async (friendsData) => {
        try {
            const lastKeyItem = await mk_db.videoInfos.bulkPut(friendsData);
            console.info('批量导入成功,最后一个插入的主键:', lastKeyItem);
            return {state: true, lastKeyItem}
        } catch (error) {
            console.error('批量导入时出错:', error);
            return {state: false, error}
        }
    };
    const getVideoInfo = async () => {
        return await mk_db.videoInfos.toArray()
    };
    const clearVideoInfosTable = async () => {
        try {
            await mk_db.videoInfos.clear();
            return true
        } catch (e) {
            console.log('清除videoInfos表失败', e);
            return false
        }
    };
    var bvDexie = {
        addVideoData,
        clearVideoInfosTable,
        bulkImportVideoInfos,
        getVideoInfo
    };
    const cache_management_vue = {
        template: `
      <div>
      <ol>
        <li>每个域名中的缓存数据不同</li>
        <li>仅仅支持导入json格式</li>
        <li>下面导入默认追加模式</li>
      </ol>
      <div>当前域名:{{ hostname }}</div>
      <button gz_type @click="outDbDataBut">导出当前域名的缓存数据</button>
      <input ref="inputDemo" type="file" @change="handleFileUpload" accept="application/json"
             style="display: none">
      <button @click="inputFIleBut" gz_type>追加导入视频缓存数据</button>
      <button gz_type @click="clearPageVideoCacheDataBut">清空当前域名的视频缓存数据</button>
      </div>`,
        data() {
            return {
                hostname: window.location.hostname
            }
        },
        methods: {
            outDbDataBut() {
                bvDexie.getVideoInfo().then((data) => {
                    if (data.length === 0) {
                        this.$message('当前域名下没有缓存视频数据');
                        return
                    }
                    data = {
                        hostName: this.hostname,
                        size: data.length,
                        data: data
                    };
                    defUtil.fileDownload(JSON.stringify(data, null, 4), 'mk-db-videoInfos-cache.json');
                    this.$message('已导出当前域名的缓存数据');
                    console.log(data);
                });
            },
            handleFileUpload(event) {
                defUtil.handleFileReader(event).then(data => {
                    const {content} = data;
                    let parse;
                    try {
                        parse = JSON.parse(content);
                    } catch (e) {
                        this.$message('文件内容有误');
                        return;
                    }
                    const {hostName = null, videoInfos = []} = parse;
                    if (!hostName) {
                        this.$message('hostName字段不存在');
                        return;
                    }
                    if (!defUtil.isIterable(videoInfos)) {
                        this.$message('文件内容有误,非可迭代的数组!');
                        return;
                    }
                    if (videoInfos.length === 0) {
                        this.$message('tags数据为空');
                        return;
                    }
                    for (let item of videoInfos) {
                        if (!item['bv']) {
                            this.$message('bv字段不存在');
                            return;
                        }
                        if (!item['tags']) {
                            this.$message('tags字段不存在');
                            return;
                        }
                        if (!item['userInfo']) {
                            this.$message('userInfo字段不存在');
                            return;
                        }
                        if (!item['videoInfo']) {
                            this.$message('videoInfo字段不存在');
                            return;
                        }
                    }
                    bvDexie.bulkImportVideoInfos(videoInfos).then((bool) => {
                        if (bool) {
                            this.$message('导入成功');
                        } else {
                            this.$message('导入失败');
                        }
                    });
                });
            },
            inputFIleBut() {
                this.$refs.inputDemo.click();
            },
            clearPageVideoCacheDataBut() {
                this.$confirm('是否清空当前域名下的tags数据').then(() => {
                    bvDexie.clearVideoInfosTable().then((bool) => {
                        if (bool) {
                            this.$message('已清空当前域名下的视频缓存数据');
                        } else {
                            this.$message('清空失败');
                        }
                    });
                });
            }
        },
        created() {
        }
    };
    var donateLayoutVue = {
        template: `
      <div>
      <el-card shadow="hover">
        <template #header>
          <span>零钱赞助</span>
        </template>
        <span>1元不嫌少,10元不嫌多,感谢支持!</span>
        <el-divider/>
        <span>生活不易,作者叹息</span>
        <el-divider/>
        <span>您的支持是我最大的更新动力</span>
      </el-card>
      <el-divider/>
      <div class="el-vertical-center">
        <el-avatar size="large"
                   src="//i0.hdslb.com/bfs/face/87e9c69a15f7d2b68294be165073c8e07a541e28.jpg@128w_128h_1c_1s.webp"></el-avatar>
      </div>
      <div class="el-vertical-center">
        <el-button round type="primary" @click="showDialogBut">打赏点猫粮</el-button>
      </div>
      <el-dialog
          center
          :title="dialogIni.title"
          :visible.sync="dialogIni.show">
        <div class="el-vertical-center">
          <el-image v-for="item in list"
                    :src="item.src"
                    style="height: 300px"
                    :preview-src-list="dialogIni.srcList"/>
        </div>
      </el-dialog>
      </div>`,
        data() {
            return {
                list: [
                    {
                        name: "支付宝赞助",
                        alt: "支付宝支持",
                        src: "https://www.mikuchase.ltd/img/paymentCodeZFB.webp"
                    },
                    {name: "微信赞助", alt: "微信支持", src: "https://www.mikuchase.ltd/img/paymentCodeWX.webp"},
                    {name: "QQ赞助", alt: "QQ支持", src: "https://www.mikuchase.ltd/img/paymentCodeQQ.webp"},
                ],
                dialogIni: {
                    title: "打赏点猫粮",
                    show: false,
                    srcList: []
                }
            }
        },
        methods: {
            showDialogBut() {
                this.dialogIni.show = true;
            }
        },
        created() {
            this.dialogIni.srcList = this.list.map(x => x.src);
        }
    };
    const outputInformationFontColor$1 = localMKData.getOutputInformationFontColor();
    const highlightInformationColor$1 = localMKData.getHighlightInformationColor();
    var outputInformationVue = {
        template: `
      <div>
      <el-button type="info" @click="clearInfoBut">清空消息</el-button>
      <div v-for="item in outputInfoArr" v-html="item"></div>
      </div>`,
        data() {
            return {
                outputInfoArr: [],
            }
        },
        methods: {
            clearInfoBut() {
                this.$confirm('是否清空信息', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.outputInfoArr = [];
                    this.$message('已清空信息');
                });
            }
        },
        created() {
            eventEmitter.on('打印信息', (content) => {
                const liEL = document.createElement("li");
                liEL.innerHTML = content;
                this.outputInfoArr.push(liEL.innerHTML);
            });
            eventEmitter.on('屏蔽视频信息', (type, matching, videoData) => {
                const toTimeString = defUtil.toTimeString();
                const {name, uid, title, videoUrl} = videoData;
                const info = `<b style="color: ${outputInformationFontColor$1}; " gz_bezel>
${toTimeString}-根据${type}-${matching ? `<b style="color: ${highlightInformationColor$1}">【${matching}】</b>` : ""}-屏蔽用户【${name}】uid=
            <a href="https://space.bilibili.com/${uid}" 
            style="color: ${highlightInformationColor$1}"
            target="_blank">【${uid}】</a>
            标题【<a href="${videoUrl}" target="_blank" style="color: ${highlightInformationColor$1}">${title}</a>】
            </b>`;
                this.outputInfoArr.push(info);
            });
            eventEmitter.on('屏蔽评论信息', (type, matching, commentData) => {
                const toTimeString = defUtil.toTimeString();
                const {name, uid, content} = commentData;
                this.outputInfoArr.push(`<b style="color: ${outputInformationFontColor$1}; " gz_bezel>
${toTimeString}-根据${type}-${matching ? `<b style="color: ${highlightInformationColor$1}">【${matching}】</b>` : ""}-屏蔽用户【${name}】uid=
            <a href="https://space.bilibili.com/${uid}" 
            style="color: ${highlightInformationColor$1}"
            target="_blank">【${uid}】</a>
            评论【${content}】
            </b>`);
            });
            eventEmitter.on('正则匹配时异常', (errorData) => {
                const {msg, e} = errorData;
                this.outputInfoArr.push(msg);
                console.error(msg);
                throw new Error(e)
            });
        }
    };
    const look_content_dialog_vue = {
        template: `
      <div>
      <el-dialog
          :fullscreen="true"
          title="提示"
          :visible.sync="dialogVisible"
          width="30%"
          :before-close="handleClose">
        <el-input autosize
                  type="textarea"
                  v-model="content"></el-input>
        <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
  </span>
      </el-dialog>
      </div>`,
        data() {
            return {
                dialogVisible: false,
                content: ''
            }
        },
        methods: {
            handleClose(done) {
                this.$confirm('确认关闭?')
                    .then(_ => {
                        done();
                    })
                    .catch(_ => {
                    });
            }
        },
        created() {
            eventEmitter.on('展示内容对话框', (newContent) => {
                this.content = newContent;
                this.$message('已更新内容');
                this.dialogVisible = true;
            });
        }
    };
    class ValueCache {
        #mapCache = new Map();
        set(key, value) {
            this.#mapCache.set(key, value);
            return value;
        }
        get(key, defaultValue = null) {
            const newVar = this.#mapCache.get(key);
            if (newVar) {
                return newVar;
            }
            return defaultValue;
        }
        getAll() {
            return this.#mapCache;
        }
    }
    const valueCache = new ValueCache();
    var video_zone = {
      "动画": [
        "MAD·AMV",
        "MMD·3D",
        "短片·手书",
        "配音",
        "手办·模玩",
        "特摄",
        "动漫杂谈"
      ],
      "番剧": [
        "资讯",
        "官方延伸",
        "完结动画"
      ],
      "国创": [
        "国产动画",
        "国产原创相关",
        "布袋戏",
        "资讯"
      ],
      "音乐": [
        "原创音乐",
        "翻唱",
        "VOCALOID·UTAU",
        "演奏",
        "MV",
        "音乐现场",
        "音乐综合",
        "乐评盘点",
        "音乐教学"
      ],
      "舞蹈": [
        "宅舞",
        "舞蹈综合",
        "舞蹈教程",
        "街舞",
        "明星舞蹈",
        "国风舞蹈"
      ],
      "游戏": [
        "单机游戏",
        "电子竞技",
        "手机游戏",
        "网络游戏",
        "桌游棋牌",
        "GMV",
        "音游"
      ],
      "知识": [
        "科学科普",
        "社科·法律·心理(原社科人文、原趣味科普人文)",
        "人文历史",
        "财经商业",
        "校园学习",
        "职业职场",
        "设计·创意",
        "野生技术协会",
        "演讲·公开课(已下线)",
        "星海(已下线)"
      ],
      "科技": [
        "数码(原手机平板)",
        "软件应用",
        "计算机技术",
        "科工机械 (原工业·工程·机械)",
        "极客DIY",
        "电脑装机(已下线)",
        "摄影摄像(已下线)"
      ],
      "运动": [
        "篮球",
        "足球",
        "健身",
        "竞技体育",
        "运动文化"
      ],
      "汽车": [
        "汽车知识科普",
        "赛车",
        "改装玩车",
        "新能源车",
        "房车",
        "摩托车",
        "购车攻略",
        "汽车生活",
        "汽车文化(已下线)",
        "汽车极客(已下线)"
      ],
      "生活": [
        "搞笑",
        "出行",
        "三农",
        "家居房产",
        "手工",
        "绘画",
        "日常",
        "亲子",
        "美食圈(重定向)",
        "动物圈(重定向)",
        "运动(重定向)",
        "汽车(重定向)"
      ],
      "美食": [
        "美食制作(原[生活]->[美食圈])",
        "美食侦探",
        "美食测评",
        "田园美食"
      ],
      "动物圈": [
        "喵星人",
        "汪星人",
        "动物二创",
        "野生动物",
        "小宠异宠"
      ],
      "鬼畜": [
        "鬼畜调教",
        "音MAD",
        "人力VOCALOID",
        "鬼畜剧场"
      ],
      "时尚": [
        "美妆护肤",
        "仿妆cos",
        "穿搭",
        "时尚潮流",
        "健身(重定向)"
      ],
      "资讯": [
        "热点",
        "环球",
        "社会"
      ],
      "广告": [],
      "娱乐": [
        "综艺",
        "娱乐杂谈",
        "粉丝创作",
        "明星综合"
      ],
      "影视": [
        "影视杂谈",
        "影视剪辑",
        "小剧场",
        "预告·资讯"
      ],
      "纪录片": [
        "人文·历史",
        "科学·探索·自然",
        "军事"
      ],
      "电影": [
        "华语电影",
        "欧美电影",
        "日本电影"
      ],
      "电视剧": [
        "国产剧"
      ]
    };
    const findKey = (itemKey) => {
        for (let key in video_zone) {
            const arr = video_zone[key];
            if (arr.some((i) => i === itemKey)) return key;
        }
        return null;
    };
    var video_zoneData = {findKey};
    const fetchGetVideoInfo = async (bvId) => {
        const response = await fetch(`https://api.bilibili.com/x/web-interface/view/detail?bvid=${bvId}`);
        const {code, data, message} = await response.json();
        const defData = {state: false, msg: '默认失败信息'};
        if (code !== 0) {
            defData.msg = message;
            return defData
        }
        defData.state = true;
        defData.msg = '获取成功';
        const {
            View: {
                staff,
                tname,
                tname_v2,
                desc,
                pubdate,
                ctime,
                copyright,
                is_upower_exclusive,
                duration,
                stat: {
                    view,
                    danmaku,
                    reply,
                    favorite,
                    coin,
                    share
                },
            }, Card: {
                follower,
                like_num,
                archive_count,
                article_count, card: {
                    mid: uid,
                    name,
                    sex, level_info: {
                        current_level
                    },
                    pendant,
                    nameplate,
                    Official,
                    official_verify,
                    vip,
                }
            }, Tags,
            participle
        } = data;
        const videoInfo = {
            staff,
            tname,
            tname_v2,
            desc,
            pubdate,
            ctime,
            copyright,
            is_upower_exclusive,
            duration,
            view,
            danmaku,
            reply,
            favorite,
            coin,
            share,
            participle,
        };
        const userInfo = {
            follower,
            like_num,
            archive_count,
            article_count,
            Official,
            official_verify,
            vip,
            uid,
            name,
            sex,
            current_level,
            pendant,
            nameplate
        };
        const tags = [];
        for (let tag of Tags) {
            tags.push(tag['tag_name']);
        }
        tags.unshift(tname, tname_v2);
        const findKey = video_zoneData.findKey(tname);
        if (findKey) {
            tags.unshift(findKey);
        }
        defData.data = {videoInfo, userInfo, tags};
        return defData
    };
    var bFetch = {
        fetchGetVideoInfo
    };
    const isDisableNetRequestsBvVideoInfo = () => {
        return gmUtil.getData('isDisableNetRequestsBvVideoInfo', false)
    };
    const setDisableNetRequestsBvVideoInfo = (b) => {
        gmUtil.setData('isDisableNetRequestsBvVideoInfo', b);
    };
    const bAfterLoadingThePageOpenMainPanel = () => {
        return gmUtil.getData('bAfterLoadingThePageOpenMainPanel', false)
    };
    const setBAfterLoadingThePageOpenMainPanel = (b) => {
        gmUtil.setData('bAfterLoadingThePageOpenMainPanel', b === true);
    };
    const debugger_management_vue = {
        template: `
      <div>
      <ol>
        <li>仅供测试</li>
      </ol>
      <el-card shadow="never">
        <template #header><span>测试</span></template>
        <el-button @click="demoBut">测试网络请求</el-button>
        <el-button @click="demo1but">测试对话框</el-button>
        <el-button @click="printValueCacheBut">打印valueCache值</el-button>
        <el-button @click="printEventBut">打印事件中心值</el-button>
        <el-divider/>
        <el-switch v-model="isDisableNetRequestsBvVideoInfo" active-text="禁用根据bv号网络请求获取视频信息"/>
        <el-switch v-model="bAfterLoadingThePageOpenMainPanel" active-text="加载完页面打开主面板"/>
      </el-card>
      </div>`,
        data() {
            return {
                isDisableNetRequestsBvVideoInfo: isDisableNetRequestsBvVideoInfo(),
                bAfterLoadingThePageOpenMainPanel: bAfterLoadingThePageOpenMainPanel()
            }
        },
        methods: {
            printValueCacheBut() {
                console.log(valueCache.getAll());
            },
            demoBut() {
                bFetch.fetchGetVideoInfo('BV152cWeXEhW').then(data => {
                    console.log(data);
                    debugger
                });
            },
            demo1but() {
                this.$alert('这是一段内容', '标题名称', {
                    confirmButtonText: '确定',
                    callback: action => {
                        this.$message({
                            type: 'info',
                            message: `action: ${action}`
                        });
                    }
                });
            },
            printEventBut() {
                console.log(eventEmitter.getEvents());
            }
        },
        watch: {
            isDisableNetRequestsBvVideoInfo(b) {
                setDisableNetRequestsBvVideoInfo(b);
            },
            bAfterLoadingThePageOpenMainPanel(b) {
                setBAfterLoadingThePageOpenMainPanel(b);
            }
        }
    };
    const getUrlUID = (url) => {
        let uid;
        if (url.startsWith('http')) {
            const parseUrl = defUtil.parseUrl(url);
            uid = parseUrl.pathSegments[0]?.trim();
            return parseInt(uid)
        }
        const isDoYouHaveAnyParameters = url.indexOf('?');
        const lastIndexOf = url.lastIndexOf("/");
        if (isDoYouHaveAnyParameters === -1) {
            if (url.endsWith('/')) {
                const nTheIndexOfTheLastSecondOccurrenceOfTheSlash = url.lastIndexOf('/', url.length - 2);
                uid = url.substring(nTheIndexOfTheLastSecondOccurrenceOfTheSlash + 1, url.length - 1);
            } else {
                uid = url.substring(lastIndexOf + 1);
            }
        } else {
            uid = url.substring(lastIndexOf + 1, isDoYouHaveAnyParameters);
        }
        return parseInt(uid);
    };
    const getUrlBV = (url) => {
        let match = url.match(/video\/(.+)\//);
        if (match === null) {
            match = url.match(/video\/(.+)\?/);
        }
        if (match === null) {
            match = url.match(/video\/(.+)/);
        }
        return match?.[1]?.trim() || null;
    };
    function findElementUntilFound(selector, config = {}) {
        const defConfig = {
            doc: document,
            interval: 1000,
            timeout: -1,
        };
        config = {...defConfig, ...config};
        return new Promise((resolve, reject) => {
            const i1 = setInterval(() => {
                const element = config.doc.querySelector(selector);
                if (element) {
                    resolve(element);
                    clearInterval(i1);
                }
            }, config.interval);
            if (config.timeout > 0) {
                setTimeout(() => {
                    clearInterval(i1);
                    reject(null); // 超时则返回 null
                }, config.timeout);
            }
        });
    }
    const findElement = async (selector, config = {}) => {
        try {
            const defConfig = {
                doc: document,
                interval: 1000,
                timeout: -1,
            };
            config = {...defConfig, ...config};
            const el = await findElementUntilFound(selector, config);
            if (config.timeout === -1) {
                return el
            }
            return {state: true, data: el}
        } catch (e) {
            return {state: false, data: e}
        }
    };
    const findElements = async (selector, config = {}) => {
        const defConfig = {doc: document, interval: 1000, timeout: -1};
        config = {...defConfig, ...config};
        try {
            const elList = await findElementsUntilFound(selector, config);
            if (config.timeout === -1) {
                return elList
            }
            return {state: true, data: elList}
        } catch (e) {
            return {state: false, data: e}
        }
    };
    function findElementsUntilFound(selector, config = {}) {
        const defConfig = {doc: document, interval: 1000, timeout: -1};
        config = {...defConfig, ...config};
        return new Promise((resolve, reject) => {
            const i1 = setInterval(() => {
                const elements = config.doc.querySelectorAll(selector);
                if (elements.length > 0) {
                    resolve(Array.from(elements));
                    clearInterval(i1);
                }
            }, config.interval);
            if (config.timeout > 0) {
                setTimeout(() => {
                    clearInterval(i1);
                    reject(null); // 超时则返回 null
                }, config.timeout);
            }
        });
    }
    const findElementsAndBindEvents = (css, callback, config = {}) => {
        config = {
            ...{
                interval: 2000,
                timeOut: 3000
            }, config
        };
        setTimeout(() => {
            findElementUntilFound(css, {interval: config.interval}).then((el) => {
                el.addEventListener("click", () => {
                    callback();
                });
            });
        }, config.timeOut);
    };
    var elUtil = {
        getUrlUID,
        getUrlBV,
        findElement,
        findElements,
        findElementUntilFound,
        findElementsUntilFound,
        findElementsAndBindEvents
    };
    const setTopInputPlaceholder = async () => {
        if (localMKData.isCompatible_BEWLY_BEWLY()) {
            return
        }
        const placeholder = valueCache.get('topInputPlaceholder');
        if (placeholder === null) {
            return
        }
        const targetInput = await elUtil.findElement('.nav-search-input');
        targetInput.placeholder = placeholder;
        eventEmitter.send('el-notification', {
            title: "tip",
            message: '已恢复顶部搜索框提示内容',
            position: 'bottom-right',
        });
    };
    const processTopInputContent = async () => {
        if (localMKData.isCompatible_BEWLY_BEWLY()) {
            return
        }
        if (!gmUtil.getData('isClearTopInputTipContent', false)) {
            return;
        }
        const targetInput = await elUtil.findElement('.nav-search-input');
        if (targetInput.placeholder === '') {
            await defUtil.wait(1500);
            await processTopInputContent();
            return
        }
        valueCache.set('topInputPlaceholder', targetInput.placeholder);
        targetInput.placeholder = '';
        eventEmitter.send('el-msg', '清空了搜索框提示内容');
    };
    eventEmitter.on('执行清空顶部搜索框提示内容', () => {
        processTopInputContent();
    });
    var topInput = {processTopInputContent, setTopInputPlaceholder};
    const page_processing_vue = {
        template: `
      <div>
      <el-card>
        <template #header>
          <span>搜索页</span>
        </template>
        <el-switch v-model="isRemoveSearchBottomContent"
                   active-text="屏蔽底部额外内容"/>
      </el-card>
      <el-card>
        <template #header>
          <span>播放页</span>
        </template>
        <el-switch v-model="isDelPlayerPageAd" active-text="屏蔽页面元素广告"/>
        <el-switch v-model="isDelPlayerPageRightGameAd" active-text="屏蔽右侧游戏推荐"/>
        <el-tooltip content="移除整个推荐列表,状态刷新生效">
          <el-switch v-model="isDelPlayerPageRightVideoList" active-text="移除右侧推荐列表"/>
        </el-tooltip>
        <el-tooltip content="状态刷新生效">
          <el-switch v-model="isDelBottomComment" active-text="移除评论区"/>
        </el-tooltip>
      </el-card>
      <el-card>
        <template #header>
          <span>顶部搜索框</span>
        </template>
        <el-switch v-model="isClearTopInputTipContent" active-text="清空内容"/>
      </el-card>
      </div>`,
        data() {
            return {
                isRemoveSearchBottomContent: gmUtil.getData('isRemoveSearchBottomContent', false),
                isDelPlayerPageAd: gmUtil.getData('isDelPlayerPageAd', false),
                isDelPlayerPageRightGameAd: gmUtil.getData('isDelPlayerPageRightGameAd', false),
                isDelPlayerPageRightVideoList: localMKData.isDelPlayerPageRightVideoList(),
                isDelBottomComment: gmUtil.getData('isDelBottomComment', false),
                isClearTopInputTipContent: gmUtil.getData('isClearTopInputTipContent', false),
            }
        },
        methods: {},
        watch: {
            isRemoveSearchBottomContent(b) {
                gmUtil.setData('isRemoveSearchBottomContent', b);
            },
            isDelPlayerPageAd(b) {
                gmUtil.setData('isDelPlayerPageAd', b);
            },
            isDelPlayerPageRightGameAd(b) {
                gmUtil.setData('isDelPlayerPageRightGameAd', b);
            },
            isDelPlayerPageRightVideoList(b) {
                gmUtil.setData('isDelPlayerPageRightVideoList', b);
            },
            isDelBottomComment(b) {
                gmUtil.setData('isDelBottomComment', b);
            },
            isClearTopInputTipContent(b) {
                gmUtil.setData('isClearTopInputTipContent', b);
                if (b) {
                    eventEmitter.send('执行清空顶部搜索框提示内容');
                    return
                }
                topInput.setTopInputPlaceholder();
            }
        }
    };
    const about_and_feedback_vue = {
        template: `
      <div>
      <el-card>
        <template #header>
          <span>作者b站</span>
        </template>
        <el-link target="_blank" href="https://space.bilibili.com/473239155" type="primary">b站传送门</el-link>
      </el-card>
      <el-card>
        <template #header>
          <span>交流群</span>
        </template>
        <el-link
            :href='group_url' target="_blank" type="primary">====》Q群传送门《====
        </el-link>
        <el-tooltip content="点击查看群二维码">
          <el-tag @click="lookImgBut">876295632</el-tag>
        </el-tooltip>
      </el-card>
      <el-card>
        <template #header>
          <span>发布、更新、反馈地址</span>
        </template>
        <el-row>
          <el-col :span="12">
            <el-card>
              <span>greasyfork</span>
              <el-link target="_blank" type="primary" href="https://greasyfork.org/scripts/461382/">===》传送门《===
              </el-link>
            </el-card>
          </el-col>
          <el-col :span="12">
            <el-card>
              <span>脚本猫</span>
              <el-link target="_blank" type="primary" :href="scriptCat_js_url">
                ===》传送门《===
              </el-link>
            </el-card>
          </el-col>
        </el-row>
      </el-card>
      <el-card>
        <template #header>
          <span>开源地址</span>
        </template>
        <el-row>
          <el-col :span="12">
            <el-card>
              <span>gitee</span>
              <el-link target="_blank" type="primary" href="https://gitee.com/hangexi/BiBiBSPUserVideoMonkeyScript"
              >https://gitee.com/hangexi/BiBiBSPUserVideoMonkeyScript
              </el-link>
            </el-card>
          </el-col>
          <el-col :span="12">
            <el-card>
              <span>github</span>
              <el-link target="_blank" type="primary" href="https://github.com/hgztask/BiBiBSPUserVideoMonkeyScript"
              >https://github.com/hgztask/BiBiBSPUserVideoMonkeyScript
              </el-link>
            </el-card>
          </el-col>
        </el-row>
      </el-card>
      </div>`,
        data() {
            return {
                group_url: globalValue.group_url,
                scriptCat_js_url: globalValue.scriptCat_js_url
            }
        },
        methods: {
            lookImgBut() {
                eventEmitter.send('显示图片对话框', {image: "https://www.mikuchase.ltd/img/qq_group_876295632.webp"});
            }
        },
        created() {
        }
    };
    const show_img_dialog_vue = {
        template: `
      <div>
      <el-dialog
          center
          :title="title"
          :modal="isModal"
          :visible.sync="show">
        <div class="el-vertical-center">
          <el-image
              :src="imgSrc" :preview-src-list="imgList"/>
        </div>
      </el-dialog>
      </div>`,
        data() {
            return {
                show: false,
                title: "图片查看",
                imgList: [],
                imgSrc: '',
                isModal: true
            }
        },
        created() {
            eventEmitter.on('显示图片对话框', ({image, title, images, isModal}) => {
                this.imgSrc = image;
                if (title) {
                    this.title = title;
                }
                if (images) {
                    this.imgList = images;
                } else {
                    this.imgList = [image];
                }
                if (isModal) {
                    this.isModal = isModal;
                }
                this.show = true;
            });
        }
    };
    const sheet_dialog_vue = {
        props: {
            show: {
                type: Boolean,
                default: false
            },
            list: {
                type: Array,
                default: () => []
            },
            closeOnClickModal: {
                type: Boolean,
                default: true
            },
            title: {
                type: String,
                default: '选项'
            },
            clickItemClose: {
                type: Boolean,
                default: false
            }
        },
        template: `
      <div>
      <el-dialog :visible="show" :title="title"
                 width="30%" center
                 :close-on-click-modal="closeOnClickModal"
                 @close="$emit('close')">
        <div>
          <el-row>
            <el-col v-for="item in list" :key="item.label">
              <el-button style="width: 100%" @click="handleClick(item)">项目{{ item.label }}</el-button>
            </el-col>
          </el-row>
        </div>
      </el-dialog>
      </div>`,
        data() {
            return {
                dialogShow: true,
                list: []
            }
        },
        methods: {
            handleClick(item) {
                if (this.clickItemClose) {
                    return;
                }
                this.$emit('options-click', item);
            }
        }
    };
    const mainLayoutEl = document.createElement('div');
    if (document.head.querySelector('#element-ui-css') === null) {
        const linkElement = document.createElement('link');
        linkElement.rel = 'stylesheet';
        linkElement.href = 'https://unpkg.com/element-ui/lib/theme-chalk/index.css';
        linkElement.id = 'element-ui-css';
        document.head.appendChild(linkElement);
        console.log('挂载element-ui样式成功');
    }
    window.addEventListener('load', () => {
        document.body.appendChild(mainLayoutEl);
        new Vue({
            el: mainLayoutEl,
            template: `
          <div>
          <el-drawer style="position: fixed"
                     :visible.sync="drawer"
                     direction="ltr"
                     size="100%"
                     :modal="false"
                     :with-header="false">
            <el-tabs type="border-card" v-model="tabsActiveName"
                     @tab-click="tabClick">
              <el-tab-pane label="面板设置" name="面板设置" lazy>
                <panel_settings_vue/>
              </el-tab-pane>
              <el-tab-pane label="规则管理" name="规则管理" lazy>
                <rule_management_vue/>
              </el-tab-pane>
              <el-tab-pane label="兼容设置" name="兼容设置" lazy>
                <compatible_setting_vue/>
              </el-tab-pane>
              <el-tab-pane label="缓存管理" name="缓存管理" lazy>
                <cache_management_vue/>
              </el-tab-pane>
              <el-tab-pane label="页面处理" name="页面处理" lazy>
                <page_processing_vue/>
              </el-tab-pane>
              <el-tab-pane label="输出信息" name="输出信息" lazy>
                <output_information_vue/>
              </el-tab-pane>
              <el-tab-pane label="支持打赏" name="支持打赏" lazy>
                <donate_layout_vue/>
              </el-tab-pane>
              <el-tab-pane label="关于和问题反馈" name="关于和问题反馈" lazy>
                <about_and_feedback_vue/>
              </el-tab-pane>
              <el-tab-pane label="调试测试" name="调试测试" lazy v-if="debug_panel_show">
                <div v-show="debug_panel_show">
                  <debugger_management_vue/>
                </div>
              </el-tab-pane>
            </el-tabs>
          </el-drawer>
          <look_content_dialog_vue/>
          <show_img_dialog_vue/>
          <sheet_dialog_vue :show="sheet_dialog.show" :list="sheet_dialog.list" :title="sheet_dialog.title"
                            @close="handleClose"
                            :close-on-click-modal="sheet_dialog.closeOnClickModal" @options-click="handleOptionsClick"/>
          </div>`,
            components: {
                output_information_vue: outputInformationVue,
                donate_layout_vue: donateLayoutVue,
                rule_management_vue: ruleManagementVue,
                cache_management_vue,
                panel_settings_vue,
                compatible_setting_vue,
                look_content_dialog_vue,
                debugger_management_vue,
                page_processing_vue,
                about_and_feedback_vue,
                show_img_dialog_vue,
                sheet_dialog_vue
            },
            data() {
                return {
                    drawer: false,
                    tabsActiveName: '规则管理',
                    debug_panel_show: gmUtil.getData('open-dev', false),
                    sheet_dialog: {
                        show: false,
                        list: [],
                        title: "",
                        optionsClick: null,
                        closeOnClickModal: true
                    }
                }
            },
            methods: {
                tabClick(tab) {
                    gmUtil.setData('mainTabsActiveName', tab.name);
                },
                handleClose() {
                    this.sheet_dialog.show = false;
                },
                handleOptionsClick(item) {
                    let tempBool;
                    const temp = this.sheet_dialog.optionsClick(item);
                    if (temp === undefined) {
                        tempBool = false;
                    } else {
                        tempBool = temp;
                    }
                    this.sheet_dialog.show = tempBool === true;
                }
            },
            created() {
                eventEmitter.on('主面板开关', () => {
                    const tempBool = this.drawer;
                    this.drawer = !tempBool;
                });
                eventEmitter.on('el-notification', (...options) => {
                    this.$notify(...options);
                });
                eventEmitter.on('el-msg', (...options) => {
                    this.$message(...options);
                });
                eventEmitter.on('el-alert', (...options) => {
                    this.$alert(...options);
                });
                eventEmitter.handler('el-confirm', (...options) => {
                    return this.$confirm(...options);
                });
                this.tabsActiveName = gmUtil.getData('mainTabsActiveName', '规则管理');
                eventEmitter.on('debugger-dev-show', (bool) => {
                    debugger
                    this.debug_panel_show = bool;
                    if (bool) {
                        this.$alert('已开启测试调试面板', 'tip');
                    } else {
                        this.$alert('已关闭测试调试面板', 'tip');
                    }
                });
                eventEmitter.on('sheet-dialog', ({list, optionsClick, title = '选项', closeOnClickModal = false}) => {
                    this.sheet_dialog.show = true;
                    this.sheet_dialog.list = list;
                    this.sheet_dialog.title = title;
                    this.sheet_dialog.optionsClick = optionsClick;
                    this.sheet_dialog.closeOnClickModal = closeOnClickModal;
                });
                eventEmitter.handler('el-prompt', (...options) => {
                    return this.$prompt(...options)
                });
                if (bAfterLoadingThePageOpenMainPanel()) {
                    this.drawer = true;
                }
            }
        });
    });
    var defCss = `
.el-vertical-center {
    display: flex;
    justify-content: center;
}
.el-horizontal-center {
    display: flex;
    align-items: center;
}
.el-horizontal-right {
    display: flex;
    justify-content: flex-end;
}
.el-horizontal-left {
    display: flex;
    justify-content: flex-start;
}
`;
    gmUtil.addStyle(`
[gz_bezel]{
border:1px solid ${localMKData.getBorderColor()}
}
`);
    gmUtil.addStyle(defCss);
    const exactMatch = (ruleList, value) => {
        if (ruleList === null || ruleList === undefined) return false;
        if (!Array.isArray(ruleList)) return false
        return ruleList.some(item => item === value);
    };
    const bFuzzyAndRegularMatchingWordsToLowercase = localMKData.bFuzzyAndRegularMatchingWordsToLowercase();
    const regexMatch = (ruleList, value) => {
        if (ruleList === null || ruleList === undefined) return null;
        if (!Array.isArray(ruleList)) return null
        if (bFuzzyAndRegularMatchingWordsToLowercase) {
            value = value.toLowerCase();
        }
        value = value.split(/[\t\r\f\n\s]*/g).join("");
        const find = ruleList.find(item => {
            try {
                return value.search(item) !== -1;
            } catch (e) {
                const msg = `正则匹配失败,请检查规则列表中的正则表达式是否正确,错误信息:${e.message}`;
                eventEmitter.send('正则匹配时异常', {e, msg});
                return false;
            }
        });
        return find === undefined ? null : find;
    };
    const fuzzyMatch = (ruleList, value) => {
        if (ruleList === null || ruleList === undefined || value === null) return null;
        if (!Array.isArray(ruleList)) return null
        const find = ruleList.find(item => value.toLowerCase().includes(item));
        return find === undefined ? null : find;
    };
    var ruleMatchingUtil = {
        exactMatch,
        regexMatch,
        fuzzyMatch
    };
    const outputInformationFontColor = localMKData.getOutputInformationFontColor();
    const highlightInformationColor = localMKData.getHighlightInformationColor();
    const getLiveRoomCommentInfoHtml = (type, matching, commentData) => {
        const toTimeString = defUtil.toTimeString();
        const {name, uid, content} = commentData;
        return `<b style="color: ${outputInformationFontColor}; " gz_bezel>
${toTimeString}-根据${type}-${matching ? `<b style="color: ${highlightInformationColor}">【${matching}】</b>` : ""}-屏蔽用户【${name}】uid=
            <a href="https://space.bilibili.com/${uid}" 
            style="color: ${highlightInformationColor}"
            target="_blank">【${uid}】</a>
            直播评论【${content}】
            </b>`
    };
    const getDynamicContentInfoHtml = (type, matching, dynamicData) => {
        const toTimeString = defUtil.toTimeString();
        const {name, uid, content} = dynamicData;
        return `<b style="color: ${outputInformationFontColor}; " gz_bezel>
${toTimeString}-根据${type}-${matching ? `<b style="color: ${highlightInformationColor}">【${matching}】</b>` : ""}-屏蔽用户【${name}】uid=
            <a href="https://space.bilibili.com/${uid}" 
            style="color: ${highlightInformationColor}"
            target="_blank">【${uid}】</a>
            动态【${content}】
            </b>`
    };
    const getLiveRoomInfoHtml = (type, matching, liveRoomData) => {
        const toTimeString = defUtil.toTimeString();
        const {name = null, uid = -1, title, liveUrl} = liveRoomData;
        return `<b style="color: ${outputInformationFontColor};" gz_bezel>
${toTimeString}-根据${type}${matching ? `<b style="color: ${highlightInformationColor}">【${matching}】</b>` : ""}-屏蔽用户【${name === null ? '' : name}】${uid === -1 ? "" : `uid=
            <a href="https://space.bilibili.com/${uid}"
            style="color: ${highlightInformationColor}"
            target="_blank">【${uid}】</a>`}
            直播间标题【<a href="${liveUrl}" target="_blank" style="color: ${highlightInformationColor}">${title}</a>】
</b>`
    };
    var output_informationTab = {
        getLiveRoomCommentInfoHtml,
        getDynamicContentInfoHtml,
        getLiveRoomInfoHtml
    };
    class VideoInfoCache {
        #caches = [];
        getCaches() {
            return this.#caches;
        }
        getCount() {
            return this.#caches.length;
        }
        addData(data) {
            this.#caches.push(data);
        }
        is(bv) {
            return this.#caches.some(item => item.bv === bv);
        }
        find(bv) {
            const find = this.#caches.find(item => item.bv === bv);
            if (find) {
                return find
            }
            return null
        }
        async update() {
            this.#caches = await bvDexie.getVideoInfo();
            return this.getCaches();
        }
    }
    const videoInfoCache = new VideoInfoCache();
    class ElEventEmitter {
        #elEvents = new Map()
        addEvent(el, eventName, callback, repeated = false) {
            const elEvents = this.#elEvents;
            if (!elEvents.has(el)) {
                elEvents.set(el, {events: [], attrs: []});
            }
            const {events, attrs} = elEvents.get(el);
            if (!repeated) {
                if (attrs.includes(eventName)) {
                    return
                }
            }
            attrs.push(eventName);
            events.push({eventName, callback});
            el.setAttribute(`gz-event`, JSON.stringify(attrs));
            el.addEventListener(eventName, callback);
        }
        hasEventName(el, eventName) {
            const elEvents = this.#elEvents;
            if (elEvents.has(el)) {
                return true
            }
            const {attrs} = elEvents.get(el);
            return attrs.includes(eventName)
        }
    }
    const elEventEmitter = new ElEventEmitter();
    const addBlockButton$1 = (data, tagCss = '', position = []) => {
        const {insertionPositionEl, explicitSubjectEl, css} = data.data;
        if (tagCss !== '') {
            if (insertionPositionEl.querySelector("." + tagCss)) return;
        }
        const buttonEL = document.createElement("button");
        buttonEL.setAttribute("gz_type", "");
        if (tagCss !== '') {
            buttonEL.className = tagCss;
        }
        buttonEL.textContent = "屏蔽";
        if (position.length !== 0) {
            buttonEL.style.position = "absolute";
        }
        if (position.includes("right")) {
            buttonEL.style.right = "0";
        }
        if (position.includes("bottom")) {
            buttonEL.style.bottom = "0";
        }
        if (css !== undefined) {
            for (let key of Object.keys(css)) {
                buttonEL.style[key] = css[key];
            }
        }
        if (explicitSubjectEl) {
            buttonEL.style.display = "none";
            elEventEmitter.addEvent(explicitSubjectEl, "mouseout", () => buttonEL.style.display = "none");
            elEventEmitter.addEvent(explicitSubjectEl, "mouseover", () => buttonEL.style.display = "");
        }
        insertionPositionEl.appendChild(buttonEL);
        buttonEL.addEventListener("click", (event) => {
            event.stopImmediatePropagation(); // 阻止事件冒泡和同一元素上的其他事件处理器
            event.preventDefault(); // 阻止默认行为
            const {uid, name} = data.data;
            eventEmitter.send('sheet-dialog', {
                title: "屏蔽选项",
                list: [
                    {
                        label: `uid精确屏蔽-用户uid=${uid}-name=${name}`,
                        value: "uid"
                    }, {
                        label: `用户名精确屏蔽(不推荐)-用户name=${name}`,
                        value: 'name'
                    }
                ],
                optionsClick: (item) => {
                    const {value} = item;
                    if (value === 'uid') {
                        if (uid === -1) {
                            eventEmitter.send('el-msg', "该页面数据不存在uid字段");
                            return;
                        }
                        const {status, res} = ruleUtil.addRulePreciseUid(uid, false);
                        if (status) {
                            data.maskingFunc();
                        }
                        eventEmitter.send('el-alert', res);
                        return;
                    }
                    if (!name) {
                        eventEmitter.send('el-alert', "该页面数据不存在name字段" + name);
                        return;
                    }
                    eventEmitter.invoke('el-confirm', '不推荐用户使用精确用户名来屏蔽,确定继续吗?').then(() => {
                        ruleUtil.addRulePreciseName(name);
                    });
                }
            });
        });
    };
    eventEmitter.on('视频添加屏蔽按钮', (data) => {
        addBlockButton$1(data, "gz_shielding_button", ["right"]);
    });
    eventEmitter.on('添加热门视频屏蔽按钮', (data) => {
        addBlockButton$1(data, "gz_shielding_button", ["right", "bottom"]);
    });
    const addTopicDetailVideoBlockButton = (data) => {
        addBlockButton$1(data, "gz_shielding_button");
    };
    const addTopicDetailContentsBlockButton = (data) => {
        const position = data.data.position;
        const loop = position !== undefined;
        addBlockButton$1(data, "gz_shielding_topic_detail_button", loop ? position : []);
    };
    const addLiveContentBlockButton = (commentsData) => {
        addBlockButton$1(commentsData, "gz_shielding_live_danmaku_button");
    };
    const shieldingVideo = (videoData) => {
        const {
            title, uid = -1,
            name, nDuration = -1,
            nBulletChat = -1, nPlayCount = -1
        } = videoData;
        if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseUidWhiteArr(), uid)) {
            return {state: false};
        }
        if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseUidArr(), uid)) {
            return {state: true, type: "精确uid"};
        }
        let matching = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getTitleArr(), title);
        if (matching !== null) {
            return {state: true, type: "模糊标题", matching};
        }
        matching = ruleMatchingUtil.regexMatch(ruleKeyListData$1.getTitleCanonicalArr(), title);
        if (matching !== null) {
            return {state: true, type: "正则标题", matching};
        }
        if (name) {
            if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseNameArr(), name)) {
                return {state: true, type: "精确用户名"};
            }
            matching = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getNameArr(), name);
            if (matching !== null) {
                return {state: true, type: "模糊用户名", matching};
            }
            matching = ruleMatchingUtil.regexMatch(ruleKeyListData$1.getNameCanonical(), name);
            if (matching !== null) {
                return {state: true, type: "正则用户名", matching};
            }
        }
        if (nDuration !== -1) {
            const min = gmUtil.getData('nMinimumDuration', -1);
            if (min > nDuration && min !== -1) {
                return {state: true, type: '最小时长', matching: min}
            }
            const max = gmUtil.getData('nMaximumDuration', -1);
            if (max < nDuration && max !== -1) {
                return {state: true, type: '最大时长', matching: max}
            }
        }
        if (nBulletChat !== -1) {
            const min = gmUtil.getData('nMinimumBarrage', -1);
            if (min > nBulletChat && min !== -1) {
                return {state: true, type: '最小弹幕数', matching: min}
            }
            const max = gmUtil.getData('nMaximumBarrage', -1);
            if (max < nBulletChat && max !== -1) {
                return {state: true, type: '最大弹幕数', matching: max}
            }
        }
        if (nPlayCount !== -1) {
            const min = gmUtil.getData('nMinimumPlay', -1);
            if (min > nPlayCount && min !== -1) {
                return {state: true, type: '最小播放量', matching: min}
            }
            const max = gmUtil.getData('nMaximumPlayback', -1);
            if (max < nPlayCount && max !== -1) {
                return {state: true, type: '最大播放量', matching: max}
            }
        }
        return {state: false};
    };
    const shieldingOtherVideoParameter = async (videoData) => {
        const {el, bv = '-1'} = videoData;
        if (bv === '-1') return
        if (videoInfoCache.getCount() === 0) {
            await videoInfoCache.update();
        }
        const find = videoInfoCache.find(bv);
        let result;
        if (find === null) {
            const {state, data, msg} = await bFetch.fetchGetVideoInfo(bv);
            if (!state) {
                console.warn('获取视频信息失败:' + msg);
                return
            }
            result = data;
            if (await bvDexie.addVideoData(bv, result)) {
                await videoInfoCache.update();
                console.log('mk-db-添加视频信息到数据库成功', result, videoData);
            }
        } else {
            result = find;
        }
        const {tags = [], userInfo, videoInfo} = result;
        let returnValue;
        if (tags.length !== 0) {
            returnValue = blockBasedVideoTag(tags);
            if (returnValue.state) {
                return returnValue
            }
        }
        const currentLevel = userInfo?.current_level || -1;
        returnValue = shieldingByLevel(currentLevel);
        if (returnValue.state) {
            return returnValue
        }
    };
    const blockBasedVideoTag = (tags) => {
        const preciseVideoTagArr = ruleKeyListData$1.getPreciseVideoTagArr();
        const videoTagArr = ruleKeyListData$1.getVideoTagArr();
        if (preciseVideoTagArr.length <= 0 && videoTagArr.length <= 0) {
            return {state: false}
        }
        for (let tag of tags) {
            if (ruleMatchingUtil.exactMatch(preciseVideoTagArr, tag)) {
                return {state: true, type: "精确视频tag", matching: tag}
            }
            let fuzzyMatch = ruleMatchingUtil.fuzzyMatch(videoTagArr, tag);
            if (fuzzyMatch) {
                return {state: true, type: "模糊视频tag", matching: fuzzyMatch}
            }
            fuzzyMatch = ruleMatchingUtil.regexMatch(ruleKeyListData$1.getVideoTagCanonicalArr(), tag);
            if (fuzzyMatch) {
                return {state: true, type: "正则视频tag", matching: fuzzyMatch}
            }
        }
        return {state: false}
    };
    const shieldingVideoDecorated = (videoData, method = "remove") => {
        const {el} = videoData;
        if (el.style.display === "none") {
            return true
        }
        const {state, type, matching = null} = shieldingVideo(videoData);
        if (state) {
            if (method === "remove") {
                el?.remove();
            } else {
                el.style.display = "none";
            }
            eventEmitter.send('屏蔽视频信息', type, matching, videoData);
            return true;
        }
        if (isDisableNetRequestsBvVideoInfo()) {
            return state
        }
        shieldingOtherVideoParameter(videoData).then(res => {
            if (!res) {
                return
            }
            const {type, matching} = res;
            if (method === "remove") {
                el.remove();
            } else {
                el.style.display = "none";
            }
            eventEmitter.send('屏蔽视频信息', type, matching, videoData);
        });
        return state;
    };
    const shieldingDynamic = (dynamicData) => {
        const {
            content = null,
            el,
            title = null,
            tag = null
        } = dynamicData;
        let matching = null;
        if (content !== null) {
            matching = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getCommentOnArr(), content);
            if (matching !== null) {
                el?.remove();
                return {state: true, type: "模糊评论内容", matching};
            }
            matching = ruleMatchingUtil.regexMatch(ruleKeyListData$1.getCommentOnCanonicalArr(), content);
            if (matching !== null) {
                el?.remove();
                return {state: true, type: "正则评论内容", matching};
            }
        }
        if (title !== null) {
            matching = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getTitleArr(), title);
            if (matching !== null) {
                el?.remove();
                return {state: true, type: "模糊标题", matching};
            }
            matching = ruleMatchingUtil.regexMatch(ruleKeyListData$1.getTitleCanonicalArr(), title);
            if (matching !== null) {
                el?.remove();
                return {state: true, type: "正则标题", matching};
            }
        }
        if (tag !== null) {
            if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseTagArr(), tag)) {
                el?.remove();
                return {state: true, type: "精确话题tag"};
            }
            matching = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getTagArr(), tag);
            if (matching !== null) {
                el?.remove();
                return {state: true, type: "模糊话题tag", matching};
            }
            matching = ruleMatchingUtil.regexMatch(ruleKeyListData$1.getTagCanonicalArr(), tag);
            if (matching !== null) {
                el?.remove();
                return {state: true, type: "正则话题tag", matching};
            }
        }
        return {state: false}
    };
    const shieldingDynamicDecorated = (dynamicData) => {
        const {state, type, matching} = shieldingDynamic(dynamicData);
        if (state) {
            const infoHtml = output_informationTab.getDynamicContentInfoHtml(type, matching, dynamicData);
            eventEmitter.send('打印信息', infoHtml);
        }
        return state;
    };
    const shieldingComment = (commentsData) => {
        const {content, uid, name, level = -1} = commentsData;
        if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseUidWhiteArr(), uid)) {
            return {state: false};
        }
        if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseUidArr(), uid)) {
            return {state: true, type: "精确uid"};
        }
        if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseNameArr(), name)) {
            return {state: true, type: "精确用户名"};
        }
        let matching = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getNameArr(), name);
        if (matching !== null) {
            return {state: true, type: "模糊用户名", matching};
        }
        matching = ruleMatchingUtil.regexMatch(ruleKeyListData$1.getNameCanonical(), name);
        if (matching !== null) {
            return {state: true, type: "正则用户名", matching};
        }
        matching = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getCommentOnArr(), content);
        if (matching !== null) {
            return {state: true, type: "模糊评论内容", matching};
        }
        matching = ruleMatchingUtil.regexMatch(ruleKeyListData$1.getCommentOnCanonicalArr(), content);
        if (matching !== null) {
            return {state: true, type: "正则评论内容", matching};
        }
        if (level !== -1) {
            return shieldingByLevel(level);
        }
        return {state: false};
    };
    const shieldingByLevel = (level) => {
        const def = {state: false};
        if (!level) {
            return def
        }
        const min = gmUtil.getData('nMinimumLevel', -1);
        if (min > level) {
            return {state: true, type: "最小用户等级过滤", matching: min};
        }
        const max = gmUtil.getData('nMaximumLevel', -1);
        if (max > level) {
            return {state: true, type: "最大用户等级过滤", matching: max};
        }
        return def
    };
    const shieldingCommentDecorated = (commentsData) => {
        const {state, type, matching} = shieldingComment(commentsData);
        if (state) {
            commentsData.el?.remove();
            eventEmitter.send('屏蔽评论信息', type, matching, commentsData);
        }
        return state;
    };
    const shieldingLiveRoomContentDecorated = (liveRoomContent) => {
        let {state, type, matching} = shieldingComment(liveRoomContent);
        const {el, fansMedal} = liveRoomContent;
        if (fansMedal !== null) {
            if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseFanCardArr(), fansMedal)) {
                el?.remove();
                state = true;
                type = "精确粉丝牌";
            }
        }
        if (state) {
            el?.remove();
        }
        if (type) {
            const infoHtml = output_informationTab.getLiveRoomCommentInfoHtml(type, matching, liveRoomContent);
            eventEmitter.send('打印信息', infoHtml);
        }
        return state;
    };
    const shieldingComments = (commentsDataList) => {
        for (let commentsData of commentsDataList) {
            if (shieldingCommentDecorated(commentsData)) continue;
            eventEmitter.send('评论添加屏蔽按钮', commentsData);
            const {replies = []} = commentsData;
            if (replies.length === 0) continue;
            for (let reply of replies) {
                if (shieldingCommentDecorated(reply)) continue;
                eventEmitter.send('评论添加屏蔽按钮', reply);
            }
        }
    };
    const shieldingLiveRoom = (liveRoomData) => {
        const {name, title, partition, uid = -1} = liveRoomData;
        if (uid !== -1) {
            if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseUidWhiteArr(), uid)) {
                return {state: false};
            }
            if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseUidArr(), uid)) {
                return {state: true, type: "精确用户uid"};
            }
        }
        let matching;
        if (name) {
            if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseNameArr(), name)) {
                return {state: true, type: "精确用户名"};
            }
            matching = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getNameArr(), name);
            if (matching) {
                return {state: true, type: "模糊用户名", matching};
            }
        }
        matching = ruleMatchingUtil.exactMatch(ruleKeyListData$1.getTitleArr(), title);
        if (matching) {
            return {state: true, type: "模糊标题", matching};
        }
        matching = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getTitleCanonicalArr(), title);
        if (matching) {
            return {state: true, type: "正则标题", matching};
        }
        if (partition) {
            if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPrecisePartitionArr(), partition)) {
                return {state: true, type: "精确直播分区"};
            }
        }
        return {state: false};
    };
    const shieldingLiveRoomDecorated = (liveRoomData) => {
        const {state, type, matching = null} = shieldingLiveRoom(liveRoomData);
        if (state) {
            liveRoomData.el?.remove();
            const infoHtml = output_informationTab.getLiveRoomInfoHtml(type, matching, liveRoomData);
            eventEmitter.send('打印信息', infoHtml);
        }
        return state;
    };
    const intervalExecutionStartShieldingVideoInert = (func, name = '') => {
        let i1 = -1;
        const start = () => {
            if (i1 !== -1) {
                return
            }
            console.log('开始执行屏蔽' + name);
            i1 = setInterval(() => {
                func();
                console.log(`执行屏蔽${name}列表-定时器正在执行`);
            }, 800);
        };
        const stop = () => {
            if (i1 === -1) {
                return
            }
            clearInterval(i1);
            console.log(`已停止执行屏蔽${name}列表`);
            i1 = -1;
        };
        return {start, stop}
    };
    var shielding = {
        shieldingVideoDecorated,
        shieldingDynamicDecorated,
        shieldingCommentDecorated,
        shieldingLiveRoomDecorated,
        shieldingComments,
        shieldingLiveRoomContentDecorated,
        addLiveContentBlockButton,
        addTopicDetailVideoBlockButton,
        addTopicDetailContentsBlockButton,
        intervalExecutionStartShieldingVideoInert,
        addBlockButton: addBlockButton$1
    };
    const toPlayCountOrBulletChat = (str) => {
        if (!str) {
            return -1
        }
        str = str.split(/[\t\r\f\n\s]*/g).join("");
        const replace = str.replace(/[^\d.]/g, '');
        if (str.endsWith('万') || str.endsWith('万次') || str.endsWith('万弹幕')) {
            return parseFloat(replace) * 10000;
        }
        if (str.endsWith('次') || str.endsWith('弹幕')) {
            return parseInt(replace);
        }
        return parseInt(str)
    };
    const timeStringToSeconds = (timeStr) => {
        if (!timeStr) {
            return -1
        }
        const parts = timeStr.split(':');
        switch (parts.length) {
            case 1: // 只有秒
                return Number(parts[0]);
            case 2: // 分钟和秒
                return Number(parts[0]) * 60 + Number(parts[1]);
            case 3: // 小时、分钟和秒
                return Number(parts[0]) * 3600 + Number(parts[1]) * 60 + Number(parts[2]);
            default:
                throw new Error('Invalid time format');
        }
    };
    var sFormatUtil = {
        toPlayCountOrBulletChat,
        timeStringToSeconds
    };
    const isHome = (url, title) => {
        if (title !== "哔哩哔哩 (゜-゜)つロ 干杯~-bilibili") {
            return false
        }
        if (url === 'https://www.bilibili.com/') {
            return true
        }
        return url.includes('https://www.bilibili.com/?spm_id_from=')
    };
    const adaptationBAppCommerce$1 = localMKData.getAdaptationBAppCommerce();
    const deDesktopDownloadTipEl = async () => {
        const el = await elUtil.findElementUntilFound(".desktop-download-tip");
        el?.remove();
        const log = "已删除下载提示";
        console.log(log, el);
    };
    const getChangeTheVideoElList = async () => {
        const elList = await elUtil.findElementsUntilFound(".container.is-version8>.feed-card");
        const list = [];
        for (let el of elList) {
            try {
                const tempData = getVideoData(el);
                const {userUrl} = tempData;
                const videoUrl = el.querySelector(".bili-video-card__info--tit>a")?.href || null;
                if (!userUrl.includes("//space.bilibili.com/")) {
                    el?.remove();
                    const log = "遍历换一换视频列表中检测到异常内容,已将该元素移除";
                    console.log(log, el);
                    continue;
                }
                const items = {
                    ...tempData, ...{
                        videoUrl,
                        el,
                        insertionPositionEl: el.querySelector(".bili-video-card__info--bottom"),
                        explicitSubjectEl: el.querySelector(".bili-video-card__info")
                    }
                };
                if (videoUrl?.includes('www.bilibili.com/video')) {
                    items.bv = elUtil.getUrlBV(videoUrl);
                }
                list.push(items);
            } catch (e) {
                el.remove();
                console.warn("获取视频信息失败");
            }
        }
        return list
    };
    const getVideoData = (el) => {
        const title = el.querySelector(".bili-video-card__info--tit").title;
        const name = el.querySelector(".bili-video-card__info--author").textContent.trim();
        let nPlayCount = el.querySelector('.bili-video-card__stats--text')?.textContent.trim();
        nPlayCount = sFormatUtil.toPlayCountOrBulletChat(nPlayCount);
        let nBulletChat = el.querySelector('.bili-video-card__stats--text')?.textContent.trim();
        nBulletChat = sFormatUtil.toPlayCountOrBulletChat(nBulletChat);
        let nDuration = el.querySelector('.bili-video-card__stats__duration')?.textContent.trim();
        nDuration = sFormatUtil.timeStringToSeconds(nDuration);
        const userUrl = el.querySelector(".bili-video-card__info--owner").getAttribute("href");
        const uid = elUtil.getUrlUID(userUrl);
        return {
            title,
            name,
            uid,
            nPlayCount,
            nBulletChat,
            nDuration,
            userUrl
        }
    };
    const getHomeVideoELList = async () => {
        const elList = await elUtil.findElementsUntilFound(".container.is-version8>.bili-video-card");
        let list = [];
        for (let el of elList) {
            try {
                const tempData = getVideoData(el);
                const {userUrl} = tempData;
                if (!userUrl.includes("//space.bilibili.com/")) {
                    el?.remove();
                    const log = "遍历换一换视频列表下面列表时检测到异常内容,已将该元素移除";
                    eventEmitter.send('打印信息', log);
                    console.log(log, el);
                    continue;
                }
                const videoUrl = el.querySelector(".bili-video-card__info--tit>a")?.href;
                const items = {
                    ...tempData, ...{
                        videoUrl,
                        el,
                        insertionPositionEl: el.querySelector(".bili-video-card__info--bottom"),
                        explicitSubjectEl: el.querySelector(".bili-video-card__info")
                    }
                };
                if (videoUrl?.includes('www.bilibili.com/video')) {
                    items.bv = elUtil.getUrlBV(videoUrl);
                }
                list.push(items);
            } catch (e) {
                el?.remove();
                console.log("遍历视频列表中检测到异常内容,已将该元素移除;");
            }
        }
        return list;
    };
    const getGateActivatedTab = async () => {
        const el = await elUtil.findElementUntilFound(".ant-radio-group>.ant-radio-button-wrapper-checked .css-1k4kcw8");
        return el?.textContent.trim();
    };
    const getGateDataList = async () => {
        const elList = await elUtil.findElementsUntilFound(".bilibili-gate-video-grid>[data-bvid].bili-video-card");
        const list = [];
        for (let el of elList) {
            const tempData = getVideoData(el);
            const videoUrl = el.querySelector("a.css-feo88y")?.href;
            const bv = elUtil.getUrlBV(videoUrl);
            const insertionPositionEl = el.querySelector(".bili-video-card__info--owner");
            list.push({
                ...tempData, ...{
                    videoUrl,
                    el,
                    bv,
                    insertionPositionEl,
                    explicitSubjectEl: el
                }
            });
        }
        return list;
    };
    const startShieldingGateVideoList = async () => {
        const list = await getGateDataList();
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData, "hide")) {
                continue;
            }
            eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingGateVideoList});
        }
    };
    const startIntervalShieldingGateVideoList = () => {
        const throttle = defUtil.throttle(startShieldingGateVideoList, 2000);
        setInterval(async () => {
            await getGateActivatedTab();
            throttle();
        }, 1500);
    };
    const startClearExcessContentList = () => {
        if (adaptationBAppCommerce$1) return;
        setInterval(() => {
            const otherElList = document.querySelectorAll(".floor-single-card");
            const liveList = document.querySelectorAll(".bili-live-card");
            const elList = [...otherElList, ...liveList];
            for (let el of elList) {
                el?.remove();
            }
        }, 1000);
        console.log("已启动每秒清理首页视频列表中多余的内容");
    };
    const startShieldingChangeVideoList = async () => {
        const list = await getChangeTheVideoElList();
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue;
            }
            eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingChangeVideoList});
        }
    };
    const startDebounceShieldingChangeVideoList = defUtil.debounce(startShieldingChangeVideoList, 200);
    const startShieldingHomeVideoList = async () => {
        const homeVideoELList = await getHomeVideoELList();
        for (const videoData of homeVideoELList) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue;
            }
            eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingHomeVideoList});
        }
    };
    const startDebounceShieldingHomeVideoList = defUtil.debounce(startShieldingHomeVideoList, 500);
    const scrollMouseUpAndDown = async () => {
        if (adaptationBAppCommerce$1) return;
        await defUtil.smoothScroll(false, 100);
        return defUtil.smoothScroll(true, 600);
    };
    var bilibiliHome = {
        isHome,
        startClearExcessContentList,
        startDebounceShieldingChangeVideoList,
        startDebounceShieldingHomeVideoList,
        scrollMouseUpAndDown,
        deDesktopDownloadTipEl,
        startIntervalShieldingGateVideoList
    };
    var css = `.to_hide_xl {
    display: block !important;
}
`;
    const installStyle = () => {
        const styleElement = document.createElement('style');
        styleElement.textContent = css;
        document.head.appendChild(styleElement);
    };
    const getLiveRoomList = async () => {
        const elList = await elUtil.findElements('.live-room-cards>.video-list-item');
        const list = [];
        for (let el of elList) {
            const titleAEl = el.querySelector('.bili-live-card__info--tit>a');
            const titleEl = el.querySelector('.bili-live-card__info--tit>a>span');
            const userEl = el.querySelector('.bili-live-card__info--uname');
            const liveUrl = titleAEl.href;
            const title = titleEl.textContent.trim();
            const userUrl = userEl.href;
            const uid = elUtil.getUrlUID(userUrl);
            const name = userEl.textContent.trim();
            list.push({
                title,
                liveUrl,
                name,
                userUrl,
                uid,
                el,
                explicitSubjectEl: el.querySelector('.bili-live-card__info'),
                insertionPositionEl: userEl
            });
        }
        return list
    };
    const addBlockButton = (data) => {
        shielding.addBlockButton(data, '', ['right']);
    };
    const startShieldingLiveRoomList = async () => {
        const list = await getLiveRoomList();
        for (let liveData of list) {
            if (shielding.shieldingLiveRoomDecorated(liveData)) {
                continue
            }
            addBlockButton({data: liveData, maskingFunc: startShieldingLiveRoomList});
        }
    };
    const InstallLiveTopTabsListener = async () => {
        const el = await elUtil.findElement('.live-condition');
        if (elEventEmitter.hasEventName(el, 'click')) return
        elEventEmitter.addEvent(el, 'click', async (event) => {
            const target = event.target;
            const label = target.textContent.trim();
            if (label === '主播') {
                return
            }
            await startShieldingLiveRoomList();
            InstallBottomPagingListener();
            installTopRoomOrderListener();
        });
        console.log("直播顶部选项卡安装监听器已安装");
    };
    const InstallBottomPagingListener = async () => {
        const el = await elUtil.findElement('.vui_pagenation--btns');
        if (elEventEmitter.hasEventName(el, 'click')) return
        elEventEmitter.addEvent(el, 'click', async (event) => {
            const target = event.target;
            if (target.tagName !== 'BUTTON') {
                return
            }
            await startShieldingLiveRoomList();
            installTopRoomOrderListener();
        });
        console.log("底部分页安装监听器已安装");
    };
    const installTopRoomOrderListener = async () => {
        const el = await elUtil.findElement('.room-order');
        if (elEventEmitter.hasEventName(el, 'click')) return
        elEventEmitter.addEvent(el, 'click', async (event) => {
            const target = event.target;
            console.log('顶部房间排序监听器触发了', target.textContent.trim(), target);
            await startShieldingLiveRoomList();
            InstallBottomPagingListener();
            installTopRoomOrderListener();
        });
        console.log('顶部房间排序监听器已安装');
    };
    var searchLive = {
        InstallLiveTopTabsListener,
        installStyle,
        startShieldingLiveRoomList,
        InstallBottomPagingListener,
        installTopRoomOrderListener
    };
    const isSearch = (url) => {
        return url.includes("search.bilibili.com")
    };
    const currentlyActivatedOptions = async () => {
        const el = await elUtil.findElement('.vui_tabs--nav-item-active .vui_tabs--nav-text');
        const label = el.textContent.trim();
        if (label === '直播') {
            await searchLive.startShieldingLiveRoomList();
            searchLive.InstallLiveTopTabsListener();
            searchLive.InstallBottomPagingListener();
            elUtil.findElementUntilFound('.live-condition>.vui_button--active').then(activeEl => {
                if (activeEl.textContent.trim() !== '主播') {
                    searchLive.installTopRoomOrderListener();
                }
            });
        }
    };
    const searchTopTabsIWrapperInstallListener = async () => {
        const tempTabs = ['番剧', '影视', '用户'];
        const el = await elUtil.findElement('.vui_tabs--navbar>ul');
        el.addEventListener("click", async (event) => {
            const eventTarget = event.target;
            if (eventTarget.className !== 'vui_tabs--nav-text') {
                return
            }
            const tabName = eventTarget.textContent.trim();
            if (tempTabs.includes(tabName)) {
                return
            }
            if (tabName === '直播') {
                searchLive.installTopRoomOrderListener();
                return
            }
            console.log("搜索页顶部选项卡监听器触发了", tabName);
        });
        console.log("搜索页顶部选项卡安装监听器已安装");
    };
    const getVideoList$1 = async (css) => {
        const elList = await elUtil.findElements(css, {interval: 200});
        const list = [];
        for (let el of elList) {
            const title = el.querySelector(".bili-video-card__info--tit").title;
            const userEl = el.querySelector(".bili-video-card__info--owner");
            if (userEl === null) {
                console.log("获取不到该视频卡片的用户地址,", el);
                el?.remove();
                continue
            }
            const userUrl = userEl.getAttribute("href");
            if (!userUrl.includes("//space.bilibili.com/")) {
                el?.remove();
                console.log("移除了非视频内容", userUrl, el);
                continue;
            }
            const videoUrl = el.querySelector(".bili-video-card__info--right>a")?.href;
            if (videoUrl?.includes('live.bilibili.com/')) {
                continue
            }
            const bv = elUtil.getUrlBV(videoUrl);
            const uid = elUtil.getUrlUID(userUrl);
            const name = userEl.querySelector(".bili-video-card__info--author").textContent.trim();
            const bili_video_card__stats_item = el.querySelectorAll('.bili-video-card__stats--item');
            let nPlayCount = bili_video_card__stats_item[0]?.textContent.trim();
            nPlayCount = sFormatUtil.toPlayCountOrBulletChat(nPlayCount);
            let nBulletChat = bili_video_card__stats_item[1]?.textContent.trim();
            nBulletChat = sFormatUtil.toPlayCountOrBulletChat(nBulletChat);
            let nDuration = el.querySelector('.bili-video-card__stats__duration')?.textContent.trim();
            nDuration = sFormatUtil.timeStringToSeconds(nDuration);
            list.push({
                title,
                userUrl,
                name,
                uid,
                bv,
                nPlayCount,
                nBulletChat,
                nDuration,
                el,
                videoUrl,
                insertionPositionEl: el.querySelector(".bili-video-card__info--bottom"),
                explicitSubjectEl: el.querySelector(".bili-video-card__info")
            });
        }
        return list;
    };
    const getTabComprehensiveSortedVideoList = () => {
        return getVideoList$1(".video.i_wrapper.search-all-list>.video-list>div");
    };
    const getOtherVideoList = () => {
        return getVideoList$1(".search-page.search-page-video>.video-list.row>div");
    };
    const startShieldingCSVideoList = async () => {
        const list = await getTabComprehensiveSortedVideoList();
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue;
            }
            eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingCSVideoList});
        }
    };
    const startShieldingOtherVideoList = async () => {
        const list = await getOtherVideoList();
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue;
            }
            eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingOtherVideoList});
        }
    };
    const getTwTabActiveItem = async () => {
        const twoTabActiveItem = await elUtil.findElement('.vui_button.vui_button--tab.vui_button--active.mr_sm', {interval: 200});
        const twoTabActiveItemLabel = twoTabActiveItem.textContent.trim();
        return {el: twoTabActiveItemLabel, label: twoTabActiveItemLabel}
    };
    const startShieldingVideoList$6 = async () => {
        const topTabActiveItem = await elUtil.findElement('.vui_tabs--nav-item.vui_tabs--nav-item-active', {interval: 200});
        const topTabActiveItemLabel = topTabActiveItem.textContent.trim();
        console.log(topTabActiveItemLabel);
        if (topTabActiveItemLabel !== '综合') {
            await startShieldingOtherVideoList();
            return
        }
        const {label} = await getTwTabActiveItem();
        if (label !== '综合排序') {
            await startShieldingOtherVideoList();
            return
        }
        const parseUrl = defUtil.parseUrl(window.location.href);
        if (parseUrl.queryParams['page']) {
            await startShieldingOtherVideoList();
        } else {
            await startShieldingCSVideoList();
            processingExactSearchVideoCardContent();
        }
    };
    const processingExactSearchVideoCardContent = async () => {
        let res;
        try {
            res = await elUtil.findElement('.user-list.search-all-list', {interval: 50, timeout: 4000});
        } catch (e) {
            return
        }
        let el;
        if (!res.state) {
            return
        }
        el = res.data;
        const infoCardEl = el.querySelector('.info-card');
        const userNameEl = infoCardEl.querySelector('.user-name');
        const name = userNameEl.textContent.trim();
        const userUrl = userNameEl.href;
        const uid = elUtil.getUrlUID(userUrl);
        if (ruleMatchingUtil.exactMatch(ruleKeyListData$1.getPreciseUidArr(), uid)) {
            el.remove();
            eventEmitter.send('打印信息', `根据精确uid匹配到用户${name}-【${uid}】`);
            return
        }
        let fuzzyMatch = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getNameArr(), name);
        if (fuzzyMatch) {
            el.remove();
            eventEmitter.send('打印信息', `根据模糊用户名【${fuzzyMatch}】匹配到用户${name}-【${uid}】`);
            return
        }
        fuzzyMatch = ruleMatchingUtil.regexMatch(ruleKeyListData$1.getNameCanonical(), name);
        if (fuzzyMatch) {
            el.remove();
            eventEmitter.send('打印信息', `根据正则用户名【${fuzzyMatch}】匹配到用户${name}-【${uid}】`);
            return
        }
        const insertionPositionEl = el.querySelector('.info-card.flex_start');
        shielding.addBlockButton({
            data: {
                name,
                uid,
                insertionPositionEl,
            }
        });
        const videoElList = el.querySelectorAll('.video-list>.video-list-item');
        const list = [];
        for (let videoEl of videoElList) {
            const titleEl = videoEl.querySelector('.bili-video-card__info--right>a');
            const videoUrl = titleEl.href;
            const bv = elUtil.getUrlBV(videoUrl);
            const title = titleEl.textContent.trim();
            let nDuration = videoEl.querySelector('.bili-video-card__stats__duration')?.textContent.trim();
            nDuration = sFormatUtil.timeStringToSeconds(nDuration);
            let nPlayCount = videoEl.querySelector('.bili-video-card__stats--item>span')?.textContent.trim();
            nPlayCount = sFormatUtil.toPlayCountOrBulletChat(nPlayCount);
            list.push({
                title,
                userUrl,
                name,
                uid,
                bv,
                nPlayCount,
                nDuration,
                el: videoEl,
                videoUrl
            });
        }
        for (let videoData of list) {
            shielding.shieldingVideoDecorated(videoData);
        }
    };
    const delFooterContent = () => {
        if (!gmUtil.getData('isRemoveSearchBottomContent', false)) {
            return
        }
        elUtil.findElement('#biliMainFooter').then(el => {
            el.remove();
            eventEmitter.send('打印信息', '已删除底部内容');
        });
    };
    var searchModel = {
        isSearch,
        searchTopTabsIWrapperInstallListener,
        startShieldingVideoList: startShieldingVideoList$6,
        currentlyActivatedOptions,
        delFooterContent
    };
    const isVideoPlayPage = (url = window.location.href) => {
        return url.includes("www.bilibili.com/video");
    };
    const selectUserBlocking = async () => {
        const {state} = await elUtil.findElement('.header.can-pointer', {timeout: 1800});
        if (state) {
            const elList = document.querySelectorAll('.container>.membersinfo-upcard-wrap>.membersinfo-upcard');
            const list = [];
            for (const el of elList) {
                const userUrl = el.querySelector('.avatar').href;
                const uid = elUtil.getUrlUID(userUrl);
                const name = el.querySelector('.staff-name').textContent.trim();
                list.push({
                    label: `用户-name=${name}-uid=${uid}`,
                    uid
                });
            }
            eventEmitter.send('sheet-dialog', {
                title: '选择要屏蔽的用户(uid精确)',
                list,
                optionsClick: (item) => {
                    ruleUtil.addRulePreciseUid(item.uid);
                    return true
                }
            });
        } else {
            const el = document.querySelector('.up-info-container');
            const nameEl = el.querySelector('.up-info--right a.up-name');
            const name = nameEl.textContent.trim();
            const userUrl = nameEl.href;
            const uid = elUtil.getUrlUID(userUrl);
            console.log('点击了屏蔽按钮', name, userUrl, uid);
            eventEmitter.invoke('el-confirm', `用户uid=${uid}-name=${name}`, 'uid精确屏蔽方式').then(() => {
                if (uid === -1) {
                    eventEmitter.send('el-msg', "该页面数据不存在uid字段");
                    return;
                }
                ruleUtil.addRulePreciseUid(uid);
            });
        }
    };
    const getGetTheVideoListOnTheRight$1 = async () => {
        await elUtil.findElementUntilFound(".video-page-card-small .b-img img");
        delAd();
        delGameAd();
        const elList = await elUtil.findElements(".rec-list>.video-page-card-small", {interval: 1000});
        const nextPlayEl = document.querySelector('.next-play>.video-page-card-small');
        if (nextPlayEl) {
            elList.push(nextPlayEl);
        }
        const list = [];
        for (let el of elList) {
            try {
                const elInfo = el.querySelector(".info");
                const title = elInfo.querySelector(".title").title;
                const name = elInfo.querySelector(".upname .name").textContent.trim();
                const userUrl = elInfo.querySelector(".upname>a").href;
                const uid = elUtil.getUrlUID(userUrl);
                const playInfo = el.querySelector('.playinfo').innerHTML.trim();
                const videoUrl = el.querySelector(".info>a").href;
                const bv = elUtil.getUrlBV(videoUrl);
                let nPlayCount = playInfo.match(/<\/svg>(.*)<svg/s)?.[1].trim();
                nPlayCount = sFormatUtil.toPlayCountOrBulletChat(nPlayCount);
                let nBulletChat = playInfo.match(/class="dm".+<\/svg>(.+)$/s)?.[1].trim();
                nBulletChat = sFormatUtil.toPlayCountOrBulletChat(nBulletChat);
                let nDuration = el.querySelector('.duration')?.textContent.trim();
                nDuration = sFormatUtil.timeStringToSeconds(nDuration);
                list.push({
                    title,
                    userUrl,
                    name,
                    uid,
                    bv,
                    nPlayCount,
                    nBulletChat,
                    nDuration,
                    el,
                    videoUrl,
                    insertionPositionEl: el.querySelector(".playinfo"),
                    explicitSubjectEl: elInfo
                });
            } catch (e) {
                console.error("获取右侧视频列表失败:", e);
            }
        }
        return list;
    };
    const startShieldingVideoList$5 = () => {
        if (localMKData.isDelPlayerPageRightVideoList()) {
            return
        }
        getGetTheVideoListOnTheRight$1().then((videoList) => {
            for (let videoData of videoList) {
                if (shielding.shieldingVideoDecorated(videoData)) {
                    continue;
                }
                eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingVideoList$5});
            }
        });
    };
    const findTheExpandButtonForTheListOnTheRightAndBindTheEvent$2 = () => {
        setTimeout(() => {
            elUtil.findElementUntilFound(".rec-footer", {interval: 2000}).then((el) => {
                console.log("找到右侧视频列表的展开按钮", el);
                el.addEventListener("click", () => {
                    startShieldingVideoList$5();
                });
            });
        }, 3000);
    };
    const getPlayerVideoList = async () => {
        const elList = await elUtil.findElements('.bpx-player-ending-related>.bpx-player-ending-related-item');
        const data = {list: [], cancelEl: null};
        for (const el of elList) {
            const title = el.querySelector('.bpx-player-ending-related-item-title')?.textContent.trim();
            const cancelEl = el.querySelector('.bpx-player-ending-related-item-cancel');
            if (cancelEl) {
                data.cancelEl = cancelEl;
            }
            data.list.push({
                title,
                el
            });
        }
        return data
    };
    const setVideoPlayerEnded = async () => {
        const videoEl = await elUtil.findElement('#bilibili-player video');
        const funcStart = async () => {
            const res = await getPlayerVideoList();
            for (let {el, title} of res.list) {
                let matching = ruleMatchingUtil.fuzzyMatch(ruleKeyListData$1.getTitleArr(), title);
                if (matching !== null) {
                    eventEmitter.send('打印信息', `根据-模糊标题-【${matching}】-屏蔽视频:${title}`);
                    el.remove();
                    continue
                }
                matching = ruleMatchingUtil.regexMatch(ruleKeyListData$1.getTitleCanonicalArr(), title);
                if (matching !== null) {
                    eventEmitter.send('打印信息', `根据-正则标题-【${matching}】-屏蔽视频:${title}`);
                    el.remove();
                }
            }
        };
        videoEl.addEventListener('ended', () => {
            console.log('视频播放结束');
            funcStart();
        });
    };
    const delAd = () => {
        if (!gmUtil.getData('isDelPlayerPageAd', false)) {
            return
        }
        elUtil.findElements('[class|=ad],#slide_ad').then(elList => {
            for (const el of elList) {
                el.style.display = 'none';
            }
            eventEmitter.send('打印信息', '隐藏了播放页的页面广告');
        });
    };
    const delRightVideoList = () => {
        if (!localMKData.isDelPlayerPageRightVideoList()) {
            return
        }
        elUtil.findElement('.recommend-list-v1').then(el => {
            el?.remove();
            eventEmitter.send('打印信息', '屏蔽了播放页的右侧推荐列表');
        });
    };
    const delGameAd = () => {
        if (!gmUtil.getData('isDelPlayerPageRightGameAd', false)) {
            return
        }
        elUtil.findElement('.video-page-game-card-small', {timeout: 10000}).then(({state, data}) => {
            if (!state) {
                eventEmitter.send('打印信息', '没有找到播放页的右侧游戏推荐');
                return
            }
            data?.remove();
            eventEmitter.send('打印信息', '屏蔽了游戏推荐');
        });
    };
    const delBottomCommentApp = () => {
        if (!gmUtil.getData('isDelBottomComment', false)) {
            return
        }
        elUtil.findElement('#commentapp').then(el => {
            el?.remove();
            eventEmitter.send('打印信息', '移除了页面底部的评论区');
        });
    };
    const delElManagement = () => {
        if (localMKData.isDelPlayerPageRightVideoList()) {
            delAd();
        }
        delRightVideoList();
        delBottomCommentApp();
    };
    var videoPlayModel = {
        isVideoPlayPage,
        startShieldingVideoList: startShieldingVideoList$5,
        findTheExpandButtonForTheListOnTheRightAndBindTheEvent: findTheExpandButtonForTheListOnTheRightAndBindTheEvent$2,
        selectUserBlocking,
        setVideoPlayerEnded,
        delElManagement
    };
    const getPlayCountAndBulletChatAndDuration = (el) => {
        const playInfo = el.querySelector('.playinfo').innerHTML.trim();
        let nPlayCount = playInfo.match(/<\/svg>(.*)<svg/s)?.[1].trim();
        nPlayCount = sFormatUtil.toPlayCountOrBulletChat(nPlayCount);
        let nBulletChat = playInfo.match(/class="dm-icon".+<\/svg>(.+)$/s)?.[1].trim();
        nBulletChat = sFormatUtil.toPlayCountOrBulletChat(nBulletChat);
        let nDuration = el.querySelector('.duration')?.textContent.trim();
        nDuration = sFormatUtil.timeStringToSeconds(nDuration);
        return {
            nPlayCount, nBulletChat, nDuration
        }
    };
    const getRightVideoDataList$1=(elList)=>{
        const list = [];
        for (let el of elList) {
            const title = el.querySelector(".title").textContent.trim();
            const userInfoEl = el.querySelector(".upname");
            const name = userInfoEl.querySelector(".name").textContent.trim();
            const userUrl = userInfoEl.href;
            const uid = elUtil.getUrlUID(userUrl);
            const videoUrl = el.querySelector(".info>a").href;
            const bv = elUtil.getUrlBV(videoUrl);
            list.push({
                ...getPlayCountAndBulletChatAndDuration(el), ...{
                    title,
                    name,
                    userUrl,
                    videoUrl,
                    uid,
                    bv,
                    el,
                    insertionPositionEl: el.querySelector(".playinfo"),
                    explicitSubjectEl: el.querySelector(".info")
                }
            });
        }
        return list;
    };
    var generalFuc = {getRightVideoDataList: getRightVideoDataList$1};
    const iscCollectionVideoPlayPage = (url) => {
        return url.includes("www.bilibili.com/list/ml")
    };
    const getGetTheVideoListOnTheRight = async () => {
        const elList = await elUtil.findElementsUntilFound(".recommend-list-container>.video-card");
        return generalFuc.getRightVideoDataList(elList);
    };
    const startShieldingVideoList$4 = () => {
        getGetTheVideoListOnTheRight().then((videoList) => {
            const css = {right: "123px"};
            for (let videoData of videoList) {
                if (shielding.shieldingVideoDecorated(videoData)) continue;
                videoData.css = css;
                eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingVideoList$4});
            }
        });
    };
    const findTheExpandButtonForTheListOnTheRightAndBindTheEvent$1 = () => {
        setTimeout(() => {
            elUtil.findElementUntilFound(".rec-footer", {interval: 2000}).then((el) => {
                el.addEventListener("click", () => {
                    startShieldingVideoList$4();
                });
            });
        }, 3000);
    };
    var collectionVideoPlayPageModel = {
        iscCollectionVideoPlayPage,
        startShieldingVideoList: startShieldingVideoList$4,
        findTheExpandButtonForTheListOnTheRightAndBindTheEvent: findTheExpandButtonForTheListOnTheRightAndBindTheEvent$1
    };
    const addEventListenerUrlChange = (callback) => {
        let oldUrl = window.location.href;
        setInterval(() => {
            const newUrl = window.location.href;
            if (oldUrl === newUrl) return;
            oldUrl = newUrl;
            const title = document.title;
            callback(newUrl, oldUrl, title);
        }, 1000);
    };
    const addEventListenerNetwork = (callback) => {
        new PerformanceObserver(() => {
            const entries = performance.getEntriesByType('resource');
            const windowUrl = window.location.href;
            const winTitle = document.title;
            for (let entry of entries) {
                const url = entry.name;
                const initiatorType = entry.initiatorType;
                if (initiatorType === "img" || initiatorType === "css" || initiatorType === "link" || initiatorType === "beacon") {
                    continue;
                }
                callback(url, windowUrl,winTitle, initiatorType);
            }
            performance.clearResourceTimings();//清除资源时间
        }).observe({entryTypes: ['resource']});
    };
    function watchElementListLengthWithInterval(selector, callback, config={}) {
        const defConfig = {};
        config = {...defConfig, ...config};
        let previousLength = -1;
        const timer = setInterval(() => {
                if (previousLength === -1) {
                    previousLength = document.querySelectorAll(selector).length;
                    return
                }
                const currentElements = document.querySelectorAll(selector);
                const currentLength = currentElements.length;
                if (currentLength !== previousLength) {
                    previousLength = currentLength;
                    callback({
                            action: currentLength > previousLength ? 'add' : 'del',
                            elements: currentElements,
                            length: currentLength
                        }
                    );
                }
            },
            config.interval
        );
        return stop = () => {
            clearInterval(timer);
        };
    }
    var watch = {
        addEventListenerUrlChange,
        addEventListenerNetwork,
        watchElementListLengthWithInterval
    };
    const isLiveRoom = (url) => {
        return url.search('/live.bilibili.com/\\d+') !== -1;
    };
    const getChatItems = async () => {
        const elList = await elUtil.findElementsUntilFound("#chat-items>div");
        if (elList.length >= 200) {
            for (let i = 0; i < 100; i++) {
                elList[i]?.remove();
            }
            console.log("弹幕列表超过200,已删除前100条");
        }
        const list = [];
        for (let el of elList) {
            if (el.className === "chat-item  convention-msg border-box") {
                continue;
            }
            if (el.className === "chat-item misc-msg guard-buy") {
                continue;
            }
            const name = el.getAttribute("data-uname");
            if (name === null) {
                continue;
            }
            const uid = el.getAttribute("data-uid");
            const content = el.getAttribute("data-danmaku");
            const timeStamp = el.getAttribute("data-timestamp");
            const fansMedalEl = el.querySelector(".fans-medal-content");
            const fansMedal = fansMedalEl === null ? null : fansMedalEl.textContent.trim();
            list.push({
                name,
                uid,
                content,
                timeStamp,
                fansMedal,
                el,
                insertionPositionEl: el,
                explicitSubjectEl: el
            });
        }
        return list;
    };
    const startShieldingLiveChatContents = async () => {
        const commentsDataList = await getChatItems();
        for (let commentsData of commentsDataList) {
            if (shielding.shieldingLiveRoomContentDecorated(commentsData)) {
                continue;
            }
            shielding.addLiveContentBlockButton({data: commentsData, maskingFunc: startShieldingLiveChatContents});
        }
    };
    const addWatchLiveRoomChatItemsListener = () => {
        const throttle = defUtil.throttle(startShieldingLiveChatContents, 1000);
        watch.watchElementListLengthWithInterval("#chat-items>div", throttle);
    };
    var liveRoomModel = {
        isLiveRoom,
        addWatchLiveRoomChatItemsListener
    };
    const isVideoPlayWatchLaterPage = (url) => {
        return url.startsWith("https://www.bilibili.com/list/watchlater")
    };
    const getRightVideoDataList = async () => {
        const elList = await elUtil.findElementsUntilFound(".recommend-video-card.video-card");
        return generalFuc.getRightVideoDataList(elList);
    };
    const startShieldingVideoList$3 = async () => {
        const videoList = await getRightVideoDataList();
        const css = {right: "123px"};
        for (let videoData of videoList) {
            videoData.css = css;
            if (shielding.shieldingVideoDecorated(videoData)) continue;
            eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingVideoList$3});
        }
    };
    const startDebounceShieldingVideoList = defUtil.debounce(startShieldingVideoList$3, 1000);
    const findTheExpandButtonForTheListOnTheRightAndBindTheEvent = () => {
        elUtil.findElementsAndBindEvents(".rec-footer", startDebounceShieldingVideoList);
    };
    var videoPlayWatchLater = {
        isVideoPlayWatchLaterPage,
        startDebounceShieldingVideoList,
        findTheExpandButtonForTheListOnTheRightAndBindTheEvent
    };
    const getBewlyEl = async () => {
        let el = await elUtil.findElementUntilFound('#bewly', {interval: 500});
        return el.shadowRoot;
    };
    const isBEWLYPage = (url) => {
        return url.includes('www.bilibili.com/?page=') ||
            url === 'https://www.bilibili.com/'
            || url.startsWith('https://www.bilibili.com/?spm_id_from=')
    };
    const getVideoList = async () => {
        const beEl = await getBewlyEl();
        const elList = await elUtil.findElementsUntilFound('.video-card.group', {doc: beEl});
        const list = [];
        for (let el of elList) {
            const parentElement = el.parentElement.parentElement;
            const title = el.querySelector('.keep-two-lines>a[title]').textContent.trim();
            const userUrlEl = el.querySelector('.channel-name');
            const userUrl = userUrlEl.href;
            const uid = elUtil.getUrlUID(userUrl);
            const name = userUrlEl.textContent.trim();
            const playInfoEl = el.querySelector('[flex="~ items-center gap-1 wrap"]>div');
            let playCount = playInfoEl.querySelector('span:first-child')?.textContent.trim() || null;
            playCount = sFormatUtil.toPlayCountOrBulletChat(playCount);
            let bulletChat = playInfoEl.querySelector('span:last-of-type')?.textContent.trim() || null;
            if (playInfoEl.querySelectorAll('span').length < 2) {
                bulletChat = -1;
            } else {
                bulletChat = sFormatUtil.toPlayCountOrBulletChat(bulletChat);
            }
            let nDuration = el.querySelector('[class*="group-hover:opacity-0"]')?.textContent.trim() || null;
            nDuration = sFormatUtil.timeStringToSeconds(nDuration);
            const videoUrl = el.querySelector('[href*="https://www.bilibili.com/video"]')?.href;
            const bv=elUtil.getUrlBV(videoUrl);
            const insertionPositionEl = el.querySelector('[class="group/desc"]');
            list.push({
                title,
                name,
                uid,
                bv,
                userUrl,
                videoUrl,
                playCount,
                bulletChat,
                nDuration,
                el: parentElement,
                insertionPositionEl,
                explicitSubjectEl: parentElement
            });
        }
        return list
    };
    const getRightTabs = async () => {
        const beEl = await getBewlyEl();
        const els = await elUtil.findElementsUntilFound(".dock-content-inner>.b-tooltip-wrapper", {doc: beEl});
        const list = [];
        for (let el of els) {
            const label = el.querySelector('.b-tooltip').textContent.trim();
            const active = !!el.querySelector('.dock-item.group.active');
            list.push({label, active, el});
        }
        return list;
    };
    const getHistoryVideoDataList = async () => {
        const beEL = await getBewlyEl();
        const elList = await elUtil.findElementsUntilFound("a.group[flex][cursor-pointer]", {doc: beEL});
        const list = [];
        for (let el of elList) {
            const titleEl = el.querySelector('h3.keep-two-lines');
            const videoUrlEl = titleEl.parentElement;
            const userEl = videoUrlEl.nextElementSibling;
            const videoUrl = videoUrlEl.href;
            const bv=elUtil.getUrlBV(videoUrl);
            const userUrl = userEl.href;
            const uid = elUtil.getUrlUID(userUrl);
            const name = userEl.textContent.trim();
            const title = titleEl?.textContent.trim();
            const tempTime = el.querySelector('div[pos][rounded-8]')?.textContent.trim().split(/[\t\r\f\n\s]*/g).join("");
            const match = tempTime?.match(/\/(.*)/);
            let nDuration = match?.[1];
            nDuration = sFormatUtil.timeStringToSeconds(nDuration);
            list.push({
                title,
                userUrl,
                name,
                uid,
                videoUrl,
                nDuration,
                bv,
                el,
                insertionPositionEl: videoUrlEl.parentElement,
                explicitSubjectEl: el
            });
        }
        return list
    };
    const startShieldingHistoryVideoList = async () => {
        const list = await getHistoryVideoDataList();
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue
            }
            eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingHistoryVideoList});
        }
    };
    const startShieldingVideoList$2 = async () => {
        const list = await getVideoList();
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue
            }
            eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingVideoList$2});
        }
    };
    const intervalExecutionStartShieldingVideo$2 = () => {
        const res = shielding.intervalExecutionStartShieldingVideoInert(startShieldingVideoList$2, '视频');
        return () => {
            return res
        }
    };
    const intervalExecutionStartShieldingHistoryVideo = () => {
        const res = shielding.intervalExecutionStartShieldingVideoInert(startShieldingHistoryVideoList, '历史记录');
        return () => {
            return res
        }
    };
    const startShieldingVideo$1 = intervalExecutionStartShieldingVideo$2();
    const startShieldingHistoryVideo = intervalExecutionStartShieldingHistoryVideo();
    const rightTabsInsertListener = () => {
        getRightTabs().then(list => {
                for (let {el, label, active} of list) {
                    el.addEventListener('click', () => {
                            console.log('右侧选项卡栏点击了' + label, active);
                            if (label === '首页') {
                                homeTopTabsInsertListener();
                                startShieldingVideo$1().start();
                            } else {
                                startShieldingVideo$1().stop();
                            }
                            if (label === '观看历史') {
                                startShieldingHistoryVideo().start();
                            } else {
                                startShieldingHistoryVideo().stop();
                            }
                        }
                    );
                }
            }
        );
    };
    const getHomeTopTabs = async () => {
        const beEl = await getBewlyEl();
        const els = beEl.querySelectorAll('.home-tabs-inside>[data-overlayscrollbars-contents]>button');
        const list = [];
        for (let el of els) {
            const label = el.textContent.trim();
            const active = el.classList.contains('tab-activated');
            list.push({label, active, el});
        }
        if (list.some(tab => tab.active === true)) {
            return list
        }
        return await getHomeTopTabs()
    };
    const excludeTabNames = ['正在关注', '订阅剧集', '直播'];
    const excludeRankingLeftTabNames = ['番剧', '综艺', '电视剧', '纪录片', '中国动画'];
    const homeTopTabsInsertListener = () => {
        getHomeTopTabs().then(list => {
            for (let {el, label} of list) {
                el.addEventListener('click', () => {
                    console.log('点击了' + label);
                    if (excludeTabNames.includes(label)) {
                        startShieldingVideo$1().stop();
                        return
                    }
                    if (label === '排行') {
                        rankingLeftTabsInsertListener();
                    }
                    startShieldingVideo$1().start();
                });
            }
        });
    };
    const getRankingLeftTabs = async () => {
        const beEl = await getBewlyEl();
        const elList = await elUtil.findElementsUntilFound('ul[flex="~ col gap-2"]>li', {doc: beEl});
        const list = [];
        for (let el of elList) {
            const label = el.textContent.trim();
            list.push({label, el});
        }
        return list
    };
    const rankingLeftTabsInsertListener = () => {
        getRankingLeftTabs().then(list => {
            for (let {el, label} of list) {
                el.addEventListener('click', () => {
                    console.log('点击了' + label);
                    if (excludeRankingLeftTabNames.includes(label)) {
                        startShieldingVideo$1().stop();
                        return
                    }
                    startShieldingVideo$1().start();
                });
            }
        });
    };
    const installBEWLStyle = () => {
        getBewlyEl().then(el => {
            gz_ui_css.addStyle(el, el);
        });
    };
    const searchBoxInsertListener = async () => {
        const beEl = await getBewlyEl();
        const input = await elUtil.findElementUntilFound('[placeholder="搜索观看历史"]', {doc: beEl});
        input.addEventListener('keydown', (event) => {
            if (event.key === 'Enter' || event.keyCode === 13) {
                console.log('回车键被按下');
                if (input['value'].length === 0) return
                setTimeout(startShieldingHistoryVideoList, 1500);
            }
        });
    };
    const startRun$1 = async (url) => {
        const parseUrl = defUtil.parseUrl(url);
        const {page} = parseUrl.queryParams;
        installBEWLStyle();
        if (page === 'Home' ||
            url.startsWith('https://www.bilibili.com/?spm_id_from=') ||
            url === 'https://www.bilibili.com/'
        ) {
            startShieldingVideo$1().start();
            homeTopTabsInsertListener();
        }
        if (page === 'History') {
            startShieldingHistoryVideo().start();
            searchBoxInsertListener();
        }
        rightTabsInsertListener();
    };
    var compatibleBewlyBewly = {
        startRun: startRun$1,
        isBEWLYPage,
    };
    const isNewHistoryPage = (url) => {
        return url.includes('://www.bilibili.com/history')
    };
    const getDuration = (str) => {
        if (str === null) {
            return -1
        }
        if (str.includes('已看完') || str === '') {
            return -1
        } else {
            const match = str?.match(/\/(.*)/);
            if (match) {
                return sFormatUtil.timeStringToSeconds(match[1]);
            }
        }
        return -1
    };
    const getVideoDataList$3 = async () => {
        const elList = await elUtil.findElementsUntilFound('.section-cards.grid-mode>div');
        const list = [];
        for (let el of elList) {
            const titleEl = el.querySelector('.bili-video-card__title');
            const title = titleEl.textContent.trim();
            const videoUrl = titleEl.firstElementChild.href||null;
            if (videoUrl?.includes('live.bilibili.com')) {
                continue
            }
            const bv=elUtil.getUrlBV(videoUrl);
            const userEl = el.querySelector('.bili-video-card__author');
            const cardTag = el.querySelector('.bili-cover-card__tag')?.textContent.trim() || null;
            const name = userEl.textContent.trim();
            const userUrl = userEl.href;
            const uid = elUtil.getUrlUID(userUrl);
            let nDuration = -1;
            if (cardTag !== '专栏') {
                nDuration = el.querySelector('.bili-cover-card__stat')?.textContent.trim() || null;
                nDuration = getDuration(nDuration);
            }
            const tempEL = el.querySelector('.bili-video-card__details');
            list.push({
                title,
                videoUrl,
                name,
                userUrl,
                nDuration,
                uid,
                el,
                bv,
                insertionPositionEl: tempEL,
                explicitSubjectEl: tempEL
            });
        }
        return list
    };
    const startShieldingVideoList$1 = async () => {
        const list = await getVideoDataList$3();
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue;
            }
            shielding.addBlockButton({data: videoData, maskingFunc: startShieldingVideoList$1}, "gz_shielding_button");
        }
    };
    const intervalExecutionStartShieldingVideo$1 = () => {
        const res = shielding.intervalExecutionStartShieldingVideoInert(startShieldingVideoList$1, '历史记录项');
        return () => {
            return res
        }
    };
    const executionStartShieldingVideo = intervalExecutionStartShieldingVideo$1();
    const getTopFilterLabel = async () => {
        const el = await elUtil.findElementUntilFound('.radio-filter>.radio-filter__item--active');
        return el.textContent?.trim()
    };
    const topFilterInsertListener = () => {
        elUtil.findElementUntilFound('.radio-filter').then((el => {
            el.addEventListener('click', (e) => {
                const target = e.target;
                const label = target.textContent?.trim();
                console.log(`点击了${label}`);
                if (label === '直播') {
                    executionStartShieldingVideo().stop();
                    return
                }
                executionStartShieldingVideo().start();
            });
        }));
    };
    const startRun = () => {
        getTopFilterLabel().then(label => {
            if (label === '直播') {
                return
            }
            executionStartShieldingVideo().start();
        });
        topFilterInsertListener();
    };
    var newHistory = {
        isNewHistoryPage,
        intervalExecutionStartShieldingVideo: intervalExecutionStartShieldingVideo$1,
        startRun
    };
    const startShieldingHotList = async () => {
        const elList = await elUtil.findElements(".trendings-col>.trending-item",
            {interval: 2000});
        console.log("检查热搜关键词中...");
        const hotSearchKeyArr = ruleKeyListData$1.getHotSearchKeyArr();
        const hotSearchKeyCanonicalArr = ruleKeyListData$1.getHotSearchKeyCanonicalArr();
        for (let el of elList) {
            const label = el.textContent.trim();
            let match = ruleMatchingUtil.fuzzyMatch(hotSearchKeyArr, label);
            if (match) {
                el.remove();
                eventEmitter.send('打印信息', `根据模糊热搜关键词-【${match}】-屏蔽-${label}`);
                continue;
            }
            match = ruleMatchingUtil.regexMatch(hotSearchKeyCanonicalArr, label);
            if (match) {
                eventEmitter.send('打印信息', `根据正则热搜关键词-【${match}】-屏蔽-${label}`);
                el.remove();
            }
        }
    };
    var hotSearch = {
        startShieldingHotList
    };
    const isMessagePage = (url = window.location.href) => {
        return url.includes("message.bilibili.com");
    };
    const modifyTopItemsZIndex = () => {
        elUtil.findElement('#home_nav').then(el => {
            el.style.zIndex = 1000;
            eventEmitter.send('打印信息', '已修改顶部的z-index值为1');
        });
    };
    var messagePage = {
        isMessagePage,
        modifyTopItemsZIndex,
    };
    const isSpacePage = (url = window.location.href) => {
        return url.startsWith('https://space.bilibili.com/')
    };
    const isPersonalHomepage = async () => {
        const keyStr = 'isPersonalHomepage';
        const cache = valueCache.get(keyStr);
        if (cache) {
            return cache
        }
        const {
            state: newState,
            data: newData
        } = await elUtil.findElements('.nav-tab__item .nav-tab__item-text', {timeout: 2500});
        if (newState) {
            const bool = newData.some(el => el.textContent.trim() === '设置');
            valueCache.set('space_version', 'new');
            return valueCache.set(keyStr, bool);
        }
        let {state} = await elUtil.findElement('.n-tab-links>.n-btn.n-setting>.n-text', {timeout: 1500});
        valueCache.set('space_version', 'old');
        return valueCache.set(keyStr, state);
    };
    const getUserInfo = async () => {
        const spaceUserInfo = valueCache.get('space_userInfo');
        if (spaceUserInfo) {
            return spaceUserInfo
        }
        await isPersonalHomepage();
        const nameData = {};
        nameData.uid = elUtil.getUrlUID(window.location.href);
        if (valueCache.get('space_version', 'new') === 'new') {
            nameData.name = await elUtil.findElement('.nickname').then(el => el.textContent.trim());
        } else {
            nameData.name = await elUtil.findElement('#h-name').then(el => el.textContent.trim());
        }
        if (!nameData.name) {
            const title = document.title;
            nameData.name = title.match(/(.+)的个人空间/)[1];
        }
        valueCache.set('space_userInfo', nameData);
        return nameData
    };
    var space = {
        isPersonalHomepage,
        isSpacePage,
        getUserInfo
    };
    const bOnlyTheHomepageIsBlocked$2 = localMKData.getBOnlyTheHomepageIsBlocked();
    const staticRoute = (title, url) => {
        console.log("静态路由", title, url);
        topInput.processTopInputContent();
        if (bOnlyTheHomepageIsBlocked$2) return;
        hotSearch.startShieldingHotList();
        eventEmitter.send('通知屏蔽');
        if (compatibleBewlyBewly.isBEWLYPage(url)) {
            if (localMKData.isCompatible_BEWLY_BEWLY()) {
                compatibleBewlyBewly.startRun(url);
                return;
            }
        }
        if (bilibiliHome.isHome(url, title)) {
            if (localMKData.isCompatible_BEWLY_BEWLY()) {
                return;
            }
            bilibiliHome.scrollMouseUpAndDown().then(() => bilibiliHome.startDebounceShieldingChangeVideoList());
            bilibiliHome.startClearExcessContentList();
            bilibiliHome.deDesktopDownloadTipEl();
        }
        if (searchModel.isSearch(url)) {
            searchModel.searchTopTabsIWrapperInstallListener();
            searchModel.startShieldingVideoList();
            searchModel.currentlyActivatedOptions();
            searchLive.installStyle();
            searchModel.delFooterContent();
        }
        if (videoPlayModel.isVideoPlayPage(url)) {
            elUtil.findElement('.v-modal').then(() => {
                const styleEl = document.createElement('style');
                styleEl.innerHTML = `.v-modal  {
    z-index: auto !important;
}`;
                document.head.appendChild(styleEl);
            });
            videoPlayModel.findTheExpandButtonForTheListOnTheRightAndBindTheEvent();
            videoPlayModel.setVideoPlayerEnded();
            videoPlayModel.delElManagement();
        }
        if (collectionVideoPlayPageModel.iscCollectionVideoPlayPage(url)) {
            collectionVideoPlayPageModel.findTheExpandButtonForTheListOnTheRightAndBindTheEvent();
        }
        if (liveRoomModel.isLiveRoom(url)) {
            liveRoomModel.addWatchLiveRoomChatItemsListener();
        }
        if (videoPlayWatchLater.isVideoPlayWatchLaterPage(url)) {
            videoPlayWatchLater.findTheExpandButtonForTheListOnTheRightAndBindTheEvent();
        }
        if (newHistory.isNewHistoryPage(url)) {
            newHistory.startRun();
        }
        if (messagePage.isMessagePage(url)) {
            messagePage.modifyTopItemsZIndex();
        }
        if (space.isSpacePage()) {
            space.getUserInfo().then(userInfo => {
                console.info('userInfo', userInfo);
            });
        }
    };
    const dynamicRouting = (title, url) => {
        console.log("动态路由", title, url);
        if (bOnlyTheHomepageIsBlocked$2) return;
        eventEmitter.send('通知屏蔽');
    };
    var router = {
        staticRoute,
        dynamicRouting
    };
    const isTopicDetailPage = (url) => {
        return url.includes("//www.bilibili.com/v/topic/detail/")
    };
    const getDataList$1 = async () => {
        const elList = await elUtil.findElementsUntilFound(".list__topic-card");
        const list = [];
        for (let el of elList) {
            const name = el.querySelector(".bili-dyn-title").textContent.trim();
            const uidEl = el.querySelector(".bili-dyn-item__following");
            const uid = parseInt(uidEl.getAttribute("data-mid"));
            const judgmentEl = el.querySelector(".bili-dyn-card-video__title");
            const data = {name, uid, el, judgmentVideo: judgmentEl !== null};
            if (judgmentEl !== null) {
                data.title = judgmentEl.textContent.trim();
                const videoUrl = el.querySelector(".bili-dyn-card-video").href;
                data.videoUrl = videoUrl;
                data.bv = elUtil.getUrlBV(videoUrl);
                data.insertionPositionEl = el.querySelector(".bili-dyn-content__orig");
                data.explicitSubjectEl = data.insertionPositionEl;
            } else {
                const dynTitle = el.querySelector(".dyn-card-opus__title");
                const contentTitle = dynTitle === null ? "" : dynTitle.textContent.trim();
                const contentBody = el.querySelector(".bili-rich-text>div").textContent.trim();
                data.insertionPositionEl = el.querySelector(".dyn-card-opus");
                data.explicitSubjectEl = data.insertionPositionEl;
                data.content = contentTitle + contentBody;
            }
            list.push(data);
        }
        return list;
    };
    const __shieldingVideo = (videoData) => {
        if (shielding.shieldingVideoDecorated(videoData)) {
            return;
        }
        shielding.addTopicDetailVideoBlockButton({data: videoData, maskingFunc: startShielding});
    };
    const __shieldingDynamic = (dynamicData) => {
        if (shielding.shieldingCommentDecorated(dynamicData)) {
            return;
        }
        shielding.addTopicDetailContentsBlockButton({data: dynamicData, maskingFunc: startShielding});
    };
    const startShielding = async () => {
        const list = await getDataList$1();
        const css = {width: "100%"};
        for (let data of list) {
            data.css = css;
            if (data.judgmentVideo) {
                __shieldingVideo(data);
            } else {
                __shieldingDynamic(data);
            }
        }
    };
    var topicDetail = {
        isTopicDetailPage,
        startShielding
    };
    eventEmitter.on('评论添加屏蔽按钮', (commentsData) => {
        shielding.addBlockButton({
            data: commentsData,
            maskingFunc: startShieldingComments
        }, "gz_shielding_comment_button");
    });
    const getUrlUserLevel = (src) => {
        const levelMath = src?.match(/level_(.+)\.svg/) || null;
        let level = -1;
        if (levelMath !== null) {
            const levelRow = levelMath[1];
            if (levelRow === 'h') {
                level = 7;
            } else {
                level = parseInt(levelRow);
            }
        }
        return level;
    };
    const getOldUserLevel = (iEl) => {
        let level = -1;
        const levelCLassName = iEl.classList[1];
        if (levelCLassName === 'level-hardcore') {
            level = 7;
        } else {
            const levelMatch = levelCLassName.match(/level-(.+)/)?.[1] || '';
            level = parseInt(levelMatch);
        }
        return level
    };
    const getCommentSectionList = async () => {
        const commentApp = await elUtil.findElementUntilFound("bili-comments",
            {interval: 500});
        const comments = await elUtil.findElementsUntilFound("#feed>bili-comment-thread-renderer",
            {doc: commentApp.shadowRoot, interval: 500});
        const commentsData = [];
        let isLoaded = false;
        for (let el of comments) {
            const theOPEl = el.shadowRoot.getElementById("comment").shadowRoot;
            const theOPUserInfo = theOPEl.querySelector("bili-comment-user-info")
                .shadowRoot.getElementById("info");
            const userNameEl = theOPUserInfo.querySelector("#user-name>a");
            const userLevelSrc = theOPUserInfo.querySelector('#user-level>img')?.src || null;
            const level = getUrlUserLevel(userLevelSrc);
            isLoaded = theOPEl.querySelector("#content>bili-rich-text")
                .shadowRoot.querySelector("#contents>*") !== null;
            if (!isLoaded) {
                break;
            }
            const theOPContentEl = theOPEl.querySelector("#content>bili-rich-text")
                .shadowRoot.querySelector("#contents");
            const theOPContent = theOPContentEl.textContent.trim();
            const userName = userNameEl.textContent.trim();
            const userUrl = userNameEl.href;
            const uid = elUtil.getUrlUID(userUrl);
            const replies = [];
            commentsData.push({
                name: userName,
                userUrl,
                uid,
                level,
                content: theOPContent,
                replies,
                el,
                insertionPositionEl: theOPUserInfo,
                explicitSubjectEl: theOPEl.querySelector("#body")
            });
            const inTheBuildingEls = el.shadowRoot.querySelector("bili-comment-replies-renderer")
                .shadowRoot.querySelectorAll("bili-comment-reply-renderer");
            for (let inTheBuildingEl of inTheBuildingEls) {
                const inTheContentEl = inTheBuildingEl.shadowRoot;
                const biliCommentUserInfo = inTheContentEl.querySelector("bili-comment-user-info");
                biliCommentUserInfo.style.display = 'block';
                const inTheBuildingUserInfo = biliCommentUserInfo.shadowRoot.getElementById("info");
                const inTheBuildingUserNameEl = inTheBuildingUserInfo.querySelector("#user-name>a");
                const inTheBuildingUserName = inTheBuildingUserNameEl.textContent.trim();
                const inTheBuildingUserUrl = inTheBuildingUserNameEl.href;
                const inTheBuildingUid = elUtil.getUrlUID(inTheBuildingUserUrl);
                const biliRichTextEL = inTheContentEl.querySelector("bili-rich-text");
                const inTheBuildingContent = biliRichTextEL.shadowRoot.getElementById("contents").textContent.trim();
                const userLevelSrc = inTheBuildingUserInfo.querySelector('#user-level>img')?.src || null;
                const level = getUrlUserLevel(userLevelSrc);
                replies.push({
                    name: inTheBuildingUserName,
                    userUrl: inTheBuildingUserUrl,
                    uid: inTheBuildingUid,
                    level,
                    content: inTheBuildingContent,
                    el: inTheBuildingEl,
                    insertionPositionEl: inTheBuildingUserInfo,
                    explicitSubjectEl: inTheBuildingEl
                });
            }
        }
        if (!isLoaded) {
            await defUtil.wait(500);
            return getCommentSectionList()
        }
        return commentsData;
    };
    const getOldCommentSectionList = async () => {
        let results;
        try {
            results = await elUtil.findElementsUntilFound(".reply-list>.reply-item", {timeout: 5000});
        } catch (e) {
            return []
        }
        const commentsData = [];
        for (let el of results) {
            const theOPEl = el.querySelector(".root-reply-container");
            const theOPUserInfoEl = theOPEl.querySelector(".user-name");
            const userName = theOPUserInfoEl.textContent.trim();
            const uid = parseInt(theOPUserInfoEl.getAttribute("data-user-id"));
            const userUrl = `https://space.bilibili.com/${uid}`;
            const theOPContent = theOPEl.querySelector(".reply-content").textContent.trim();
            const userInfoEl = el.querySelector(".user-info");
            const iEl = userInfoEl.querySelector('i');
            const level = getOldUserLevel(iEl);
            const replies = [];
            commentsData.push({
                name: userName,
                userUrl,
                uid,
                content: theOPContent,
                level,
                replies,
                el,
                insertionPositionEl: userInfoEl,
                explicitSubjectEl: el.querySelector(".content-warp")
            });
            const inTheBuildingEls = el.querySelectorAll(".sub-reply-container>.sub-reply-list>.sub-reply-item");
            for (let inTheBuildingEl of inTheBuildingEls) {
                const subUserNameEl = inTheBuildingEl.querySelector(".sub-user-name");
                const uid = parseInt(subUserNameEl.getAttribute("data-user-id"));
                const userName = subUserNameEl.textContent.trim();
                const userUrl = `https://space.bilibili.com/${uid}`;
                const subContent = inTheBuildingEl.querySelector(".reply-content").textContent.trim();
                const subUserInfoEl = inTheBuildingEl.querySelector(".sub-user-info");
                const iEl = subUserInfoEl.querySelector('i');
                const level = getOldUserLevel(iEl);
                const replyContentContainerEl = inTheBuildingEl.querySelector('span.reply-content-container');
                replyContentContainerEl.style.display = 'block';
                replies.push({
                    name: userName,
                    userUrl,
                    uid,
                    level,
                    content: subContent,
                    el: inTheBuildingEl,
                    insertionPositionEl: subUserInfoEl,
                    explicitSubjectEl: inTheBuildingEl
                });
            }
        }
        return commentsData;
    };
    const startShieldingComments = async () => {
        if (videoPlayModel.isVideoPlayPage() && gmUtil.getData('isDelBottomComment', false)) {
            return
        }
        let list;
        const href = window.location.href;
        if (localMKData.isDiscardOldCommentAreas()) {
            list = await getCommentSectionList();
        } else if (href.includes("https://space.bilibili.com/") || topicDetail.isTopicDetailPage(href)) {
            list = await getOldCommentSectionList();
        } else {
            list = await getCommentSectionList();
        }
        shielding.shieldingComments(list);
    };
    var commentSectionModel = {
        startShieldingComments
    };
    const getVideDataList = async (isWeekly = false) => {
        const css = isWeekly ? ".video-list>.video-card" : ".card-list>.video-card";
        const elList = await elUtil.findElementsUntilFound(css);
        const list = [];
        for (let el of elList) {
            const videoCardInfoEl = el.querySelector(".video-card__info");
            const title = videoCardInfoEl.querySelector(".video-name").title.trim();
            const name = videoCardInfoEl.querySelector(".up-name__text").title;
            const videoUrl = el.querySelector('.video-card__content>a')?.href || null;
            const bv = elUtil.getUrlBV(videoUrl);
            let nPlayCount = el.querySelector('.play-text').textContent.trim();
            nPlayCount = sFormatUtil.toPlayCountOrBulletChat(nPlayCount);
            let nBulletChat = el.querySelector('.like-text').textContent.trim();
            nBulletChat = sFormatUtil.toPlayCountOrBulletChat(nBulletChat);
            list.push({
                el,
                title,
                name,
                uid: -1,
                videoUrl,
                bv,
                nPlayCount,
                nBulletChat,
                nDuration: -1,
                insertionPositionEl: videoCardInfoEl.querySelector("div"),
                explicitSubjectEl: videoCardInfoEl
            });
        }
        return list;
    };
    const startShieldingVideoList = async (isWeekly = false) => {
        const list = await getVideDataList(isWeekly);
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue;
            }
            eventEmitter.send('添加热门视频屏蔽按钮', {data: videoData, maskingFunc: startShieldingVideoList});
        }
    };
    var popularAll = {
        startShieldingVideoList
    };
    const isDynamicPage = (url) => {
        return url.search("space.bilibili.com/\\d+/dynamic") !== -1;
    };
    const getDataList = async () => {
        const elList = await elUtil.findElementsUntilFound(".bili-dyn-list__items>.bili-dyn-list__item");
        const list = [];
        for (let el of elList) {
            const videoCardEl = el.querySelector(".bili-dyn-card-video__title");
            const name = el.querySelector(".bili-dyn-title").textContent.trim();
            const tagEl = el.querySelector(".bili-dyn-topic__text");
            const data = {el, name};
            if (tagEl !== null) {
                data.tag = tagEl.textContent.trim();
            }
            data.judgmentVideo = videoCardEl !== null;
            if (data.judgmentVideo) {
                data.title = videoCardEl.textContent.trim();
            } else {
                const contentTitleEL = el.querySelector(".dyn-card-opus>.dyn-card-opus__title");
                const contentTitle = contentTitleEL === null ? "" : contentTitleEL.textContent.trim();
                const contentElBody = el.querySelector(".bili-rich-text").textContent.trim();
                data.content = contentTitle + contentElBody;
            }
            list.push(data);
        }
        return list;
    };
    const startShieldingDynamicContent = async () => {
        const personalHomepage = space.isPersonalHomepage();
        if (personalHomepage) return;
        const list = await getDataList();
        for (let dynamicContent of list) {
            shielding.shieldingDynamicDecorated(dynamicContent);
        }
    };
    const startThrottleShieldingDynamicContent = defUtil.throttle(startShieldingDynamicContent, 2000);
    var dynamic = {
        isDynamicPage,
        startThrottleShieldingDynamicContent
    };
    const isLiveSection = (url) => {
        return url.includes("live.bilibili.com/p/eden/area-tags")
    };
    const getRoomCardDataList = async () => {
        const elList = await elUtil.findElementsUntilFound("#room-card-list>div");
        const list = [];
        for (let el of elList) {
            const liveUrl = el.querySelector("#card").href;
            const name = el.querySelector(".Item_nickName_KO2QE").textContent.trim();
            const title = el.querySelector(".Item_roomTitle_ax3eD").textContent.trim();
            const partition = el.querySelector(".Item_area-name_PXDG4")?.textContent.trim() || null;
            const popularity = el.querySelector(".Item_onlineCount_FmOW6").textContent.trim();
            list.push({liveUrl, name, title, partition, popularity, el});
        }
        return list;
    };
    const startShieldingLiveRoom$1 = async () => {
        const liveList = await getRoomCardDataList();
        for (let liveData of liveList) {
            shielding.shieldingLiveRoomDecorated(liveData);
        }
    };
    var liveSectionModel = {
        isLiveSection,
        startShieldingLiveRoom: startShieldingLiveRoom$1
    };
    const isLiveHomePage = (url) => {
        return url.includes("https://live.bilibili.com/?spm_id_from=333.1007.0.0") ||
            url === "https://live.bilibili.com/"
    };
    const getTopLiveRoomDataList = async () => {
        const verification = await elUtil.findElementUntilFound(".v-top>.aside-item .t-left.aside-item-tips.p-absolute.w-100.border-box");
        if (verification.textContent.trim() === "--") {
            return await getTopLiveRoomDataList();
        }
        const elList = await elUtil.findElementsUntilFound(".v-top>.aside-item", {interval: 2000});
        const list = [];
        for (let el of elList) {
            const classList = el.classList;
            const active = classList.contains("active");
            const title = el.getAttribute("title");
            const {up_id: uid, room_id} = JSON.parse(el.getAttribute("data-report"));
            const liveUrl = `https://live.bilibili.com/${room_id}`;
            list.push({title, uid, active, liveUrl, el});
        }
        return list;
    };
    const getLiveRoomDataList = async () => {
        const elList = await elUtil.findElementsUntilFound(".room-card-wrapper.p-relative.dp-i-block");
        const list = [];
        for (let el of elList) {
            const cardEl = el.querySelector(".room-card-ctnr.p-relative.w-100");
            const cardData = JSON.parse(cardEl.getAttribute("data-bl-report-click") || "");
            const {up_id: uid, room_id} = cardData.msg;
            const liveUrl = `https://live.bilibili.com/${room_id}`;
            const name = el.querySelector(".room-anchor>span").textContent.trim();
            const title = el.querySelector(".room-title.card-text").textContent.trim();
            const partition = el.querySelector(".area-name").textContent.trim();
            const popularity = el.querySelector(".room-anchor .v-middle").textContent.trim();
            list.push({name, title, partition, popularity, liveUrl, uid, el});
        }
        return list;
    };
    const startShieldingLiveRoom = async () => {
        const list = await getLiveRoomDataList();
        for (let liveData of list) {
            shielding.shieldingLiveRoomDecorated(liveData);
        }
    };
    const startShieldingTopLiveRoom = async () => {
        const list = await getTopLiveRoomDataList();
        for (let liveData of list) {
            shielding.shieldingLiveRoomDecorated(liveData);
        }
    };
    var liveHome = {
        isLiveHomePage,
        startShieldingLiveRoom,
        startShieldingTopLiveRoom
    };
    const isPartition = (url) => {
        return url.includes('www.bilibili.com/v/');
    };
    const getHotVideoDayList = async () => {
        const elList = await elUtil.findElementsUntilFound('.bili-rank-list-video__item');
        const list = [];
        for (let el of elList) {
            let videoUrlEl = el.querySelector('a.rank-video-card');
            const titleEl = el.querySelector('.rank-video-card__info--tit');
            const videoUrl = videoUrlEl.href;
            const title = titleEl.textContent.trim();
            const bv = elUtil.getUrlBV(videoUrl);
            list.push({
                title, videoUrl, bv, el
            });
        }
        return list
    };
    const getVideoDataList$2 = async () => {
        const elList = await elUtil.findElementsUntilFound('.bili-video-card');
        const list = [];
        const oneTitleEl = elList[0].querySelector('.bili-video-card__info--tit>a');
        if (oneTitleEl === null) {
            await defUtil.wait();
            return await getVideoDataList$2()
        }
        for (let el of elList) {
            const titleEl = el.querySelector('.bili-video-card__info--tit>a');
            if (titleEl === null) {
                continue
            }
            const userEl = el.querySelector('a.bili-video-card__info--owner');
            const playAndDmu = el.querySelectorAll('.bili-video-card__stats--item>span');
            let nDuration = el.querySelector('.bili-video-card__stats__duration')?.textContent.trim();
            let nPlayCount = playAndDmu[0]?.textContent.trim();
            nPlayCount = sFormatUtil.toPlayCountOrBulletChat(nPlayCount);
            let nBulletChat = playAndDmu[1]?.textContent.trim();
            nBulletChat = sFormatUtil.toPlayCountOrBulletChat(nBulletChat);
            nDuration = sFormatUtil.toPlayCountOrBulletChat(nDuration);
            const title = titleEl.textContent.trim();
            const videoUrl = titleEl.href;
            const userUrl = userEl.href;
            const name = userEl
                .querySelector('.bili-video-card__info--author')
                ?.textContent.trim() || null;
            const uid = elUtil.getUrlUID(userUrl);
            const bv = elUtil.getUrlBV(videoUrl);
            list.push({
                name, title, uid, bv, userUrl, videoUrl, el,
                nPlayCount, nBulletChat, nDuration,
                explicitSubjectEl: el.querySelector('.bili-video-card__info'),
                insertionPositionEl: el.querySelector('.bili-video-card__info--bottom')
            });
        }
        return list
    };
    const shieldingVideoList = async () => {
        const list = await getVideoDataList$2();
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue
            }
            eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: shieldingVideoList});
        }
    };
    const startShieldingHotVideoDayList = async () => {
        const list = await getHotVideoDayList();
        for (let videoData of list) {
            shielding.shieldingVideoDecorated(videoData);
        }
    };
    const startIntervalShieldingVideoList = () => {
        setInterval(async () => {
            await shieldingVideoList();
        }, 1500);
    };
    var partition = {
        isPartition,
        startIntervalShieldingVideoList,
        startShieldingHotVideoDayList
    };
    const bOnlyTheHomepageIsBlocked$1 = localMKData.getBOnlyTheHomepageIsBlocked();
    const compatible_BEWLY_BEWLY = localMKData.isCompatible_BEWLY_BEWLY();
    const observeNetwork = (url, windowUrl, winTitle, initiatorType) => {
        if (!url.includes('api')) {
            return;
        }
        if (bOnlyTheHomepageIsBlocked$1) {
            if (!bilibiliHome.isHome(windowUrl, winTitle)) {
                return;
            }
        }
        if (url.startsWith("https://api.bilibili.com/x/web-interface/wbi/index/top/feed/rcmd?web_location=")) {
            if (compatible_BEWLY_BEWLY) {
                return;
            }
            bilibiliHome.startDebounceShieldingChangeVideoList();
            bilibiliHome.startDebounceShieldingHomeVideoList();
            console.log("检测到首页加载了换一换视频列表和其下面的视频列表");
            return;
        }
        if (url.startsWith("https://api.bilibili.com/x/v2/reply/wbi/main?oid=")) {
            console.log("检测到评论区楼主评论加载了");
            commentSectionModel.startShieldingComments();
            return;
        }
        if (url.startsWith("https://api.bilibili.com/x/v2/reply/reply?oid=")) {
            console.log("检测到评论区楼主层中的子层评论列表加载了");
            commentSectionModel.startShieldingComments();
        }
        if (url.startsWith("https://api.bilibili.com/x/web-interface/popular?ps=")) {
            popularAll.startShieldingVideoList();
        }
        if (url.startsWith("https://api.bilibili.com/x/web-interface/popular/series/one?number=")) {
            popularAll.startShieldingVideoList(true);
        }
        if (url.startsWith("https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?offset=")) {
            console.log("检测到用户动态加载了");
            dynamic.startThrottleShieldingDynamicContent();
        }
        if (url.startsWith("https://api.live.bilibili.com/xlive/web-interface/v1/second/getList?platform=web&parent_area_id=")) {
            console.log("检测到直播间加载了分区下的房间列表");
            liveSectionModel.startShieldingLiveRoom();
        }
        if (url.startsWith("https://api.live.bilibili.com/xlive/web-interface/v1/index/getList?platform=web")) {
            console.log("检测到直播间加载了推荐房间列表");
            liveHome.startShieldingLiveRoom();
        }
        if (url.startsWith('https://api.bilibili.com/x/web-interface/ranking/region?day=')) {
            console.log("检测到专区热门排行榜加载了");
            partition.startShieldingHotVideoDayList();
        }
    };
    var observeNetwork$1 = {
        observeNetwork
    };
    const shielding_user_vue = {
        template: `
      <div>
      <el-dropdown v-if="shieldingModelShow"
                   @command="dropdownEvent">
        <el-button round>
          屏蔽操作<i class="el-icon-arrow-down el-icon--right"></i>
        </el-button>
        <el-dropdown-menu v-slot="dropdown">
          <el-dropdown-item command="屏蔽uid"
                            v-if="shieldingUseUIDrButShow">屏蔽(uid)
          </el-dropdown-item>
          <el-dropdown-item command="移除屏蔽uid"
                            v-if="removedShieldingUIDrButShow">移除屏蔽(uid)
          </el-dropdown-item>
          <el-dropdown-item command="选择用户屏蔽" v-if="selectUserBlockingButShow">选择用户屏蔽</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
      </div>`,
        data() {
            return {
                shieldingModelShow: true,
                shieldingUseUIDrButShow: false,
                removedShieldingUIDrButShow: false,
                selectUserBlockingButShow: false,
                uid: -1
            }
        },
        methods: {
            async dropdownEvent(item) {
                if (item === '屏蔽uid') {
                    const {name, uid} = await space.getUserInfo();
                    this.$confirm(`是否屏蔽当前用户【${name}】uid=【${uid}】`, '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning'
                    }).then(() => {
                        const {status, res} = ruleUtil.addRulePreciseUid(uid, false);
                        this.$alert(res);
                        if (status) {
                            this.shieldingUseUIDrButShow = false;
                            this.removedShieldingUIDrButShow = true;
                        }
                    });
                    return
                }
                if (item === '移除屏蔽uid') {
                    const {uid} = await space.getUserInfo();
                    ruleUtil.delRUlePreciseUid(uid);
                    return
                }
                if (item === '选择用户屏蔽') {
                    await videoPlayModel.selectUserBlocking();
                    return
                }
                this.$message('未知选项');
            }
        },
        async created() {
            if (videoPlayModel.isVideoPlayPage()) {
                this.selectUserBlockingButShow = true;
            }
            if (space.isSpacePage()) {
                this.urlUID = elUtil.getUrlUID(window.location.href);
                if (ruleKeyListData$1.getPreciseUidArr().includes(this.urlUID)) {
                    this.shieldingModelShow = true;
                    this.removedShieldingUIDrButShow = true;
                    await this.$alert('当前用户为已标记uid黑名单', '提示');
                    return;
                }
                if (await space.isPersonalHomepage()) {
                    this.shieldingModelShow = false;
                    return;
                }
                this.shieldingModelShow = true;
                this.shieldingUseUIDrButShow = true;
            }
        }
    };
    const addLayout = () => {
        const div = document.createElement('div');
        const divStyle = div.style;
        divStyle.position = 'fixed';
        divStyle.zIndex = '9000';
        divStyle.right = "0";
        divStyle.top = '13%';
        divStyle.transition = 'transform 0.5s';
        if (!localMKData.isFirstFullDisplay()) {
            divStyle.transform = 'translateX(80%)';
        } else {
            if (localMKData.isHalfHiddenIntervalAfterInitialDisplay()) {
                setTimeout(() => {
                    divStyle.transform = 'translateX(80%)';
                    eventEmitter.send('el-msg', '自动隐藏外部主面板显隐按钮');
                }, 8000);
            }
        }
        const vueDiv = document.createElement('div');
        div.appendChild(vueDiv);
        document.body.appendChild(div);
        const config = {
            components: {
                shielding_user_vue,
            },
            el: vueDiv,
            template: `
          <div v-show="panelShow" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
          <div>
            <el-button round @click="showBut">主面板</el-button>
          </div>
          <shielding_user_vue/>
          </div>`,
            data() {
                return {
                    panelShow: localMKData.isShowRightTopMainButSwitch(),
                }
            },
            methods: {
                showBut() {
                    eventEmitter.send('主面板开关');
                },
                handleMouseEnter() {
                    divStyle.transform = "translateX(0)";
                },
                handleMouseLeave() {
                    divStyle.transform = 'translateX(80%)';
                }
            },
            created() {
                eventEmitter.on('显隐主面板开关', (bool) => {
                    this.panelShow = bool;
                });
            }
        };
        new Vue(config);
    };
    var rightFloatingLayoutVue = {
        addLayout
    };
    const generalUrl=[
        "popular/rank/all",
        "popular/rank/douga",
        "popular/rank/music",
        "popular/rank/dance",
        "popular/rank/game",
        "popular/rank/knowledge",
        "popular/rank/tech",
        "popular/rank/sports",
        "popular/rank/car",
        "popular/rank/life",
        "popular/rank/food",
        "popular/rank/animal",
        "popular/rank/kichiku",
        "popular/rank/fashion",
        "popular/rank/ent",
        "popular/rank/cinephile",
        "popular/rank/origin",
        "popular/rank/rookie"
    ];
    const isPopularHistory = (url) => {
        return url.includes("popular/history")
    };
    const isPopularAllPage = (url) => {
        return url.includes("www.bilibili.com/v/popular/all");
    };
    const isPopularWeeklyPage = (url) => {
        return url.includes("www.bilibili.com/v/popular/weekly");
    };
    const isGeneralPopularRank=(url)=>{
        return generalUrl.some(itemUrl => url.includes(itemUrl));
    };
    const getVideoDataList$1 = async () => {
        const elList = await elUtil.findElementsUntilFound(".rank-list>li");
        const list = [];
        for (let el of elList) {
            const title = el.querySelector(".title").textContent.trim();
            const userUrl = el.querySelector(".detail>a").href;
            const uid = elUtil.getUrlUID(userUrl);
            const name = el.querySelector(".up-name").textContent.trim();
            const detailStateEls = el.querySelectorAll('.detail-state>.data-box');
            let nPlayCount = detailStateEls[0].textContent.trim();
            nPlayCount = sFormatUtil.toPlayCountOrBulletChat(nPlayCount);
            let nBulletChat = detailStateEls[1].textContent.trim();
            nBulletChat = sFormatUtil.toPlayCountOrBulletChat(nBulletChat);
            const videoUrl = el.querySelector('.img>a')?.href || null;
            const bv = elUtil.getUrlBV(videoUrl);
            list.push({
                title,
                userUrl,
                uid,
                name,
                videoUrl,
                bv,
                nPlayCount,
                nBulletChat,
                nDuration: -1,
                el,
                insertionPositionEl: el.querySelector(".detail-state"),
                explicitSubjectEl: el.querySelector(".info")
            });
        }
        return list;
    };
    const startShieldingRankVideoList = async () => {
        const list = await getVideoDataList$1();
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue;
            }
            eventEmitter.send('添加热门视频屏蔽按钮', {data: videoData, maskingFunc: startShieldingRankVideoList});
        }
    };
    var popular = {
        isPopularHistory,
        isPopularAllPage,
        isGeneralPopularRank,
        isPopularWeeklyPage,
        startShieldingRankVideoList,
    };
    const isOldHistory = (url) => {
        return url.includes('https://www.bilibili.com/account/history')
    };
    const getVideoDataList = async () => {
        const elList = await elUtil.findElementsUntilFound('#history_list>.history-record');
        const list = [];
        for (let el of elList) {
            const labelEL = el.querySelector('.cover-contain>.label');
            if (labelEL !== null) {
                const label = labelEL.textContent.trim();
                console.log(`排除${label}`);
                continue
            }
            const titleEl = el.querySelector('.title');
            const userEl = el.querySelector('.w-info>span>a');
            const title = titleEl.textContent.trim();
            const videoUrl = titleEl.href;
            const bv = elUtil.getUrlBV(videoUrl);
            const name = userEl.textContent.trim();
            const userUrl = userEl.href;
            const uid = elUtil.getUrlUID(userUrl);
            list.push({
                title,
                videoUrl,
                name,
                userUrl,
                uid,
                el,
                bv,
                explicitSubjectEl: el.querySelector('.r-txt'),
                insertionPositionEl: el.querySelector('.subtitle')
            });
        }
        return list
    };
    const startShieldingVideo = async () => {
        console.log('开始屏蔽旧版历史记录视频列表');
        const list = await getVideoDataList();
        const css = {right: "45px"};
        for (let videoData of list) {
            if (shielding.shieldingVideoDecorated(videoData)) {
                continue;
            }
            videoData.css = css;
            eventEmitter.send('视频添加屏蔽按钮', {data: videoData, maskingFunc: startShieldingVideo});
        }
        console.log('屏蔽旧版历史记录视频列表完成');
    };
    const intervalExecutionStartShieldingVideo = () => {
        setInterval(startShieldingVideo, 2000);
    };
    var oldHistory = {
        isOldHistory,
        intervalExecutionStartShieldingVideo
    };
    const bOnlyTheHomepageIsBlocked = localMKData.getBOnlyTheHomepageIsBlocked();
    const compatibleBEWLYBEWLY = localMKData.isCompatible_BEWLY_BEWLY();
    const adaptationBAppCommerce = localMKData.getAdaptationBAppCommerce();
    eventEmitter.on('通知屏蔽', () => {
        const url = window.location.href;
        const title = document.title;
        if (bOnlyTheHomepageIsBlocked) return;
        if (searchModel.isSearch(url)) {
            searchModel.startShieldingVideoList();
        }
        if (bilibiliHome.isHome(url, title)) {
            if (compatibleBEWLYBEWLY) {
                return;
            }
            if (adaptationBAppCommerce) {
                bilibiliHome.startIntervalShieldingGateVideoList();
            }
            bilibiliHome.startDebounceShieldingHomeVideoList();
        }
        if (videoPlayModel.isVideoPlayPage(url)) {
            videoPlayModel.startShieldingVideoList();
        }
        if (collectionVideoPlayPageModel.iscCollectionVideoPlayPage(url)) {
            collectionVideoPlayPageModel.startShieldingVideoList();
        }
        if (popular.isPopularAllPage(url) || popular.isPopularHistory(url)) {
            popularAll.startShieldingVideoList();
        }
        if (popular.isPopularWeeklyPage(url)) {
            popularAll.startShieldingVideoList(true);
        }
        if (popular.isGeneralPopularRank(url)) {
            popular.startShieldingRankVideoList();
        }
        if (topicDetail.isTopicDetailPage(url)) {
            topicDetail.startShielding();
        }
        if (dynamic.isDynamicPage(url)) {
            dynamic.startThrottleShieldingDynamicContent();
        }
        if (videoPlayWatchLater.isVideoPlayWatchLaterPage(url)) {
            videoPlayWatchLater.startDebounceShieldingVideoList();
        }
        if (liveSectionModel.isLiveSection(url)) {
            liveSectionModel.startShieldingLiveRoom();
        }
        if (liveHome.isLiveHomePage(url)) {
            liveHome.startShieldingLiveRoom();
            liveHome.startShieldingTopLiveRoom();
        }
        if (oldHistory.isOldHistory(url)) {
            oldHistory.intervalExecutionStartShieldingVideo();
        }
        if (partition.isPartition(url)) {
            partition.startIntervalShieldingVideoList();
        }
    });
    window.addEventListener('load', () => {
        console.log('页面加载完成');
        rightFloatingLayoutVue.addLayout();
        router.staticRoute(document.title, window.location.href);
        watch.addEventListenerUrlChange((newUrl, oldUrl, title) => {
            router.dynamicRouting(title, newUrl);
        });
    });
    watch.addEventListenerNetwork((url, windowUrl, winTitle, initiatorType) => {
        observeNetwork$1.observeNetwork(url, windowUrl, winTitle, initiatorType);
    });
    document.addEventListener('keydown', function (event) {
        if (event.key === "`") {
            eventEmitter.send('主面板开关');
        }
    });
})(Vue, Dexie);