// ==UserScript== // @name RSSHub 订阅助手 // @name:en RSSHub Subscription Helper // @name:zh-CN RSSHub 订阅助手 // @namespace github.com/chlorinec/rsshub-monkey-helper // @version 1.0.0 // @author chlorinec // @description 快速生成并复制RSSHub订阅链接,支持Bilibili、YouTube、X等主流平台 // @description:en Quickly generate and copy RSSHub subscription links for Bilibili, YouTube, X, and more. // @description:zh-CN 快速生成并复制RSSHub订阅链接,支持Bilibili、YouTube、X等主流平台 // @license MIT // @icon https://docs.rsshub.app/logo.png // @homepage https://github.com/chlorinec/rsshub-monkey-helper // @homepageURL https://github.com/chlorinec/rsshub-monkey-helper // @source https://github.com/chlorinec/rsshub-monkey-helper.git // @supportURL https://github.com/chlorinec/rsshub-monkey-helper/issues // @match https://www.bilibili.com/* // @match https://space.bilibili.com/* // @match https://www.youtube.com/* // @match https://youtube.com/* // @match https://x.com/* // @match https://twitter.com/* // @grant GM_addElement // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // @grant GM_xmlhttpRequest // @run-at document-end // @noframes // @downloadURL none // ==/UserScript== (function () { 'use strict'; const d=new Set;const importCSS = async e=>{d.has(e)||(d.add(e),(t=>{typeof GM_addStyle=="function"?GM_addStyle(t):document.head.appendChild(document.createElement("style")).append(t);})(e));}; importCSS(" ._fab_1ykjg_4{position:fixed;right:32px;bottom:32px;z-index:10000;width:56px;height:56px;background:var(--fab-bg, #fff);border-radius:50%;box-shadow:0 2px 12px #0000002e;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:box-shadow .2s;pointer-events:auto!important}._fab_1ykjg_4:hover{box-shadow:0 4px 24px #00000047}._panelBg_1ykjg_27{position:fixed;inset:0;background:#0000002e;z-index:2147483646;transition:background .2s}._dialog_1ykjg_38._panel_1ykjg_27{position:fixed;left:50%;top:50%;width:380px;min-height:220px;max-height:80vh;background:var(--panel-bg, #fff);box-shadow:0 8px 40px #00000038;z-index:2147483647;display:flex;flex-direction:column;border-radius:18px;overflow:hidden;animation:_dialogIn_1ykjg_1 .25s cubic-bezier(.4,2,.6,1);transition:box-shadow .2s,transform .25s cubic-bezier(.4,2,.6,1);-webkit-user-select:none;user-select:none;pointer-events:auto!important}@keyframes _dialogIn_1ykjg_1{0%{opacity:0;transform:scale(.85) translate(-50%,-50%)}to{opacity:1;transform:scale(1) translate(-50%,-50%)}}@keyframes _slideIn_1ykjg_1{0%{right:-340px}to{right:0}}._panelHeader_1ykjg_67{display:flex;align-items:center;gap:12px;padding:20px 24px 12px;border-bottom:1px solid var(--panel-border, #eee);font-size:20px;font-weight:600;color:var(--panel-header-color, #222)}._expandIcon_1ykjg_78{display:inline-flex;align-items:center;justify-content:center;font-size:15px;margin-top:2px;margin-left:2px;color:#888;transform:rotate(0);transition:transform .2s}@media (prefers-color-scheme: dark){:root{--fab-bg: #23272e;--panel-bg: #181a20;--panel-border: #23242a;--tab-color: #eee;--rule-bg: #23242a;--rule-title: #fff;--rule-desc: #bbb;--rule-link-bg: #23272e;--rule-link: #eee;--close-color: #aaa;--panel-header-color: #fff}}._closeBtn_1ykjg_104{margin-left:auto;background:none;border:none;font-size:24px;cursor:pointer;color:var(--close-color, #888);padding:0 2px}._closeBtn_1ykjg_104:hover{color:#f44336}._tabs_1ykjg_117{display:flex;gap:16px;padding:16px 24px 0}._tabs_1ykjg_117 button{background:none;border:none;padding:10px 10px 6px;border-radius:10px;display:flex;flex-direction:column;align-items:center;justify-content:center;min-width:64px;max-width:110px;gap:4px;font-size:15px;cursor:pointer;color:var(--tab-color, #333);transition:background .15s,color .15s;overflow:visible}._tabActive_1ykjg_140{background:#f9a82522;color:#f9a825;font-weight:600}._tabIcon_1ykjg_145{width:32px;height:32px;display:flex;align-items:center;justify-content:center;margin-bottom:2px}._tabName_1ykjg_153{width:100%;max-width:90px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:14px;font-weight:500;line-height:1.2;cursor:pointer;position:relative}._tabName_1ykjg_153:hover:after{content:attr(data-fullname);position:absolute;left:50%;top:120%;transform:translate(-50%);background:#222;color:#fff;padding:3px 10px;border-radius:6px;font-size:13px;white-space:pre;z-index:9999;box-shadow:0 2px 8px #0000002e;pointer-events:none}._rules_1ykjg_184{flex:1;overflow-y:auto;padding:20px 24px 32px}._toast_1ykjg_190{position:fixed;bottom:100px;right:40px;background:#222;color:#fff;padding:10px 22px;border-radius:8px;font-size:15px;z-index:2147483647;box-shadow:0 2px 12px #0000002e;animation:_fadeIn_1ykjg_1 .2s}@keyframes _fadeIn_1ykjg_1{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@media (prefers-color-scheme: dark){:root{--fab-bg: #23272e;--panel-bg: #181a20;--panel-border: #23242a;--tab-color: #eee;--rule-bg: #23242a;--rule-title: #fff;--rule-desc: #bbb;--rule-link-bg: #23272e;--rule-link: #eee;--close-color: #aaa}}._panelBg_1ay11_1{position:fixed;inset:0;background:#0000002e;z-index:2147483646;transition:background .2s}._dialog_1ay11_8._panel_1ay11_1{position:fixed;left:50%;top:50%;width:380px;min-height:220px;max-height:80vh;background:var(--panel-bg, #fff);box-shadow:0 8px 40px #00000038;z-index:2147483647;display:flex;flex-direction:column;border-radius:18px;overflow:hidden;animation:_dialogIn_1ay11_1 .25s cubic-bezier(.4,2,.6,1);transition:box-shadow .2s,transform .25s cubic-bezier(.4,2,.6,1);-webkit-user-select:none;user-select:none;pointer-events:auto!important}@keyframes _dialogIn_1ay11_1{0%{opacity:0;transform:scale(.85) translate(-50%,-50%)}to{opacity:1;transform:scale(1) translate(-50%,-50%)}}._panelHeader_1ay11_31{display:flex;align-items:center;gap:12px;padding:20px 24px 12px;border-bottom:1px solid var(--panel-border, #eee);font-size:20px;font-weight:600;color:var(--panel-header-color, #222)}._closeBtn_1ay11_41{margin-left:auto;background:none;border:none;font-size:24px;cursor:pointer;color:var(--close-color, #888);padding:0 2px}._closeBtn_1ay11_41:hover{color:#f44336}._tabs_1ay11_53{display:flex;gap:16px;padding:16px 24px 0}._tabs_1ay11_53 button{background:none;border:none;padding:10px 10px 6px;border-radius:10px;display:flex;flex-direction:column;align-items:center;justify-content:center;min-width:64px;max-width:110px;gap:4px;font-size:15px;cursor:pointer;color:var(--tab-color, #333);transition:background .15s,color .15s;overflow:visible}._tabActive_1ay11_76{background:#f9a82522;color:#f9a825;font-weight:600}._tabIcon_1ay11_81{width:32px;height:32px;display:flex;align-items:center;justify-content:center;margin-bottom:2px}._tabName_1ay11_89{width:100%;max-width:90px;text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:14px;font-weight:500;line-height:1.2;cursor:pointer;position:relative}._tabName_1ay11_89:hover:after{content:attr(data-fullname);position:absolute;left:50%;top:120%;transform:translate(-50%);background:#222;color:#fff;padding:3px 10px;border-radius:6px;font-size:13px;white-space:pre;z-index:9999;box-shadow:0 2px 8px #0000002e;pointer-events:none}._expandIcon_1ay11_118{display:inline-flex;align-items:center;justify-content:center;font-size:15px;margin-top:2px;margin-left:2px;color:#888;transform:rotate(0);transition:transform .2s}._rules_1ay11_129{flex:1;overflow-y:auto;padding:20px 24px 32px}._ruleItem_17zs6_1{background:var(--rule-bg, #fafbfc);border-radius:10px;margin-bottom:20px;padding:16px 16px 12px;box-shadow:0 1px 6px #0000000d;display:flex;flex-direction:column;gap:6px}._ruleTitle_17zs6_11{font-size:17px;font-weight:600;margin-bottom:2px;line-height:1.3}._ruleTitle_17zs6_11 a{color:var(--rule-title, #1f2328);text-decoration:none;transition:color .15s}._ruleTitle_17zs6_11 a:hover{color:#f9a825}._ruleDesc_17zs6_25{font-size:14px;color:var(--rule-desc, #666);margin-bottom:4px}._ruleCopyBox_17zs6_30{display:flex;align-items:center;gap:8px;width:100%;background:var(--rule-link-bg, #f3f3f3);border:none;border-radius:6px;padding:4px 12px 4px 10px;margin-top:6px;cursor:pointer;font-family:monospace;font-size:14px;color:var(--rule-link, #333);transition:background .15s,box-shadow .15s;-webkit-user-select:all;user-select:all;position:relative;outline:none}._ruleCopyBox_17zs6_30:hover,._ruleCopyBox_17zs6_30:focus{background:#ffe082;box-shadow:0 2px 8px #f9a82514}._ruleLink_17zs6_53{flex:1;text-align:left;background:none;padding:0;border:none;color:inherit;font-family:inherit;font-size:inherit;-webkit-user-select:all;user-select:all;overflow-x:auto}._copyIcon_17zs6_65{width:18px;height:18px;display:flex;align-items:center;justify-content:center;color:#f9a825;margin-left:6px} "); const IS_DEV = false; const equalFn = (a, b) => a === b; const $TRACK = Symbol("solid-track"); const signalOptions = { equals: equalFn }; let runEffects = runQueue; const STALE = 1; const PENDING = 2; const UNOWNED = { owned: null, cleanups: null, context: null, owner: null }; var Owner = null; let Transition = null; let ExternalSourceConfig = null; let Listener = null; let Updates = null; let Effects = null; let ExecCount = 0; function createRoot(fn, detachedOwner) { const listener = Listener, owner = Owner, unowned = fn.length === 0, current = detachedOwner === void 0 ? owner : detachedOwner, root = unowned ? UNOWNED : { owned: null, cleanups: null, context: current ? current.context : null, owner: current }, updateFn = unowned ? fn : () => fn(() => untrack(() => cleanNode(root))); Owner = root; Listener = null; try { return runUpdates(updateFn, true); } finally { Listener = listener; Owner = owner; } } function createSignal(value, options) { options = options ? Object.assign({}, signalOptions, options) : signalOptions; const s = { value, observers: null, observerSlots: null, comparator: options.equals || void 0 }; const setter = (value2) => { if (typeof value2 === "function") { value2 = value2(s.value); } return writeSignal(s, value2); }; return [readSignal.bind(s), setter]; } function createRenderEffect(fn, value, options) { const c = createComputation(fn, value, false, STALE); updateComputation(c); } function createEffect(fn, value, options) { runEffects = runUserEffects; const c = createComputation(fn, value, false, STALE); c.user = true; Effects ? Effects.push(c) : updateComputation(c); } function createMemo(fn, value, options) { options = options ? Object.assign({}, signalOptions, options) : signalOptions; const c = createComputation(fn, value, true, 0); c.observers = null; c.observerSlots = null; c.comparator = options.equals || void 0; updateComputation(c); return readSignal.bind(c); } function untrack(fn) { if (Listener === null) return fn(); const listener = Listener; Listener = null; try { if (ExternalSourceConfig) ; return fn(); } finally { Listener = listener; } } function onMount(fn) { createEffect(() => untrack(fn)); } function onCleanup(fn) { if (Owner === null) ; else if (Owner.cleanups === null) Owner.cleanups = [fn]; else Owner.cleanups.push(fn); return fn; } function readSignal() { if (this.sources && this.state) { if (this.state === STALE) updateComputation(this); else { const updates = Updates; Updates = null; runUpdates(() => lookUpstream(this), false); Updates = updates; } } if (Listener) { const sSlot = this.observers ? this.observers.length : 0; if (!Listener.sources) { Listener.sources = [this]; Listener.sourceSlots = [sSlot]; } else { Listener.sources.push(this); Listener.sourceSlots.push(sSlot); } if (!this.observers) { this.observers = [Listener]; this.observerSlots = [Listener.sources.length - 1]; } else { this.observers.push(Listener); this.observerSlots.push(Listener.sources.length - 1); } } return this.value; } function writeSignal(node, value, isComp) { let current = node.value; if (!node.comparator || !node.comparator(current, value)) { node.value = value; if (node.observers && node.observers.length) { runUpdates(() => { for (let i = 0; i < node.observers.length; i += 1) { const o = node.observers[i]; const TransitionRunning = Transition && Transition.running; if (TransitionRunning && Transition.disposed.has(o)) ; if (TransitionRunning ? !o.tState : !o.state) { if (o.pure) Updates.push(o); else Effects.push(o); if (o.observers) markDownstream(o); } if (!TransitionRunning) o.state = STALE; } if (Updates.length > 1e6) { Updates = []; if (IS_DEV) ; throw new Error(); } }, false); } } return value; } function updateComputation(node) { if (!node.fn) return; cleanNode(node); const time = ExecCount; runComputation(node, node.value, time); } function runComputation(node, value, time) { let nextValue; const owner = Owner, listener = Listener; Listener = Owner = node; try { nextValue = node.fn(value); } catch (err) { if (node.pure) { { node.state = STALE; node.owned && node.owned.forEach(cleanNode); node.owned = null; } } node.updatedAt = time + 1; return handleError(err); } finally { Listener = listener; Owner = owner; } if (!node.updatedAt || node.updatedAt <= time) { if (node.updatedAt != null && "observers" in node) { writeSignal(node, nextValue); } else node.value = nextValue; node.updatedAt = time; } } function createComputation(fn, init, pure, state = STALE, options) { const c = { fn, state, updatedAt: null, owned: null, sources: null, sourceSlots: null, cleanups: null, value: init, owner: Owner, context: Owner ? Owner.context : null, pure }; if (Owner === null) ; else if (Owner !== UNOWNED) { { if (!Owner.owned) Owner.owned = [c]; else Owner.owned.push(c); } } return c; } function runTop(node) { if (node.state === 0) return; if (node.state === PENDING) return lookUpstream(node); if (node.suspense && untrack(node.suspense.inFallback)) return node.suspense.effects.push(node); const ancestors = [node]; while ((node = node.owner) && (!node.updatedAt || node.updatedAt < ExecCount)) { if (node.state) ancestors.push(node); } for (let i = ancestors.length - 1; i >= 0; i--) { node = ancestors[i]; if (node.state === STALE) { updateComputation(node); } else if (node.state === PENDING) { const updates = Updates; Updates = null; runUpdates(() => lookUpstream(node, ancestors[0]), false); Updates = updates; } } } function runUpdates(fn, init) { if (Updates) return fn(); let wait = false; if (!init) Updates = []; if (Effects) wait = true; else Effects = []; ExecCount++; try { const res = fn(); completeUpdates(wait); return res; } catch (err) { if (!wait) Effects = null; Updates = null; handleError(err); } } function completeUpdates(wait) { if (Updates) { runQueue(Updates); Updates = null; } if (wait) return; const e = Effects; Effects = null; if (e.length) runUpdates(() => runEffects(e), false); } function runQueue(queue) { for (let i = 0; i < queue.length; i++) runTop(queue[i]); } function runUserEffects(queue) { let i, userLength = 0; for (i = 0; i < queue.length; i++) { const e = queue[i]; if (!e.user) runTop(e); else queue[userLength++] = e; } for (i = 0; i < userLength; i++) runTop(queue[i]); } function lookUpstream(node, ignore) { node.state = 0; for (let i = 0; i < node.sources.length; i += 1) { const source = node.sources[i]; if (source.sources) { const state = source.state; if (state === STALE) { if (source !== ignore && (!source.updatedAt || source.updatedAt < ExecCount)) runTop(source); } else if (state === PENDING) lookUpstream(source, ignore); } } } function markDownstream(node) { for (let i = 0; i < node.observers.length; i += 1) { const o = node.observers[i]; if (!o.state) { o.state = PENDING; if (o.pure) Updates.push(o); else Effects.push(o); o.observers && markDownstream(o); } } } function cleanNode(node) { let i; if (node.sources) { while (node.sources.length) { const source = node.sources.pop(), index = node.sourceSlots.pop(), obs = source.observers; if (obs && obs.length) { const n = obs.pop(), s = source.observerSlots.pop(); if (index < obs.length) { n.sourceSlots[s] = index; obs[index] = n; source.observerSlots[index] = s; } } } } if (node.tOwned) { for (i = node.tOwned.length - 1; i >= 0; i--) cleanNode(node.tOwned[i]); delete node.tOwned; } if (node.owned) { for (i = node.owned.length - 1; i >= 0; i--) cleanNode(node.owned[i]); node.owned = null; } if (node.cleanups) { for (i = node.cleanups.length - 1; i >= 0; i--) node.cleanups[i](); node.cleanups = null; } node.state = 0; } function castError(err) { if (err instanceof Error) return err; return new Error(typeof err === "string" ? err : "Unknown error", { cause: err }); } function handleError(err, owner = Owner) { const error = castError(err); throw error; } const FALLBACK = Symbol("fallback"); function dispose(d) { for (let i = 0; i < d.length; i++) d[i](); } function mapArray(list, mapFn, options = {}) { let items = [], mapped = [], disposers = [], len = 0, indexes = mapFn.length > 1 ? [] : null; onCleanup(() => dispose(disposers)); return () => { let newItems = list() || [], newLen = newItems.length, i, j; newItems[$TRACK]; return untrack(() => { let newIndices, newIndicesNext, temp, tempdisposers, tempIndexes, start, end, newEnd, item; if (newLen === 0) { if (len !== 0) { dispose(disposers); disposers = []; items = []; mapped = []; len = 0; indexes && (indexes = []); } if (options.fallback) { items = [FALLBACK]; mapped[0] = createRoot((disposer) => { disposers[0] = disposer; return options.fallback(); }); len = 1; } } else if (len === 0) { mapped = new Array(newLen); for (j = 0; j < newLen; j++) { items[j] = newItems[j]; mapped[j] = createRoot(mapper); } len = newLen; } else { temp = new Array(newLen); tempdisposers = new Array(newLen); indexes && (tempIndexes = new Array(newLen)); for (start = 0, end = Math.min(len, newLen); start < end && items[start] === newItems[start]; start++) ; for (end = len - 1, newEnd = newLen - 1; end >= start && newEnd >= start && items[end] === newItems[newEnd]; end--, newEnd--) { temp[newEnd] = mapped[end]; tempdisposers[newEnd] = disposers[end]; indexes && (tempIndexes[newEnd] = indexes[end]); } newIndices = new Map(); newIndicesNext = new Array(newEnd + 1); for (j = newEnd; j >= start; j--) { item = newItems[j]; i = newIndices.get(item); newIndicesNext[j] = i === void 0 ? -1 : i; newIndices.set(item, j); } for (i = start; i <= end; i++) { item = items[i]; j = newIndices.get(item); if (j !== void 0 && j !== -1) { temp[j] = mapped[i]; tempdisposers[j] = disposers[i]; indexes && (tempIndexes[j] = indexes[i]); j = newIndicesNext[j]; newIndices.set(item, j); } else disposers[i](); } for (j = start; j < newLen; j++) { if (j in temp) { mapped[j] = temp[j]; disposers[j] = tempdisposers[j]; if (indexes) { indexes[j] = tempIndexes[j]; indexes[j](j); } } else mapped[j] = createRoot(mapper); } mapped = mapped.slice(0, len = newLen); items = newItems.slice(0); } return mapped; }); function mapper(disposer) { disposers[j] = disposer; if (indexes) { const [s, set] = createSignal(j); indexes[j] = set; return mapFn(newItems[j], s); } return mapFn(newItems[j]); } }; } function createComponent(Comp, props) { return untrack(() => Comp(props || {})); } const narrowedError = (name) => `Stale read from <${name}>.`; function For(props) { const fallback = "fallback" in props && { fallback: () => props.fallback }; return createMemo(mapArray(() => props.each, props.children, fallback || void 0)); } function Show(props) { const keyed = props.keyed; const conditionValue = createMemo(() => props.when, void 0, void 0); const condition = keyed ? conditionValue : createMemo(conditionValue, void 0, { equals: (a, b) => !a === !b }); return createMemo(() => { const c = condition(); if (c) { const child = props.children; const fn = typeof child === "function" && child.length > 0; return fn ? untrack(() => child(keyed ? c : () => { if (!untrack(condition)) throw narrowedError("Show"); return conditionValue(); })) : child; } return props.fallback; }, void 0, void 0); } const memo = (fn) => createMemo(() => fn()); function reconcileArrays(parentNode, a, b) { let bLength = b.length, aEnd = a.length, bEnd = bLength, aStart = 0, bStart = 0, after = a[aEnd - 1].nextSibling, map = null; while (aStart < aEnd || bStart < bEnd) { if (a[aStart] === b[bStart]) { aStart++; bStart++; continue; } while (a[aEnd - 1] === b[bEnd - 1]) { aEnd--; bEnd--; } if (aEnd === aStart) { const node = bEnd < bLength ? bStart ? b[bStart - 1].nextSibling : b[bEnd - bStart] : after; while (bStart < bEnd) parentNode.insertBefore(b[bStart++], node); } else if (bEnd === bStart) { while (aStart < aEnd) { if (!map || !map.has(a[aStart])) a[aStart].remove(); aStart++; } } else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) { const node = a[--aEnd].nextSibling; parentNode.insertBefore(b[bStart++], a[aStart++].nextSibling); parentNode.insertBefore(b[--bEnd], node); a[aEnd] = b[bEnd]; } else { if (!map) { map = new Map(); let i = bStart; while (i < bEnd) map.set(b[i], i++); } const index = map.get(a[aStart]); if (index != null) { if (bStart < index && index < bEnd) { let i = aStart, sequence = 1, t; while (++i < aEnd && i < bEnd) { if ((t = map.get(a[i])) == null || t !== index + sequence) break; sequence++; } if (sequence > index - bStart) { const node = a[aStart]; while (bStart < index) parentNode.insertBefore(b[bStart++], node); } else parentNode.replaceChild(b[bStart++], a[aStart++]); } else aStart++; } else a[aStart++].remove(); } } } const $$EVENTS = "_$DX_DELEGATE"; function render(code, element, init, options = {}) { let disposer; createRoot((dispose2) => { disposer = dispose2; element === document ? code() : insert(element, code(), element.firstChild ? null : void 0, init); }, options.owner); return () => { disposer(); element.textContent = ""; }; } function template(html, isImportNode, isSVG, isMathML) { let node; const create = () => { const t = document.createElement("template"); t.innerHTML = html; return t.content.firstChild; }; const fn = () => (node || (node = create())).cloneNode(true); fn.cloneNode = fn; return fn; } function delegateEvents(eventNames, document2 = window.document) { const e = document2[$$EVENTS] || (document2[$$EVENTS] = new Set()); for (let i = 0, l = eventNames.length; i < l; i++) { const name = eventNames[i]; if (!e.has(name)) { e.add(name); document2.addEventListener(name, eventHandler); } } } function setAttribute(node, name, value) { if (value == null) node.removeAttribute(name); else node.setAttribute(name, value); } function className(node, value) { if (value == null) node.removeAttribute("class"); else node.className = value; } function addEventListener(node, name, handler, delegate) { { if (Array.isArray(handler)) { node[`$$${name}`] = handler[0]; node[`$$${name}Data`] = handler[1]; } else node[`$$${name}`] = handler; } } function setStyleProperty(node, name, value) { value != null ? node.style.setProperty(name, value) : node.style.removeProperty(name); } function insert(parent, accessor, marker, initial) { if (marker !== void 0 && !initial) initial = []; if (typeof accessor !== "function") return insertExpression(parent, accessor, initial, marker); createRenderEffect((current) => insertExpression(parent, accessor(), current, marker), initial); } function eventHandler(e) { let node = e.target; const key = `$$${e.type}`; const oriTarget = e.target; const oriCurrentTarget = e.currentTarget; const retarget = (value) => Object.defineProperty(e, "target", { configurable: true, value }); const handleNode = () => { const handler = node[key]; if (handler && !node.disabled) { const data = node[`${key}Data`]; data !== void 0 ? handler.call(node, data, e) : handler.call(node, e); if (e.cancelBubble) return; } node.host && typeof node.host !== "string" && !node.host._$host && node.contains(e.target) && retarget(node.host); return true; }; const walkUpTree = () => { while (handleNode() && (node = node._$host || node.parentNode || node.host)) ; }; Object.defineProperty(e, "currentTarget", { configurable: true, get() { return node || document; } }); if (e.composedPath) { const path = e.composedPath(); retarget(path[0]); for (let i = 0; i < path.length - 2; i++) { node = path[i]; if (!handleNode()) break; if (node._$host) { node = node._$host; walkUpTree(); break; } if (node.parentNode === oriCurrentTarget) { break; } } } else walkUpTree(); retarget(oriTarget); } function insertExpression(parent, value, current, marker, unwrapArray) { while (typeof current === "function") current = current(); if (value === current) return current; const t = typeof value, multi = marker !== void 0; parent = multi && current[0] && current[0].parentNode || parent; if (t === "string" || t === "number") { if (t === "number") { value = value.toString(); if (value === current) return current; } if (multi) { let node = current[0]; if (node && node.nodeType === 3) { node.data !== value && (node.data = value); } else node = document.createTextNode(value); current = cleanChildren(parent, current, marker, node); } else { if (current !== "" && typeof current === "string") { current = parent.firstChild.data = value; } else current = parent.textContent = value; } } else if (value == null || t === "boolean") { current = cleanChildren(parent, current, marker); } else if (t === "function") { createRenderEffect(() => { let v = value(); while (typeof v === "function") v = v(); current = insertExpression(parent, v, current, marker); }); return () => current; } else if (Array.isArray(value)) { const array = []; const currentArray = current && Array.isArray(current); if (normalizeIncomingArray(array, value, current, unwrapArray)) { createRenderEffect(() => current = insertExpression(parent, array, current, marker, true)); return () => current; } if (array.length === 0) { current = cleanChildren(parent, current, marker); if (multi) return current; } else if (currentArray) { if (current.length === 0) { appendNodes(parent, array, marker); } else reconcileArrays(parent, current, array); } else { current && cleanChildren(parent); appendNodes(parent, array); } current = array; } else if (value.nodeType) { if (Array.isArray(current)) { if (multi) return current = cleanChildren(parent, current, marker, value); cleanChildren(parent, current, null, value); } else if (current == null || current === "" || !parent.firstChild) { parent.appendChild(value); } else parent.replaceChild(value, parent.firstChild); current = value; } else ; return current; } function normalizeIncomingArray(normalized, array, current, unwrap) { let dynamic = false; for (let i = 0, len = array.length; i < len; i++) { let item = array[i], prev = current && current[normalized.length], t; if (item == null || item === true || item === false) ; else if ((t = typeof item) === "object" && item.nodeType) { normalized.push(item); } else if (Array.isArray(item)) { dynamic = normalizeIncomingArray(normalized, item, prev) || dynamic; } else if (t === "function") { if (unwrap) { while (typeof item === "function") item = item(); dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item], Array.isArray(prev) ? prev : [prev]) || dynamic; } else { normalized.push(item); dynamic = true; } } else { const value = String(item); if (prev && prev.nodeType === 3 && prev.data === value) normalized.push(prev); else normalized.push(document.createTextNode(value)); } } return dynamic; } function appendNodes(parent, array, marker = null) { for (let i = 0, len = array.length; i < len; i++) parent.insertBefore(array[i], marker); } function cleanChildren(parent, current, marker, replacement) { if (marker === void 0) return parent.textContent = ""; const node = replacement || document.createTextNode(""); if (current.length) { let inserted = false; for (let i = current.length - 1; i >= 0; i--) { const el = current[i]; if (node !== el) { const isParent = el.parentNode === parent; if (!inserted && !i) isParent ? parent.replaceChild(node, el) : parent.insertBefore(node, marker); else isParent && el.remove(); } else inserted = true; } } else parent.insertBefore(node, marker); return [node]; } const indexCss = "body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:flex}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}"; importCSS(indexCss); const fab = "_fab_1ykjg_4"; const toast$1 = "_toast_1ykjg_190"; const styles$2 = { fab, toast: toast$1 }; const bilibiliIcon = ``; const youtubeIcon = ``; const xIcon = ``; const platforms = [ { id: "bilibili", name: "Bilibili", icon: bilibiliIcon, rules: [ { id: "user-video", name: "UP主投稿", desc: "获取UP主最新投稿", doc: "https://docs.rsshub.app/routes/social-media#bilibili", genLink: ({ uid }) => `/bilibili/user/video/${uid}`, preview: "/bilibili/user/video/2267573" }, { id: "user-video-all", name: "UP主所有视频", desc: "获取UP主所有视频", doc: "https://docs.rsshub.app/routes/social-media#bilibili", genLink: ({ uid }) => `/bilibili/user/video-all/${uid}`, preview: "/bilibili/user/video-all/2267573" }, { id: "ranking", name: "排行榜", desc: "B站分区排行榜", doc: "https://docs.rsshub.app/routes/social-media#bilibili", genLink: ({ rid_index }) => `/bilibili/ranking/${rid_index || ""}`, preview: "/bilibili/ranking/0" }, { id: "weekly", name: "周推", desc: "B站每周热门推荐", doc: "https://docs.rsshub.app/routes/social-media#bilibili", genLink: () => "/bilibili/weekly", preview: "/bilibili/weekly" } ] }, { id: "youtube", name: "YouTube", icon: youtubeIcon, rules: [ { id: "user", name: "频道(@handle)", desc: "通过@handle订阅频道", doc: "https://docs.rsshub.app/routes/social-media#youtube", genLink: ({ username }) => `/youtube/user/${username}`, preview: "/youtube/user/@JFlaMusic" }, { id: "playlist", name: "播放列表", desc: "订阅YouTube播放列表", doc: "https://docs.rsshub.app/routes/social-media#youtube", genLink: ({ id }) => `/youtube/playlist/${id}`, preview: "/youtube/playlist/PL9tY0BWXOZFv2b4p1p6rQ1QK2vNhbbX6h" } ] }, { id: "x", name: "X(Twitter)", icon: xIcon, rules: [ { id: "user", name: "用户推文", desc: "订阅指定用户推文", doc: "https://docs.rsshub.app/routes/social-media#x", genLink: ({ id }) => `/x/user/${id}`, preview: "/x/user/jack" }, { id: "custom", name: "自定义参数", desc: "自定义X规则参数", doc: "https://docs.rsshub.app/routes/social-media#x", genLink: ({ routeParams }) => `/x/${routeParams || ""}`, preview: "/x/readable=true&showAuthorInTitle=true" } ] } ]; function detectBilibiliParams() { const url = window.location.href; const spaceMatch = url.match(/space\.bilibili\.com\/(\d+)/); if (spaceMatch) return { uid: spaceMatch[1] }; const bvMatch = url.match(/bilibili\.com\/video\/(BV[\w]+)/i); if (bvMatch) { const upLink = document.querySelector("a.up-name, a.username, a.bili-avatar"); if (upLink && upLink.href) { const upUid = upLink.href.match(/space\.bilibili\.com\/(\d+)/); if (upUid) return { uid: upUid[1] }; } } return {}; } function detectYouTubeParams() { const url = window.location.href; const handleMatch = url.match(/youtube\.com\/@([\w\-\.]+)/); if (handleMatch) return { username: "@" + handleMatch[1] }; const channelMatch = url.match(/youtube\.com\/channel\/(UC[\w\-]+)/); if (channelMatch) return { username: channelMatch[1] }; return {}; } function detectXParams() { const url = window.location.href; const userMatch = url.match(/(?:x|twitter)\.com\/([\w_]+)/); if (userMatch && !["home", "explore", "i", "notifications", "messages", "search", "settings"].includes(userMatch[1])) { return { id: userMatch[1] }; } return {}; } function detectParams(platform) { if (platform === "bilibili") return detectBilibiliParams(); if (platform === "youtube") return detectYouTubeParams(); if (platform === "x") return detectXParams(); return {}; } const rsshubLogo = ``; const panelBg = "_panelBg_1ay11_1"; const dialog = "_dialog_1ay11_8"; const panel = "_panel_1ay11_1"; const panelHeader = "_panelHeader_1ay11_31"; const closeBtn = "_closeBtn_1ay11_41"; const tabs = "_tabs_1ay11_53"; const tabActive = "_tabActive_1ay11_76"; const tabIcon = "_tabIcon_1ay11_81"; const tabName = "_tabName_1ay11_89"; const expandIcon = "_expandIcon_1ay11_118"; const rules = "_rules_1ay11_129"; const styles$1 = { panelBg, dialog, panel, panelHeader, closeBtn, tabs, tabActive, tabIcon, tabName, expandIcon, rules }; const ruleItem = "_ruleItem_17zs6_1"; const ruleTitle = "_ruleTitle_17zs6_11"; const ruleDesc = "_ruleDesc_17zs6_25"; const ruleCopyBox = "_ruleCopyBox_17zs6_30"; const ruleLink = "_ruleLink_17zs6_53"; const copyIcon$1 = "_copyIcon_17zs6_65"; const styles = { ruleItem, ruleTitle, ruleDesc, ruleCopyBox, ruleLink, copyIcon: copyIcon$1 }; const copyIcon = ``; var _tmpl$$2 = template(`