(() => { const KEY = "__cab"; const MAGIC = "cab" + Math.random().toString(36).slice(2); const origParse = JSON.parse; const applied = new Set(); const hooked = new Set(); const S = { jsonPrune: [], fetchPrune: [], xhrPrune: [], fetchReplace: [], xhrReplace: [], nostif: [], nosiif: [], stb: [], sib: [], aeld: [], nowoif: [], nofetch: [], noxhr: [], noevalif: [] }; const hook = (name, fn) => { if (hooked.has(name)) return; hooked.add(name); try { fn(); } catch (e) {} }; const regexOf = p => { const m = /^\/(.+)\/([gimsuy]*)$/.exec(p); return m ? new RegExp(m[1], m[2].replace("g", "")) : null; }; const needle = p => { if (!p) return () => true; let neg = false; if (p[0] === "!") { neg = true; p = p.slice(1); } const re = regexOf(p); return s => (re ? re.test(String(s)) : String(s).includes(p)) !== neg; }; const delayMatch = p => { if (!p) return () => true; const neg = p[0] === "!"; const n = parseInt(neg ? p.slice(1) : p, 10); if (isNaN(n)) return () => true; return d => (Number(d) === n) !== neg; }; const urlMatcher = p => { if (!p) return () => true; if (p.startsWith("url:")) p = p.slice(4); else if (/^\w+:/.test(p) && !/^https?:/.test(p)) return () => true; const re = regexOf(p); return u => (re ? re.test(u) : u.includes(p)); }; const propsMatcher = s => { const props = []; for (const tok of s.split(/\s+/).filter(Boolean)) { const m = /^(\w+):(.*)$/.exec(tok); if (m && !/^https?$/.test(m[1])) props.push([m[1].toLowerCase(), needle(m[2])]); else props.push(["url", needle(tok)]); } return info => props.every(([k, n]) => info[k] !== undefined && n(info[k])); }; const words = s => (s || "").split(/\s+/).filter(Boolean).map(x => x.split(".")); const varargs = a => { const o = {}; for (let i = 0; i + 1 < a.length; i += 2) o[a[i]] = a[i + 1]; return o; }; const toRegex = p => { const m = /^\/(.+)\/([gimsuy]*)$/.exec(p); if (m) return new RegExp(m[1], m[2]); return new RegExp(p.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"); }; const has = (o, segs, i) => { if (i >= segs.length) return true; if (o === null || typeof o !== "object") return false; const s = segs[i]; if (s === "[]" || s === "[-]") return Object.keys(o).some(k => has(o[k], segs, i + 1)); if (!(s in o)) return false; return has(o[s], segs, i + 1); }; const prunePath = (o, segs, i) => { if (o === null || typeof o !== "object") return false; const s = segs[i]; const last = i === segs.length - 1; if (s === "[]") { let ch = false; for (const k of Object.keys(o)) ch = prunePath(o[k], segs, i + 1) || ch; return ch; } if (s === "[-]") { if (last) return false; let ch = false; if (Array.isArray(o)) { for (let k = o.length - 1; k >= 0; k--) if (has(o[k], segs, i + 1)) { o.splice(k, 1); ch = true; } } else { for (const k of Object.keys(o)) if (has(o[k], segs, i + 1)) { delete o[k]; ch = true; } } return ch; } if (!(s in o)) return false; if (last) { delete o[s]; return true; } return prunePath(o[s], segs, i + 1); }; const applyPrune = (obj, r) => { if (obj === null || typeof obj !== "object") return false; if (!r.needs.every(n => has(obj, n, 0))) return false; let ch = false; for (const p of r.paths) ch = prunePath(obj, p, 0) || ch; return ch; }; const transform = (txt, url, prune, replace) => { const pr = prune.filter(r => r.match(url)); const rp = replace.filter(r => r.match(url)); if (!pr.length && !rp.length) return txt; let out = txt; for (const r of rp) { r.re.lastIndex = 0; out = out.replace(r.re, r.rep); } if (pr.length) { try { const o = origParse(out); let ch = false; for (const r of pr) ch = applyPrune(o, r) || ch; if (ch) out = JSON.stringify(o); } catch (e) {} } return out; }; const SKIP = {}; const constVal = (raw, trusted) => { switch (raw) { case "undefined": return undefined; case "false": return false; case "true": return true; case "null": return null; case "''": case "emptyStr": case "": return ""; case "noopFunc": return function () {}; case "trueFunc": return function () { return true; }; case "falseFunc": return function () { return false; }; case "throwFunc": return function () { throw new Error(); }; case "emptyObj": return {}; case "emptyArr": return []; case "noopPromiseResolve": return function () { return Promise.resolve(); }; case "noopPromiseReject": return function () { return Promise.reject(); }; case "noopCallbackFunc": return function () { return function () {}; }; case "yes": case "no": case "on": case "off": return raw; } if (/^-?\d+$/.test(raw) && Math.abs(parseInt(raw, 10)) <= 32767) return parseInt(raw, 10); if (trusted) { try { return origParse(raw); } catch (e) { return raw; } } return SKIP; }; const isObj = v => v !== null && (typeof v === "object" || typeof v === "function"); const onChain = (path, leaf) => { if (!path) return; const parts = path.replace(/^window\./, "").split("."); const walk = (owner, i) => { const p = parts[i]; if (i === parts.length - 1) { try { leaf(owner, p); } catch (e) {} return; } let cur; try { cur = owner[p]; } catch (e) { return; } if (isObj(cur)) { walk(cur, i + 1); return; } const d = Object.getOwnPropertyDescriptor(owner, p); if (d && d.configurable === false) return; let v = cur; try { Object.defineProperty(owner, p, { configurable: true, enumerable: true, get() { return v; }, set(nv) { v = nv; if (isObj(nv)) walk(nv, i + 1); } }); } catch (e) {} }; walk(window, 0); }; const leafSet = (raw, trusted) => { const value = constVal(raw, trusted); return (o, p) => { if (value === SKIP) return; const d = Object.getOwnPropertyDescriptor(o, p); if (d && d.configurable === false) return; if (d && "value" in d) { const cur = d.value; if (cur !== undefined && cur !== null && value !== undefined && value !== null && typeof cur !== typeof value) return; } Object.defineProperty(o, p, { configurable: true, enumerable: d ? d.enumerable : true, get() { return value; }, set() {} }); }; }; const installErr = () => { window.addEventListener("error", e => { if (String(e.message).includes(MAGIC)) { e.preventDefault(); e.stopImmediatePropagation(); } }, true); }; const leafAopr = (o, p) => { const d = Object.getOwnPropertyDescriptor(o, p); if (d && d.configurable === false) return; let v = d && "value" in d ? d.value : undefined; Object.defineProperty(o, p, { configurable: true, get() { throw new ReferenceError(MAGIC); }, set(nv) { v = nv; } }); }; const leafAopw = (o, p) => { const d = Object.getOwnPropertyDescriptor(o, p); if (d && d.configurable === false) return; const v = d && "value" in d ? d.value : undefined; Object.defineProperty(o, p, { configurable: true, get() { return v; }, set() { throw new ReferenceError(MAGIC); } }); }; const leafAcs = n => (o, p) => { const d = Object.getOwnPropertyDescriptor(o, p); if (d && d.configurable === false) return; let v = d && "value" in d ? d.value : undefined; const g = d && d.get; const s = d && d.set; const check = () => { const cs = document.currentScript; if (!cs || cs.tagName !== "SCRIPT") return; const text = cs.src ? cs.src + "\n" + cs.textContent : cs.textContent; if (n(text)) throw new ReferenceError(MAGIC); }; Object.defineProperty(o, p, { configurable: true, get() { check(); return g ? g.call(this) : v; }, set(nv) { check(); if (s) s.call(this, nv); else v = nv; } }); }; const installTimers = () => { const wrap = (orig, block, boost) => new Proxy(orig, { apply(t, th, a) { let s = ""; try { s = typeof a[0] === "function" ? Function.prototype.toString.call(a[0]) : String(a[0]); } catch (e) {} for (const r of block) { if (r.cb(s) && r.dl(a[1])) { a = [function () {}, a[1]]; break; } } for (const r of boost) { if (r.cb(s) && (r.dl === "*" || Number(a[1]) === Number(r.dl))) { a = Array.from(a); a[1] = Number(a[1]) * r.boost; break; } } return Reflect.apply(t, th, a); } }); window.setTimeout = wrap(window.setTimeout, S.nostif, S.stb); window.setInterval = wrap(window.setInterval, S.nosiif, S.sib); }; const installAeld = () => { const P = EventTarget.prototype; P.addEventListener = new Proxy(P.addEventListener, { apply(t, th, a) { let hs = ""; try { const h = a[1]; hs = typeof h === "function" ? Function.prototype.toString.call(h) : String(h && h.handleEvent); } catch (e) {} for (const r of S.aeld) if (r.type(String(a[0])) && r.h(hs)) return; return Reflect.apply(t, th, a); } }); }; const decoy = () => ({ closed: false, opener: null, location: { href: "" }, document: { write() {}, writeln() {}, open() {}, close() {} }, close() { this.closed = true; }, focus() {}, blur() {}, postMessage() {}, addEventListener() {}, removeEventListener() {} }); const installWo = () => { window.open = new Proxy(window.open, { apply(t, th, a) { const url = String(a[0] === undefined ? "" : a[0]); for (const n of S.nowoif) if (n(url)) return decoy(); return Reflect.apply(t, th, a); } }); }; const installJson = () => { JSON.parse = new Proxy(origParse, { apply(t, th, a) { const r = Reflect.apply(t, th, a); try { for (const rule of S.jsonPrune) applyPrune(r, rule); } catch (e) {} return r; } }); const origJson = Response.prototype.json; Response.prototype.json = new Proxy(origJson, { apply(t, th, a) { return Reflect.apply(t, th, a).then(r => { try { for (const rule of S.jsonPrune) applyPrune(r, rule); } catch (e) {} return r; }); } }); if (/(^|\.)youtube(-nocookie)?\.com$/.test(location.hostname)) { let yipr = window.ytInitialPlayerResponse; try { Object.defineProperty(window, "ytInitialPlayerResponse", { configurable: true, get() { return yipr; }, set(v) { try { for (const rule of S.jsonPrune) applyPrune(v, rule); } catch (e) {} yipr = v; } }); } catch (e) {} } }; const installFetch = () => { window.fetch = new Proxy(window.fetch, { apply(t, th, a) { let url = ""; let method = "GET"; try { if (a[0] instanceof Request) { url = a[0].url; method = a[0].method; } else url = String(a[0]); if (a[1] && a[1].method) method = String(a[1].method); } catch (e) {} const info = { url, method: method.toUpperCase() }; for (const m of S.nofetch) { if (m(info)) return Promise.resolve(new Response("", { status: 200, statusText: "OK" })); } const p = Reflect.apply(t, th, a); const any = S.fetchPrune.some(r => r.match(url)) || S.fetchReplace.some(r => r.match(url)); if (!any) return p; return p.then(res => res.clone().text().then(txt => { const out = transform(txt, url, S.fetchPrune, S.fetchReplace); if (out === txt) return res; const nr = new Response(out, { status: res.status, statusText: res.statusText, headers: res.headers }); Object.defineProperties(nr, { url: { value: res.url }, redirected: { value: res.redirected }, type: { value: res.type } }); return nr; }).catch(() => res)); } }); }; const installXhr = () => { const XP = XMLHttpRequest.prototype; const info = new WeakMap(); const cache = new WeakMap(); XP.open = new Proxy(XP.open, { apply(t, th, a) { try { info.set(th, { url: String(a[1]), method: String(a[0] || "GET").toUpperCase() }); cache.delete(th); } catch (e) {} return Reflect.apply(t, th, a); } }); XP.send = new Proxy(XP.send, { apply(t, th, a) { const i = info.get(th); if (i && S.noxhr.some(m => m(i))) { const props = { readyState: 4, status: 200, statusText: "OK", response: "", responseText: "", responseURL: i.url }; for (const k in props) Object.defineProperty(th, k, { configurable: true, value: props[k] }); setTimeout(() => { for (const ev of ["readystatechange", "load", "loadend"]) { try { th.dispatchEvent(new Event(ev)); } catch (e) {} } }, 1); return; } return Reflect.apply(t, th, a); } }); const dText = Object.getOwnPropertyDescriptor(XP, "responseText"); const dResp = Object.getOwnPropertyDescriptor(XP, "response"); const xform = xhr => { if (xhr.readyState !== 4) return null; if (cache.has(xhr)) return cache.get(xhr); let result = null; try { const url = (info.get(xhr) || {}).url || ""; const type = xhr.responseType; if (type === "" || type === "text" || type === "json") { const raw = dResp.get.call(xhr); const txt = type === "json" ? JSON.stringify(raw) : raw; if (typeof txt === "string") { const out = transform(txt, url, S.xhrPrune, S.xhrReplace); if (out !== txt) result = { v: type === "json" ? origParse(out) : out }; } } } catch (e) {} cache.set(xhr, result); return result; }; Object.defineProperty(XP, "response", { configurable: true, enumerable: dResp.enumerable, get() { const r = xform(this); return r ? r.v : dResp.get.call(this); } }); Object.defineProperty(XP, "responseText", { configurable: true, enumerable: dText.enumerable, get() { const r = xform(this); return r && typeof r.v === "string" ? r.v : dText.get.call(this); } }); }; const onReady = fn => { if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", fn, { once: true }); else fn(); }; const domRemove = (a, kind) => { const tokens = (a[0] || "").split(/\s*\|\s*/).filter(Boolean); if (!tokens.length) return; const selector = a[1] || tokens.map(t => (kind === "attr" ? "[" + t + "]" : "." + t)).join(","); const run = () => { try { document.querySelectorAll(selector).forEach(el => { for (const t of tokens) { if (kind === "attr") el.removeAttribute(t); else el.classList.remove(t); } }); } catch (e) {} }; onReady(run); window.addEventListener("load", run, { once: true }); if ((a[2] || "").includes("stay")) { let pending = false; const mo = new MutationObserver(() => { if (pending) return; pending = true; requestAnimationFrame(() => { pending = false; run(); }); }); onReady(() => mo.observe(document.documentElement, { childList: true, subtree: true, attributes: true })); } }; const LS_OK = new Set(["undefined", "false", "true", "null", "yes", "no", "on", "off", "accept", "accepted", "reject", "rejected", "allow", "allowed", "deny", "denied"]); const lsItem = a => { const key = a[0]; let raw = a[1] || ""; if (!key) return; try { if (raw === "$remove$") { const re = regexOf(key); if (re) { for (const k of Object.keys(localStorage)) if (re.test(k)) localStorage.removeItem(k); } else localStorage.removeItem(key); return; } if (raw === "emptyObj") raw = "{}"; else if (raw === "emptyArr") raw = "[]"; else if (raw === "''" || raw === "emptyStr") raw = ""; else if (!LS_OK.has(raw) && !(/^\d+$/.test(raw) && parseInt(raw, 10) <= 32767)) return; localStorage.setItem(key, raw); } catch (e) {} }; const cookieRemove = a => { const n = needle(a[0] || ""); const rm = () => { for (const c of document.cookie.split(";")) { const name = c.split("=")[0].trim(); if (!name || !n(name)) continue; const exp = "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; const h = location.hostname; document.cookie = name + exp; document.cookie = name + exp + "; domain=" + h; document.cookie = name + exp + "; domain=." + h.split(".").slice(-2).join("."); } }; rm(); window.addEventListener("beforeunload", rm); onReady(rm); }; const H = { "json-prune": a => { const paths = words(a[0]); if (!paths.length) return; S.jsonPrune.push({ paths, needs: words(a[1]) }); hook("json", installJson); }, "json-prune-fetch-response": a => { const paths = words(a[0]); if (!paths.length) return; S.fetchPrune.push({ paths, needs: words(a[1]), match: urlMatcher(varargs(a.slice(2)).propsToMatch) }); hook("fetch", installFetch); }, "json-prune-xhr-response": a => { const paths = words(a[0]); if (!paths.length) return; S.xhrPrune.push({ paths, needs: words(a[1]), match: urlMatcher(varargs(a.slice(2)).propsToMatch) }); hook("xhr", installXhr); }, "trusted-replace-fetch-response": a => { if (!a[0]) return; S.fetchReplace.push({ re: toRegex(a[0]), rep: a[1] || "", match: urlMatcher(a[2]) }); hook("fetch", installFetch); }, "trusted-replace-xhr-response": a => { if (!a[0]) return; S.xhrReplace.push({ re: toRegex(a[0]), rep: a[1] || "", match: urlMatcher(a[2]) }); hook("xhr", installXhr); }, set: a => onChain(a[0], leafSet(a[1] || "undefined", false)), "trusted-set": a => onChain(a[0], leafSet(a[1] || "undefined", true)), aopr: a => { hook("err", installErr); onChain(a[0], leafAopr); }, aopw: a => { hook("err", installErr); onChain(a[0], leafAopw); }, acs: a => { hook("err", installErr); onChain(a[0], leafAcs(needle(a[1]))); }, nostif: a => { S.nostif.push({ cb: needle(a[0]), dl: delayMatch(a[1]) }); hook("timers", installTimers); }, nosiif: a => { S.nosiif.push({ cb: needle(a[0]), dl: delayMatch(a[1]) }); hook("timers", installTimers); }, "nano-stb": a => { S.stb.push({ cb: needle(a[0] === "*" ? "" : a[0]), dl: a[1] || "1000", boost: parseFloat(a[2] || "0.05") || 0.05 }); hook("timers", installTimers); }, "nano-sib": a => { S.sib.push({ cb: needle(a[0] === "*" ? "" : a[0]), dl: a[1] || "1000", boost: parseFloat(a[2] || "0.05") || 0.05 }); hook("timers", installTimers); }, aeld: a => { S.aeld.push({ type: needle(a[0]), h: needle(a[1]) }); hook("aeld", installAeld); }, nowoif: a => { S.nowoif.push(needle(a[0])); hook("wo", installWo); }, "no-fetch-if": a => { if (!a[0]) return; S.nofetch.push(propsMatcher(a[0])); hook("fetch", installFetch); }, "no-xhr-if": a => { if (!a[0]) return; S.noxhr.push(propsMatcher(a[0])); hook("xhr", installXhr); }, noeval: () => hook("noeval", () => { window.eval = new Proxy(window.eval, { apply() { return undefined; } }); }), "noeval-if": a => { S.noevalif.push(needle(a[0])); hook("evalif", () => { window.eval = new Proxy(window.eval, { apply(t, th, x) { if (S.noevalif.some(n => n(String(x[0])))) return undefined; return Reflect.apply(t, th, x); } }); }); }, ra: a => domRemove(a, "attr"), rc: a => domRemove(a, "class"), "set-local-storage-item": lsItem, "remove-cookie": cookieRemove }; const run = rules => { if (!Array.isArray(rules)) return; for (const r of rules) { if (!r || !H[r.t]) continue; const k = r.t + "|" + JSON.stringify(r.a || []); if (applied.has(k)) continue; applied.add(k); try { H[r.t](r.a || []); } catch (e) {} } }; try { const cached = localStorage.getItem(KEY); if (cached) run(origParse(cached)); } catch (e) {} window.addEventListener(KEY, e => { try { run(origParse(e.detail)); } catch (x) {} }); })();