// ==UserScript== // @name 哔哩哔哩屏蔽增强器 // @namespace http://tampermonkey.net/ // @license Apache-2.0 // @version 2.0 // @author byhgz // @description 对B站视频或评论进行屏蔽,支持关键词模糊正则等,支持时长播放弹幕过滤等,如视频、评论、动态、直播间的评论等,详情可看下面支持的屏蔽类型 // @icon https://static.hdslb.com/images/favicon.ico // @noframes // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_addStyle // @grant GM_unregisterMenuCommand // @grant GM_registerMenuCommand // @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://update.greasyfork.org/scripts/517928/gz_ui_css-v1.js // @require https://update.greasyfork.org/scripts/521941/about_and_feedback_components.js // @require https://greasyfork.org/scripts/462234-message/code/Message.js // @require https://update.greasyfork.org/scripts/449512/Xtiper.js // @require https://update.greasyfork.org/scripts/516282/Drawer_gz%E9%A1%B5%E9%9D%A2%E4%BE%A7%E8%BE%B9%E6%8A%BD%E5%B1%89%E7%BB%84%E4%BB%B6.js // @require https://update.greasyfork.org/scripts/517538/DynamicTabs_gz.js // ==/UserScript== "use strict"; (function (Vue) { '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); }, }; 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 isHideMainButSwitch=()=>{ return gmUtil.getData("hideMainButSwitch", false) === true; }; const setHideMainButSwitch=(bool)=>{ gmUtil.setData("hideMainButSwitch", 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); }; var localMKData = { setBorderColor, getBorderColor, setOutputInformationFontColor, getOutputInformationFontColor, setHighlightInformationColor, getHighlightInformationColor, setBOnlyTheHomepageIsBlocked, getBOnlyTheHomepageIsBlocked, getAdaptationBAppCommerce, setAdaptationBAppCommerce, setDefaultColorInfo, isHideMainButSwitch, setHideMainButSwitch, isCompatible_BEWLY_BEWLY, setCompatible_BEWLY_BEWLY }; const mainDrawer = new Drawer_gz({ show: false, height: "50vh", headerShow: false, title: "屏蔽器主面板", direction: "top", externalButtonText: "屏蔽器", externalButtonWidth: "80px", externalButtonShow: !localMKData.isHideMainButSwitch(), zIndex: 9000, drawerBorder: `1px solid ${localMKData.getBorderColor()}`, bodyHtml: `
`, }); const options = { styles: ` .my-custom-tab-button { font-size: 16px; } .my-custom-tab-content { background-color: #f9f9f9; } `, classes: { tabButton: 'my-custom-tab-button', tabButtonActive: 'my-custom-tab-button-active', tabContent: 'my-custom-tab-content', tabContentActive: 'my-custom-tab-content-active' }, backgroundColor: '#eee', borderColor: '#ddd', textColor: '#333', fontWeight: 'bold', activeBackgroundColor: '#0056b3', activeTextColor: '#fff', contentBorderColor: '#bbb', contentBackgroundColor: '#ffffff', onTabClick: (id, title, content) => { const tab = tabsConfig.find(item => item.title === title); const height = tab.height; mainDrawer.setHeight(height ? height : '50vh'); }, }; const tabsConfig = [ { id: 'tab01', title: '面板设置', content: '
', height: "23vh", }, { id: 'tab02', title: '规则管理', content: '
', height: "96vh" }, { id: 'tab03', title: '其他参数过滤', content: `
`, }, { id:'id04', title: '兼容设置', content: `
`, }, { id: 'tab05', title: '输出信息', content: `
`, height: "96vh" }, { id: 'tab06', title: '支持打赏', content: '
', height: "80vh" }, { id: 'tab07', title: '关于和问题反馈', content: `
`, height: '53vh' } ]; new DynamicTabs_gz('#shield', tabsConfig, options ); const returnVue$4 = () => { return new Vue({ template: `
选色器:


说明

  1. 按键盘tab键上的~键为展开关闭主面板
`, el: '#shield #panel_settings_vue', data() { return { input_color: "", hideMainButSwitch: localMKData.isHideMainButSwitch() } }, methods: { setBorderColorBut() { console.log(this.input_color); xtip.confirm("是要否设置面板边框颜色吗?", { icon: "a", btn1: () => { localMKData.setBorderColor(this.input_color); xtip.alert("已设置面板边框颜色,刷新生效"); } }); }, setDefFontColorForOutputInformationBut() { xtip.confirm("是要否设置输出信息默认字体颜色吗?", { icon: "a", btn1: () => { localMKData.setOutputInformationFontColor(this.input_color); xtip.alert("已设置输出信息默认字体颜色,刷新生效"); } }); }, setTheFontColorForOutputInformationBut() { xtip.confirm("是要否设置输出信息高亮字体颜色吗?", { icon: "a", btn1: () => { localMKData.setHighlightInformationColor(this.input_color); xtip.alert("已设置输出信息高亮字体颜色,刷新生效"); } }); }, setDefInfoBut() { localMKData.setDefaultColorInfo(); xtip.alert("已恢复默认颜色,刷新生效"); } }, watch: { hideMainButSwitch(newVal) { localMKData.setHideMainButSwitch(newVal); mainDrawer.externalButtonShow(!newVal); } } }); }; 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 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 }; }; var defUtil = { wait, fileDownload, toTimeString, smoothScroll, debounce, debounceAsync, throttle, throttleAsync, parseUrl }; 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: "直播分区黑名单(精确匹配)" } ]; 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", []); }; var ruleKeyListData$1 = { getNameArr, getPreciseNameArr, getNameCanonical, getPreciseUidArr, getPreciseUidWhiteArr, getTitleArr, getTitleCanonicalArr, getCommentOnArr, getCommentOnCanonicalArr, getRuleKeyListData, getPreciseTagArr, getTagArr, getTagCanonicalArr, getPreciseFanCardArr, getPrecisePartitionArr }; const verificationInputValue = (ruleValue, type) => { if (ruleValue === null) return null; if (type === "precise_uid" || type === "precise_uid_white") { ruleValue = parseInt(ruleValue); if (isNaN(ruleValue)) { Qmsg.info('请输入数字!'); return null; } } else { ruleValue.trim(); } if (ruleValue === '') { Qmsg.info('内容为空'); return null; } return ruleValue; }; const addRule = (ruleValue, type) => { const inputValue = verificationInputValue(ruleValue, type); return new Promise((resolve, reject) => { if (inputValue === null) { reject('取消添加'); return; } const arr = gmUtil.getData(type, []); if (arr.includes(inputValue)) { reject('已存在此内容'); return; } arr.push(inputValue); gmUtil.setData(type, arr); resolve('添加成功'); } ) }; const showAddRuleInput = (type) => { const ruleValue = window.prompt('请输入要添加的规则内容', ''); return addRule(ruleValue, type); }; const showDelRuleInput = (type) => { let prompt = window.prompt('请输入要移除的规则内容', ''); const inputValue = verificationInputValue(prompt, type); return new Promise((resolve, reject) => { if (inputValue === null) { reject('取消添加'); return; } const arr = gmUtil.getData(type, []); const indexOf = arr.indexOf(inputValue); if (indexOf === -1) { reject('不存在此内容'); return; } arr.splice(indexOf, 1); gmUtil.setData(type, arr); resolve('移除成功'); }) }; const showSetRuleInput = (type) => { let prompt = window.prompt('请输入要修改的规则内容', ''); const inputValue = verificationInputValue(prompt, type); return new Promise((resolve, reject) => { if (inputValue === null) return; const arr = gmUtil.getData(type, []); const indexOf = arr.indexOf(inputValue); if (indexOf === -1) { reject('不存在此内容'); return; } prompt = window.prompt('请输入要修改的内容', ''); const newInputValue = verificationInputValue(prompt, type); if (newInputValue === null) return; if (arr.includes(newInputValue)) { reject('已存在要修改过后的值内容'); return; } arr[indexOf] = newInputValue; gmUtil.setData(type, arr); resolve('修改成功'); }) }; 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 (let key of keyArr) { 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; }; var ruleUtil = { addRule, showAddRuleInput, showDelRuleInput, showSetRuleInput, getRuleContent, overwriteImportRules, appendImportRules, overwriteImportRulesV1, getNewRuleKeyList, }; const returnVue$3 = () => { return new Vue({ template: `

使用说明

  1. 脚本中会对要匹配的内容进行去除空格和转成小写,比如有个内容是【不 要 笑 挑 战 ChallEnGE】,会被识别称为【不要笑挑战challenge】
  2. 在上述一点的情况下,模糊匹配和正则匹配的方式时不用考虑要匹配的内容中大写问题
  3. 大部分情况下模糊匹配比精确匹配好用
  4. 如果用户要添加自己的正则匹配相关的规则时,建议先去该网址进行测试再添加,避免浪费时间 >>>正则表达式在线测试<<<
《====可点击切换条件

导出规则


导入规则

  1. 规则内容请在下面编辑框中导入
  2. 旧版本的需要使用下面的v1旧版本导入规则
  3. 旧版本的只能覆盖导入
  4. v1之后的版本可以选择覆盖和追加

规则信息

{{ item.name }}
`, el: '#shield #rule_management_vue', data() { return { selectVal: 'name', selectText: "", ruleContentImport: "", ruleActions: [ { type: "uid", name: "uid(精确)", } ], ruleKeyArr: [], ruleInfoArr: [], ruleReference: [ { title: "旧版本规则参考", content: ` {"用户名黑名单模式(精确匹配)":["账号已注销"],"BV号黑名单模式(精确匹配)":[], "用户名黑名单模式(模糊匹配)":["bili_","_bili"],"用户uid黑名单模式(精确匹配)":[442010132,76525078,225219967,3493283164588093], "用户uid白名单模式(精确匹配)":[344490740,1861980711],"标题黑名单模式(模糊匹配)":["激励计划","蚌不住","手游激励","游戏活动打卡"], "标题黑名单模式(正则匹配)":["感觉.*不如","不要笑.*挑战"],"评论关键词黑名单模式(模糊匹配)":["感觉不如","差不多的了"], "评论关键词黑名单模式(正则匹配)":["这不.+吗","玩.*的","不要笑.*挑战"],"粉丝牌黑名单模式(精确匹配)":[], "专栏关键词内容黑名单模式(模糊匹配)":[],"动态关键词内容黑名单模式(模糊匹配)":["拼多多","京东红包","京东618红包","618活动"]}` }, { title: "新版本规则参考", content: "待补充" } ], bOnlyTheHomepageIsBlocked: localMKData.getBOnlyTheHomepageIsBlocked() } }, methods: { operationBut(model) { debugger const type = this.selectVal; if (model === "add") { ruleUtil.showAddRuleInput(type).then((msg) => { this.refreshInfoBut(); alert(msg); }).catch(errMsg => { Qmsg.info(errMsg); }); } if (model === "del") { ruleUtil.showDelRuleInput(type).then((msg) => { this.refreshInfoBut(); alert(msg); }).catch(errMsg => { Qmsg.info(errMsg); }); } if (model === "set") { ruleUtil.showSetRuleInput(type).then((msg) => { this.refreshInfoBut(); alert(msg); }).catch(errMsg => { Qmsg.info(errMsg); }); } if (model === "del_all") { if (!window.confirm("确定要删除所有规则吗?")) { Qmsg.info('取消删除全部操作'); return; } for (let x of this.ruleKeyArr) { gmUtil.delData(x); } alert("删除全部规则成功"); this.refreshInfoBut(); } }, 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() { xtip.msg('已导出到控制台上!', {icon: 's'}); console.log(ruleUtil.getRuleContent()); }, refreshInfoBut() { for (let x of this.ruleInfoArr) { x.len = gmUtil.getData(x.type, []).length; } Qmsg.info('已刷新规则信息'); }, overwriteImportRulesBut() { const trim = this.ruleContentImport.trim(); if (ruleUtil.overwriteImportRules(this.ruleKeyArr, trim)) { xtip.msg('已导入成功!', {icon: 's'}); this.refreshInfoBut(); } }, appendImportRulesBut() { const trim = this.ruleContentImport.trim(); if (ruleUtil.appendImportRules(this.ruleKeyArr, trim)) { xtip.msg('已导入成功!', {icon: 's'}); this.refreshInfoBut(); } }, overwriteImportRulesV1But() { const trim = this.ruleContentImport.trim(); if (ruleUtil.overwriteImportRulesV1(trim)) { xtip.msg('已导入成功!', {icon: 's'}); this.refreshInfoBut(); } }, xtipAlertBut(content, title) { xtip.alert(content, {title: title}); } }, watch: { bOnlyTheHomepageIsBlocked(newVal) { localMKData.setBOnlyTheHomepageIsBlocked(newVal); }, 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, len: 0 }); } const find = this.ruleInfoArr.find(item => item.type === this.selectVal); this.selectText = find.name; this.refreshInfoBut(); } }); }; const returnVue$2 = () => { return new Vue({ el: "#station_b_shield_donate", template: `

零钱赞助

  • 1元不嫌少,10元不嫌多哦!感谢支持!
  • 生活不易,作者叹息
  • 您的支持是我最大的更新动力

{{ item.name }}

打赏点猫粮

`, data: { 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"}, ] } }); }; const returnVue$1 = () => { return new Vue({ el: '#other_parameter_filter', template: `

使用说明

  1. 如设置时长相关单位为秒
  2. 如设置播放量和弹幕量相关单位为个
  3. 设置最小播放量则小于该值的视频会屏蔽
  4. 设置最大播放量则大于该值的视频会屏蔽
  5. 设置最小弹幕量则小于该值的视频会屏蔽
  6. 设置最大弹幕量则大于该值的视频会屏蔽
  7. 设置最小时长则小于该值的视频会屏蔽
  8. 设置最大时长则大于该值的视频会屏蔽
  9. 设置评论区最小用户等级则小于该值的会屏蔽,低于该值的会屏蔽掉
  10. 设置评论区最大用户等级则大于该值的会屏蔽,高于该值的会屏蔽掉
  11. 取消相关限制条件则不做限制处理
  12. 右侧信息关键条件-1则为未做任何限制处理
  13. 最后因为设置限制条件冲突或限制太多,视频未能限制的情况下,请按需设置限制条件
《====可点击切换限制条件
{{ item.name }} {{ item.name.includes('时长') ? '秒' : '' }}
`, data() { return { index: 0, selectList: [ { 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 } ], 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.index > associatedVal && associatedVal !== -1) { if (associatedFind.bLarge) { xtip.alert(`要设置的${find.name}值不能大于${associatedFind.name}的值`); return } console.log('正常修改'); } xtip.alert(`已设置${find.name},值为${this.index}`); gmUtil.setData(this.selectValue, this.index); this.updateInfo(); }, cancelBut() { gmUtil.setData(this.selectValue, -1); const find = this.selectList.find(item => item.value === this.selectValue); xtip.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(); xtip.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.index > 6) { this.index = 6; } if (this.index < 3) { this.index = 3; } } else { this.inputMin = 0; this.inputMax = ''; } } }, created() { this.updateInfo(); } }) }; const returnVue = () => { return new Vue({ el: "#shield #compatible_setting", template: `
`, data() { return { adaptationBAppRecommend: localMKData.getAdaptationBAppCommerce(), compatible_BEWLY_BEWLY: localMKData.isCompatible_BEWLY_BEWLY() } }, watch:{ adaptationBAppRecommend(newVal) { localMKData.setAdaptationBAppCommerce(newVal); }, compatible_BEWLY_BEWLY(newVal) { localMKData.setCompatible_BEWLY_BEWLY(newVal); }, } }) }; document.querySelector("#output_information button")?.addEventListener("click", () => { olEL.innerHTML = ""; alert("已清空消息"); }); const olEL = document.querySelector("#output_information>.info"); const addInfo = (content) => { const liEL = document.createElement("li"); liEL.innerHTML = content; olEL.appendChild(liEL); }; const outputInformationFontColor = localMKData.getOutputInformationFontColor(); const highlightInformationColor = localMKData.getHighlightInformationColor(); const getVideoInfoHtml = (type, matching, videoData) => { const toTimeString = defUtil.toTimeString(); const {name, uid, title, videoUrl} = videoData; return ` ${toTimeString}-根据${type}-${matching ? `【${matching}】` : ""}-屏蔽用户【${name}】uid= 【${uid}】 标题【${title}` }; const getCommentInfoHtml = (type, matching, commentData) => { const toTimeString = defUtil.toTimeString(); const {name, uid, content} = commentData; return ` ${toTimeString}-根据${type}-${matching ? `【${matching}】` : ""}-屏蔽用户【${name}】uid= 【${uid}】 评论【${content}】 ` }; const getLiveRoomCommentInfoHtml = (type, matching, commentData) => { const toTimeString = defUtil.toTimeString(); const {name, uid, content} = commentData; return ` ${toTimeString}-根据${type}-${matching ?`【${matching}】` : ""}-屏蔽用户【${name}】uid= 【${uid}】 直播评论【${content}】 ` }; const getDynamicContentInfoHtml = (type, matching, dynamicData) => { const toTimeString = defUtil.toTimeString(); const {name, uid, content} = dynamicData; return ` ${toTimeString}-根据${type}-${matching ? `【${matching}】` : ""}-屏蔽用户【${name}】uid= 【${uid}】 动态【${content}】 ` }; const getLiveRoomInfoHtml = (type, matching, liveRoomData) => { const toTimeString = defUtil.toTimeString(); const {name = null, uid = -1, title, liveUrl} = liveRoomData; return ` ${toTimeString}-根据${type}${matching ? `【${matching}】` : ""}-屏蔽用户【${name === null ? '' : name}】${uid === -1 ? "" : `uid= 【${uid}】`} 直播间标题【${title}` }; var output_informationTab = { addInfo, getVideoInfoHtml, getCommentInfoHtml, getLiveRoomCommentInfoHtml, getDynamicContentInfoHtml, getLiveRoomInfoHtml }; returnVue$4(); returnVue$3(); returnVue$2(); returnVue$1(); returnVue(); installAboutAndFeedbackComponentsVue('#station_b_shield_problem_feedback', { title: 'B站屏蔽增强器', gfFeedbackUrl: 'https://greasyfork.org/zh-CN/scripts/461382' } ); gmUtil.addStyle(` [gz_bezel]{ border:1px solid ${localMKData.getBorderColor()} } `); const getUrlUID = (url) => { const isDoYouHaveAnyParameters = url.indexOf('?'); const lastIndexOf = url.lastIndexOf("/"); let uid; 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 eventRegistry = new Map(); function addEventListenerWithTracking(element, eventName, handler) { if (!eventRegistry.has(element)) { eventRegistry.set(element, new Map()); } const elementEvents = eventRegistry.get(element); if (!elementEvents.has(eventName)) { elementEvents.set(eventName, new Set()); } elementEvents.get(eventName).add(handler); element.addEventListener(eventName, handler); } function findElementUntilFound(selector, config = {}) { const defConfig = {doc: document, interval: 1000}; config = {...defConfig, ...config}; return new Promise((resolve) => { const i1 = setInterval(() => { const element = config.doc.querySelector(selector); if (element) { resolve(element); clearInterval(i1); } }, config.interval); }); } function findElementsUntilFound(selector, config = {}) { const defConfig = {doc: document, interval: 1000}; config = {...defConfig, ...config}; return new Promise((resolve) => { function attemptToFind() { const elements = config.doc.querySelectorAll(selector); if (elements.length > 0) { resolve(elements); } else { setTimeout(attemptToFind, config.interval); } } attemptToFind(); }); } function findElementWithTimeout(selector, config = {}) { const defConfig = { doc: document, interval: 1000, timeout: 60000 }; config = {...defConfig, ...config}; return new Promise((resolve) => { let intervalId; function attemptToFind() { const element = config.doc.querySelector(selector); if (element) { clearInterval(intervalId); resolve({ state: true, msg: "已找到元素", el: element }); } } intervalId = setInterval(attemptToFind, config.interval); const timeout = setTimeout(() => { clearInterval(intervalId); resolve({ state: false, msg: "已超时:" + config.timeout }); // 超时后提示信息 clearTimeout(timeout); }, config.timeout); attemptToFind(); // 立即尝试一次 }); } function findElementsWithTimeout(selector, config = {}) { const defConfig = { doc: document, interval: 1000, timeout: 60000 }; config = {...defConfig, ...config}; return new Promise((resolve, reject) => { let timer; let intervalId; function attemptToFind() { const elements = config.doc.querySelectorAll(selector); if (elements.length > 0) { clearTimeout(timer); clearInterval(intervalId); resolve(elements); } } intervalId = setInterval(attemptToFind, config.interval); timer = setTimeout(() => { clearInterval(intervalId); reject(null); // 超时后返回 null }, config.timeout); attemptToFind(); // 立即尝试一次 }); } 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, addEventListenerWithTracking, findElementUntilFound, findElementWithTimeout, findElementsUntilFound, findElementsWithTimeout, findElementsAndBindEvents }; const exactMatch = (ruleList, value) => { if (ruleList === null || ruleList === undefined) return false; if (!Array.isArray(ruleList)) return false return ruleList.some(item => item === value); }; const regexMatch = (ruleList, value) => { if (ruleList === null || ruleList === undefined) return null; if (!Array.isArray(ruleList)) return null value = value.toLowerCase(); value = value.split(/[\t\r\f\n\s]*/g).join(""); const find = ruleList.find(item => value.search(item) !== -1); return find===undefined ? null : find; }; const fuzzyMatch = (ruleList, value) => { if (ruleList === null || ruleList === undefined) return null; if (!Array.isArray(ruleList)) return null const find = ruleList.find(item => value.includes(item)); return find === undefined ? null : find; }; var ruleMatchingUtil = { exactMatch, regexMatch, fuzzyMatch }; const Tip = { success(text, config) { Qmsg.success(text, config); }, successBottomRight(text) { this.success(text, {position: "bottomright"}); }, videoBlock(text) {//屏蔽了视频的提示 this.success(text, {position: "bottomright"}); }, info(text, config) { Qmsg.info(text, config); }, infoBottomRight(text) { this.info(text, {position: "bottomright"}); }, error(text, config) { Qmsg.error(text, config); }, errorBottomRight(text) { this.error(text, {position: "bottomright"}); }, warning(text, config) { Qmsg.warning(text, config); }, config(cfg) {//设置全局Tip配置 Qmsg.config(cfg); }, loading(text, config) { return Qmsg.loading(text, config); }, close(loading) { try { loading.close(); } catch (e) { console.error(e); this.error("loading关闭失败!"); } }, printLn(content) { Util.printElement("#outputInfo", `
${content}
`); }, printVideo(color, content, name, uid, title, videoHref) { Util.printElement("#outputInfo", `
${Util.toTimeString()}${content}屏蔽用户【${name}】uid=【${uid}】标题【${title}
`); }, printCommentOn(color, content, name, uid, primaryContent) { Util.printElement("#outputInfo", `
${Util.toTimeString()}${content} 屏蔽用户【${name}】uid=【${uid}】 原言论=【${primaryContent}】
`); } }; 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(); data.videoUrl = el.querySelector(".bili-dyn-card-video").href; 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 }; 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 inTheBuildingUserInfo = inTheContentEl.querySelector("bili-comment-user-info") .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 inTheBuildingContent = inTheContentEl.querySelector("bili-rich-text") .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: inTheContentEl }); } } if (!isLoaded) { await defUtil.wait(500); return getCommentSectionList() } return commentsData; }; const getOldCommentSectionList = async () => { const results = await elUtil.findElementsWithTimeout(".reply-list>.reply-item"); if (results === null) { 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); replies.push({ name: userName, userUrl, uid, level, content: subContent, el: inTheBuildingEl, insertionPositionEl: subUserInfoEl, explicitSubjectEl: inTheBuildingEl }); } } debugger return commentsData; }; const startShieldingComments = async () => { let list; const href = window.location.href; if (href.includes("https://space.bilibili.com/") || topicDetail.isTopicDetailPage(href)) { list = await getOldCommentSectionList(); } else { list = await getCommentSectionList(); } shielding.shieldingComments(list); }; var commentSectionModel = { startShieldingComments }; const addBlockButton = (data, tagCss, position = []) => { const {insertionPositionEl, explicitSubjectEl, css} = data.data; if (insertionPositionEl.querySelector("." + tagCss)) return; const buttonEL = document.createElement("button"); buttonEL.setAttribute("gz_type", ""); 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]; } } buttonEL.style.display = "none"; elUtil.addEventListenerWithTracking(explicitSubjectEl, "mouseover", () => buttonEL.style.display = "block"); elUtil.addEventListenerWithTracking(explicitSubjectEl, "mouseout", () => buttonEL.style.display = "none"); insertionPositionEl.appendChild(buttonEL); buttonEL.addEventListener("click", (event) => { event.stopImmediatePropagation(); // 阻止事件冒泡和同一元素上的其他事件处理器 event.preventDefault(); // 阻止默认行为 const tempData = data.data; console.log("该选项数据:", data); xtip.sheet({ btn: ['uid精确屏蔽(推荐)', '用户名精确屏蔽(不推荐)'], btn1: () => { const tipContent = `uid精确屏蔽\n 用户${tempData.name}\n uid:${tempData.uid}`; xtip.confirm(tipContent, { title: "添加规则", icon: "a", btn1: () => { if (tempData.uid === -1) { Tip.error("该页面数据不存在uid字段"); return; } ruleUtil.addRule(tempData.uid, "precise_uid").then(msg => { xtip.alert(msg, {icon: 's'}); data.maskingFunc(); }).catch(msg => { xtip.alert(msg, {icon: 'e'}); }); } }); }, btn2: () => { xtip.msg('暂未开放.'); }, }); }); }; const addVideoBlockButton$1 = (data) => { addBlockButton(data, "gz_shielding_button", ["right"]); }; const addPopularVideoBlockButton = (data) => { addBlockButton(data, "gz_shielding_button", ["right", "bottom"]); }; const addTopicDetailVideoBlockButton = (data) => { addBlockButton(data, "gz_shielding_button"); }; const addTopicDetailContentsBlockButton = (data) => { const position = data.data.position; const loop = position !== undefined; addBlockButton(data, "gz_shielding_topic_detail_button", loop ? position : []); }; const addCommentBlockButton = (commentsData) => { const data = { data: commentsData, maskingFunc: commentSectionModel.startShieldingComments }; addBlockButton(data, "gz_shielding_comment_button"); }; const addLiveContentBlockButton = (commentsData) => { addBlockButton(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 (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) { return {state: true, type: '最小时长', matching: min} } const max = gmUtil.getData('nMaximumDuration', -1); if (max > nDuration) { return {state: true, type: '最大时长', matching: max} } } if (nBulletChat !== -1) { const min = gmUtil.getData('nMinimumBarrage', -1); if (min > nBulletChat) { return {state: true, type: '最小弹幕数', matching: min} } const max = gmUtil.getData('nMaximumBarrage', -1); if (max > nBulletChat) { return {state: true, type: '最大弹幕数', matching: max} } } if (nPlayCount !== -1) { const min = gmUtil.getData('nMinimumPlay', -1); if (min > nPlayCount) { return {state: true, type: '最小播放量', matching: min} } const max = gmUtil.getData('nMaximumPlayback', -1); if (max > nPlayCount) { return {state: true, type: '最大播放量', matching: max} } } 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"; } Tip.successBottomRight("屏蔽了视频"); const videoInfoHtml = output_informationTab.getVideoInfoHtml(type, matching, videoData); output_informationTab.addInfo(videoInfoHtml); } 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) { Tip.successBottomRight("屏蔽了视频"); output_informationTab.addInfo(output_informationTab.getDynamicContentInfoHtml(type, matching, dynamicData)); } 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) { 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 {state: false}; }; const shieldingCommentDecorated = (commentsData) => { const {state, type, matching} = shieldingComment(commentsData); if (state) { commentsData.el?.remove(); Tip.successBottomRight("屏蔽了评论"); output_informationTab.addInfo(output_informationTab.getCommentInfoHtml(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(); Tip.successBottomRight("屏蔽了直播间评论"); } if (type) { output_informationTab.addInfo(output_informationTab.getLiveRoomCommentInfoHtml(type, matching, liveRoomContent)); } return state; }; const shieldingComments = (commentsDataList) => { for (let commentsData of commentsDataList) { if (shieldingCommentDecorated(commentsData)) continue; addCommentBlockButton(commentsData); const {replies = []} = commentsData; if (replies.length === 0) continue; for (let reply of replies) { if (shieldingCommentDecorated(reply)) continue; addCommentBlockButton(reply); } } }; const shieldingLiveRoom = (liveRoomData) => { const {name = null, 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 !== null) { 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 (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(); Tip.successBottomRight("屏蔽了直播间"); output_informationTab.addInfo(output_informationTab.getLiveRoomInfoHtml(type, matching, liveRoomData)); } return state; }; var shielding = { shieldingVideoDecorated, shieldingDynamicDecorated, shieldingCommentDecorated, shieldingLiveRoomDecorated, shieldingComments, addVideoBlockButton: addVideoBlockButton$1, addCommentBlockButton, shieldingLiveRoomContentDecorated, addLiveContentBlockButton, addPopularVideoBlockButton, addTopicDetailVideoBlockButton, addTopicDetailContentsBlockButton, addBlockButton }; 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 === 'https://www.bilibili.com/?spm_id_from=333.1007.0.0' }; const adaptationBAppCommerce$1 = localMKData.getAdaptationBAppCommerce(); const deDesktopDownloadTipEl = async () => { const el = await elUtil.findElementUntilFound(".desktop-download-tip"); el?.remove(); const log = "已删除下载提示"; Tip.infoBottomRight(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; if (!userUrl.includes("//space.bilibili.com/")) { el?.remove(); const log = "遍历换一换视频列表中检测到异常内容,已将该元素移除"; Tip.infoBottomRight(log); console.log(log, el); continue; } list.push({ ...tempData, ...{ videoUrl, el, insertionPositionEl: el.querySelector(".bili-video-card__info--bottom"), explicitSubjectEl: el.querySelector(".bili-video-card__info") } }); } catch (e) { el.remove(); Qmsg.error("获取视频信息失败"); } } 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 = "遍历换一换视频列表下面列表时检测到异常内容,已将该元素移除"; Tip.infoBottomRight(log); console.log(log, el); continue; } list.push({ ...tempData, ...{ videoUrl: el.querySelector(".bili-video-card__info--tit>a").href, el, insertionPositionEl: el.querySelector(".bili-video-card__info--bottom"), explicitSubjectEl: el.querySelector(".bili-video-card__info") } }); } catch (e) { el?.remove(); Tip.infoBottomRight("遍历视频列表中检测到异常内容,已将该元素移除;"); } } 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 insertionPositionEl = el.querySelector(".bili-video-card__info--owner"); list.push({ ...tempData, ...{ videoUrl, el, insertionPositionEl, explicitSubjectEl: el } }); } return list; }; const startShieldingGateVideoList = async () => { const list = await getGateDataList(); for (let videoData of list) { if (shielding.shieldingVideoDecorated(videoData, "hide")) { continue; } shielding.addVideoBlockButton({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; } shielding.addVideoBlockButton({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; } shielding.addVideoBlockButton({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 }; const isSearch = (url) => { return url.includes("search.bilibili.com") }; const getVideoList$1 = async (css) => { const elList = await elUtil.findElementsWithTimeout(css); 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"); let userUrl; try { userUrl = userEl.getAttribute("href"); } catch (e) { console.error(e); } if (!userUrl.includes("//space.bilibili.com/")) { el?.remove(); Tip.infoBottomRight("移除了非视频内容"); console.log("移除了非视频内容", userUrl, el); continue; } 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, nPlayCount, nBulletChat, nDuration, el, videoUrl: el.querySelector(".bili-video-card__info--right>a").href, 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 startShieldingVideoList$5 = () => { getTabComprehensiveSortedVideoList().then(list => { for (let videoData of list) { if (shielding.shieldingVideoDecorated(videoData)) { continue; } shielding.addVideoBlockButton({data: videoData, maskingFunc: startShieldingVideoList$5}); } console.log("搜索页综合选项卡中的综合排序视频列表已处理完成"); }); getOtherVideoList().then(list => { for (let videoData of list) { if (shielding.shieldingVideoDecorated(videoData)) { continue; } shielding.addVideoBlockButton({data: videoData, maskingFunc: startShieldingVideoList$5}); } }); }; const startDebounceShieldingVideoList$1 = defUtil.debounce(startShieldingVideoList$5, 500); var searchModel = { isSearch, startDebounceShieldingVideoList: startDebounceShieldingVideoList$1 }; const isVideoPlayPage = (url) => { return url.includes("www.bilibili.com/video"); }; const getGetTheVideoListOnTheRight$1 = async () => { await elUtil.findElementUntilFound(".video-page-card-small .b-img img"); const elList = await elUtil.findElementsUntilFound(".video-page-card-small", {interval: 50}); 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(); let nPlayCount = playInfo.match(/<\/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, nPlayCount, nBulletChat, nDuration, el, videoUrl: el.querySelector(".info>a").href, insertionPositionEl: el.querySelector(".playinfo"), explicitSubjectEl: elInfo }); } catch (e) { console.error("获取右侧视频列表失败:", e); } } return list; }; const startShieldingVideoList$4 = () => { getGetTheVideoListOnTheRight$1().then((videoList) => { for (let videoData of videoList) { if (shielding.shieldingVideoDecorated(videoData)) { continue; } shielding.addVideoBlockButton({data: videoData, maskingFunc: startShieldingVideoList$4}); } }); }; const findTheExpandButtonForTheListOnTheRightAndBindTheEvent$2 = () => { setTimeout(() => { elUtil.findElementUntilFound(".rec-footer", {interval: 2000}).then((el) => { console.log("找到右侧视频列表的展开按钮"); console.log(el); el.addEventListener("click", () => { startShieldingVideoList$4(); }); }); }, 3000); }; var videoPlayModel = { isVideoPlayPage, startShieldingVideoList: startShieldingVideoList$4, findTheExpandButtonForTheListOnTheRightAndBindTheEvent: findTheExpandButtonForTheListOnTheRightAndBindTheEvent$2, }; const getPlayCountAndBulletChatAndDuration = (el) => { const playInfo = el.querySelector('.playinfo').innerHTML.trim(); let nPlayCount = playInfo.match(/<\/svg>(.*)(.+)$/s)?.[1].trim(); nBulletChat = sFormatUtil.toPlayCountOrBulletChat(nBulletChat); let nDuration = el.querySelector('.duration')?.textContent.trim(); nDuration = sFormatUtil.timeStringToSeconds(nDuration); return { nPlayCount, nBulletChat, nDuration } }; var generalFuc = {getPlayCountAndBulletChatAndDuration}; const iscCollectionVideoPlayPage = (url) => { return url.includes("www.bilibili.com/list/ml") }; const getGetTheVideoListOnTheRight = async () => { const elList = await elUtil.findElementsUntilFound(".recommend-list-container>.video-card"); const list = []; for (let el of elList) { const title = el.querySelector(".title").title; const name = el.querySelector(".name").textContent.trim(); const userUrl = el.querySelector(".upname").href; const uid = elUtil.getUrlUID(userUrl); list.push({ ...generalFuc.getPlayCountAndBulletChatAndDuration(el), ...{ title, name, userUrl, videoUrl: el.querySelector(".info>a").href, uid, el, insertionPositionEl: el.querySelector(".playinfo"), explicitSubjectEl: el.querySelector(".info") } }); } return list; }; const startShieldingVideoList$3 = () => { getGetTheVideoListOnTheRight().then((videoList) => { const css = {right: "123px"}; for (let videoData of videoList) { if (shielding.shieldingVideoDecorated(videoData)) continue; videoData.css = css; shielding.addVideoBlockButton({data: videoData, maskingFunc: startShieldingVideoList$3}); } }); }; const findTheExpandButtonForTheListOnTheRightAndBindTheEvent$1 = () => { setTimeout(() => { elUtil.findElementUntilFound(".rec-footer", {interval: 2000}).then((el) => { el.addEventListener("click", () => { startShieldingVideoList$3(); }); }); }, 3000); }; var collectionVideoPlayPageModel = { iscCollectionVideoPlayPage, startShieldingVideoList: startShieldingVideoList$3, 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 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; 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, nPlayCount, nBulletChat, nDuration: -1, insertionPositionEl: videoCardInfoEl.querySelector("div"), explicitSubjectEl: videoCardInfoEl }); } return list; }; const startShieldingVideoList$2 = async (isWeekly = false) => { const list = await getVideDataList(isWeekly); for (let videoData of list) { if (shielding.shieldingVideoDecorated(videoData)) { continue; } shielding.addPopularVideoBlockButton({data: videoData, maskingFunc: startShieldingVideoList$2}); } }; var popularAll = { startShieldingVideoList: startShieldingVideoList$2 }; 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 = 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); list.push({ title, userUrl, uid, name, nPlayCount, nBulletChat, nDuration: -1, el, insertionPositionEl: el.querySelector(".detail-state"), explicitSubjectEl: el.querySelector(".info") }); } return list; }; const startShieldingRankVideoList = async () => { const list = await getVideoDataList(); for (let videoData of list) { if (shielding.shieldingVideoDecorated(videoData)) { continue; } shielding.addPopularVideoBlockButton({data: videoData, maskingFunc: startShieldingRankVideoList}); } }; var popular = { isPopularHistory, isPopularAllPage, isGeneralPopularRank, isPopularWeeklyPage, startShieldingRankVideoList, }; const cacheData = { isPersonalHomepage: null, }; const isPersonalHomepage = async () => { if (cacheData.isPersonalHomepage !== null) { return cacheData.isPersonalHomepage; } const {state} = await elUtil.findElementWithTimeout(".h-action", {timeout: 2000, interval: 200}); const res = !state; cacheData.isPersonalHomepage = res; return res; }; const isThrottleAsyncPersonalHomepage = defUtil.throttleAsync(isPersonalHomepage,2000); var space = { isThrottleAsyncPersonalHomepage, }; 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 = await space.isThrottleAsyncPersonalHomepage(); 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 isVideoPlayWatchLaterPage = (url) => { return url.startsWith("https://www.bilibili.com/list/watchlater") }; const getRightVideoDataList = async () => { const elList = await elUtil.findElementsUntilFound(".recommend-video-card.video-card"); 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); list.push({ ...generalFuc.getPlayCountAndBulletChatAndDuration(el), ...{ title, name, userUrl, videoUrl: el.querySelector(".info>a").href, uid, el, insertionPositionEl: el.querySelector(".playinfo"), explicitSubjectEl: el.querySelector(".info") } }); } return list; }; const startShieldingVideoList$1 = async () => { const videoList = await getRightVideoDataList(); const css = {right: "123px"}; for (let videoData of videoList) { videoData.css = css; if (shielding.shieldingVideoDecorated(videoData)) continue; shielding.addVideoBlockButton({data: videoData, maskingFunc: startShieldingVideoList$1}); } }; const startDebounceShieldingVideoList = defUtil.debounce(startShieldingVideoList$1, 1000); const findTheExpandButtonForTheListOnTheRightAndBindTheEvent = () => { elUtil.findElementsAndBindEvents(".rec-footer", startDebounceShieldingVideoList); }; var videoPlayWatchLater = { isVideoPlayWatchLaterPage, startDebounceShieldingVideoList, findTheExpandButtonForTheListOnTheRightAndBindTheEvent }; 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 getBewlyEl = async () => { let el = await elUtil.findElementUntilFound('#bewly', {interval: 500}); return el.shadowRoot; }; const isBEWLYPage = (url) => { return url.includes('www.bilibili.com/?spm_id_from=333.788.0.0&page='); }; 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 || null; const insertionPositionEl = el.querySelector('[class="group/desc"]'); list.push({ title, name, uid, 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 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, el, insertionPositionEl: videoUrlEl.parentElement, explicitSubjectEl: el }); } return list }; const intervalExecutionStartShieldingVideoInert = (func, name = '') => { let i1 = -1; const start = () => { if (i1 !== -1) { return } console.log('开始执行屏蔽' + name); i1 = setInterval(() => { func(); console.log(`执行屏蔽${name}列表-定时器正在执行`); }, 1500); }; const stop = () => { if (i1 === -1) { return } clearInterval(i1); console.log(`已停止执行屏蔽${name}列表`); i1 = -1; }; return {start, stop} }; const startShieldingHistoryVideoList = async () => { const list = await getHistoryVideoDataList(); for (let videoData of list) { if (shielding.shieldingVideoDecorated(videoData)) { continue } shielding.addVideoBlockButton({data: videoData, maskingFunc: startShieldingHistoryVideoList}); } }; const startShieldingVideoList = async () => { const list = await getVideoList(); for (let videoData of list) { if (shielding.shieldingVideoDecorated(videoData)) { continue } addVideoBlockButton({data: videoData, maskingFunc: startShieldingVideoList}); } }; const intervalExecutionStartShieldingVideo = () => { const res = intervalExecutionStartShieldingVideoInert(startShieldingVideoList, '视频'); return () => { return res } }; const intervalExecutionStartShieldingHistoryVideo = () => { const res = intervalExecutionStartShieldingVideoInert(startShieldingHistoryVideoList, '历史记录'); return () => { return res } }; const startShieldingVideo = intervalExecutionStartShieldingVideo(); const startShieldingHistoryVideo = intervalExecutionStartShieldingHistoryVideo(); const rightTabsInsertListener = () => { getRightTabs().then(list => { for (let {el, label, active} of list) { el.addEventListener('click', () => { console.log('右侧选项卡栏点击了' + label, active); if (label === '首页') { debugger homeTopTabsInsertListener(); startShieldingVideo().start(); } else { startShieldingVideo().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().stop(); return } if (label === '排行') { rankingLeftTabsInsertListener(); } startShieldingVideo().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().stop(); return } startShieldingVideo().start(); }); } }); }; const addVideoBlockButton = (data) => { shielding.addBlockButton(data, "gz_shielding_button", ["right", 'bottom']); }; 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 = async (parseUrl) => { const {page} = parseUrl.queryParams; installBEWLStyle(); if (page === 'Home') { startShieldingVideo().start(); homeTopTabsInsertListener(); } if (page === 'History') { startShieldingHistoryVideo().start(); searchBoxInsertListener(); } rightTabsInsertListener(); }; var compatibleBewlyBewly = { startRun, isBEWLYPage, }; const bOnlyTheHomepageIsBlocked$1 = localMKData.getBOnlyTheHomepageIsBlocked(); const adaptationBAppCommerce = localMKData.getAdaptationBAppCommerce(); const compatible_BEWLY_BEWLY$1 = localMKData.isCompatible_BEWLY_BEWLY(); const staticRoute = (title, url) => { console.log("静态路由", title, url); if (compatible_BEWLY_BEWLY$1 && compatibleBewlyBewly.isBEWLYPage(url)) { const parseUrl = defUtil.parseUrl(url); compatibleBewlyBewly.startRun(parseUrl); return; } if (bilibiliHome.isHome(url, title)) { if (compatible_BEWLY_BEWLY$1) { return; } if (adaptationBAppCommerce) { bilibiliHome.startIntervalShieldingGateVideoList(); } bilibiliHome.scrollMouseUpAndDown().then(() => bilibiliHome.startDebounceShieldingChangeVideoList()); bilibiliHome.startClearExcessContentList(); bilibiliHome.deDesktopDownloadTipEl(); bilibiliHome.startDebounceShieldingHomeVideoList(); } if (bOnlyTheHomepageIsBlocked$1) return; if (searchModel.isSearch(url)) { searchModel.startDebounceShieldingVideoList(); } if (videoPlayModel.isVideoPlayPage(url)) { videoPlayModel.startShieldingVideoList(); videoPlayModel.findTheExpandButtonForTheListOnTheRightAndBindTheEvent(); } if (collectionVideoPlayPageModel.iscCollectionVideoPlayPage(url)) { collectionVideoPlayPageModel.startShieldingVideoList(); collectionVideoPlayPageModel.findTheExpandButtonForTheListOnTheRightAndBindTheEvent(); } if (liveRoomModel.isLiveRoom(url)) { liveRoomModel.addWatchLiveRoomChatItemsListener(); } 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(); videoPlayWatchLater.findTheExpandButtonForTheListOnTheRightAndBindTheEvent(); } if (liveSectionModel.isLiveSection(url)) { liveSectionModel.startShieldingLiveRoom(); } if (liveHome.isLiveHomePage(url)) { liveHome.startShieldingLiveRoom(); liveHome.startShieldingTopLiveRoom(); } }; const dynamicRouting = (title, url) => { console.log("动态路由", title, url); if (bOnlyTheHomepageIsBlocked$1) return; if (searchModel.isSearch(url)) { searchModel.startDebounceShieldingVideoList(); } if (videoPlayModel.isVideoPlayPage(url)) { videoPlayModel.startShieldingVideoList(); } if (popular.isPopularAllPage(url) || popular.isPopularHistory(url)) { popularAll.startShieldingVideoList(); } if (popular.isPopularWeeklyPage(url)) { popularAll.startShieldingVideoList(true); } if (popular.isGeneralPopularRank(url)) { popular.startShieldingRankVideoList(); } if (dynamic.isDynamicPage(url)) { dynamic.startThrottleShieldingDynamicContent(); } }; var router = { staticRoute, dynamicRouting }; const bOnlyTheHomepageIsBlocked = localMKData.getBOnlyTheHomepageIsBlocked(); const compatible_BEWLY_BEWLY = localMKData.isCompatible_BEWLY_BEWLY(); const observeNetwork = (url, windowUrl,winTitle, initiatorType) => { if (bOnlyTheHomepageIsBlocked) { 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(); } }; var observeNetwork$1 = { observeNetwork }; 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 === "`") { mainDrawer.showDrawer(); } }); })(Vue);