import { d as dt, t } from './parse_token.util-73818eef.js'; import { n, e, c } from './constants-27e12ede.js'; import { n as n$1 } from './router.interface-6cdbc015.js'; import { s, m as m$1 } from './storage-6f9cf62e.js'; class i extends Error { constructor(t, e) { super(e), this.code = t, this.message = e; } } const l = (t, e = {}, n) => ({ body: e, meta: { isSuccess: !1, code: t, nonce: n } }); let u; const d = t => s.cookies.getAll({ url: t }).then((t => t.filter((t => !t.name.startsWith("ST-"))).map((t => [t.name, t.value])))).then(Object.fromEntries), p = { "@me": async () => { const t = await m$1.auth.get("token2"); return dt(t) }, token: async () => m$1.auth.get("token2"), logout: async () => { const t = await m$1.auth.get("token2"); await fetch("https://truffle-tv-source-test.truffle-tv.workers.dev/auth/youtube", { method: "DELETE", headers: { Authorization: `Bearer ${t}` } }), await m$1.auth.remove("token2"); }, login: async t => { const n = await d(t.href), o = await fetch("https://truffle-tv-source-test.truffle-tv.workers.dev/auth/youtube", { method: "POST", body: JSON.stringify(Object.assign(Object.assign({}, t), { cookies: n })) }); if (200 !== o.status) return null; const { jwt: r } = await o.json(); return await m$1.auth.set("token2", r), r }, link: async t => { const n = await m$1.auth.get("token2"), r = await fetch(`https://truffle-tv-source-test.truffle-tv.workers.dev/link/${t}`, { method: "GET", headers: { Authorization: `Bearer ${n}` } }); if (200 !== r.status) return; const s = await r.text(); await chrome.cookies.set({ url: "https://truffle-tv-source-test.truffle-tv.workers.dev", name: "Authorization", value: n, httpOnly: !0, path: `/link/${t}/callback`, expirationDate: Math.floor(Date.now() / 1e3) + 3600 }), await chrome.windows.create({ url: s, focused: !0, type: "popup", width: 850, height: 800 }); const a = await new Promise((t => { u = t; })); return m$1.auth.set("token2", a), dt(a) }, "finish-link": async (t, e) => { var o, r; (null === (o = e.sender.tab) || void 0 === o ? void 0 : o.id) && s.tabs.remove(null === (r = e.sender.tab) || void 0 === r ? void 0 : r.id), null == u || u(t); }, "disconnect-link": async t => { const n = await m$1.auth.get("token2"), r = await fetch(`https://truffle-tv-source-test.truffle-tv.workers.dev/link/${t}`, { method: "DELETE", headers: { Authorization: `Bearer ${n}` } }); if (200 !== r.status) return; const { jwt: s } = await r.json(); return await m$1.auth.set("token2", s), dt(s) } }; const h = { "get-stream": async () => { const t = await m$1.cache.get("get-stream"); let n; if (t && t.expiresAt > Date.now()) n = t.value; else { const t = Date.now() + 6e4; n = await async function() { try { const t = await fetch("https://youtube.com/channel/UCrPseYLGpNygVi34QpGNqpA/live"); if (200 !== t.status) return null; const e = await t.text(), n = /(?:window\s*\[\s*["']ytInitialData["']\s*\]|ytInitialData)\s*=\s*({.+?})\s*;/.exec(e); if (n) { const t = JSON.parse(n[1]), e = t.currentVideoEndpoint.watchEndpoint.videoId, o = t.contents.twoColumnWatchNextResults.results.results.contents[0].videoPrimaryInfoRenderer, r = t.contents.twoColumnWatchNextResults.results.results.contents[1].videoSecondaryInfoRenderer.owner.videoOwnerRenderer.thumbnail.thumbnails[0].url, s = o.viewCount.videoViewCountRenderer.viewCount.runs.find((t => /^[0-9,]+$/.test(t.text))).text; return { title: o.title.runs[0].text, viewersCount: parseInt(s.replace(/,/g, "")), previewImageURL: `https://i.ytimg.com/vi/${e}/mqdefault.jpg`, profileImageURL: r } } } catch (t) { console.warn(t); } return null }(), await m$1.cache.set("get-stream", { expiresAt: t, value: n }); } return n }, "get-user": async t => { const e$1 = await d(t.href), n = await e(Object.assign(Object.assign({}, t), { cookies: e$1 })); if (!n.success) throw new i(n.code, n.message); return n.data } }, g = async (t, { cacheExpirationMs: n = c.ONE_SECOND_MS, cacheControlFallback: o = c.FIVE_MINUTE_SECONDS } = {}) => { var r, s; const a = await m$1.cache.get(t); let i; if (a && a.expiresAt > Date.now()) i = a.value; else { const a = await fetch("https://truffle-tv-source-test.truffle-tv.workers.dev" + t), c = Number(a.headers.get("age")), l = Number((null === (s = null === (r = a.headers.get("cache-control")) || void 0 === r ? void 0 : r.match(/max-age=(\d+)/)) || void 0 === s ? void 0 : s[1]) || o) - c, u = Date.now() + l * n; i = await a.json(), await m$1.cache.set(t, { expiresAt: u, value: i }); } return i }, f = (t, { cacheExpirationMs: e = c.ONE_SECOND_MS, cacheControlFallback: n = c.FIVE_MINUTE_SECONDS } = {}) => async () => g(t, { cacheControlFallback: n, cacheExpirationMs: e }), w = { users: t => (console.log("fetching channelId"), g(`/gateway/users/c/${t}`)), emotes: f("/gateway/emotes"), badges: f("/gateway/badges"), "set-settings": async t => { console.log("updating settings", t); const n = await m$1.auth.get("token2"), r = await fetch("https://truffle-tv-source-test.truffle-tv.workers.dev/gateway/settings", { method: "PUT", headers: { Authorization: `Bearer ${n}` }, body: JSON.stringify(t) }), { jwt: s } = await r.json(); return m$1.auth.set("token2", s), dt(s) } }; async function v(t, n, { expireSeconds: o = c.ONE_MINUTE_SECONDS } = {}) { const r = await m$1.cache.get(t); let s; const a = (null == r ? void 0 : r.expiresAt) > Date.now(); if ((null == r ? void 0 : r.value) && a) s = r.value; else { s = await n(); const r = Date.now() + o * c.ONE_SECOND_MS; await m$1.cache.set(t, { expiresAt: r, value: s }); } return s } function y(t$1, e) { const n = function(t$1) { if (null == t$1 ? void 0 : t$1.nodes) return t$1.nodes.map((t$1 => { if (t$1) return function(t$1) { return { id: t$1.collectible.id, name: t$1.collectible.slug, ext: t$1.collectible.fileRel.fileObj.ext, provider: t.Spore } }(t$1) })).filter(m); return [] }(null == e ? void 0 : e.ownedCollectibleConnection), o = (s = null == e ? void 0 : e.ownedCollectibleConnection, null === (a = null == s ? void 0 : s.nodes) || void 0 === a ? void 0 : a.map((t => { var e; return null === (e = null == t ? void 0 : t.collectible) || void 0 === e ? void 0 : e.slug }))); var s, a; const c = function(t) { var e; return null === (e = null == t ? void 0 : t.nodes) || void 0 === e ? void 0 : e.map((t => { var e; return null === (e = null == t ? void 0 : t.powerup) || void 0 === e ? void 0 : e.slug })) }(null == e ? void 0 : e.activePowerupConnection); return { id: t$1, emotes: o, badges: c, serializedEmotes: n } } const m = t => !!t; async function b(t, e, n, { throwIfErrors: o } = {}) { var r; const s = await fetch(t, { method: "POST", headers: { Authorization: "Bearer pk_1K4r062GimOrw71jtDpzSAhii0lExREdcMZ2Fp5Y2uBjiZ1gS", "Content-Type": "application/json" }, body: JSON.stringify({ query: e, variables: n }) }), a = await s.json(); if (o && (null === (r = a.data) || void 0 === r ? void 0 : r.errors)) throw new Error(`spore graphql error ${a.data.errors}`); return a.data } const S = { youtube: h, gateway: w, auth: p, extension: { popup: () => s.action.openPopup(), "open-tab": async t => { await s.tabs.create({ url: t }); } }, spore: { "fetch-extension-mappings": async ({ channelId: t, extensionVersion: e }) => (console.log("fetching ext. mappigns", { channelId: t, extensionVersion: e }), await async function(t, e, n) { const o = { sourceType: t, sourceId: e, extensionVersion: n }; try { const t = await b("https://zygote.spore.build/graphql", "query GetExtensionMappingConnection($sourceType: String, $sourceId: String, $extensionVersion: String) {\n\textensionMappingConnection(sourceType: $sourceType, sourceId: $sourceId, extensionVersion: $extensionVersion) {\n\t\tnodes {\n\t\t\tid\n\t\t\tslug\n\t\t\tiframeUrl\n\t\t\tdomAction\n\t\t\tquerySelector\n\t\t\tiframeQuerySelector\n\t\t}\n\t}\n}", o); return console.log("res", t), t.extensionMappingConnection.nodes } catch (t) { console.error(t); } }("youtube", t, e)), "fetch-spore-user": async ({ connectionSourceId: t, sporeOrgId: e, preferCache: n = !0 } = {}) => { const o = async () => { const n = await async function(t, e) { const n = { orgId: e, connectionSourceType: "youtube", connectionSourceId: t, collectibleType: "emote" }; try { return (await b("https://zygote.spore.build/graphql", "query CacheableOrgUserWithCollectiblesAndActivePowerups(\n $orgId: ID\n $connectionSourceType: String,\n $connectionSourceId: String,\n $collectibleType: String\n ) {\n orgUser(\n orgId: $orgId\n connectionSourceType: $connectionSourceType,\n connectionSourceId: $connectionSourceId\n\t\t\t) \n\t\t{\n\t\t\tid\n\t\t\tuserId\n\t\t\torgId\n\t\t\townedCollectibleConnection(collectibleType: $collectibleType) {\n\t\t\t\tnodes {\n\t\t\t\t\tuserId\n\t\t\t\t\tcollectible {\n\t\t\t\t\t\tid\n\t\t\t\t\t\tname\n\t\t\t\t\t\tslug\n\t\t\t\t\t\tfileRel {\n\t\t\t\t\t\t\tfileObj {\n\t\t\t\t\t\t\t\tsrc\n\t\t\t\t\t\t\t\text\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tactivePowerupConnection {\n\t\t\t\ttotalCount\n\t\t\t\tnodes {\n\t\t\t\t\tid\n\t\t\t\t\tuserId\n\t\t\t\t\tpowerup {\n\t\t\t\t\t\tid\n\t\t\t\t\t\tslug\n\t\t\t\t\t\tcomponentRels {\n\t\t\t\t\t\t\tprops\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n }\n\t}", n)).orgUser } catch (t) { console.error(t); } }(t, e); return y(t, n) }; if (n) { const t = ((t, e) => `${t}:${e}`)(e, e); return v(t, o, { expireSeconds: 15 }) } return o() }, "fetch-youtube-channel": async t => { const e = (t => `spore-org-yt-channel:${t}`)(t); return v(e, (() => async function(t) { const e = { id: t }; try { return (await b("https://zygote.spore.build/graphql", "query YoutubeChannelById($id: String) {\n\tyoutubeChannel(id: $id) {\n\t\tid\n\t\tsporeOrgId\n\t\tchannelName\n\t\tisLive\t\n\t}\n}", e)).youtubeChannel } catch (t) { console.error(t); } }(t)), { expireSeconds: 60 }) } } }, x = async (e, n$2) => { var o; const { path: r, body: a } = e; if (!r) return; e.meta ? e.meta.sender = n$2 : e.meta = { sender: n$2, isPort: !1 }, e.meta.isPort || (e.meta.isPort = !1); const c = (t => { const e = Date.now(); return console.groupEnd(), console.groupCollapsed(`${t.meta.isPort?"P":""}-> %c${t.path}`, `color: ${n(t.path)}`), void 0 !== t.body && console.log("%cBody:", "color: hsl(0deg, 100%, 70%); font-weight: bold;", t.body), console.log("%cMeta:", "color: hsl(30deg, 100%, 70%); font-weight: bold;", t.meta), console.groupEnd(), n$1 => { console.groupEnd(), console.groupCollapsed(`${t.meta.isPort?"P":""}<- %c${n$1.meta.code}%c ${t.path} %c${Date.now()-e}ms`, `background: ${n$1.meta.isSuccess?"#2ecc71":"#e74c3c"}; color: black; padding: 2px; border-radius: 2px;`, `color: ${n(t.path)}`, "color: white; font-weight: normal"), console.log("%cBody:", "color: hsl(0deg, 100%, 70%); font-weight: bold;", n$1.body), console.groupEnd(); } })(e), i = r.split("/").filter(Boolean), u = i[0]; if (!(u in S)) { const n = l(n$1.NotFound, void 0, e.nonce); return c(n), n } const d = S[u][i.slice(1).join("/")]; if (!d) { const n = l(n$1.NotFound, void 0, e.nonce); return c(n), n } try { const n = ((e, n) => ({ body: e, meta: { isSuccess: !0, code: n$1.Success, nonce: n } }))(await d(a, e.meta), e.nonce); return c(n), n } catch (n) { const r = n; console.error("error in background", r); const s = l(null !== (o = r.code) && void 0 !== o ? o : n$1.Unknown, { message: r.message }, e.nonce); return c(s), s } }; s.runtime.onConnect.addListener((t => { var e; const o = t.sender; o && (console.log(`%cCONNECT:%c ${null===(e=t.sender)||void 0===e?void 0:e.url}`, "color: black; font-weight: bold; background: #2ecc71; padding: 2px; border-radius: 2px;", ""), t.onDisconnect.addListener((() => { var e; console.log(`%cDISCONNECT:%c ${null===(e=t.sender)||void 0===e?void 0:e.url}`, "color: black; font-weight: bold; background: #e74c3c; padding: 2px; border-radius: 2px;", ""); })), t.onMessage.addListener((async e => { e.meta = { isPort: !0 }; const n = await x(e, o); t.postMessage(n); })), s.tabs.onUpdated.addListener(((e, n, o) => { t.postMessage({ type: "tab:updated", tabId: e, changeInfo: n, tab: o }); }))); })), s.runtime.onMessage.addListener(x);