您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A real-time comment checker, Fuck YouTube’s opaque comment censorship
- // ==UserScript==
- // @name youtube-comment-censor-detector
- // @name:zh-CN YouTube发评反诈
- // @name:zh-TW YouTube發評反詐
- // @namespace npm/vite-plugin-monkey
- // @version 2.0.0
- // @author freedom-introvert
- // @description A real-time comment checker, Fuck YouTube’s opaque comment censorship
- // @description:zh-CN Fuck YouTube版“阿瓦隆系统”,实时检查评论状态,防止评论被儿童偷偷误食你还被蒙在鼓里
- // @description:zh-TW Fuck YouTube版“阿瓦隆系統”,即時檢查評論狀態,防止評論被兒童偷偷誤食你還被蒙在鼓裡
- // @license GPL
- // @icon https://raw.githubusercontent.com/freedom-introvert/youtube-comment-censor-detector/refs/heads/main/logo/logo_256x256.avif
- // @match *://*.youtube.com/*
- // @require https://cdn.jsdelivr.net/npm/vue@3.5.15/dist/vue.global.prod.js
- // @require https://unpkg.com/vue-demi@latest/lib/index.iife.js
- // @require data:application/javascript,window.Vue%3DVue%3B
- // @require https://cdn.jsdelivr.net/npm/element-plus@2.9.11/dist/index.full.min.js
- // @resource element-plus/dist/index.css https://cdn.jsdelivr.net/npm/element-plus@2.9.11/dist/index.css
- // @grant GM_addStyle
- // @grant GM_getResourceText
- // @grant GM_registerMenuCommand
- // @grant unsafeWindow
- // @run-at document-start
- // ==/UserScript==
- (e=>{if(typeof GM_addStyle=="function"){GM_addStyle(e);return}const a=document.createElement("style");a.textContent=e,document.head.append(a)})(" .el-message,.is-message-box{z-index:9999!important}.comment-checker[data-v-684910ce]{font-size:12px}.container[data-v-684910ce]{width:80%;margin:0 auto}.comment-checker[data-v-684910ce]{padding:15px 15px 11px;border-radius:8px;transition:background-color .3s}.title[data-v-684910ce]{font-weight:700;margin-bottom:6px}.message[data-v-684910ce]{margin-bottom:10px}.el-progress[data-v-684910ce]{margin-bottom:4px}.buttons[data-v-684910ce]>[data-v-684910ce]{display:inline-flex;align-items:center;padding:4px 8px;margin-left:-8px;color:#4b5e9d;border-radius:4px;transition:background-color .2s,color .2s;-webkit-user-select:none;user-select:none;margin-right:10px}.buttons[data-v-684910ce]>[data-v-684910ce]:hover{background-color:#0000000d}.buttons[data-v-684910ce]>[data-v-684910ce]:active{background-color:#0000001a}.comment-checker.not-check[data-v-684910ce]{background-color:#00f3}.comment-checker.normal[data-v-684910ce]{background-color:#0f03}.comment-checker.deleted[data-v-684910ce]{background-color:#f003}.comment-checker.shadow-ban[data-v-684910ce]{background-color:#ff03}.hot-ban-checker[data-v-e5341f8d]{background-color:#007bff1a;border:1px solid rgba(0,60,136,.4);border-radius:6px;padding:1rem;margin:10px 0}.title[data-v-e5341f8d]{font-weight:700;margin-bottom:6px}.message[data-v-e5341f8d]{margin-bottom:10px}.actions[data-v-e5341f8d]{margin-top:10px}.buttons[data-v-e5341f8d]>[data-v-e5341f8d]{display:inline-flex;align-items:center;padding:4px 8px;margin-left:-8px;color:#4b5e9d;border-radius:4px;transition:background-color .2s,color .2s;-webkit-user-select:none;user-select:none;margin-right:10px}.buttons[data-v-e5341f8d]>[data-v-e5341f8d]:hover{background-color:#0000000d}.buttons[data-v-e5341f8d]>[data-v-e5341f8d]:active{background-color:#0000001a}[data-v-ff4696c9] .dialog-body{height:calc(100% - 40px);display:flex;flex-direction:column}.pagination[data-v-ff4696c9]{margin-top:6px}.detail[data-v-ff4696c9]{margin-left:10px}.info-table td[data-v-ff4696c9]:nth-child(1){white-space:nowrap;vertical-align:top}.info-table td[data-v-ff4696c9]:nth-child(2){padding-left:16px}.comment-content[data-v-ff4696c9]{white-space:break-spaces}summary[data-v-ff4696c9]{cursor:pointer;margin-top:2px;-webkit-user-select:none;user-select:none}.locate-link[data-v-ff4696c9]{width:100%}[data-v-ff4696c9] .locate-link>span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.post-locate-link[data-v-ff4696c9]{font-size:10px} ");
- (function (vue, ElementPlus) {
- 'use strict';
- function sleep(time) {
- return new Promise((resolve, reject) => {
- setTimeout(() => {
- resolve();
- }, time);
- });
- }
- function urlSafeBase64ToStandard(urlSafeBase64) {
- let standardBase64 = urlSafeBase64.replace(/%3D/g, "=").replace(/-/g, "+").replace(/_/g, "/");
- return standardBase64;
- }
- function standardBase64ToUrlSafe(standardBase64) {
- let urlSafeBase64 = standardBase64.replace(/=/g, "%3D").replace(/\+/g, "-").replace(/\//g, "_");
- return urlSafeBase64;
- }
- function createUrl(path) {
- return new URL(new URL(window.location.href).origin + path);
- }
- function formatSecondsToMMSS(seconds) {
- const sec = parseInt(seconds, 10);
- const minutes = Math.floor(sec / 60);
- const remainingSeconds = sec % 60;
- const formattedMinutes = String(minutes).padStart(2, "0");
- const formattedSeconds = String(remainingSeconds).padStart(2, "0");
- return `${formattedMinutes}:${formattedSeconds}`;
- }
- function formatTimestamp(timestamp) {
- if (!timestamp) {
- return "--:--:--";
- }
- const date = new Date(timestamp);
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, "0");
- const day = String(date.getDate()).padStart(2, "0");
- const hours = String(date.getHours()).padStart(2, "0");
- const minutes = String(date.getMinutes()).padStart(2, "0");
- const seconds = String(date.getSeconds()).padStart(2, "0");
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
- }
- function translateState(state) {
- switch (state) {
- case "NORMAL":
- return "正常";
- case "DELETED":
- return "已删除";
- case "SHADOW_BAN":
- return "仅自己可见";
- case "NOT_CHECK":
- return "还未检查";
- }
- }
- const _export_sfc = (sfc, props) => {
- const target = sfc.__vccOpts || sfc;
- for (const [key, val] of props) {
- target[key] = val;
- }
- return target;
- };
- const _hoisted_1$2 = { class: "title" };
- const _hoisted_2$2 = { class: "message" };
- const _hoisted_3$2 = { key: 0 };
- const _hoisted_4$2 = { class: "message" };
- const _hoisted_5$1 = { class: "buttons" };
- const maxTimeSec = 120;
- const _sfc_main$2 = {
- __name: "CommentChecker",
- setup(__props) {
- const check2 = vue.inject("check");
- const hotBanCheck2 = vue.inject("hotBanCheck");
- const commentRecord = vue.inject("commentRecord");
- const onClose = vue.inject("onClose");
- const onUnblock = vue.inject("onUnblock");
- const interval = vue.inject("interval");
- const showCancelButton = vue.ref(true);
- const showConfirmButton = vue.ref(false);
- const showCloseButton = vue.ref(false);
- const showHotBanCheckButton = vue.ref(false);
- const showStopHotBanCheckButton = vue.ref(false);
- const showLetMeAccessButtton = vue.ref(false);
- const showHotBanChecker = vue.ref(false);
- const stateClass = vue.ref("not-check");
- const title = vue.ref("等待检查中……");
- const message = vue.ref("");
- const messageByHotCheck = vue.ref("等待检查中……");
- let completed = false;
- let netErr = false;
- let hotBanCheckerController = {
- isCancelled: false
- };
- let skipHotBanCheckWait = false;
- const stripedFlow = vue.ref(false);
- const currentTimeSec = vue.ref(0);
- const percentage = vue.computed(() => {
- if (currentTimeSec.value < 0 || currentTimeSec.value > maxTimeSec) {
- return 100;
- } else {
- return currentTimeSec.value / maxTimeSec * 100;
- }
- });
- function format() {
- if (currentTimeSec.value < 0) {
- return `--:-- / ${formatSecondsToMMSS(maxTimeSec)}`;
- } else {
- return `${formatSecondsToMMSS(currentTimeSec.value)} / ${formatSecondsToMMSS(maxTimeSec)}`;
- }
- }
- let shown = null;
- let startTime = Date.now() / 1e3;
- async function startCheck() {
- while (currentTimeSec.value < maxTimeSec || netErr) {
- if (!netErr) {
- for (let i = interval; i > 0; i--) {
- message.value = "等待 " + i + "s 后检查评论状态";
- await sleep(1e3);
- currentTimeSec.value = Date.now() / 1e3 - startTime;
- if (completed) {
- onStateCheckComplete();
- return;
- }
- }
- } else {
- currentTimeSec.value = Date.now() / 1e3 - startTime;
- if (completed) {
- onStateCheckComplete();
- return;
- }
- }
- message.value = "检查评论状态中……";
- stripedFlow.value = true;
- try {
- await check2(commentRecord);
- } catch (err) {
- netErr = true;
- title.value = "网络错误,获取当前状态失败";
- showConfirmButton.value = false;
- showCloseButton.value = true;
- stripedFlow.value = false;
- console.error(err);
- continue;
- }
- netErr = false;
- showCancelButton.value = false;
- showCloseButton.value = false;
- stripedFlow.value = false;
- if (commentRecord.currentState == "NORMAL") {
- title.value = "当前状态:正常";
- stateClass.value = "normal";
- shown = commentRecord.currentState;
- } else if (commentRecord.currentState == "SHADOW_BAN") {
- title.value = "当前状态:仅自己可见";
- stateClass.value = "shadow-ban";
- shown = commentRecord.currentState;
- } else if (commentRecord.currentState == "DELETED") {
- title.value = "当前状态:已被删除";
- stateClass.value = "deleted";
- if (shown) {
- completed = true;
- message.value = `不用等了,你的评论检查到的状态先从『${shown == "NORMAL" ? "正常" : "仅自己可见"}』再到删除,系统偷偷删了无疑。如果不信,你可以尝试编辑评论或添加回复来求证`;
- onStateCheckComplete();
- return;
- }
- }
- showConfirmButton.value = true;
- }
- onStateCheckComplete();
- completed = true;
- message.value = "观察时间已足够,当前状态可信,检查完毕";
- buttonText.value = "关闭";
- }
- function onStateCheckComplete() {
- showConfirmButton.value = false;
- showCloseButton.value = true;
- if (commentRecord.currentState == "NORMAL") {
- showHotBanCheckButton.value = true;
- } else if (commentRecord.currentState == "DELETED") {
- onUnblock(commentRecord);
- }
- }
- startCheck();
- function cancelCheck() {
- completed = true;
- onClose(commentRecord);
- }
- function confirmCurrentState() {
- completed = true;
- message.value = "您已确认当前状态,检查完毕";
- }
- function close() {
- onClose(commentRecord);
- }
- async function checkHotBan() {
- if (commentRecord.commentId.indexOf(".") == -1) {
- try {
- await ElementPlus.ElMessageBox.confirm(
- "确认检查吗?该检查需要遍历热门评论区,请注意评论区的评论数量(总数大于3000的评论区慎重考虑)!数量太多将导致漫长的检查过程,同时频繁调用API可能会引发不可预料的后果!",
- "警告",
- {
- confirmButtonText: "确定",
- cancelButtonText: "取消"
- }
- );
- } catch (err) {
- return;
- }
- }
- showCloseButton.value = false;
- showHotBanCheckButton.value = false;
- showHotBanChecker.value = true;
- showStopHotBanCheckButton.value = true;
- while (currentTimeSec.value < maxTimeSec && !hotBanCheckerController.isCancelled) {
- messageByHotCheck.value = `为避免检查误判,检查需要等待至状态可信任时开始,剩余 ${Math.floor(maxTimeSec - currentTimeSec.value)}s`;
- if (!skipHotBanCheckWait && currentTimeSec.value > 50) {
- showLetMeAccessButtton.value = true;
- }
- if (skipHotBanCheckWait) {
- break;
- }
- await sleep(1e3);
- if (hotBanCheckerController.isCancelled) {
- return;
- }
- currentTimeSec.value = Date.now() / 1e3 - startTime;
- }
- showLetMeAccessButtton.value = false;
- messageByHotCheck.value = "正在重新检查评论状态……";
- await check2(commentRecord);
- if (commentRecord.currentState != "NORMAL") {
- if (commentRecord.currentState == "SHADOW_BAN") {
- title.value = "当前状态:仅自己可见";
- stateClass.value = "shadow-ban";
- messageByHotCheck.value = "评论已被ShadowBan,热门的屏蔽的检查已取消";
- } else if (commentRecord.currentState == "DELETED") {
- title.value = "当前状态:已被删除";
- stateClass.value = "deleted";
- messageByHotCheck.value = "评论已被删除,热门的屏蔽的检查已取消";
- }
- showStopHotBanCheckButton.value = false;
- showCloseButton.value = true;
- return;
- }
- messageByHotCheck.value = "评论状态正常,准备检查中……";
- let observer = {
- onCountChange(c, p) {
- messageByHotCheck.value = `正在搜索热门列表,已搜寻至:第${c}个 第${p}页`;
- }
- };
- if (await hotBanCheck2(commentRecord, observer, hotBanCheckerController)) {
- if (commentRecord.hotBan) {
- messageByHotCheck.value = "⚠ 你的评论未在热门列表找到,已被热门屏蔽,检查完成";
- } else {
- messageByHotCheck.value = "✔ 你的评论已在热门列表找到,没有被热门屏蔽,检查完成";
- }
- }
- showStopHotBanCheckButton.value = false;
- showCloseButton.value = true;
- }
- function stopHotBanCheck() {
- hotBanCheckerController.isCancelled = true;
- messageByHotCheck.value = "你已终止热门屏蔽的检查";
- showStopHotBanCheckButton.value = false;
- showCloseButton.value = true;
- }
- function letMeAccess() {
- skipHotBanCheckWait = true;
- showLetMeAccessButtton.value = false;
- }
- return (_ctx, _cache) => {
- const _component_el_progress = vue.resolveComponent("el-progress");
- return vue.openBlock(), vue.createElementBlock("div", {
- class: vue.normalizeClass(["comment-checker", stateClass.value])
- }, [
- vue.createElementVNode("div", _hoisted_1$2, vue.toDisplayString(title.value), 1),
- vue.createElementVNode("div", _hoisted_2$2, vue.toDisplayString(message.value), 1),
- vue.createVNode(_component_el_progress, {
- percentage: percentage.value,
- striped: "",
- format,
- "striped-flow": stripedFlow.value
- }, null, 8, ["percentage", "striped-flow"]),
- showHotBanChecker.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3$2, [
- _cache[0] || (_cache[0] = vue.createElementVNode("div", { class: "title" }, "热门屏蔽检查", -1)),
- vue.createElementVNode("div", _hoisted_4$2, vue.toDisplayString(messageByHotCheck.value), 1)
- ])) : vue.createCommentVNode("", true),
- vue.createElementVNode("div", _hoisted_5$1, [
- showCancelButton.value ? (vue.openBlock(), vue.createElementBlock("span", {
- key: 0,
- onClick: cancelCheck
- }, "取消")) : vue.createCommentVNode("", true),
- showConfirmButton.value ? (vue.openBlock(), vue.createElementBlock("span", {
- key: 1,
- onClick: confirmCurrentState
- }, "确认当前状态")) : vue.createCommentVNode("", true),
- showCloseButton.value ? (vue.openBlock(), vue.createElementBlock("span", {
- key: 2,
- onClick: close
- }, "关闭")) : vue.createCommentVNode("", true),
- showHotBanCheckButton.value ? (vue.openBlock(), vue.createElementBlock("span", {
- key: 3,
- onClick: checkHotBan
- }, "热门屏蔽检查")) : vue.createCommentVNode("", true),
- showStopHotBanCheckButton.value ? (vue.openBlock(), vue.createElementBlock("span", {
- key: 4,
- onClick: stopHotBanCheck
- }, "终止检查")) : vue.createCommentVNode("", true),
- showLetMeAccessButtton.value ? (vue.openBlock(), vue.createElementBlock("span", {
- key: 5,
- onClick: letMeAccess
- }, "让我检查!")) : vue.createCommentVNode("", true)
- ])
- ], 2);
- };
- }
- };
- const CommentChecker = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-684910ce"]]);
- var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
- var indexMinimal = {};
- var minimal$1 = {};
- var aspromise;
- var hasRequiredAspromise;
- function requireAspromise() {
- if (hasRequiredAspromise) return aspromise;
- hasRequiredAspromise = 1;
- aspromise = asPromise;
- function asPromise(fn, ctx) {
- var params = new Array(arguments.length - 1), offset = 0, index = 2, pending = true;
- while (index < arguments.length)
- params[offset++] = arguments[index++];
- return new Promise(function executor(resolve, reject) {
- params[offset] = function callback(err) {
- if (pending) {
- pending = false;
- if (err)
- reject(err);
- else {
- var params2 = new Array(arguments.length - 1), offset2 = 0;
- while (offset2 < params2.length)
- params2[offset2++] = arguments[offset2];
- resolve.apply(null, params2);
- }
- }
- };
- try {
- fn.apply(ctx || null, params);
- } catch (err) {
- if (pending) {
- pending = false;
- reject(err);
- }
- }
- });
- }
- return aspromise;
- }
- var base64 = {};
- var hasRequiredBase64;
- function requireBase64() {
- if (hasRequiredBase64) return base64;
- hasRequiredBase64 = 1;
- (function(exports) {
- var base642 = exports;
- base642.length = function length(string) {
- var p = string.length;
- if (!p)
- return 0;
- var n = 0;
- while (--p % 4 > 1 && string.charAt(p) === "=")
- ++n;
- return Math.ceil(string.length * 3) / 4 - n;
- };
- var b64 = new Array(64);
- var s64 = new Array(123);
- for (var i = 0; i < 64; )
- s64[b64[i] = i < 26 ? i + 65 : i < 52 ? i + 71 : i < 62 ? i - 4 : i - 59 | 43] = i++;
- base642.encode = function encode(buffer, start, end) {
- var parts = null, chunk = [];
- var i2 = 0, j = 0, t;
- while (start < end) {
- var b = buffer[start++];
- switch (j) {
- case 0:
- chunk[i2++] = b64[b >> 2];
- t = (b & 3) << 4;
- j = 1;
- break;
- case 1:
- chunk[i2++] = b64[t | b >> 4];
- t = (b & 15) << 2;
- j = 2;
- break;
- case 2:
- chunk[i2++] = b64[t | b >> 6];
- chunk[i2++] = b64[b & 63];
- j = 0;
- break;
- }
- if (i2 > 8191) {
- (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
- i2 = 0;
- }
- }
- if (j) {
- chunk[i2++] = b64[t];
- chunk[i2++] = 61;
- if (j === 1)
- chunk[i2++] = 61;
- }
- if (parts) {
- if (i2)
- parts.push(String.fromCharCode.apply(String, chunk.slice(0, i2)));
- return parts.join("");
- }
- return String.fromCharCode.apply(String, chunk.slice(0, i2));
- };
- var invalidEncoding = "invalid encoding";
- base642.decode = function decode(string, buffer, offset) {
- var start = offset;
- var j = 0, t;
- for (var i2 = 0; i2 < string.length; ) {
- var c = string.charCodeAt(i2++);
- if (c === 61 && j > 1)
- break;
- if ((c = s64[c]) === void 0)
- throw Error(invalidEncoding);
- switch (j) {
- case 0:
- t = c;
- j = 1;
- break;
- case 1:
- buffer[offset++] = t << 2 | (c & 48) >> 4;
- t = c;
- j = 2;
- break;
- case 2:
- buffer[offset++] = (t & 15) << 4 | (c & 60) >> 2;
- t = c;
- j = 3;
- break;
- case 3:
- buffer[offset++] = (t & 3) << 6 | c;
- j = 0;
- break;
- }
- }
- if (j === 1)
- throw Error(invalidEncoding);
- return offset - start;
- };
- base642.test = function test(string) {
- return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(string);
- };
- })(base64);
- return base64;
- }
- var eventemitter;
- var hasRequiredEventemitter;
- function requireEventemitter() {
- if (hasRequiredEventemitter) return eventemitter;
- hasRequiredEventemitter = 1;
- eventemitter = EventEmitter;
- function EventEmitter() {
- this._listeners = {};
- }
- EventEmitter.prototype.on = function on(evt, fn, ctx) {
- (this._listeners[evt] || (this._listeners[evt] = [])).push({
- fn,
- ctx: ctx || this
- });
- return this;
- };
- EventEmitter.prototype.off = function off(evt, fn) {
- if (evt === void 0)
- this._listeners = {};
- else {
- if (fn === void 0)
- this._listeners[evt] = [];
- else {
- var listeners = this._listeners[evt];
- for (var i = 0; i < listeners.length; )
- if (listeners[i].fn === fn)
- listeners.splice(i, 1);
- else
- ++i;
- }
- }
- return this;
- };
- EventEmitter.prototype.emit = function emit(evt) {
- var listeners = this._listeners[evt];
- if (listeners) {
- var args = [], i = 1;
- for (; i < arguments.length; )
- args.push(arguments[i++]);
- for (i = 0; i < listeners.length; )
- listeners[i].fn.apply(listeners[i++].ctx, args);
- }
- return this;
- };
- return eventemitter;
- }
- var float;
- var hasRequiredFloat;
- function requireFloat() {
- if (hasRequiredFloat) return float;
- hasRequiredFloat = 1;
- float = factory(factory);
- function factory(exports) {
- if (typeof Float32Array !== "undefined") (function() {
- var f32 = new Float32Array([-0]), f8b = new Uint8Array(f32.buffer), le = f8b[3] === 128;
- function writeFloat_f32_cpy(val, buf, pos) {
- f32[0] = val;
- buf[pos] = f8b[0];
- buf[pos + 1] = f8b[1];
- buf[pos + 2] = f8b[2];
- buf[pos + 3] = f8b[3];
- }
- function writeFloat_f32_rev(val, buf, pos) {
- f32[0] = val;
- buf[pos] = f8b[3];
- buf[pos + 1] = f8b[2];
- buf[pos + 2] = f8b[1];
- buf[pos + 3] = f8b[0];
- }
- exports.writeFloatLE = le ? writeFloat_f32_cpy : writeFloat_f32_rev;
- exports.writeFloatBE = le ? writeFloat_f32_rev : writeFloat_f32_cpy;
- function readFloat_f32_cpy(buf, pos) {
- f8b[0] = buf[pos];
- f8b[1] = buf[pos + 1];
- f8b[2] = buf[pos + 2];
- f8b[3] = buf[pos + 3];
- return f32[0];
- }
- function readFloat_f32_rev(buf, pos) {
- f8b[3] = buf[pos];
- f8b[2] = buf[pos + 1];
- f8b[1] = buf[pos + 2];
- f8b[0] = buf[pos + 3];
- return f32[0];
- }
- exports.readFloatLE = le ? readFloat_f32_cpy : readFloat_f32_rev;
- exports.readFloatBE = le ? readFloat_f32_rev : readFloat_f32_cpy;
- })();
- else (function() {
- function writeFloat_ieee754(writeUint, val, buf, pos) {
- var sign = val < 0 ? 1 : 0;
- if (sign)
- val = -val;
- if (val === 0)
- writeUint(1 / val > 0 ? (
- /* positive */
- 0
- ) : (
- /* negative 0 */
- 2147483648
- ), buf, pos);
- else if (isNaN(val))
- writeUint(2143289344, buf, pos);
- else if (val > 34028234663852886e22)
- writeUint((sign << 31 | 2139095040) >>> 0, buf, pos);
- else if (val < 11754943508222875e-54)
- writeUint((sign << 31 | Math.round(val / 1401298464324817e-60)) >>> 0, buf, pos);
- else {
- var exponent = Math.floor(Math.log(val) / Math.LN2), mantissa = Math.round(val * Math.pow(2, -exponent) * 8388608) & 8388607;
- writeUint((sign << 31 | exponent + 127 << 23 | mantissa) >>> 0, buf, pos);
- }
- }
- exports.writeFloatLE = writeFloat_ieee754.bind(null, writeUintLE);
- exports.writeFloatBE = writeFloat_ieee754.bind(null, writeUintBE);
- function readFloat_ieee754(readUint, buf, pos) {
- var uint = readUint(buf, pos), sign = (uint >> 31) * 2 + 1, exponent = uint >>> 23 & 255, mantissa = uint & 8388607;
- return exponent === 255 ? mantissa ? NaN : sign * Infinity : exponent === 0 ? sign * 1401298464324817e-60 * mantissa : sign * Math.pow(2, exponent - 150) * (mantissa + 8388608);
- }
- exports.readFloatLE = readFloat_ieee754.bind(null, readUintLE);
- exports.readFloatBE = readFloat_ieee754.bind(null, readUintBE);
- })();
- if (typeof Float64Array !== "undefined") (function() {
- var f64 = new Float64Array([-0]), f8b = new Uint8Array(f64.buffer), le = f8b[7] === 128;
- function writeDouble_f64_cpy(val, buf, pos) {
- f64[0] = val;
- buf[pos] = f8b[0];
- buf[pos + 1] = f8b[1];
- buf[pos + 2] = f8b[2];
- buf[pos + 3] = f8b[3];
- buf[pos + 4] = f8b[4];
- buf[pos + 5] = f8b[5];
- buf[pos + 6] = f8b[6];
- buf[pos + 7] = f8b[7];
- }
- function writeDouble_f64_rev(val, buf, pos) {
- f64[0] = val;
- buf[pos] = f8b[7];
- buf[pos + 1] = f8b[6];
- buf[pos + 2] = f8b[5];
- buf[pos + 3] = f8b[4];
- buf[pos + 4] = f8b[3];
- buf[pos + 5] = f8b[2];
- buf[pos + 6] = f8b[1];
- buf[pos + 7] = f8b[0];
- }
- exports.writeDoubleLE = le ? writeDouble_f64_cpy : writeDouble_f64_rev;
- exports.writeDoubleBE = le ? writeDouble_f64_rev : writeDouble_f64_cpy;
- function readDouble_f64_cpy(buf, pos) {
- f8b[0] = buf[pos];
- f8b[1] = buf[pos + 1];
- f8b[2] = buf[pos + 2];
- f8b[3] = buf[pos + 3];
- f8b[4] = buf[pos + 4];
- f8b[5] = buf[pos + 5];
- f8b[6] = buf[pos + 6];
- f8b[7] = buf[pos + 7];
- return f64[0];
- }
- function readDouble_f64_rev(buf, pos) {
- f8b[7] = buf[pos];
- f8b[6] = buf[pos + 1];
- f8b[5] = buf[pos + 2];
- f8b[4] = buf[pos + 3];
- f8b[3] = buf[pos + 4];
- f8b[2] = buf[pos + 5];
- f8b[1] = buf[pos + 6];
- f8b[0] = buf[pos + 7];
- return f64[0];
- }
- exports.readDoubleLE = le ? readDouble_f64_cpy : readDouble_f64_rev;
- exports.readDoubleBE = le ? readDouble_f64_rev : readDouble_f64_cpy;
- })();
- else (function() {
- function writeDouble_ieee754(writeUint, off0, off1, val, buf, pos) {
- var sign = val < 0 ? 1 : 0;
- if (sign)
- val = -val;
- if (val === 0) {
- writeUint(0, buf, pos + off0);
- writeUint(1 / val > 0 ? (
- /* positive */
- 0
- ) : (
- /* negative 0 */
- 2147483648
- ), buf, pos + off1);
- } else if (isNaN(val)) {
- writeUint(0, buf, pos + off0);
- writeUint(2146959360, buf, pos + off1);
- } else if (val > 17976931348623157e292) {
- writeUint(0, buf, pos + off0);
- writeUint((sign << 31 | 2146435072) >>> 0, buf, pos + off1);
- } else {
- var mantissa;
- if (val < 22250738585072014e-324) {
- mantissa = val / 5e-324;
- writeUint(mantissa >>> 0, buf, pos + off0);
- writeUint((sign << 31 | mantissa / 4294967296) >>> 0, buf, pos + off1);
- } else {
- var exponent = Math.floor(Math.log(val) / Math.LN2);
- if (exponent === 1024)
- exponent = 1023;
- mantissa = val * Math.pow(2, -exponent);
- writeUint(mantissa * 4503599627370496 >>> 0, buf, pos + off0);
- writeUint((sign << 31 | exponent + 1023 << 20 | mantissa * 1048576 & 1048575) >>> 0, buf, pos + off1);
- }
- }
- }
- exports.writeDoubleLE = writeDouble_ieee754.bind(null, writeUintLE, 0, 4);
- exports.writeDoubleBE = writeDouble_ieee754.bind(null, writeUintBE, 4, 0);
- function readDouble_ieee754(readUint, off0, off1, buf, pos) {
- var lo = readUint(buf, pos + off0), hi = readUint(buf, pos + off1);
- var sign = (hi >> 31) * 2 + 1, exponent = hi >>> 20 & 2047, mantissa = 4294967296 * (hi & 1048575) + lo;
- return exponent === 2047 ? mantissa ? NaN : sign * Infinity : exponent === 0 ? sign * 5e-324 * mantissa : sign * Math.pow(2, exponent - 1075) * (mantissa + 4503599627370496);
- }
- exports.readDoubleLE = readDouble_ieee754.bind(null, readUintLE, 0, 4);
- exports.readDoubleBE = readDouble_ieee754.bind(null, readUintBE, 4, 0);
- })();
- return exports;
- }
- function writeUintLE(val, buf, pos) {
- buf[pos] = val & 255;
- buf[pos + 1] = val >>> 8 & 255;
- buf[pos + 2] = val >>> 16 & 255;
- buf[pos + 3] = val >>> 24;
- }
- function writeUintBE(val, buf, pos) {
- buf[pos] = val >>> 24;
- buf[pos + 1] = val >>> 16 & 255;
- buf[pos + 2] = val >>> 8 & 255;
- buf[pos + 3] = val & 255;
- }
- function readUintLE(buf, pos) {
- return (buf[pos] | buf[pos + 1] << 8 | buf[pos + 2] << 16 | buf[pos + 3] << 24) >>> 0;
- }
- function readUintBE(buf, pos) {
- return (buf[pos] << 24 | buf[pos + 1] << 16 | buf[pos + 2] << 8 | buf[pos + 3]) >>> 0;
- }
- return float;
- }
- var inquire_1;
- var hasRequiredInquire;
- function requireInquire() {
- if (hasRequiredInquire) return inquire_1;
- hasRequiredInquire = 1;
- inquire_1 = inquire;
- function inquire(moduleName) {
- try {
- var mod = eval("quire".replace(/^/, "re"))(moduleName);
- if (mod && (mod.length || Object.keys(mod).length))
- return mod;
- } catch (e) {
- }
- return null;
- }
- return inquire_1;
- }
- var utf8 = {};
- var hasRequiredUtf8;
- function requireUtf8() {
- if (hasRequiredUtf8) return utf8;
- hasRequiredUtf8 = 1;
- (function(exports) {
- var utf82 = exports;
- utf82.length = function utf8_length(string) {
- var len = 0, c = 0;
- for (var i = 0; i < string.length; ++i) {
- c = string.charCodeAt(i);
- if (c < 128)
- len += 1;
- else if (c < 2048)
- len += 2;
- else if ((c & 64512) === 55296 && (string.charCodeAt(i + 1) & 64512) === 56320) {
- ++i;
- len += 4;
- } else
- len += 3;
- }
- return len;
- };
- utf82.read = function utf8_read(buffer, start, end) {
- var len = end - start;
- if (len < 1)
- return "";
- var parts = null, chunk = [], i = 0, t;
- while (start < end) {
- t = buffer[start++];
- if (t < 128)
- chunk[i++] = t;
- else if (t > 191 && t < 224)
- chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;
- else if (t > 239 && t < 365) {
- t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 65536;
- chunk[i++] = 55296 + (t >> 10);
- chunk[i++] = 56320 + (t & 1023);
- } else
- chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;
- if (i > 8191) {
- (parts || (parts = [])).push(String.fromCharCode.apply(String, chunk));
- i = 0;
- }
- }
- if (parts) {
- if (i)
- parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
- return parts.join("");
- }
- return String.fromCharCode.apply(String, chunk.slice(0, i));
- };
- utf82.write = function utf8_write(string, buffer, offset) {
- var start = offset, c1, c2;
- for (var i = 0; i < string.length; ++i) {
- c1 = string.charCodeAt(i);
- if (c1 < 128) {
- buffer[offset++] = c1;
- } else if (c1 < 2048) {
- buffer[offset++] = c1 >> 6 | 192;
- buffer[offset++] = c1 & 63 | 128;
- } else if ((c1 & 64512) === 55296 && ((c2 = string.charCodeAt(i + 1)) & 64512) === 56320) {
- c1 = 65536 + ((c1 & 1023) << 10) + (c2 & 1023);
- ++i;
- buffer[offset++] = c1 >> 18 | 240;
- buffer[offset++] = c1 >> 12 & 63 | 128;
- buffer[offset++] = c1 >> 6 & 63 | 128;
- buffer[offset++] = c1 & 63 | 128;
- } else {
- buffer[offset++] = c1 >> 12 | 224;
- buffer[offset++] = c1 >> 6 & 63 | 128;
- buffer[offset++] = c1 & 63 | 128;
- }
- }
- return offset - start;
- };
- })(utf8);
- return utf8;
- }
- var pool_1;
- var hasRequiredPool;
- function requirePool() {
- if (hasRequiredPool) return pool_1;
- hasRequiredPool = 1;
- pool_1 = pool;
- function pool(alloc, slice, size) {
- var SIZE = size || 8192;
- var MAX = SIZE >>> 1;
- var slab = null;
- var offset = SIZE;
- return function pool_alloc(size2) {
- if (size2 < 1 || size2 > MAX)
- return alloc(size2);
- if (offset + size2 > SIZE) {
- slab = alloc(SIZE);
- offset = 0;
- }
- var buf = slice.call(slab, offset, offset += size2);
- if (offset & 7)
- offset = (offset | 7) + 1;
- return buf;
- };
- }
- return pool_1;
- }
- var longbits;
- var hasRequiredLongbits;
- function requireLongbits() {
- if (hasRequiredLongbits) return longbits;
- hasRequiredLongbits = 1;
- longbits = LongBits;
- var util = requireMinimal$1();
- function LongBits(lo, hi) {
- this.lo = lo >>> 0;
- this.hi = hi >>> 0;
- }
- var zero = LongBits.zero = new LongBits(0, 0);
- zero.toNumber = function() {
- return 0;
- };
- zero.zzEncode = zero.zzDecode = function() {
- return this;
- };
- zero.length = function() {
- return 1;
- };
- var zeroHash = LongBits.zeroHash = "\0\0\0\0\0\0\0\0";
- LongBits.fromNumber = function fromNumber(value) {
- if (value === 0)
- return zero;
- var sign = value < 0;
- if (sign)
- value = -value;
- var lo = value >>> 0, hi = (value - lo) / 4294967296 >>> 0;
- if (sign) {
- hi = ~hi >>> 0;
- lo = ~lo >>> 0;
- if (++lo > 4294967295) {
- lo = 0;
- if (++hi > 4294967295)
- hi = 0;
- }
- }
- return new LongBits(lo, hi);
- };
- LongBits.from = function from(value) {
- if (typeof value === "number")
- return LongBits.fromNumber(value);
- if (util.isString(value)) {
- if (util.Long)
- value = util.Long.fromString(value);
- else
- return LongBits.fromNumber(parseInt(value, 10));
- }
- return value.low || value.high ? new LongBits(value.low >>> 0, value.high >>> 0) : zero;
- };
- LongBits.prototype.toNumber = function toNumber(unsigned) {
- if (!unsigned && this.hi >>> 31) {
- var lo = ~this.lo + 1 >>> 0, hi = ~this.hi >>> 0;
- if (!lo)
- hi = hi + 1 >>> 0;
- return -(lo + hi * 4294967296);
- }
- return this.lo + this.hi * 4294967296;
- };
- LongBits.prototype.toLong = function toLong(unsigned) {
- return util.Long ? new util.Long(this.lo | 0, this.hi | 0, Boolean(unsigned)) : { low: this.lo | 0, high: this.hi | 0, unsigned: Boolean(unsigned) };
- };
- var charCodeAt = String.prototype.charCodeAt;
- LongBits.fromHash = function fromHash(hash) {
- if (hash === zeroHash)
- return zero;
- return new LongBits(
- (charCodeAt.call(hash, 0) | charCodeAt.call(hash, 1) << 8 | charCodeAt.call(hash, 2) << 16 | charCodeAt.call(hash, 3) << 24) >>> 0,
- (charCodeAt.call(hash, 4) | charCodeAt.call(hash, 5) << 8 | charCodeAt.call(hash, 6) << 16 | charCodeAt.call(hash, 7) << 24) >>> 0
- );
- };
- LongBits.prototype.toHash = function toHash() {
- return String.fromCharCode(
- this.lo & 255,
- this.lo >>> 8 & 255,
- this.lo >>> 16 & 255,
- this.lo >>> 24,
- this.hi & 255,
- this.hi >>> 8 & 255,
- this.hi >>> 16 & 255,
- this.hi >>> 24
- );
- };
- LongBits.prototype.zzEncode = function zzEncode() {
- var mask = this.hi >> 31;
- this.hi = ((this.hi << 1 | this.lo >>> 31) ^ mask) >>> 0;
- this.lo = (this.lo << 1 ^ mask) >>> 0;
- return this;
- };
- LongBits.prototype.zzDecode = function zzDecode() {
- var mask = -(this.lo & 1);
- this.lo = ((this.lo >>> 1 | this.hi << 31) ^ mask) >>> 0;
- this.hi = (this.hi >>> 1 ^ mask) >>> 0;
- return this;
- };
- LongBits.prototype.length = function length() {
- var part0 = this.lo, part1 = (this.lo >>> 28 | this.hi << 4) >>> 0, part2 = this.hi >>> 24;
- return part2 === 0 ? part1 === 0 ? part0 < 16384 ? part0 < 128 ? 1 : 2 : part0 < 2097152 ? 3 : 4 : part1 < 16384 ? part1 < 128 ? 5 : 6 : part1 < 2097152 ? 7 : 8 : part2 < 128 ? 9 : 10;
- };
- return longbits;
- }
- var hasRequiredMinimal$1;
- function requireMinimal$1() {
- if (hasRequiredMinimal$1) return minimal$1;
- hasRequiredMinimal$1 = 1;
- (function(exports) {
- var util = exports;
- util.asPromise = requireAspromise();
- util.base64 = requireBase64();
- util.EventEmitter = requireEventemitter();
- util.float = requireFloat();
- util.inquire = requireInquire();
- util.utf8 = requireUtf8();
- util.pool = requirePool();
- util.LongBits = requireLongbits();
- util.isNode = Boolean(typeof commonjsGlobal !== "undefined" && commonjsGlobal && commonjsGlobal.process && commonjsGlobal.process.versions && commonjsGlobal.process.versions.node);
- util.global = util.isNode && commonjsGlobal || typeof window !== "undefined" && window || typeof self !== "undefined" && self || minimal$1;
- util.emptyArray = Object.freeze ? Object.freeze([]) : (
- /* istanbul ignore next */
- []
- );
- util.emptyObject = Object.freeze ? Object.freeze({}) : (
- /* istanbul ignore next */
- {}
- );
- util.isInteger = Number.isInteger || /* istanbul ignore next */
- function isInteger(value) {
- return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
- };
- util.isString = function isString(value) {
- return typeof value === "string" || value instanceof String;
- };
- util.isObject = function isObject(value) {
- return value && typeof value === "object";
- };
- util.isset = /**
- * Checks if a property on a message is considered to be present.
- * @param {Object} obj Plain object or message instance
- * @param {string} prop Property name
- * @returns {boolean} `true` if considered to be present, otherwise `false`
- */
- util.isSet = function isSet(obj, prop) {
- var value = obj[prop];
- if (value != null && obj.hasOwnProperty(prop))
- return typeof value !== "object" || (Array.isArray(value) ? value.length : Object.keys(value).length) > 0;
- return false;
- };
- util.Buffer = function() {
- try {
- var Buffer = util.inquire("buffer").Buffer;
- return Buffer.prototype.utf8Write ? Buffer : (
- /* istanbul ignore next */
- null
- );
- } catch (e) {
- return null;
- }
- }();
- util._Buffer_from = null;
- util._Buffer_allocUnsafe = null;
- util.newBuffer = function newBuffer(sizeOrArray) {
- return typeof sizeOrArray === "number" ? util.Buffer ? util._Buffer_allocUnsafe(sizeOrArray) : new util.Array(sizeOrArray) : util.Buffer ? util._Buffer_from(sizeOrArray) : typeof Uint8Array === "undefined" ? sizeOrArray : new Uint8Array(sizeOrArray);
- };
- util.Array = typeof Uint8Array !== "undefined" ? Uint8Array : Array;
- util.Long = /* istanbul ignore next */
- util.global.dcodeIO && /* istanbul ignore next */
- util.global.dcodeIO.Long || /* istanbul ignore next */
- util.global.Long || util.inquire("long");
- util.key2Re = /^true|false|0|1$/;
- util.key32Re = /^-?(?:0|[1-9][0-9]*)$/;
- util.key64Re = /^(?:[\\x00-\\xff]{8}|-?(?:0|[1-9][0-9]*))$/;
- util.longToHash = function longToHash(value) {
- return value ? util.LongBits.from(value).toHash() : util.LongBits.zeroHash;
- };
- util.longFromHash = function longFromHash(hash, unsigned) {
- var bits = util.LongBits.fromHash(hash);
- if (util.Long)
- return util.Long.fromBits(bits.lo, bits.hi, unsigned);
- return bits.toNumber(Boolean(unsigned));
- };
- function merge(dst, src, ifNotSet) {
- for (var keys = Object.keys(src), i = 0; i < keys.length; ++i)
- if (dst[keys[i]] === void 0 || !ifNotSet)
- dst[keys[i]] = src[keys[i]];
- return dst;
- }
- util.merge = merge;
- util.lcFirst = function lcFirst(str) {
- return str.charAt(0).toLowerCase() + str.substring(1);
- };
- function newError(name) {
- function CustomError(message, properties) {
- if (!(this instanceof CustomError))
- return new CustomError(message, properties);
- Object.defineProperty(this, "message", { get: function() {
- return message;
- } });
- if (Error.captureStackTrace)
- Error.captureStackTrace(this, CustomError);
- else
- Object.defineProperty(this, "stack", { value: new Error().stack || "" });
- if (properties)
- merge(this, properties);
- }
- CustomError.prototype = Object.create(Error.prototype, {
- constructor: {
- value: CustomError,
- writable: true,
- enumerable: false,
- configurable: true
- },
- name: {
- get: function get() {
- return name;
- },
- set: void 0,
- enumerable: false,
- // configurable: false would accurately preserve the behavior of
- // the original, but I'm guessing that was not intentional.
- // For an actual error subclass, this property would
- // be configurable.
- configurable: true
- },
- toString: {
- value: function value() {
- return this.name + ": " + this.message;
- },
- writable: true,
- enumerable: false,
- configurable: true
- }
- });
- return CustomError;
- }
- util.newError = newError;
- util.ProtocolError = newError("ProtocolError");
- util.oneOfGetter = function getOneOf(fieldNames) {
- var fieldMap = {};
- for (var i = 0; i < fieldNames.length; ++i)
- fieldMap[fieldNames[i]] = 1;
- return function() {
- for (var keys = Object.keys(this), i2 = keys.length - 1; i2 > -1; --i2)
- if (fieldMap[keys[i2]] === 1 && this[keys[i2]] !== void 0 && this[keys[i2]] !== null)
- return keys[i2];
- };
- };
- util.oneOfSetter = function setOneOf(fieldNames) {
- return function(name) {
- for (var i = 0; i < fieldNames.length; ++i)
- if (fieldNames[i] !== name)
- delete this[fieldNames[i]];
- };
- };
- util.toJSONOptions = {
- longs: String,
- enums: String,
- bytes: String,
- json: true
- };
- util._configure = function() {
- var Buffer = util.Buffer;
- if (!Buffer) {
- util._Buffer_from = util._Buffer_allocUnsafe = null;
- return;
- }
- util._Buffer_from = Buffer.from !== Uint8Array.from && Buffer.from || /* istanbul ignore next */
- function Buffer_from(value, encoding) {
- return new Buffer(value, encoding);
- };
- util._Buffer_allocUnsafe = Buffer.allocUnsafe || /* istanbul ignore next */
- function Buffer_allocUnsafe(size) {
- return new Buffer(size);
- };
- };
- })(minimal$1);
- return minimal$1;
- }
- var writer;
- var hasRequiredWriter;
- function requireWriter() {
- if (hasRequiredWriter) return writer;
- hasRequiredWriter = 1;
- writer = Writer;
- var util = requireMinimal$1();
- var BufferWriter;
- var LongBits = util.LongBits, base642 = util.base64, utf82 = util.utf8;
- function Op(fn, len, val) {
- this.fn = fn;
- this.len = len;
- this.next = void 0;
- this.val = val;
- }
- function noop() {
- }
- function State(writer2) {
- this.head = writer2.head;
- this.tail = writer2.tail;
- this.len = writer2.len;
- this.next = writer2.states;
- }
- function Writer() {
- this.len = 0;
- this.head = new Op(noop, 0, 0);
- this.tail = this.head;
- this.states = null;
- }
- var create = function create2() {
- return util.Buffer ? function create_buffer_setup() {
- return (Writer.create = function create_buffer() {
- return new BufferWriter();
- })();
- } : function create_array() {
- return new Writer();
- };
- };
- Writer.create = create();
- Writer.alloc = function alloc(size) {
- return new util.Array(size);
- };
- if (util.Array !== Array)
- Writer.alloc = util.pool(Writer.alloc, util.Array.prototype.subarray);
- Writer.prototype._push = function push(fn, len, val) {
- this.tail = this.tail.next = new Op(fn, len, val);
- this.len += len;
- return this;
- };
- function writeByte(val, buf, pos) {
- buf[pos] = val & 255;
- }
- function writeVarint32(val, buf, pos) {
- while (val > 127) {
- buf[pos++] = val & 127 | 128;
- val >>>= 7;
- }
- buf[pos] = val;
- }
- function VarintOp(len, val) {
- this.len = len;
- this.next = void 0;
- this.val = val;
- }
- VarintOp.prototype = Object.create(Op.prototype);
- VarintOp.prototype.fn = writeVarint32;
- Writer.prototype.uint32 = function write_uint32(value) {
- this.len += (this.tail = this.tail.next = new VarintOp(
- (value = value >>> 0) < 128 ? 1 : value < 16384 ? 2 : value < 2097152 ? 3 : value < 268435456 ? 4 : 5,
- value
- )).len;
- return this;
- };
- Writer.prototype.int32 = function write_int32(value) {
- return value < 0 ? this._push(writeVarint64, 10, LongBits.fromNumber(value)) : this.uint32(value);
- };
- Writer.prototype.sint32 = function write_sint32(value) {
- return this.uint32((value << 1 ^ value >> 31) >>> 0);
- };
- function writeVarint64(val, buf, pos) {
- while (val.hi) {
- buf[pos++] = val.lo & 127 | 128;
- val.lo = (val.lo >>> 7 | val.hi << 25) >>> 0;
- val.hi >>>= 7;
- }
- while (val.lo > 127) {
- buf[pos++] = val.lo & 127 | 128;
- val.lo = val.lo >>> 7;
- }
- buf[pos++] = val.lo;
- }
- Writer.prototype.uint64 = function write_uint64(value) {
- var bits = LongBits.from(value);
- return this._push(writeVarint64, bits.length(), bits);
- };
- Writer.prototype.int64 = Writer.prototype.uint64;
- Writer.prototype.sint64 = function write_sint64(value) {
- var bits = LongBits.from(value).zzEncode();
- return this._push(writeVarint64, bits.length(), bits);
- };
- Writer.prototype.bool = function write_bool(value) {
- return this._push(writeByte, 1, value ? 1 : 0);
- };
- function writeFixed32(val, buf, pos) {
- buf[pos] = val & 255;
- buf[pos + 1] = val >>> 8 & 255;
- buf[pos + 2] = val >>> 16 & 255;
- buf[pos + 3] = val >>> 24;
- }
- Writer.prototype.fixed32 = function write_fixed32(value) {
- return this._push(writeFixed32, 4, value >>> 0);
- };
- Writer.prototype.sfixed32 = Writer.prototype.fixed32;
- Writer.prototype.fixed64 = function write_fixed64(value) {
- var bits = LongBits.from(value);
- return this._push(writeFixed32, 4, bits.lo)._push(writeFixed32, 4, bits.hi);
- };
- Writer.prototype.sfixed64 = Writer.prototype.fixed64;
- Writer.prototype.float = function write_float(value) {
- return this._push(util.float.writeFloatLE, 4, value);
- };
- Writer.prototype.double = function write_double(value) {
- return this._push(util.float.writeDoubleLE, 8, value);
- };
- var writeBytes = util.Array.prototype.set ? function writeBytes_set(val, buf, pos) {
- buf.set(val, pos);
- } : function writeBytes_for(val, buf, pos) {
- for (var i = 0; i < val.length; ++i)
- buf[pos + i] = val[i];
- };
- Writer.prototype.bytes = function write_bytes(value) {
- var len = value.length >>> 0;
- if (!len)
- return this._push(writeByte, 1, 0);
- if (util.isString(value)) {
- var buf = Writer.alloc(len = base642.length(value));
- base642.decode(value, buf, 0);
- value = buf;
- }
- return this.uint32(len)._push(writeBytes, len, value);
- };
- Writer.prototype.string = function write_string(value) {
- var len = utf82.length(value);
- return len ? this.uint32(len)._push(utf82.write, len, value) : this._push(writeByte, 1, 0);
- };
- Writer.prototype.fork = function fork() {
- this.states = new State(this);
- this.head = this.tail = new Op(noop, 0, 0);
- this.len = 0;
- return this;
- };
- Writer.prototype.reset = function reset() {
- if (this.states) {
- this.head = this.states.head;
- this.tail = this.states.tail;
- this.len = this.states.len;
- this.states = this.states.next;
- } else {
- this.head = this.tail = new Op(noop, 0, 0);
- this.len = 0;
- }
- return this;
- };
- Writer.prototype.ldelim = function ldelim() {
- var head = this.head, tail = this.tail, len = this.len;
- this.reset().uint32(len);
- if (len) {
- this.tail.next = head.next;
- this.tail = tail;
- this.len += len;
- }
- return this;
- };
- Writer.prototype.finish = function finish() {
- var head = this.head.next, buf = this.constructor.alloc(this.len), pos = 0;
- while (head) {
- head.fn(head.val, buf, pos);
- pos += head.len;
- head = head.next;
- }
- return buf;
- };
- Writer._configure = function(BufferWriter_) {
- BufferWriter = BufferWriter_;
- Writer.create = create();
- BufferWriter._configure();
- };
- return writer;
- }
- var writer_buffer;
- var hasRequiredWriter_buffer;
- function requireWriter_buffer() {
- if (hasRequiredWriter_buffer) return writer_buffer;
- hasRequiredWriter_buffer = 1;
- writer_buffer = BufferWriter;
- var Writer = requireWriter();
- (BufferWriter.prototype = Object.create(Writer.prototype)).constructor = BufferWriter;
- var util = requireMinimal$1();
- function BufferWriter() {
- Writer.call(this);
- }
- BufferWriter._configure = function() {
- BufferWriter.alloc = util._Buffer_allocUnsafe;
- BufferWriter.writeBytesBuffer = util.Buffer && util.Buffer.prototype instanceof Uint8Array && util.Buffer.prototype.set.name === "set" ? function writeBytesBuffer_set(val, buf, pos) {
- buf.set(val, pos);
- } : function writeBytesBuffer_copy(val, buf, pos) {
- if (val.copy)
- val.copy(buf, pos, 0, val.length);
- else for (var i = 0; i < val.length; )
- buf[pos++] = val[i++];
- };
- };
- BufferWriter.prototype.bytes = function write_bytes_buffer(value) {
- if (util.isString(value))
- value = util._Buffer_from(value, "base64");
- var len = value.length >>> 0;
- this.uint32(len);
- if (len)
- this._push(BufferWriter.writeBytesBuffer, len, value);
- return this;
- };
- function writeStringBuffer(val, buf, pos) {
- if (val.length < 40)
- util.utf8.write(val, buf, pos);
- else if (buf.utf8Write)
- buf.utf8Write(val, pos);
- else
- buf.write(val, pos);
- }
- BufferWriter.prototype.string = function write_string_buffer(value) {
- var len = util.Buffer.byteLength(value);
- this.uint32(len);
- if (len)
- this._push(writeStringBuffer, len, value);
- return this;
- };
- BufferWriter._configure();
- return writer_buffer;
- }
- var reader;
- var hasRequiredReader;
- function requireReader() {
- if (hasRequiredReader) return reader;
- hasRequiredReader = 1;
- reader = Reader;
- var util = requireMinimal$1();
- var BufferReader;
- var LongBits = util.LongBits, utf82 = util.utf8;
- function indexOutOfRange(reader2, writeLength) {
- return RangeError("index out of range: " + reader2.pos + " + " + (writeLength || 1) + " > " + reader2.len);
- }
- function Reader(buffer) {
- this.buf = buffer;
- this.pos = 0;
- this.len = buffer.length;
- }
- var create_array = typeof Uint8Array !== "undefined" ? function create_typed_array(buffer) {
- if (buffer instanceof Uint8Array || Array.isArray(buffer))
- return new Reader(buffer);
- throw Error("illegal buffer");
- } : function create_array2(buffer) {
- if (Array.isArray(buffer))
- return new Reader(buffer);
- throw Error("illegal buffer");
- };
- var create = function create2() {
- return util.Buffer ? function create_buffer_setup(buffer) {
- return (Reader.create = function create_buffer(buffer2) {
- return util.Buffer.isBuffer(buffer2) ? new BufferReader(buffer2) : create_array(buffer2);
- })(buffer);
- } : create_array;
- };
- Reader.create = create();
- Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore next */
- util.Array.prototype.slice;
- Reader.prototype.uint32 = /* @__PURE__ */ function read_uint32_setup() {
- var value = 4294967295;
- return function read_uint32() {
- value = (this.buf[this.pos] & 127) >>> 0;
- if (this.buf[this.pos++] < 128) return value;
- value = (value | (this.buf[this.pos] & 127) << 7) >>> 0;
- if (this.buf[this.pos++] < 128) return value;
- value = (value | (this.buf[this.pos] & 127) << 14) >>> 0;
- if (this.buf[this.pos++] < 128) return value;
- value = (value | (this.buf[this.pos] & 127) << 21) >>> 0;
- if (this.buf[this.pos++] < 128) return value;
- value = (value | (this.buf[this.pos] & 15) << 28) >>> 0;
- if (this.buf[this.pos++] < 128) return value;
- if ((this.pos += 5) > this.len) {
- this.pos = this.len;
- throw indexOutOfRange(this, 10);
- }
- return value;
- };
- }();
- Reader.prototype.int32 = function read_int32() {
- return this.uint32() | 0;
- };
- Reader.prototype.sint32 = function read_sint32() {
- var value = this.uint32();
- return value >>> 1 ^ -(value & 1) | 0;
- };
- function readLongVarint() {
- var bits = new LongBits(0, 0);
- var i = 0;
- if (this.len - this.pos > 4) {
- for (; i < 4; ++i) {
- bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0;
- if (this.buf[this.pos++] < 128)
- return bits;
- }
- bits.lo = (bits.lo | (this.buf[this.pos] & 127) << 28) >>> 0;
- bits.hi = (bits.hi | (this.buf[this.pos] & 127) >> 4) >>> 0;
- if (this.buf[this.pos++] < 128)
- return bits;
- i = 0;
- } else {
- for (; i < 3; ++i) {
- if (this.pos >= this.len)
- throw indexOutOfRange(this);
- bits.lo = (bits.lo | (this.buf[this.pos] & 127) << i * 7) >>> 0;
- if (this.buf[this.pos++] < 128)
- return bits;
- }
- bits.lo = (bits.lo | (this.buf[this.pos++] & 127) << i * 7) >>> 0;
- return bits;
- }
- if (this.len - this.pos > 4) {
- for (; i < 5; ++i) {
- bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0;
- if (this.buf[this.pos++] < 128)
- return bits;
- }
- } else {
- for (; i < 5; ++i) {
- if (this.pos >= this.len)
- throw indexOutOfRange(this);
- bits.hi = (bits.hi | (this.buf[this.pos] & 127) << i * 7 + 3) >>> 0;
- if (this.buf[this.pos++] < 128)
- return bits;
- }
- }
- throw Error("invalid varint encoding");
- }
- Reader.prototype.bool = function read_bool() {
- return this.uint32() !== 0;
- };
- function readFixed32_end(buf, end) {
- return (buf[end - 4] | buf[end - 3] << 8 | buf[end - 2] << 16 | buf[end - 1] << 24) >>> 0;
- }
- Reader.prototype.fixed32 = function read_fixed32() {
- if (this.pos + 4 > this.len)
- throw indexOutOfRange(this, 4);
- return readFixed32_end(this.buf, this.pos += 4);
- };
- Reader.prototype.sfixed32 = function read_sfixed32() {
- if (this.pos + 4 > this.len)
- throw indexOutOfRange(this, 4);
- return readFixed32_end(this.buf, this.pos += 4) | 0;
- };
- function readFixed64() {
- if (this.pos + 8 > this.len)
- throw indexOutOfRange(this, 8);
- return new LongBits(readFixed32_end(this.buf, this.pos += 4), readFixed32_end(this.buf, this.pos += 4));
- }
- Reader.prototype.float = function read_float() {
- if (this.pos + 4 > this.len)
- throw indexOutOfRange(this, 4);
- var value = util.float.readFloatLE(this.buf, this.pos);
- this.pos += 4;
- return value;
- };
- Reader.prototype.double = function read_double() {
- if (this.pos + 8 > this.len)
- throw indexOutOfRange(this, 4);
- var value = util.float.readDoubleLE(this.buf, this.pos);
- this.pos += 8;
- return value;
- };
- Reader.prototype.bytes = function read_bytes() {
- var length = this.uint32(), start = this.pos, end = this.pos + length;
- if (end > this.len)
- throw indexOutOfRange(this, length);
- this.pos += length;
- if (Array.isArray(this.buf))
- return this.buf.slice(start, end);
- if (start === end) {
- var nativeBuffer = util.Buffer;
- return nativeBuffer ? nativeBuffer.alloc(0) : new this.buf.constructor(0);
- }
- return this._slice.call(this.buf, start, end);
- };
- Reader.prototype.string = function read_string() {
- var bytes = this.bytes();
- return utf82.read(bytes, 0, bytes.length);
- };
- Reader.prototype.skip = function skip(length) {
- if (typeof length === "number") {
- if (this.pos + length > this.len)
- throw indexOutOfRange(this, length);
- this.pos += length;
- } else {
- do {
- if (this.pos >= this.len)
- throw indexOutOfRange(this);
- } while (this.buf[this.pos++] & 128);
- }
- return this;
- };
- Reader.prototype.skipType = function(wireType) {
- switch (wireType) {
- case 0:
- this.skip();
- break;
- case 1:
- this.skip(8);
- break;
- case 2:
- this.skip(this.uint32());
- break;
- case 3:
- while ((wireType = this.uint32() & 7) !== 4) {
- this.skipType(wireType);
- }
- break;
- case 5:
- this.skip(4);
- break;
- /* istanbul ignore next */
- default:
- throw Error("invalid wire type " + wireType + " at offset " + this.pos);
- }
- return this;
- };
- Reader._configure = function(BufferReader_) {
- BufferReader = BufferReader_;
- Reader.create = create();
- BufferReader._configure();
- var fn = util.Long ? "toLong" : (
- /* istanbul ignore next */
- "toNumber"
- );
- util.merge(Reader.prototype, {
- int64: function read_int64() {
- return readLongVarint.call(this)[fn](false);
- },
- uint64: function read_uint64() {
- return readLongVarint.call(this)[fn](true);
- },
- sint64: function read_sint64() {
- return readLongVarint.call(this).zzDecode()[fn](false);
- },
- fixed64: function read_fixed64() {
- return readFixed64.call(this)[fn](true);
- },
- sfixed64: function read_sfixed64() {
- return readFixed64.call(this)[fn](false);
- }
- });
- };
- return reader;
- }
- var reader_buffer;
- var hasRequiredReader_buffer;
- function requireReader_buffer() {
- if (hasRequiredReader_buffer) return reader_buffer;
- hasRequiredReader_buffer = 1;
- reader_buffer = BufferReader;
- var Reader = requireReader();
- (BufferReader.prototype = Object.create(Reader.prototype)).constructor = BufferReader;
- var util = requireMinimal$1();
- function BufferReader(buffer) {
- Reader.call(this, buffer);
- }
- BufferReader._configure = function() {
- if (util.Buffer)
- BufferReader.prototype._slice = util.Buffer.prototype.slice;
- };
- BufferReader.prototype.string = function read_string_buffer() {
- var len = this.uint32();
- return this.buf.utf8Slice ? this.buf.utf8Slice(this.pos, this.pos = Math.min(this.pos + len, this.len)) : this.buf.toString("utf-8", this.pos, this.pos = Math.min(this.pos + len, this.len));
- };
- BufferReader._configure();
- return reader_buffer;
- }
- var rpc = {};
- var service;
- var hasRequiredService;
- function requireService() {
- if (hasRequiredService) return service;
- hasRequiredService = 1;
- service = Service;
- var util = requireMinimal$1();
- (Service.prototype = Object.create(util.EventEmitter.prototype)).constructor = Service;
- function Service(rpcImpl, requestDelimited, responseDelimited) {
- if (typeof rpcImpl !== "function")
- throw TypeError("rpcImpl must be a function");
- util.EventEmitter.call(this);
- this.rpcImpl = rpcImpl;
- this.requestDelimited = Boolean(requestDelimited);
- this.responseDelimited = Boolean(responseDelimited);
- }
- Service.prototype.rpcCall = function rpcCall(method, requestCtor, responseCtor, request, callback) {
- if (!request)
- throw TypeError("request must be specified");
- var self2 = this;
- if (!callback)
- return util.asPromise(rpcCall, self2, method, requestCtor, responseCtor, request);
- if (!self2.rpcImpl) {
- setTimeout(function() {
- callback(Error("already ended"));
- }, 0);
- return void 0;
- }
- try {
- return self2.rpcImpl(
- method,
- requestCtor[self2.requestDelimited ? "encodeDelimited" : "encode"](request).finish(),
- function rpcCallback(err, response) {
- if (err) {
- self2.emit("error", err, method);
- return callback(err);
- }
- if (response === null) {
- self2.end(
- /* endedByRPC */
- true
- );
- return void 0;
- }
- if (!(response instanceof responseCtor)) {
- try {
- response = responseCtor[self2.responseDelimited ? "decodeDelimited" : "decode"](response);
- } catch (err2) {
- self2.emit("error", err2, method);
- return callback(err2);
- }
- }
- self2.emit("data", response, method);
- return callback(null, response);
- }
- );
- } catch (err) {
- self2.emit("error", err, method);
- setTimeout(function() {
- callback(err);
- }, 0);
- return void 0;
- }
- };
- Service.prototype.end = function end(endedByRPC) {
- if (this.rpcImpl) {
- if (!endedByRPC)
- this.rpcImpl(null, null, null);
- this.rpcImpl = null;
- this.emit("end").off();
- }
- return this;
- };
- return service;
- }
- var hasRequiredRpc;
- function requireRpc() {
- if (hasRequiredRpc) return rpc;
- hasRequiredRpc = 1;
- (function(exports) {
- var rpc2 = exports;
- rpc2.Service = requireService();
- })(rpc);
- return rpc;
- }
- var roots;
- var hasRequiredRoots;
- function requireRoots() {
- if (hasRequiredRoots) return roots;
- hasRequiredRoots = 1;
- roots = {};
- return roots;
- }
- var hasRequiredIndexMinimal;
- function requireIndexMinimal() {
- if (hasRequiredIndexMinimal) return indexMinimal;
- hasRequiredIndexMinimal = 1;
- (function(exports) {
- var protobuf = exports;
- protobuf.build = "minimal";
- protobuf.Writer = requireWriter();
- protobuf.BufferWriter = requireWriter_buffer();
- protobuf.Reader = requireReader();
- protobuf.BufferReader = requireReader_buffer();
- protobuf.util = requireMinimal$1();
- protobuf.rpc = requireRpc();
- protobuf.roots = requireRoots();
- protobuf.configure = configure;
- function configure() {
- protobuf.util._configure();
- protobuf.Writer._configure(protobuf.BufferWriter);
- protobuf.Reader._configure(protobuf.BufferReader);
- }
- configure();
- })(indexMinimal);
- return indexMinimal;
- }
- var minimal;
- var hasRequiredMinimal;
- function requireMinimal() {
- if (hasRequiredMinimal) return minimal;
- hasRequiredMinimal = 1;
- minimal = requireIndexMinimal();
- return minimal;
- }
- var minimalExports = requireMinimal();
- const $Writer = minimalExports.Writer;
- const $root$2 = minimalExports.roots["default"] || (minimalExports.roots["default"] = {});
- const NextContinuation = $root$2.NextContinuation = (() => {
- function NextContinuation2(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- NextContinuation2.prototype.commentAreaWrapper = null;
- NextContinuation2.prototype.uField3 = 0;
- NextContinuation2.prototype.mainCommentRequest = null;
- NextContinuation2.encode = function encode(m, w) {
- if (!w)
- w = $Writer.create();
- if (m.commentAreaWrapper != null && Object.hasOwnProperty.call(m, "commentAreaWrapper"))
- $root$2.CommentAreaWrapper.encode(m.commentAreaWrapper, w.uint32(18).fork()).ldelim();
- if (m.uField3 != null && Object.hasOwnProperty.call(m, "uField3"))
- w.uint32(24).int32(m.uField3);
- if (m.mainCommentRequest != null && Object.hasOwnProperty.call(m, "mainCommentRequest"))
- $root$2.MainCommentRequest.encode(m.mainCommentRequest, w.uint32(50).fork()).ldelim();
- return w;
- };
- return NextContinuation2;
- })();
- $root$2.CommentAreaWrapper = (() => {
- function CommentAreaWrapper(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- CommentAreaWrapper.prototype.videoId = "";
- CommentAreaWrapper.encode = function encode(m, w) {
- if (!w)
- w = $Writer.create();
- if (m.videoId != null && Object.hasOwnProperty.call(m, "videoId"))
- w.uint32(18).string(m.videoId);
- return w;
- };
- return CommentAreaWrapper;
- })();
- $root$2.MainCommentRequest = (() => {
- function MainCommentRequest(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- MainCommentRequest.prototype.commentParameters = null;
- MainCommentRequest.prototype.commentReplyParameters = null;
- MainCommentRequest.prototype.sectionIdentifier = "";
- MainCommentRequest.encode = function encode(m, w) {
- if (!w)
- w = $Writer.create();
- if (m.commentReplyParameters != null && Object.hasOwnProperty.call(m, "commentReplyParameters"))
- $root$2.CommentReplyParameters.encode(m.commentReplyParameters, w.uint32(26).fork()).ldelim();
- if (m.commentParameters != null && Object.hasOwnProperty.call(m, "commentParameters"))
- $root$2.CommentParameters.encode(m.commentParameters, w.uint32(34).fork()).ldelim();
- if (m.sectionIdentifier != null && Object.hasOwnProperty.call(m, "sectionIdentifier"))
- w.uint32(66).string(m.sectionIdentifier);
- return w;
- };
- return MainCommentRequest;
- })();
- $root$2.CommentParameters = (() => {
- function CommentParameters(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- CommentParameters.prototype.videoId = "";
- CommentParameters.prototype.postId = "";
- CommentParameters.prototype.channelId = "";
- CommentParameters.prototype.sortType = 0;
- CommentParameters.prototype.targetCommentId = "";
- CommentParameters.encode = function encode(m, w) {
- if (!w)
- w = $Writer.create();
- if (m.videoId != null && Object.hasOwnProperty.call(m, "videoId"))
- w.uint32(34).string(m.videoId);
- if (m.sortType != null && Object.hasOwnProperty.call(m, "sortType"))
- w.uint32(48).int32(m.sortType);
- if (m.targetCommentId != null && Object.hasOwnProperty.call(m, "targetCommentId"))
- w.uint32(130).string(m.targetCommentId);
- if (m.postId != null && Object.hasOwnProperty.call(m, "postId"))
- w.uint32(234).string(m.postId);
- if (m.channelId != null && Object.hasOwnProperty.call(m, "channelId"))
- w.uint32(242).string(m.channelId);
- return w;
- };
- CommentParameters.SortType = function() {
- const valuesById = {}, values = Object.create(valuesById);
- values[valuesById[0] = "HOT"] = 0;
- values[valuesById[1] = "LATEST"] = 1;
- return values;
- }();
- return CommentParameters;
- })();
- $root$2.CommentReplyParameters = (() => {
- function CommentReplyParameters(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- CommentReplyParameters.prototype.rootCommentId = "";
- CommentReplyParameters.prototype.channelId = "";
- CommentReplyParameters.prototype.videoId = "";
- CommentReplyParameters.prototype.postId = "";
- CommentReplyParameters.prototype.pageSize = 0;
- CommentReplyParameters.prototype.sortParam = null;
- CommentReplyParameters.encode = function encode(m, w) {
- if (!w)
- w = $Writer.create();
- if (m.rootCommentId != null && Object.hasOwnProperty.call(m, "rootCommentId"))
- w.uint32(18).string(m.rootCommentId);
- if (m.channelId != null && Object.hasOwnProperty.call(m, "channelId"))
- w.uint32(42).string(m.channelId);
- if (m.videoId != null && Object.hasOwnProperty.call(m, "videoId"))
- w.uint32(50).string(m.videoId);
- if (m.pageSize != null && Object.hasOwnProperty.call(m, "pageSize"))
- w.uint32(72).int32(m.pageSize);
- if (m.postId != null && Object.hasOwnProperty.call(m, "postId"))
- w.uint32(122).string(m.postId);
- if (m.sortParam != null && Object.hasOwnProperty.call(m, "sortParam"))
- $root$2.CommentReplyParameters.SortParam.encode(m.sortParam, w.uint32(130).fork()).ldelim();
- return w;
- };
- CommentReplyParameters.SortParam = function() {
- function SortParam(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- SortParam.prototype.sortType = 0;
- SortParam.encode = function encode(m, w) {
- if (!w)
- w = $Writer.create();
- if (m.sortType != null && Object.hasOwnProperty.call(m, "sortType"))
- w.uint32(8).int32(m.sortType);
- return w;
- };
- SortParam.SortType = function() {
- const valuesById = {}, values = Object.create(valuesById);
- values[valuesById[0] = "DEFAULT"] = 0;
- values[valuesById[1] = "HOT"] = 1;
- values[valuesById[2] = "LATEST"] = 2;
- return values;
- }();
- return SortParam;
- }();
- return CommentReplyParameters;
- })();
- const BrowserContinuation = $root$2.BrowserContinuation = (() => {
- function BrowserContinuation2(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- BrowserContinuation2.prototype.request = null;
- BrowserContinuation2.encode = function encode(m, w) {
- if (!w)
- w = $Writer.create();
- if (m.request != null && Object.hasOwnProperty.call(m, "request"))
- $root$2.BrowserContinuation.Request.encode(m.request, w.uint32(641815778).fork()).ldelim();
- return w;
- };
- BrowserContinuation2.Request = function() {
- function Request(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- Request.prototype.description = "";
- Request.prototype.continuationBase64 = "";
- Request.encode = function encode(m, w) {
- if (!w)
- w = $Writer.create();
- if (m.description != null && Object.hasOwnProperty.call(m, "description"))
- w.uint32(18).string(m.description);
- if (m.continuationBase64 != null && Object.hasOwnProperty.call(m, "continuationBase64"))
- w.uint32(26).string(m.continuationBase64);
- return w;
- };
- return Request;
- }();
- return BrowserContinuation2;
- })();
- const BrowserCommentListContinuation = $root$2.BrowserCommentListContinuation = (() => {
- function BrowserCommentListContinuation2(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- BrowserCommentListContinuation2.prototype.description = "";
- BrowserCommentListContinuation2.prototype.mainCommentRequest = null;
- BrowserCommentListContinuation2.encode = function encode(m, w) {
- if (!w)
- w = $Writer.create();
- if (m.description != null && Object.hasOwnProperty.call(m, "description"))
- w.uint32(18).string(m.description);
- if (m.mainCommentRequest != null && Object.hasOwnProperty.call(m, "mainCommentRequest"))
- $root$2.MainCommentRequest.encode(m.mainCommentRequest, w.uint32(426).fork()).ldelim();
- return w;
- };
- return BrowserCommentListContinuation2;
- })();
- const $Reader$1 = minimalExports.Reader;
- const $root$1 = minimalExports.roots["default"] || (minimalExports.roots["default"] = {});
- const CommentAction = $root$1.CommentAction = (() => {
- function CommentAction2(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- CommentAction2.prototype.action = 0;
- CommentAction2.prototype.commentId = "";
- CommentAction2.decode = function decode(r, l, e) {
- if (!(r instanceof $Reader$1))
- r = $Reader$1.create(r);
- var c = l === void 0 ? r.len : r.pos + l, m = new $root$1.CommentAction();
- while (r.pos < c) {
- var t = r.uint32();
- if (t === e)
- break;
- switch (t >>> 3) {
- case 1: {
- m.action = r.int32();
- break;
- }
- case 3: {
- m.commentId = r.string();
- break;
- }
- default:
- r.skipType(t & 7);
- break;
- }
- }
- return m;
- };
- return CommentAction2;
- })();
- $root$1.Action = (() => {
- const valuesById = {}, values = Object.create(valuesById);
- values[valuesById[0] = "DEFAULT"] = 0;
- values[valuesById[5] = "LIKE"] = 5;
- values[valuesById[6] = "DELETE"] = 6;
- return values;
- })();
- const $Reader = minimalExports.Reader;
- const $root = minimalExports.roots["default"] || (minimalExports.roots["default"] = {});
- const UpdateCommentParams = $root.UpdateCommentParams = (() => {
- function UpdateCommentParams2(p) {
- if (p) {
- for (var ks = Object.keys(p), i = 0; i < ks.length; ++i)
- if (p[ks[i]] != null)
- this[ks[i]] = p[ks[i]];
- }
- }
- UpdateCommentParams2.prototype.commentId = "";
- UpdateCommentParams2.decode = function decode(r, l, e) {
- if (!(r instanceof $Reader))
- r = $Reader.create(r);
- var c = l === void 0 ? r.len : r.pos + l, m = new $root.UpdateCommentParams();
- while (r.pos < c) {
- var t = r.uint32();
- if (t === e)
- break;
- switch (t >>> 3) {
- case 1: {
- m.commentId = r.string();
- break;
- }
- default:
- r.skipType(t & 7);
- break;
- }
- }
- return m;
- };
- return UpdateCommentParams2;
- })();
- var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
- var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
- const cssLoader = (e) => {
- const t = GM_getResourceText(e);
- return GM_addStyle(t), t;
- };
- cssLoader("element-plus/dist/index.css");
- const _hoisted_1$1 = {
- key: 0,
- class: "hot-ban-checker"
- };
- const _hoisted_2$1 = { class: "message" };
- const _hoisted_3$1 = { class: "buttons" };
- const _hoisted_4$1 = { class: "actions" };
- const _sfc_main$1 = {
- __name: "CommentActions",
- props: ["comment"],
- emits: ["delete", "checkHotBan"],
- setup(__props, { emit: __emit }) {
- const props = __props;
- const emit = __emit;
- const comment = props.comment;
- const check2 = vue.inject("check");
- const hotBanCheck2 = vue.inject("hotBanCheck");
- const updating = vue.ref(false);
- const showHotBanChecker = vue.ref(false);
- const hotBanCheckerMessage = vue.ref("等待检查中……");
- let hotBanCheckerController = vue.reactive({ isCancelled: false });
- function updateState() {
- updating.value = true;
- check2(comment).then(() => {
- updating.value = false;
- ElementPlus.ElMessage({
- type: comment.currentState == "NORMAL" ? "success" : "warning",
- message: "更新成功,当前状态:" + translateState(comment.currentState)
- });
- }).catch((err) => {
- updating.value = false;
- let msg = err.message;
- if (msg == "COMMENT_AREA_CLOSED") {
- msg = "评论区已关闭";
- }
- ElementPlus.ElMessage.error("更新失败,因为:" + msg);
- });
- }
- function copyComment(commentText) {
- if (navigator.clipboard) {
- navigator.clipboard.writeText(commentText).then(() => {
- ElementPlus.ElMessage({
- message: "评论已复制到剪贴板",
- type: "success"
- });
- }).catch((err) => {
- ElementPlus.ElMessage.error("无法复制文本,因为: " + err);
- });
- } else {
- const textArea = document.createElement("textarea");
- textArea.value = commentText;
- document.body.appendChild(textArea);
- textArea.select();
- try {
- document.execCommand("copy");
- ElementPlus.ElMessage({
- message: "评论已复制到剪贴板",
- type: "success"
- });
- } catch (err) {
- ElementPlus.ElMessage.error("无法复制文本,因为: " + err);
- }
- document.body.removeChild(textArea);
- }
- }
- function askDelete() {
- ElementPlus.ElMessageBox.confirm("确定要删除这条记录吗(这不会删除你在YouTube上发布的评论)?删除操作无法撤销!").then(() => {
- emit("delete");
- }).catch(() => {
- });
- }
- async function toHotBanCheck() {
- if (Date.now() - comment.recordedTime < 120 * 1e3) {
- ElementPlus.ElMessage.warning(`当前时间距评论记录时间不足2分钟,状态不可信,请到 ${formatTimestamp(comment.recordedTime + 120 * 1e3)} 来检查`);
- return;
- }
- if (comment.commentId.indexOf(".") == -1) {
- try {
- await ElementPlus.ElMessageBox.confirm(
- "确认检查吗?该检查需要遍历热门评论区,请注意评论区的评论数量(总数大于3000的评论区慎重考虑)!数量太多将导致漫长的检查过程,同时频繁调用API可能会引发不可预料的后果!",
- "警告",
- {
- confirmButtonText: "确定",
- cancelButtonText: "取消"
- }
- );
- } catch (err) {
- return;
- }
- }
- hotBanCheckerMessage.value = "正在重新检查评论状态……";
- hotBanCheckerController.isCancelled = false;
- showHotBanChecker.value = true;
- try {
- await check2(comment);
- if (comment.currentState != "NORMAL") {
- ElementPlus.ElMessage.error(`评论状态重新检查后为${translateState(comment.currentState)},无法继续进行检查`);
- showHotBanChecker.value = false;
- return;
- }
- } catch (err) {
- let msg = err.message;
- if (msg == "COMMENT_AREA_CLOSED") {
- msg = "评论区已关闭";
- }
- ElementPlus.ElMessage.error("检查失败,因为" + msg);
- showHotBanChecker.value = false;
- return;
- }
- let observer = {
- onCountChange(c, p) {
- hotBanCheckerMessage.value = `正在搜索热门列表,已搜寻至:第${c}个 第${p}页`;
- }
- };
- let notCancelled;
- try {
- notCancelled = await hotBanCheck2(comment, observer, hotBanCheckerController);
- } catch (err) {
- showHotBanChecker.value = false;
- ElementPlus.ElMessage.error(err.message);
- return;
- }
- if (notCancelled) {
- if (comment.hotBan) {
- ElementPlus.ElMessage.warning("你的评论未在热门列表找到,已被热门屏蔽,检查完成");
- } else {
- ElementPlus.ElMessage.success("你的评论已在热门列表找到,没有被热门屏蔽,检查完成");
- }
- }
- showHotBanChecker.value = false;
- }
- return (_ctx, _cache) => {
- const _component_el_button = vue.resolveComponent("el-button");
- return vue.openBlock(), vue.createElementBlock("div", null, [
- showHotBanChecker.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [
- _cache[2] || (_cache[2] = vue.createElementVNode("div", { class: "title" }, "热门屏蔽检查", -1)),
- vue.createElementVNode("div", _hoisted_2$1, vue.toDisplayString(hotBanCheckerMessage.value), 1),
- vue.createElementVNode("div", _hoisted_3$1, [
- vue.createElementVNode("span", {
- onClick: _cache[0] || (_cache[0] = ($event) => vue.unref(hotBanCheckerController).isCancelled = true)
- }, "终止检查")
- ])
- ])) : vue.createCommentVNode("", true),
- vue.createElementVNode("div", _hoisted_4$1, [
- vue.unref(comment).isUserDelete == false ? (vue.openBlock(), vue.createBlock(_component_el_button, {
- key: 0,
- type: "primary",
- plain: "",
- onClick: updateState,
- loading: updating.value
- }, {
- default: vue.withCtx(() => _cache[3] || (_cache[3] = [
- vue.createTextVNode("更新状态")
- ])),
- _: 1,
- __: [3]
- }, 8, ["loading"])) : vue.createCommentVNode("", true),
- vue.unref(comment).currentState == "NORMAL" ? (vue.openBlock(), vue.createBlock(_component_el_button, {
- key: 1,
- type: "primary",
- plain: "",
- onClick: toHotBanCheck
- }, {
- default: vue.withCtx(() => _cache[4] || (_cache[4] = [
- vue.createTextVNode("热门屏蔽检查")
- ])),
- _: 1,
- __: [4]
- })) : vue.createCommentVNode("", true),
- vue.createVNode(_component_el_button, {
- type: "primary",
- plain: "",
- onClick: _cache[1] || (_cache[1] = ($event) => copyComment(vue.unref(comment).content))
- }, {
- default: vue.withCtx(() => _cache[5] || (_cache[5] = [
- vue.createTextVNode("复制")
- ])),
- _: 1,
- __: [5]
- }),
- vue.createVNode(_component_el_button, {
- type: "danger",
- plain: "",
- onClick: askDelete
- }, {
- default: vue.withCtx(() => _cache[6] || (_cache[6] = [
- vue.createTextVNode("删除记录")
- ])),
- _: 1,
- __: [6]
- })
- ])
- ]);
- };
- }
- };
- const CommentActions = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-e5341f8d"]]);
- const _hoisted_1 = { class: "detail" };
- const _hoisted_2 = { class: "info-table" };
- const _hoisted_3 = { class: "comment-content" };
- const _hoisted_4 = { key: 0 };
- const _hoisted_5 = { key: 3 };
- const _hoisted_6 = { class: "comment-content" };
- const _hoisted_7 = { class: "pagination" };
- const pageSize = 20;
- const _sfc_main = {
- __name: "App",
- setup(__props) {
- const dialogVisible = vue.ref(false);
- const menuListener = vue.inject("menuListener");
- const deleteComment2 = vue.inject("deleteComment");
- const db2 = vue.inject("db");
- const comments = vue.reactive([]);
- const loadingComments = vue.ref(false);
- const prevTime = vue.ref(null);
- const nextTime = vue.ref(null);
- var prevStack = [null];
- function loadComments(direction = "next") {
- loadingComments.value = true;
- comments.length = 0;
- let time = null;
- if (direction == "next") {
- time = nextTime.value;
- prevStack.push(time ? time : -1);
- prevTime.value = prevStack[prevStack.length - 2];
- } else if (direction == "prev") {
- time = prevStack[prevStack.length - 2];
- time = time == -1 ? null : time;
- prevStack.pop();
- prevTime.value = prevStack[prevStack.length - 2];
- }
- db2.transaction("comments").objectStore("comments").index("recordedTime").openCursor(time ? IDBKeyRange.upperBound(time) : null, "prev").onsuccess = (event) => {
- var cursor = event.target.result;
- if (cursor) {
- if (comments.length < pageSize) {
- comments.push(cursor.value);
- cursor.continue();
- } else {
- nextTime.value = cursor.value.recordedTime;
- loadingComments.value = false;
- }
- } else {
- nextTime.value = null;
- loadingComments.value = false;
- }
- };
- }
- menuListener.onOpenHistory = () => {
- dialogVisible.value = true;
- nextTime.value = null;
- prevStack = [null];
- loadComments();
- };
- function formatStateDesc(comment) {
- switch (comment.currentState) {
- case "NORMAL":
- if (comment.hotBan === true) {
- return "热门屏蔽";
- } else if (comment.hotBan === false) {
- return "完全正常";
- } else {
- return "正常";
- }
- case "DELETED":
- if (comment.isUserDelete) {
- return "用户删除";
- } else {
- return "已删除";
- }
- case "SHADOW_BAN":
- return "仅自己可见";
- case "NOT_CHECK":
- return "还未检查";
- }
- }
- function formatCommentArea(comment, needEmojiHead) {
- var commentAreaInfo = comment.commentAreaInfo;
- switch (comment.webPageType) {
- case "WEB_PAGE_TYPE_WATCH":
- return "📺 " + commentAreaInfo.videoId;
- case "WEB_PAGE_TYPE_BROWSE":
- return "📰" + commentAreaInfo.postId;
- }
- }
- function formatHotBan(hotBan) {
- if (hotBan == null) {
- return "未检查";
- }
- return hotBan ? "是" : "否";
- }
- function deleteCommentItem(comment) {
- deleteComment2(comment.commentId).then(() => {
- const index = comments.findIndex((item) => item.commentId == comment.commentId);
- if (index !== -1) {
- comments.splice(index, 1);
- ElementPlus.ElMessage.success("评论删除成功");
- }
- }).catch((err) => {
- ElementPlus.ElMessage.error("评论删除失败");
- console.error("delete comment from database failed", err);
- });
- }
- return (_ctx, _cache) => {
- const _component_el_table_column = vue.resolveComponent("el-table-column");
- const _component_el_link = vue.resolveComponent("el-link");
- const _component_el_table = vue.resolveComponent("el-table");
- const _component_el_button = vue.resolveComponent("el-button");
- const _component_el_dialog = vue.resolveComponent("el-dialog");
- return vue.openBlock(), vue.createElementBlock("div", null, [
- vue.createVNode(_component_el_dialog, {
- modelValue: dialogVisible.value,
- "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => dialogVisible.value = $event),
- "z-index": 3e3,
- title: "历史评论列表",
- width: "80%",
- style: { "height": "92vh" },
- "body-class": "dialog-body",
- "align-center": ""
- }, {
- default: vue.withCtx(() => [
- vue.createVNode(_component_el_table, {
- data: comments,
- "row-key": "commentId",
- height: "100%",
- class: "comment-list"
- }, {
- default: vue.withCtx(() => [
- vue.createVNode(_component_el_table_column, {
- prop: "content",
- label: "评论内容",
- align: "left",
- "show-overflow-tooltip": ""
- }),
- vue.createVNode(_component_el_table_column, {
- prop: "state",
- label: "当前状态",
- align: "center",
- width: "136",
- formatter: formatStateDesc
- }),
- vue.createVNode(_component_el_table_column, {
- prop: "recordedTime",
- label: "记录时间",
- align: "center",
- width: "160",
- formatter: (comment) => vue.unref(formatTimestamp)(comment.recordedTime)
- }, null, 8, ["formatter"]),
- vue.createVNode(_component_el_table_column, {
- prop: "area",
- label: "所在评论区",
- align: "center",
- width: "240"
- }, {
- default: vue.withCtx(({ row }) => [
- vue.createElementVNode("div", null, [
- vue.createVNode(_component_el_link, {
- type: "primary",
- href: row.url,
- class: vue.normalizeClass(["locate-link", { "post-locate-link": row.webPageType == "WEB_PAGE_TYPE_BROWSE" }])
- }, {
- default: vue.withCtx(() => [
- vue.createTextVNode(vue.toDisplayString(formatCommentArea(row)), 1)
- ]),
- _: 2
- }, 1032, ["href", "class"])
- ])
- ]),
- _: 1
- }),
- vue.createVNode(_component_el_table_column, { type: "expand" }, {
- default: vue.withCtx(({ row }) => [
- vue.createElementVNode("div", _hoisted_1, [
- vue.createElementVNode("table", _hoisted_2, [
- vue.createElementVNode("tbody", null, [
- vue.createElementVNode("tr", null, [
- _cache[3] || (_cache[3] = vue.createElementVNode("td", null, "评论内容", -1)),
- vue.createElementVNode("td", _hoisted_3, vue.toDisplayString(row.content), 1)
- ]),
- vue.createElementVNode("tr", null, [
- _cache[4] || (_cache[4] = vue.createElementVNode("td", null, "当前状态", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(vue.unref(translateState)(row.currentState)), 1)
- ]),
- row.currentState == "DELETED" ? (vue.openBlock(), vue.createElementBlock("tr", _hoisted_4, [
- _cache[5] || (_cache[5] = vue.createElementVNode("td", null, "用户删除", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(row.isUserDelete ? "是" : "否"), 1)
- ])) : vue.createCommentVNode("", true),
- vue.createElementVNode("tr", null, [
- _cache[6] || (_cache[6] = vue.createElementVNode("td", null, "热门屏蔽", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(formatHotBan(row.hotBan)), 1)
- ]),
- vue.createElementVNode("tr", null, [
- _cache[7] || (_cache[7] = vue.createElementVNode("td", null, "发送者", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(row.displayName), 1)
- ]),
- vue.createElementVNode("tr", null, [
- _cache[8] || (_cache[8] = vue.createElementVNode("td", null, "评论ID", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(row.commentId), 1)
- ]),
- row.webPageType == "WEB_PAGE_TYPE_WATCH" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 1 }, [
- _cache[10] || (_cache[10] = vue.createElementVNode("tr", null, [
- vue.createElementVNode("td", null, "评论区类型"),
- vue.createElementVNode("td", null, "视频")
- ], -1)),
- vue.createElementVNode("tr", null, [
- _cache[9] || (_cache[9] = vue.createElementVNode("td", null, "视频ID", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(row.commentAreaInfo.videoId), 1)
- ])
- ], 64)) : row.webPageType == "WEB_PAGE_TYPE_BROWSE" ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
- _cache[13] || (_cache[13] = vue.createElementVNode("tr", null, [
- vue.createElementVNode("td", null, "评论区类型"),
- vue.createElementVNode("td", null, "帖子")
- ], -1)),
- vue.createElementVNode("tr", null, [
- _cache[11] || (_cache[11] = vue.createElementVNode("td", null, "帖子所属频道ID", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(row.commentAreaInfo.channelId), 1)
- ]),
- vue.createElementVNode("tr", null, [
- _cache[12] || (_cache[12] = vue.createElementVNode("td", null, "帖子ID", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(row.commentAreaInfo.postId), 1)
- ])
- ], 64)) : vue.createCommentVNode("", true),
- vue.createElementVNode("tr", null, [
- _cache[14] || (_cache[14] = vue.createElementVNode("td", null, "点赞数", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(row.likeCount), 1)
- ]),
- row.commentId.indexOf(".") == -1 ? (vue.openBlock(), vue.createElementBlock("tr", _hoisted_5, [
- _cache[15] || (_cache[15] = vue.createElementVNode("td", null, "回复数", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(row.replyCount), 1)
- ])) : vue.createCommentVNode("", true),
- vue.createElementVNode("tr", null, [
- _cache[16] || (_cache[16] = vue.createElementVNode("td", null, "记录时间", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(vue.unref(formatTimestamp)(row.recordedTime)), 1)
- ]),
- vue.createElementVNode("tr", null, [
- _cache[17] || (_cache[17] = vue.createElementVNode("td", null, "更新时间", -1)),
- vue.createElementVNode("td", null, vue.toDisplayString(vue.unref(formatTimestamp)(row.updatedTime)), 1)
- ])
- ])
- ]),
- vue.createElementVNode("details", null, [
- _cache[18] || (_cache[18] = vue.createElementVNode("summary", null, "历史检查记录", -1)),
- vue.createVNode(_component_el_table, {
- data: row.histories,
- style: { "width": "100%" }
- }, {
- default: vue.withCtx(() => [
- vue.createVNode(_component_el_table_column, {
- prop: "time",
- label: "时间戳",
- width: "160",
- formatter: (history) => vue.unref(formatTimestamp)(history.time)
- }, null, 8, ["formatter"]),
- vue.createVNode(_component_el_table_column, {
- prop: "state",
- label: "状态",
- width: "136",
- formatter: (history) => vue.unref(translateState)(history.state)
- }, null, 8, ["formatter"]),
- vue.createVNode(_component_el_table_column, {
- prop: "hotBan",
- label: "热门屏蔽",
- width: "120",
- formatter: (history) => formatHotBan(history.hotBan)
- }, null, 8, ["formatter"]),
- vue.createVNode(_component_el_table_column, {
- prop: "content",
- label: "评论内容",
- "show-overflow-tooltip": ""
- }),
- vue.createVNode(_component_el_table_column, { type: "expand" }, {
- default: vue.withCtx(({ row: row2 }) => [
- vue.createElementVNode("div", _hoisted_6, vue.toDisplayString(row2.content), 1)
- ]),
- _: 2
- }, 1024)
- ]),
- _: 2
- }, 1032, ["data"])
- ]),
- vue.createVNode(CommentActions, {
- comment: row,
- onDelete: ($event) => deleteCommentItem(row)
- }, null, 8, ["comment", "onDelete"])
- ])
- ]),
- _: 1
- })
- ]),
- _: 1
- }, 8, ["data"]),
- vue.createElementVNode("div", _hoisted_7, [
- prevTime.value ? (vue.openBlock(), vue.createBlock(_component_el_button, {
- key: 0,
- onClick: _cache[0] || (_cache[0] = ($event) => loadComments("prev")),
- disabled: loadingComments.value
- }, {
- default: vue.withCtx(() => [
- vue.createTextVNode("< " + vue.toDisplayString(prevTime.value == -1 ? "NOW" : vue.unref(formatTimestamp)(prevTime.value)), 1)
- ]),
- _: 1
- }, 8, ["disabled"])) : vue.createCommentVNode("", true),
- nextTime.value ? (vue.openBlock(), vue.createBlock(_component_el_button, {
- key: 1,
- onClick: _cache[1] || (_cache[1] = ($event) => loadComments("next")),
- disabled: loadingComments.value
- }, {
- default: vue.withCtx(() => [
- vue.createTextVNode(vue.toDisplayString(vue.unref(formatTimestamp)(nextTime.value)) + " >", 1)
- ]),
- _: 1
- }, 8, ["disabled"])) : vue.createCommentVNode("", true)
- ])
- ]),
- _: 1
- }, 8, ["modelValue"])
- ]);
- };
- }
- };
- const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-ff4696c9"]]);
- const originalFetch = _unsafeWindow.fetch;
- var authorizationCache = null;
- var contextCache = null;
- var trueLoaded = false;
- var db = null;
- const checkingCommentIdSet = /* @__PURE__ */ new Set();
- function waitForElement(observeSelector, targetSelector) {
- return new Promise((resolve) => {
- const parent = document.querySelector(observeSelector);
- if (!parent) return;
- const found = parent.querySelector(targetSelector);
- if (found) {
- resolve(found);
- return;
- }
- const observer = new MutationObserver(() => {
- const el = parent.querySelector(targetSelector);
- if (el) {
- observer.disconnect();
- resolve(el);
- }
- });
- observer.observe(parent, { childList: true, subtree: true });
- });
- }
- async function findComment(commentRecord, isLogin = true) {
- let continuation;
- let requestUrl;
- if (commentRecord.webPageType == "WEB_PAGE_TYPE_WATCH") {
- let payload = {
- uField3: 6,
- commentAreaWrapper: {
- videoId: commentRecord.commentAreaInfo.videoId
- },
- mainCommentRequest: {
- sectionIdentifier: "comments-section",
- commentParameters: {
- videoId: commentRecord.commentAreaInfo.videoId,
- targetCommentId: commentRecord.commentId
- }
- }
- };
- let encoded = NextContinuation.encode(payload);
- let buffer = encoded.finish();
- continuation = btoa(String.fromCharCode(...buffer));
- continuation = standardBase64ToUrlSafe(continuation);
- requestUrl = "https://www.youtube.com/youtubei/v1/next?prettyPrint=false";
- } else if (commentRecord.webPageType == "WEB_PAGE_TYPE_BROWSE") {
- let payload = {
- description: "community",
- mainCommentRequest: {
- sectionIdentifier: "comments-section",
- commentParameters: {
- channelId: commentRecord.commentAreaInfo.channelId,
- postId: commentRecord.commentAreaInfo.postId,
- targetCommentId: commentRecord.commentId
- }
- }
- };
- let encoded = BrowserCommentListContinuation.encode(payload);
- let buffer = encoded.finish();
- continuation = btoa(String.fromCharCode(...buffer));
- continuation = standardBase64ToUrlSafe(continuation);
- payload = {
- request: {
- description: "FEcomment_post_detail_page_web_top_level",
- continuationBase64: continuation
- }
- };
- encoded = BrowserContinuation.encode(payload);
- buffer = encoded.finish();
- continuation = btoa(String.fromCharCode(...buffer));
- continuation = standardBase64ToUrlSafe(continuation);
- requestUrl = "https://www.youtube.com/youtubei/v1/browse?prettyPrint=false";
- } else {
- throw new Error("Unsupported webPageType : " + commentRecord.webPageType);
- }
- let data = {
- context: contextCache,
- continuation
- };
- let headers = {};
- if (isLogin) {
- headers.authorization = authorizationCache;
- }
- let options = {
- method: "POST",
- body: JSON.stringify(data),
- headers
- };
- let response = await (await originalFetch(requestUrl, options)).json();
- let loggedOut = response.responseContext.mainAppWebResponseContext.loggedOut;
- if (loggedOut == isLogin) {
- console.warn("登录(不可用)状态不符,需要的:" + isLogin + " API返回的:" + !loggedOut);
- }
- if (!response.frameworkUpdates) {
- throw new Error("COMMENT_AREA_CLOSED");
- }
- let mutations = response.frameworkUpdates.entityBatchUpdate.mutations;
- for (let i = 0; i < mutations.length; i++) {
- let mutation = mutations[i];
- if (mutation.payload.commentEntityPayload) {
- let entity = mutation.payload.commentEntityPayload;
- let commentId = entity.properties.commentId;
- if (commentId == commentRecord.commentId) {
- let likeCount = parseInt(entity.toolbar.likeCountNotliked);
- likeCount = likeCount ? likeCount : 0;
- let replyCount = parseInt(entity.toolbar.replyCount);
- replyCount = replyCount ? replyCount : 0;
- return {
- content: entity.properties.content.content,
- commentId,
- likeCount,
- replyCount
- };
- }
- }
- }
- }
- async function insertComment() {
- }
- async function updateComment() {
- }
- async function selectComment() {
- }
- async function deleteComment() {
- }
- function appendHistory(commentRecord) {
- let histories = commentRecord.histories;
- let needPush = false;
- if (histories.length == 0) {
- needPush = true;
- } else {
- let lastHistory = histories[histories.length - 1];
- needPush = lastHistory.state != commentRecord.currentState || lastHistory.content != commentRecord.content || lastHistory.hotBan != commentRecord.hotBan;
- }
- if (needPush) {
- histories.push({
- time: commentRecord.updatedTime,
- content: commentRecord.content,
- state: commentRecord.currentState,
- hotBan: commentRecord.hotBan
- });
- }
- }
- function updateRecord(commentRecord, state, result) {
- commentRecord.updatedTime = Date.now();
- if (state) {
- commentRecord.currentState = state;
- }
- if (result) {
- commentRecord.likeCount = result.likeCount;
- commentRecord.replyCount = result.replyCount;
- commentRecord.content = result.content;
- }
- appendHistory(commentRecord);
- updateComment(commentRecord);
- }
- async function check(commentRecord) {
- let loggedOutResult = await findComment(commentRecord, false);
- if (loggedOutResult) {
- updateRecord(commentRecord, "NORMAL", loggedOutResult);
- return;
- }
- let loggedInResult = await findComment(commentRecord, true);
- if (loggedInResult) {
- updateRecord(commentRecord, "SHADOW_BAN", loggedInResult);
- } else {
- updateRecord(commentRecord, "DELETED");
- }
- }
- async function toCheck(commentRecord) {
- checkingCommentIdSet.add(commentRecord.commentId);
- let selector;
- if (window.location.pathname.startsWith("/channel")) {
- selector = "ytd-item-section-renderer#sections";
- } else {
- selector = "#comments";
- }
- let element = (await waitForElement(selector, `a[href='${commentRecord.url}']`)).parentNode.parentNode.parentNode.parentNode;
- let div = document.createElement("div");
- div.style.marginTop = "8px";
- div.id = "checker";
- element.append(div);
- let app = vue.createApp(CommentChecker);
- app.use(ElementPlus);
- app.provide("check", check);
- app.provide("hotBanCheck", hotBanCheck);
- app.provide("commentRecord", commentRecord);
- app.provide("interval", 5);
- app.provide("onUnblock", (commentRecord2) => {
- checkingCommentIdSet.delete(commentRecord2.commentId);
- });
- app.provide("onClose", (commentRecord2) => {
- checkingCommentIdSet.delete(commentRecord2.commentId);
- console.log("评论检查完成", commentRecord2);
- div.remove();
- });
- app.mount(div);
- }
- function createCommentListRequest(commentRecord, isLatestSort) {
- let api;
- let continuation;
- if (commentRecord.webPageType == "WEB_PAGE_TYPE_WATCH") {
- api = "https://www.youtube.com/youtubei/v1/next?prettyPrint=false";
- if (commentRecord.commentId.indexOf(".") != -1) {
- let rootCommentId = commentRecord.commentId.split(".")[0];
- let payload = {
- uField3: 6,
- commentAreaWrapper: {
- videoId: commentRecord.commentAreaInfo.videoId
- },
- mainCommentRequest: {
- sectionIdentifier: `comment-replies-item-${rootCommentId}`,
- commentReplyParameters: {
- rootCommentId,
- channelId: commentRecord.commentAreaInfo.channelId,
- videoId: commentRecord.commentAreaInfo.videoId,
- pageSize: 10,
- sortParam: {
- sortType: 1
- }
- }
- }
- };
- let encoded = NextContinuation.encode(payload);
- let buffer = encoded.finish();
- continuation = btoa(String.fromCharCode(...buffer));
- continuation = standardBase64ToUrlSafe(continuation);
- } else {
- let payload = {
- uField3: 6,
- commentAreaWrapper: {
- videoId: commentRecord.commentAreaInfo.videoId
- },
- mainCommentRequest: {
- sectionIdentifier: "comments-section",
- commentParameters: {
- videoId: commentRecord.commentAreaInfo.videoId,
- sortType: 0
- }
- }
- };
- let encoded = NextContinuation.encode(payload);
- let buffer = encoded.finish();
- continuation = btoa(String.fromCharCode(...buffer));
- continuation = standardBase64ToUrlSafe(continuation);
- }
- } else if (commentRecord.webPageType == "WEB_PAGE_TYPE_BROWSE") {
- api = "https://www.youtube.com/youtubei/v1/browse?prettyPrint=false";
- if (commentRecord.commentId.indexOf(".") != -1) {
- let rootCommentId = commentRecord.commentId.split(".")[0];
- let payload = {
- description: "community",
- mainCommentRequest: {
- sectionIdentifier: `comment-replies-item-${rootCommentId}`,
- commentReplyParameters: {
- rootCommentId,
- channelId: commentRecord.commentAreaInfo.channelId,
- postId: commentRecord.commentAreaInfo.postId,
- pageSize: 10,
- sortParam: {
- sortType: 1
- }
- }
- }
- };
- let encoded = BrowserCommentListContinuation.encode(payload);
- let buffer = encoded.finish();
- continuation = btoa(String.fromCharCode(...buffer));
- continuation = standardBase64ToUrlSafe(continuation);
- payload = {
- request: {
- description: "FEcomment_post_detail_page_web_replies_page",
- continuationBase64: continuation
- }
- };
- encoded = BrowserContinuation.encode(payload);
- buffer = encoded.finish();
- continuation = btoa(String.fromCharCode(...buffer));
- continuation = standardBase64ToUrlSafe(continuation);
- } else {
- let payload = {
- description: "community",
- mainCommentRequest: {
- sectionIdentifier: "comments-section",
- commentParameters: {
- channelId: commentRecord.commentAreaInfo.channelId,
- postId: commentRecord.commentAreaInfo.postId,
- sortType: 0
- }
- }
- };
- let encoded = BrowserCommentListContinuation.encode(payload);
- let buffer = encoded.finish();
- continuation = btoa(String.fromCharCode(...buffer));
- continuation = standardBase64ToUrlSafe(continuation);
- payload = {
- request: {
- description: "FEcomment_post_detail_page_web_top_level",
- continuationBase64: continuation
- }
- };
- encoded = BrowserContinuation.encode(payload);
- buffer = encoded.finish();
- continuation = btoa(String.fromCharCode(...buffer));
- continuation = standardBase64ToUrlSafe(continuation);
- }
- }
- return { api, continuation };
- }
- async function hotBanCheck(commentRecord, observer, controller) {
- var _a, _b, _c, _d, _e;
- if (!observer) {
- observer = {
- onCountChange(c, p) {
- }
- };
- }
- if (!controller) {
- controller = {
- isCancelled: false
- };
- }
- let pageCpunt = 0;
- let commentCount = 0;
- let { api, continuation } = createCommentListRequest(commentRecord);
- while (continuation) {
- if (controller.isCancelled) {
- return false;
- }
- let data = {
- context: contextCache,
- continuation
- };
- let options = {
- method: "POST",
- body: JSON.stringify(data)
- };
- let response = await (await originalFetch(api, options)).json();
- pageCpunt++;
- if (!response.frameworkUpdates) {
- commentRecord.hotBan = true;
- updateRecord(commentRecord);
- return true;
- }
- for (let mutation of response.frameworkUpdates.entityBatchUpdate.mutations) {
- let entity = mutation.payload.commentEntityPayload;
- if (entity) {
- let commentId = entity.properties.commentId;
- commentCount++;
- observer.onCountChange(commentCount, pageCpunt);
- if (commentId == commentRecord.commentId) {
- commentRecord.hotBan = false;
- updateRecord(commentRecord);
- return true;
- }
- }
- }
- continuation = null;
- for (const endpoint of response.onResponseReceivedEndpoints) {
- const items = ((_a = endpoint.appendContinuationItemsAction) == null ? void 0 : _a.continuationItems) || ((_b = endpoint.reloadContinuationItemsCommand) == null ? void 0 : _b.continuationItems);
- if (!items) continue;
- for (const item of items) {
- const token = (_e = (_d = (_c = item.continuationItemRenderer) == null ? void 0 : _c.continuationEndpoint) == null ? void 0 : _d.continuationCommand) == null ? void 0 : _e.token;
- if (token) {
- continuation = token;
- break;
- }
- }
- if (continuation) break;
- }
- }
- commentRecord.hotBan = true;
- updateRecord(commentRecord);
- return true;
- }
- async function handlerYoutubei(request) {
- let requsetClone = request.clone();
- let requestBody = await requsetClone.json();
- if (requestBody && requestBody.context) {
- contextCache = requestBody.context;
- if (!trueLoaded) {
- console.log("fetch已成功劫持");
- _GM_registerMenuCommand("✅ 脚本已完全加载");
- trueLoaded = true;
- }
- }
- if (request.url.startsWith("https://www.youtube.com/youtubei/v1/comment/create_comment")) {
- let response = await originalFetch(request);
- if (response.status != 200) {
- return response;
- }
- let responseClone = response.clone();
- try {
- let json = await responseClone.json();
- if (json.frameworkUpdates.entityBatchUpdate.mutations.length == 1) {
- return response;
- }
- let entity = json.frameworkUpdates.entityBatchUpdate.mutations[0].payload.commentEntityPayload;
- let innertubeCommand = json.frameworkUpdates.entityBatchUpdate.mutations[1].payload.commentSurfaceEntityPayload.publishedTimeCommand.innertubeCommand;
- let webCommandMetadata = innertubeCommand.commandMetadata.webCommandMetadata;
- let webPageType = webCommandMetadata.webPageType;
- let url = webCommandMetadata.url;
- let commentAreaInfo = {};
- if (webPageType == "WEB_PAGE_TYPE_WATCH") {
- commentAreaInfo.videoId = innertubeCommand.watchEndpoint.videoId;
- commentAreaInfo.channelId = json.actions[0].runAttestationCommand.ids[2].externalChannelId;
- } else if (webPageType == "WEB_PAGE_TYPE_BROWSE") {
- commentAreaInfo.channelId = url.split("/")[2];
- commentAreaInfo.postId = createUrl(url).searchParams.get("lb");
- }
- let author = entity.author;
- let properties = entity.properties;
- let content = properties.content.content;
- let recordedTime = Date.now();
- let commentRecord = {
- //评论ID
- commentId: properties.commentId,
- //@发送者
- displayName: author.displayName,
- //频道ID,类似UID
- channelId: author.channelId,
- //评论内容
- content,
- //webPageType 评论区类型 视频 or 帖子
- webPageType,
- //URL 点击可跳转“所要查看的评论” 例如 /watch?v=${视频ID}&lc=${评论ID}
- url,
- //评论区信息,视频{视频ID},帖子{频道ID,帖子ID}
- commentAreaInfo,
- //当前状态 默认从SHADOW_BAN开始,到NORMAL或DELETED
- currentState: "NOT_CHECK",
- //是否在热门排序中被禁止显示(搜索整个热门评论区来检查),前提条件currentState = "NORMAL",值:null | false | true
- //此状态不会因为修改评论内容而解除,但会因为修改评论内容而赋予
- hotBan: null,
- //历史记录,时间 内容 状态 是否热门屏蔽
- histories: [],
- //{ time: recordedTime, state: "SHADOW_BAN", content, hotBan: null }
- //点赞与回复数,不记录历史
- likeCount: 0,
- replyCount: 0,
- //记录的时间,用的是系统当前时间,约等于评论的发布时间,API里的publishedTime距离发布时间戳多久的Shit不是时间戳(PS:YouTube开放API可查询具体发布时间戳)
- recordedTime,
- //更新时间
- updatedTime: recordedTime,
- //是否是用户自己执行的删除?用于区分是被系统删的还是自己删除。state为"DELETED"时该属性为才有意义。(劫持删除评论请求时记录)
- isUserDelete: false
- };
- console.log(commentRecord);
- insertComment(commentRecord);
- console.log(createUrl(url).href);
- toCheck(commentRecord);
- } catch (err) {
- console.error(err);
- throw err;
- }
- return response;
- } else if (request.url.startsWith("https://www.youtube.com/youtubei/v1/comment/perform_comment_action")) {
- let actionBase64 = urlSafeBase64ToStandard(requestBody.actions[0]);
- let actionInfo = CommentAction.decode(Uint8Array.from(atob(actionBase64), (c) => c.charCodeAt(0)));
- if (actionInfo.action == 6) {
- if (checkingCommentIdSet.has(actionInfo.commentId)) {
- alert("现在不能删除该评论,因为评论还未完成检查,请先完成检查!");
- const responseBody = {
- "error": {
- "code": 403,
- "message": "Can't delete comment now",
- "errors": [
- {
- "message": "Can't delete comment now",
- "domain": "global",
- "reason": "forbidden"
- }
- ],
- "status": "FORBIDDEN"
- }
- };
- return new Response(JSON.stringify(responseBody), {
- status: 403,
- headers: {
- "Content-Type": "application/json"
- }
- });
- } else {
- let response = await originalFetch(request);
- let responseBody = await response.clone().json();
- if (responseBody.actions && responseBody.actions[0].removeCommentAction.actionResult.status == "STATUS_SUCCEEDED") {
- let commentRecord = await selectComment(actionInfo.commentId);
- if (commentRecord) {
- commentRecord.isUserDelete = true;
- updateRecord(commentRecord, "DELETED");
- }
- }
- return response;
- }
- }
- } else if (request.url.startsWith("https://www.youtube.com/youtubei/v1/comment/update_comment")) {
- let updateCommentParams = urlSafeBase64ToStandard(requestBody.updateCommentParams);
- let decodedParams = UpdateCommentParams.decode(Uint8Array.from(atob(updateCommentParams), (c) => c.charCodeAt(0)));
- if (checkingCommentIdSet.has(decodedParams.commentId)) {
- alert("现在不能修改该评论,因为评论还未完成检查,请先完成检查!");
- const responseBody2 = {
- "error": {
- "code": 403,
- "message": "Can't edit comment now",
- "errors": [
- {
- "message": "Can't edit comment now",
- "domain": "global",
- "reason": "forbidden"
- }
- ],
- "status": "FORBIDDEN"
- }
- };
- return new Response(JSON.stringify(responseBody2), {
- status: 403,
- headers: {
- "Content-Type": "application/json"
- }
- });
- }
- let response = await originalFetch(request);
- let responseBody = await response.clone().json();
- if (responseBody.actions && responseBody.actions[0].updateCommentAction.actionResult.status == "STATUS_SUCCEEDED") {
- let commentRecord = await selectComment(decodedParams.commentId);
- if (commentRecord) {
- commentRecord.content = requestBody.commentText;
- commentRecord.currentState = "NOT_CHECK";
- commentRecord.hotBan = null;
- updateRecord(commentRecord);
- }
- }
- return response;
- }
- return await originalFetch(request);
- }
- const fetchProxy = function(resource, options) {
- if (typeof resource == "string") {
- return originalFetch(resource, options);
- }
- if (!resource.url.startsWith("https://www.youtube.com/youtubei/")) {
- return originalFetch(resource, options);
- }
- let auth = resource.headers.get("Authorization");
- if (auth) {
- authorizationCache = auth;
- if (resource.method != "POST") {
- return originalFetch(resource);
- } else {
- return handlerYoutubei(resource);
- }
- }
- return originalFetch(resource, options);
- };
- try {
- _unsafeWindow.fetch = fetchProxy;
- } catch (err) {
- console.warn("替换 unsafeWindow.fetch 失败!相关信息:", err, Object.getOwnPropertyDescriptor(_unsafeWindow, "fetch"));
- if (confirm("fetch已被提前锁定,替换失败,YouTube发评反诈可能无法正常工作。\n你可以安装本项目的 Define property blocker 插件来反制锁定。\n\n点击“确定”前往项目地址,点击“取消”忽略。")) {
- window.location.href = "https://github.com/freedom-introvert/youtube-comment-censor-detector";
- }
- }
- const _createElement = Document.prototype.createElement;
- Document.prototype.createElement = function(tagName, ...args) {
- const el = _createElement.call(this, tagName, ...args);
- if (tagName.toLowerCase() === "iframe") {
- el.addEventListener("load", () => {
- var _a;
- try {
- const fetchFromIframe = (_a = el.contentWindow) == null ? void 0 : _a.fetch;
- if (fetchFromIframe) {
- el.contentWindow.fetch = fetchProxy;
- console.log("已替换iframe window的fetch", el);
- }
- } catch (e) {
- console.log("未替换该iframe的fetch", el, e);
- }
- });
- }
- return el;
- };
- function openDB() {
- return new Promise((resolve, reject) => {
- let request = indexedDB.open("YT-CCD", 1);
- request.onerror = (event) => {
- reject(event);
- };
- request.onsuccess = (event) => {
- resolve(event.target.result);
- };
- request.onupgradeneeded = (event) => {
- let db2 = event.target.result;
- let objectStore = db2.createObjectStore("comments", { keyPath: "commentId" });
- objectStore.createIndex("recordedTime", "recordedTime", { unique: false });
- };
- });
- }
- async function init() {
- try {
- db = await openDB();
- insertComment = function(comment) {
- return new Promise((resolve, reject) => {
- let request = db.transaction("comments", "readwrite").objectStore("comments").add(comment);
- request.onsuccess = (event) => {
- resolve(event);
- };
- request.onerror = (event) => {
- reject(event);
- };
- });
- };
- updateComment = function(comment) {
- return new Promise((resolve, reject) => {
- let request = db.transaction("comments", "readwrite").objectStore("comments").put(vue.toRaw(comment));
- request.onsuccess = (event) => {
- resolve(event);
- };
- request.onerror = (event) => {
- reject(event);
- };
- });
- };
- selectComment = function(commentId) {
- return new Promise((resolve, reject) => {
- let request = db.transaction("comments").objectStore("comments").get(commentId);
- request.onsuccess = (event) => {
- resolve(request.result);
- };
- request.onerror = (event) => {
- reject(event);
- };
- });
- };
- deleteComment = function(commentId) {
- return new Promise((resolve, reject) => {
- let request = db.transaction("comments", "readwrite").objectStore("comments").delete(commentId);
- request.onsuccess = (event) => {
- resolve(request.result);
- };
- request.onerror = (event) => {
- reject(event);
- };
- });
- };
- } catch (err) {
- console.log("indexedDB数据库打开失败,评论历史记录相关功能已禁用,错误信息:", err);
- }
- const menuListener = {
- onOpenHistory: () => {
- alert("脚本正在初始化,请稍后……");
- }
- };
- _GM_registerMenuCommand("🧾 历史评论记录", () => {
- menuListener.onOpenHistory();
- });
- const div = document.createElement("div");
- div.id = "yt-ccd";
- div.style.position = "absolute";
- document.body.append(div);
- let app = vue.createApp(App);
- app.use(ElementPlus);
- app.provide("menuListener", menuListener);
- app.provide("db", db);
- app.provide("check", check);
- app.provide("hotBanCheck", hotBanCheck);
- app.provide("deleteComment", deleteComment);
- app.mount(div);
- }
- window.addEventListener("load", () => {
- init().then(() => {
- console.log("YouTube反诈加载完成");
- }).catch((err) => {
- console.error("YouTube反诈加载失败", err);
- });
- });
- })(Vue, ElementPlus);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址