@axis-network/butter-col 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +81 -2
  3. package/bin/butter-col.js +4 -0
  4. package/dist/bootstrap.html +67 -0
  5. package/dist/client.js +2 -0
  6. package/dist/client.js.map +7 -0
  7. package/dist/controller.mjs +2 -0
  8. package/dist/controller.mjs.map +7 -0
  9. package/dist/formatter.mjs +2 -0
  10. package/dist/formatter.mjs.map +7 -0
  11. package/dist/sw.js +30 -0
  12. package/dist/sw.js.map +7 -0
  13. package/dist/transports/butter.js +2 -0
  14. package/dist/transports/butter.js.map +7 -0
  15. package/dist/types/controller/index.d.ts +65 -0
  16. package/dist/types/formatter/codecs.d.ts +17 -0
  17. package/dist/types/formatter/css.d.ts +10 -0
  18. package/dist/types/formatter/html.d.ts +61 -0
  19. package/dist/types/formatter/index.d.ts +77 -0
  20. package/dist/types/formatter/js.d.ts +27 -0
  21. package/dist/types/formatter/url.d.ts +40 -0
  22. package/lib/cli.js +257 -0
  23. package/lib/index.d.ts +68 -0
  24. package/lib/index.js +166 -0
  25. package/package.json +77 -4
  26. package/server/conf/butter-proxy.conf.template +29 -0
  27. package/server/conf/mime.types +19 -0
  28. package/server/conf/nginx.conf.template +152 -0
  29. package/server/config.lua +34 -0
  30. package/server/lua/butter/config.lua +160 -0
  31. package/server/lua/butter/cookiejar.lua +197 -0
  32. package/server/lua/butter/dns.lua +67 -0
  33. package/server/lua/butter/guard.lua +78 -0
  34. package/server/lua/butter/headers.lua +83 -0
  35. package/server/lua/butter/init.lua +18 -0
  36. package/server/lua/butter/ip.lua +165 -0
  37. package/server/lua/butter/limit.lua +18 -0
  38. package/server/lua/butter/session.lua +42 -0
  39. package/server/lua/butter/store.lua +77 -0
  40. package/server/lua/butter/transport.lua +248 -0
  41. package/server/lua/butter/url.lua +78 -0
  42. package/site/app.css +373 -0
  43. package/site/app.js +335 -0
  44. package/site/butter-col.png +0 -0
  45. package/site/index.html +139 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/formatter/codecs.js", "../src/formatter/url.js", "../src/formatter/css.js", "../src/formatter/js.js", "../src/formatter/html.js", "../src/formatter/index.js", "../../butter-transport/src/errors.ts", "../../butter-transport/src/util.ts", "../../butter-transport/src/index.ts", "../src/client/cookies.js", "../src/client/core.js", "../src/client/location.js", "../src/client/util.js", "../src/client/hooks/globals.js", "../src/client/websocket.js", "../src/client/hooks/network.js", "../src/client/hooks/window.js", "../src/client/hooks/document.js", "../src/client/hooks/dom.js", "../src/client/hooks/storage.js", "../src/client/install.js", "../src/client/index.js"],
4
+ "sourcesContent": ["/**\n * URL codecs. A codec turns an absolute target URL (without its fragment)\n * into the string that follows the proxy prefix, and back again.\n *\n * Every codec must satisfy: decode(encode(url)) === url.\n */\n\n/** @typedef {{ encode(url: string): string, decode(encoded: string): string }} Codec */\n\n/** Structure preserving: /butter/go/https://example.com/a/b?c */\nconst none = {\n encode: (url) => url,\n decode: (encoded) => encoded,\n};\n\n/** encodeURIComponent of the whole URL (same idea as Scramjet's \"plain\"). */\nconst plain = {\n encode: (url) => encodeURIComponent(url),\n decode: (encoded) => decodeURIComponent(encoded),\n};\n\n/** XOR every second character with 2 (same scheme as Ultraviolet). */\nfunction xorString(str) {\n let out = \"\";\n for (let i = 0; i < str.length; i++) {\n out += i % 2 ? String.fromCharCode(str.charCodeAt(i) ^ 2) : str[i];\n }\n return out;\n}\n\nconst xor = {\n encode: (url) => encodeURIComponent(xorString(url)),\n decode: (encoded) => xorString(decodeURIComponent(encoded)),\n};\n\n/** URL-safe base64 of the UTF-8 bytes, without padding. */\nconst base64 = {\n encode(url) {\n const bytes = new TextEncoder().encode(url);\n let bin = \"\";\n for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);\n return btoa(bin).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n },\n decode(encoded) {\n let b64 = encoded.replace(/-/g, \"+\").replace(/_/g, \"/\");\n while (b64.length % 4) b64 += \"=\";\n const bin = atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n },\n};\n\n/** @type {Record<string, Codec>} */\nexport const codecs = { none, plain, xor, base64 };\n\n/**\n * @param {string} name\n * @returns {Codec}\n */\nexport function getCodec(name) {\n const codec = codecs[name];\n if (!codec) throw new Error(`butter: unknown codec \"${name}\"`);\n return codec;\n}\n", "import { getCodec } from \"./codecs.js\";\n\n/** Marker placed after the prefix for module workers: /butter/go/~m/<encoded> */\nexport const MODULE_WORKER_MARK = \"~m/\";\n\nconst PASSTHROUGH_SCHEMES = /^(?:data|blob|about|mailto|tel|sms|javascript|intent|chrome|chrome-extension|moz-extension|file|filesystem):/i;\nconst TARGET_SCHEME = /^(?:https?|wss?):\\/\\//i;\n\n/**\n * @typedef {object} UrlRewriterOptions\n * @property {string} origin Proxy origin, e.g. \"https://proxy.example\"\n * @property {string} prefix Path prefix for proxied URLs, e.g. \"/butter/go/\"\n * @property {string} codec Codec name, see codecs.js\n */\n\n/**\n * @param {UrlRewriterOptions} options\n */\nexport function createUrlRewriter({ origin, prefix, codec: codecName }) {\n const codec = getCodec(codecName);\n const absPrefix = origin + prefix;\n\n /**\n * Decode the part of a proxied path that follows the prefix.\n * Returns null when the tail is not a valid encoded URL (for example a\n * relative path that the browser resolved against the proxy URL).\n * @param {string} tail\n * @returns {string | null}\n */\n function decodeTail(tail) {\n if (tail.startsWith(MODULE_WORKER_MARK)) tail = tail.slice(MODULE_WORKER_MARK.length);\n let decoded;\n try {\n decoded = codec.decode(tail);\n } catch {\n return null;\n }\n if (!TARGET_SCHEME.test(decoded)) return null;\n try {\n return new URL(decoded).href;\n } catch {\n return null;\n }\n }\n\n /**\n * Is this an already rewritten URL (absolute or path-absolute)?\n * @param {string} url\n */\n function isProxied(url) {\n return url.startsWith(absPrefix) || url.startsWith(prefix);\n }\n\n /**\n * Rewrite a URL found in a page so that it points through the proxy.\n * Non-http(s) URLs and fragment-only references are returned unchanged.\n * @param {string} raw\n * @param {string | URL} base The target (unproxied) base URL\n * @param {{ moduleWorker?: boolean }} [opts]\n * @returns {string}\n */\n function rewrite(raw, base, opts) {\n if (raw == null) return raw;\n const str = String(raw);\n const trimmed = str.trim();\n if (!trimmed || trimmed.startsWith(\"#\") || PASSTHROUGH_SCHEMES.test(trimmed)) return str;\n if (isProxied(trimmed)) return trimmed;\n let abs;\n try {\n abs = new URL(trimmed, base);\n } catch {\n return str;\n }\n if (abs.protocol !== \"http:\" && abs.protocol !== \"https:\") return str;\n const hash = abs.hash;\n abs.hash = \"\";\n const mark = opts && opts.moduleWorker ? MODULE_WORKER_MARK : \"\";\n return absPrefix + mark + codec.encode(abs.href) + hash;\n }\n\n /**\n * Turn a proxied URL back into the target URL. Anything that is not a\n * proxied URL is returned unchanged.\n * @param {string} url\n * @returns {string}\n */\n function unrewrite(url) {\n if (url == null) return url;\n const str = String(url);\n let rest;\n if (str.startsWith(absPrefix)) rest = str.slice(absPrefix.length);\n else if (str.startsWith(prefix)) rest = str.slice(prefix.length);\n else return str;\n\n let hash = \"\";\n const hashAt = rest.indexOf(\"#\");\n if (hashAt !== -1) {\n hash = rest.slice(hashAt);\n rest = rest.slice(0, hashAt);\n }\n let search = \"\";\n const searchAt = rest.indexOf(\"?\");\n if (searchAt !== -1) {\n search = rest.slice(searchAt);\n rest = rest.slice(0, searchAt);\n }\n const decoded = decodeTail(rest);\n if (decoded === null) return str;\n if (!search) return decoded + hash;\n const target = new URL(decoded);\n target.search = search;\n return target.href + hash;\n }\n\n /**\n * @param {string} value A srcset attribute value\n * @param {string | URL} base\n * @param {(url: string, base: string | URL) => string} [map]\n */\n function rewriteSrcset(value, base, map = rewrite) {\n // Follows the HTML \"parse a srcset attribute\" algorithm closely enough to\n // keep data: URLs (which contain commas) intact.\n let out = \"\";\n let i = 0;\n const n = value.length;\n while (i < n) {\n const wsStart = i;\n while (i < n && (/\\s/.test(value[i]) || value[i] === \",\")) i++;\n out += value.slice(wsStart, i);\n if (i >= n) break;\n const urlStart = i;\n while (i < n && !/\\s/.test(value[i])) i++;\n let url = value.slice(urlStart, i);\n let trailing = \"\";\n const commas = url.match(/,+$/);\n if (commas) {\n trailing = commas[0];\n url = url.slice(0, -trailing.length);\n }\n out += map(url, base) + trailing;\n if (trailing) continue;\n // Descriptors run until the next comma that is not inside parentheses.\n const descStart = i;\n let depth = 0;\n while (i < n) {\n const ch = value[i];\n if (ch === \"(\") depth++;\n else if (ch === \")\") depth = Math.max(0, depth - 1);\n else if (ch === \",\" && depth === 0) break;\n i++;\n }\n out += value.slice(descStart, i);\n }\n return out;\n }\n\n return {\n origin,\n prefix,\n codec,\n decodeTail,\n isProxied,\n rewrite,\n unrewrite,\n rewriteSrcset,\n unrewriteSrcset: (value) => rewriteSrcset(value, \"\", (url) => unrewrite(url)),\n };\n}\n\n/** @typedef {ReturnType<typeof createUrlRewriter>} UrlRewriter */\n", "/**\n * CSS rewriting: url(...) references and @import strings.\n */\n\nconst URL_FUNCTION = /url\\(\\s*(?:\"((?:[^\"\\\\\\n]|\\\\.)*)\"|'((?:[^'\\\\\\n]|\\\\.)*)'|((?:[^)\\s\"'\\\\]|\\\\.)*))\\s*\\)/gi;\nconst IMPORT_STRING = /@import\\s+(?:\"((?:[^\"\\\\\\n]|\\\\.)*)\"|'((?:[^'\\\\\\n]|\\\\.)*)')/gi;\n\n/**\n * @param {string} css\n * @param {string | URL} base\n * @param {(url: string, base: string | URL) => string} rewriteUrl\n * @returns {string}\n */\nexport function rewriteCss(css, base, rewriteUrl) {\n if (!css || (css.indexOf(\"url(\") === -1 && css.indexOf(\"URL(\") === -1 && css.indexOf(\"@import\") === -1)) {\n return css;\n }\n const map = (raw) => {\n // CSS escapes inside URLs are rare; only unescape the trivial cases.\n const url = raw.replace(/\\\\([^0-9a-fA-F\\n])/g, \"$1\");\n if (!url || url.startsWith(\"#\") || /^data:/i.test(url)) return null;\n const rewritten = rewriteUrl(url, base);\n return rewritten === url ? null : rewritten;\n };\n return css\n .replace(URL_FUNCTION, (match, dq, sq, bare) => {\n const raw = dq ?? sq ?? bare ?? \"\";\n const rewritten = map(raw);\n return rewritten === null ? match : `url(\"${rewritten.replace(/[\"\\\\\\n]/g, \"\\\\$&\")}\")`;\n })\n .replace(IMPORT_STRING, (match, dq, sq) => {\n const rewritten = map(dq ?? sq ?? \"\");\n return rewritten === null ? match : `@import \"${rewritten.replace(/[\"\\\\\\n]/g, \"\\\\$&\")}\"`;\n });\n}\n", "/**\n * JavaScript rewriting.\n *\n * butter-col does not parse JavaScript into an AST. Instead a small,\n * error-tolerant tokenizer walks the source and applies a handful of targeted\n * edits. Everything else (fetches, imports, workers, ...) is handled at\n * runtime by the service worker and the client hooks, so the rewriter only\n * has to deal with what cannot be hooked:\n *\n * location / x.location / x?.location / x[\"location\"]\n * -> __butter$location (resolved by an accessor on Object.prototype)\n * eval(code)\n * -> eval(__butter$js(code)) (stays a *direct* eval)\n * import.meta.url\n * -> __butter$unrewrite(import.meta.url)\n *\n * The tokenizer never edits inside strings, template text, comments or regex\n * literals, and every edit is local, so a mis-scan can at worst miss an edit.\n */\n\nexport const LOCATION = \"__butter$location\";\nexport const EVAL_WRAP = \"__butter$js\";\nexport const UNREWRITE = \"__butter$unrewrite\";\n\nconst NEEDS_REWRITE = /location|eval|import\\s*\\.\\s*meta/;\n\n/** Identifiers after which a `/` starts a regular expression. */\nconst EXPR_KEYWORDS = new Set([\n \"return\", \"typeof\", \"instanceof\", \"in\", \"of\", \"new\", \"delete\", \"void\", \"throw\",\n \"case\", \"do\", \"else\", \"yield\", \"await\", \"extends\",\n]);\n\n/** Punctuators after which `{` opens an object literal rather than a block. */\nconst OBJECT_AFTER_PUNC = new Set([\n \"(\", \"[\", \",\", \"=\", \":\", \"?\", \"...\", \"!\", \"&\", \"|\", \"^\", \"~\", \"+\", \"-\", \"*\", \"/\", \"%\",\n \"<\", \">\", \"${\", \"??\", \"?.\",\n]);\nconst OBJECT_AFTER_KEYWORD = new Set([\n \"return\", \"yield\", \"await\", \"typeof\", \"void\", \"in\", \"of\", \"case\", \"throw\", \"delete\",\n]);\n\nconst IMPORT_META_URL = /import\\s*\\.\\s*meta\\s*\\.\\s*url(?![\\w$])/y;\n\nfunction isIdStart(c) {\n return (c >= 97 && c <= 122) || (c >= 65 && c <= 90) || c === 36 || c === 95 || c >= 128;\n}\n\nfunction isIdPart(c) {\n return isIdStart(c) || (c >= 48 && c <= 57);\n}\n\nfunction isWhitespace(c) {\n return c === 32 || c === 9 || c === 10 || c === 13 || c === 11 || c === 12 ||\n c === 0xa0 || c === 0xfeff || c === 0x2028 || c === 0x2029 || c === 0x1680 ||\n (c >= 0x2000 && c <= 0x200a) || c === 0x202f || c === 0x205f || c === 0x3000;\n}\n\nfunction isLineTerminator(c) {\n return c === 10 || c === 13 || c === 0x2028 || c === 0x2029;\n}\n\n/**\n * @param {string} src\n * @returns {string}\n */\nexport function rewriteJs(src) {\n if (typeof src !== \"string\" || !NEEDS_REWRITE.test(src)) return src;\n\n const n = src.length;\n /** @type {Array<[number, number, string]>} start, end, replacement */\n const edits = [];\n\n let prevType = \"\"; // \"id\" | \"num\" | \"str\" | \"tmpl\" | \"regex\" | \"punc\"\n let prevVal = \"\";\n let prev2Type = \"\";\n let prev2Val = \"\";\n /** Open `{` kinds: \"obj\" | \"block\" | \"ie-import\" | \"ie-export\" | \"tmpl\" */\n const braces = [];\n /** Open `(`: null, or the index of the `(` of an eval call */\n const parens = [];\n /** Inside an import statement, before `from` */\n let inImport = false;\n\n const push = (type, val) => {\n prev2Type = prevType;\n prev2Val = prevVal;\n prevType = type;\n prevVal = val;\n };\n\n /** Index of the next character that is not whitespace or a comment. */\n const skipTrivia = (pos) => {\n while (pos < n) {\n const c = src.charCodeAt(pos);\n if (isWhitespace(c)) {\n pos++;\n } else if (c === 47 && src.charCodeAt(pos + 1) === 47) {\n while (pos < n && !isLineTerminator(src.charCodeAt(pos))) pos++;\n } else if (c === 47 && src.charCodeAt(pos + 1) === 42) {\n const end = src.indexOf(\"*/\", pos + 2);\n pos = end === -1 ? n : end + 2;\n } else {\n break;\n }\n }\n return pos;\n };\n\n const peekWord = (pos) => {\n let j = skipTrivia(pos);\n const start = j;\n while (j < n && isIdPart(src.charCodeAt(j))) j++;\n return src.slice(start, j);\n };\n\n const regexAllowed = () => {\n if (!prevType) return true;\n if (prevType === \"punc\") return prevVal !== \")\" && prevVal !== \"]\" && prevVal !== \"++\" && prevVal !== \"--\";\n if (prevType === \"id\") return EXPR_KEYWORDS.has(prevVal);\n return false;\n };\n\n const scanString = (i, quote) => {\n let j = i + 1;\n while (j < n) {\n const c = src.charCodeAt(j);\n if (c === 92) j += 2;\n else if (c === quote) return j + 1;\n else if (c === 10 || c === 13) return j; // unterminated, recover\n else j++;\n }\n return n;\n };\n\n /** Scan template text starting at j. Returns [end, opensSubstitution]. */\n const scanTemplate = (j) => {\n while (j < n) {\n const c = src.charCodeAt(j);\n if (c === 92) j += 2;\n else if (c === 96) return [j + 1, false];\n else if (c === 36 && src.charCodeAt(j + 1) === 123) return [j + 2, true];\n else j++;\n }\n return [n, false];\n };\n\n /** Returns the end of the regex literal starting at i, or -1. */\n const scanRegex = (i) => {\n let j = i + 1;\n let inClass = false;\n while (j < n) {\n const c = src.charCodeAt(j);\n if (isLineTerminator(c)) return -1;\n if (c === 92) {\n if (j + 1 >= n || isLineTerminator(src.charCodeAt(j + 1))) return -1;\n j += 2;\n continue;\n }\n if (inClass) {\n if (c === 93) inClass = false;\n } else if (c === 91) {\n inClass = true;\n } else if (c === 47) {\n j++;\n while (j < n && isIdPart(src.charCodeAt(j))) j++;\n return j;\n }\n j++;\n }\n return -1;\n };\n\n const handleTemplate = (start) => {\n const [end, opens] = scanTemplate(start);\n if (opens) {\n braces.push(\"tmpl\");\n push(\"punc\", \"${\");\n } else {\n push(\"tmpl\", \"\");\n }\n return end;\n };\n\n const handleLocation = (start, end) => {\n if (prevType === \"punc\" && (prevVal === \".\" || prevVal === \"?.\")) {\n edits.push([start, end, LOCATION]);\n return;\n }\n const top = braces[braces.length - 1];\n if (top === \"ie-import\" || top === \"ie-export\") {\n const importing = top === \"ie-import\";\n if (prevType === \"id\" && prevVal === \"as\") {\n if (importing) edits.push([start, end, LOCATION]); // local binding\n } else if (peekWord(end) === \"as\") {\n if (!importing) edits.push([start, end, LOCATION]); // local binding\n } else {\n edits.push([start, end, importing ? `location as ${LOCATION}` : `${LOCATION} as location`]);\n }\n return;\n }\n if (top === \"obj\" && prevType === \"punc\" && (prevVal === \"{\" || prevVal === \",\")) {\n const next = src[skipTrivia(end)];\n if (next === \":\") return; // property key\n if (next === \",\" || next === \"}\") {\n edits.push([start, end, `location: ${LOCATION}`]); // shorthand property\n return;\n }\n }\n edits.push([start, end, LOCATION]);\n };\n\n let i = 0;\n if (src.startsWith(\"#!\")) {\n while (i < n && !isLineTerminator(src.charCodeAt(i))) i++;\n }\n\n while (i < n) {\n const c = src.charCodeAt(i);\n\n if (isWhitespace(c)) {\n i++;\n continue;\n }\n\n // Comments, regular expressions and division.\n if (c === 47) {\n const d = src.charCodeAt(i + 1);\n if (d === 47 || d === 42) {\n i = skipTrivia(i);\n continue;\n }\n if (regexAllowed()) {\n const end = scanRegex(i);\n if (end !== -1) {\n i = end;\n push(\"regex\", \"\");\n continue;\n }\n }\n i++;\n push(\"punc\", \"/\");\n continue;\n }\n\n // Strings.\n if (c === 34 || c === 39) {\n const end = scanString(i, c);\n const value = src.slice(i + 1, end - 1);\n if (\n value === \"location\" &&\n prevType === \"punc\" && prevVal === \"[\" &&\n ((prev2Type === \"id\" && !EXPR_KEYWORDS.has(prev2Val)) || prev2Val === \")\" || prev2Val === \"]\") &&\n src[skipTrivia(end)] === \"]\"\n ) {\n const quote = src[i];\n edits.push([i, end, quote + LOCATION + quote]);\n }\n i = end;\n push(\"str\", value);\n continue;\n }\n\n // Template literals.\n if (c === 96) {\n i = handleTemplate(i + 1);\n continue;\n }\n\n // Identifiers and keywords.\n if (isIdStart(c) || c === 92) {\n let j = i;\n let escaped = false;\n while (j < n) {\n const cc = src.charCodeAt(j);\n if (cc === 92) {\n // \\uXXXX or \\u{X...} escape inside an identifier\n escaped = true;\n if (src.charCodeAt(j + 2) === 123) {\n const close = src.indexOf(\"}\", j);\n j = close === -1 ? n : close + 1;\n } else {\n j += 6;\n }\n } else if (isIdPart(cc) && !isWhitespace(cc)) {\n j++;\n } else {\n break;\n }\n }\n const value = src.slice(i, j);\n const afterDot = prevType === \"punc\" && (prevVal === \".\" || prevVal === \"?.\");\n\n if (!escaped) {\n if (value === \"location\") {\n handleLocation(i, j);\n } else if (value === \"import\" && !afterDot) {\n IMPORT_META_URL.lastIndex = i;\n if (IMPORT_META_URL.test(src)) {\n const end = IMPORT_META_URL.lastIndex;\n edits.push([i, end, `${UNREWRITE}(import.meta.url)`]);\n i = end;\n push(\"punc\", \")\");\n continue;\n }\n const next = src[skipTrivia(j)];\n if (next !== \"(\" && next !== \".\") inImport = true;\n } else if (value === \"from\" && inImport) {\n inImport = false;\n }\n }\n\n i = j;\n push(\"id\", value);\n continue;\n }\n\n // Private names and numbers.\n if (c === 35) {\n let j = i + 1;\n while (j < n && isIdPart(src.charCodeAt(j))) j++;\n push(\"id\", src.slice(i, j));\n i = j;\n continue;\n }\n if ((c >= 48 && c <= 57) || (c === 46 && src.charCodeAt(i + 1) >= 48 && src.charCodeAt(i + 1) <= 57)) {\n let j = i + 1;\n while (j < n) {\n const cc = src.charCodeAt(j);\n if (isIdPart(cc) || cc === 46) j++;\n else break;\n }\n i = j;\n push(\"num\", \"\");\n continue;\n }\n\n // Punctuators.\n switch (c) {\n case 123: { // {\n let kind = \"block\";\n if (prevType === \"id\" && (prevVal === \"import\" || prevVal === \"export\") && prev2Val !== \".\" && prev2Val !== \"?.\") {\n kind = \"ie-\" + prevVal;\n } else if (inImport && prevType === \"punc\" && prevVal === \",\") {\n kind = \"ie-import\";\n } else if ((prevType === \"punc\" && OBJECT_AFTER_PUNC.has(prevVal)) || (prevType === \"id\" && OBJECT_AFTER_KEYWORD.has(prevVal))) {\n kind = \"obj\";\n }\n braces.push(kind);\n i++;\n push(\"punc\", \"{\");\n continue;\n }\n case 125: { // }\n const kind = braces.pop();\n if (kind === \"tmpl\") {\n i = handleTemplate(i + 1);\n continue;\n }\n i++;\n push(\"punc\", \"}\");\n continue;\n }\n case 40: { // (\n const isEvalCall = prevType === \"id\" && prevVal === \"eval\" &&\n prev2Val !== \".\" && prev2Val !== \"?.\" && prev2Val !== \"function\";\n parens.push(isEvalCall ? i : null);\n i++;\n push(\"punc\", \"(\");\n continue;\n }\n case 41: { // )\n const open = parens.pop();\n // `eval(x) {` is a method definition, not a call.\n if (open != null && src[skipTrivia(i + 1)] !== \"{\") {\n edits.push([open + 1, open + 1, EVAL_WRAP + \"(\"]);\n edits.push([i, i, \")\"]);\n }\n i++;\n push(\"punc\", \")\");\n continue;\n }\n case 46: // .\n if (src.charCodeAt(i + 1) === 46 && src.charCodeAt(i + 2) === 46) {\n i += 3;\n push(\"punc\", \"...\");\n } else {\n i++;\n push(\"punc\", \".\");\n }\n continue;\n case 63: { // ?\n const d = src.charCodeAt(i + 1);\n const e = src.charCodeAt(i + 2);\n if (d === 46 && !(e >= 48 && e <= 57)) {\n i += 2;\n push(\"punc\", \"?.\");\n } else if (d === 63) {\n i += 2;\n push(\"punc\", \"??\");\n } else {\n i++;\n push(\"punc\", \"?\");\n }\n continue;\n }\n case 43: // +\n case 45: // -\n if (src.charCodeAt(i + 1) === c) {\n i += 2;\n push(\"punc\", c === 43 ? \"++\" : \"--\");\n } else {\n i++;\n push(\"punc\", src[i - 1]);\n }\n continue;\n case 61: // =\n if (src.charCodeAt(i + 1) === 62) {\n i += 2;\n push(\"punc\", \"=>\");\n } else {\n i++;\n push(\"punc\", \"=\");\n }\n continue;\n case 59: // ;\n inImport = false;\n i++;\n push(\"punc\", \";\");\n continue;\n default:\n i++;\n push(\"punc\", src[i - 1]);\n }\n }\n\n if (edits.length === 0) return src;\n\n edits.sort((a, b) => a[0] - b[0] || (a[1] - a[0]) - (b[1] - b[0]));\n let out = \"\";\n let last = 0;\n for (const [start, end, text] of edits) {\n if (start < last) continue; // overlapping edit; keep the first\n out += src.slice(last, start) + text;\n last = end;\n }\n return out + src.slice(last);\n}\n", "/**\n * HTML rewriting with a small, forgiving tokenizer (service workers have no\n * DOMParser). Only start tags are modified; text, comments and end tags are\n * copied through byte for byte, and unchanged tags keep their exact source.\n */\n\nconst RAW_TEXT = new Set([\"script\", \"style\", \"textarea\", \"title\", \"xmp\", \"iframe\", \"noembed\", \"noframes\", \"plaintext\"]);\n\nconst JS_TYPE = /^(?:|module|(?:text|application)\\/(?:x-)?(?:javascript|ecmascript)|text\\/jscript|text\\/livescript|text\\/javascript1\\.[0-5])$/i;\n\n/** Attributes holding a single URL, on any element. */\nexport const URL_ATTRS = new Set([\n \"href\", \"src\", \"action\", \"formaction\", \"poster\", \"background\", \"cite\", \"longdesc\",\n \"manifest\", \"codebase\", \"icon\", \"lowsrc\", \"dynsrc\", \"xlink:href\",\n]);\n\n/** Attributes whose name is changed so the browser ignores them. */\nconst NEUTRALIZE = {\n integrity: \"data-butter-integrity\",\n sandbox: \"data-butter-sandbox\", // sandboxed frames cannot be controlled by the service worker\n};\n\nconst NAMED_ENTITIES = { amp: \"&\", lt: \"<\", gt: \">\", quot: '\"', apos: \"'\", nbsp: String.fromCharCode(0xa0) };\nconst ENTITY = /&(?:#(\\d{1,7});?|#[xX]([0-9a-fA-F]{1,6});?|(amp|lt|gt|quot|apos|nbsp)(?:;|(?![=\\w])))/g;\n\n/** @param {string} value */\nexport function decodeEntities(value) {\n if (value.indexOf(\"&\") === -1) return value;\n return value.replace(ENTITY, (match, dec, hex, named) => {\n if (named) return NAMED_ENTITIES[named];\n const code = dec ? parseInt(dec, 10) : parseInt(hex, 16);\n return code > 0 && code <= 0x10ffff ? String.fromCodePoint(code) : String.fromCharCode(0xfffd);\n });\n}\n\n/** @param {string} value */\nexport function escapeAttribute(value) {\n return value.replace(/&/g, \"&amp;\").replace(/\"/g, \"&quot;\");\n}\n\nfunction isWs(c) {\n return c === 32 || c === 9 || c === 10 || c === 12 || c === 13;\n}\n\nfunction isLetter(c) {\n return (c >= 97 && c <= 122) || (c >= 65 && c <= 90);\n}\n\n/**\n * @typedef {object} RewriteContext\n * @property {string} base Target base URL used to resolve relative URLs\n * @property {string} [inject] Markup inserted at the start of the document\n */\n\n/**\n * Rewrite one attribute value. Returns the new value (possibly identical).\n * Shared by the HTML rewriter and the client runtime's setAttribute hook.\n *\n * @param {import(\"./index.js\").Formatter} f\n * @param {string} tag Lower-case tag name\n * @param {string} name Attribute name\n * @param {string} value Decoded attribute value\n * @param {RewriteContext} ctx\n * @returns {string}\n */\nexport function rewriteAttribute(f, tag, name, value, ctx) {\n const attr = name.toLowerCase();\n if (attr.length > 2 && attr.startsWith(\"on\")) return f.js(value);\n switch (attr) {\n case \"style\":\n return f.css(value, ctx.base);\n case \"srcset\":\n case \"imagesrcset\":\n return f.url.rewriteSrcset(value, ctx.base);\n case \"ping\":\n return value.split(/(\\s+)/).map((part) => (part.trim() ? f.rewriteUrl(part, ctx.base) : part)).join(\"\");\n case \"srcdoc\":\n return tag === \"iframe\" ? f.html(value, { base: ctx.base, inject: ctx.inject }) : value;\n case \"data\":\n return tag === \"object\" ? f.rewriteUrl(value, ctx.base) : value;\n }\n if (URL_ATTRS.has(attr)) {\n const trimmed = value.trim();\n if (/^javascript:/i.test(trimmed)) {\n const code = trimmed.slice(11);\n return code.indexOf(\"%\") === -1 ? \"javascript:\" + f.js(code) : value;\n }\n return f.rewriteUrl(value, ctx.base);\n }\n return value;\n}\n\n/**\n * @typedef {object} Attr\n * @property {string} name\n * @property {string | null} value Decoded value, null for boolean attributes\n * @property {number} start\n * @property {number} end\n * @property {string} [newName]\n * @property {string | null} [newValue]\n */\n\n/**\n * Parse a start tag beginning at `i` (src[i] === \"<\", src[i + 1] is a letter).\n * @param {string} src\n * @param {number} i\n */\nfunction parseStartTag(src, i) {\n const n = src.length;\n let j = i + 1;\n while (j < n) {\n const c = src.charCodeAt(j);\n if (isWs(c) || c === 47 || c === 62) break;\n j++;\n }\n const name = src.slice(i + 1, j).toLowerCase();\n /** @type {Attr[]} */\n const attrs = [];\n let selfClosing = false;\n\n while (j < n) {\n let c = src.charCodeAt(j);\n if (isWs(c)) {\n j++;\n continue;\n }\n if (c === 47) {\n if (src.charCodeAt(j + 1) === 62) {\n selfClosing = true;\n return { name, attrs, selfClosing, end: j + 2 };\n }\n j++;\n continue;\n }\n if (c === 62) return { name, attrs, selfClosing, end: j + 1 };\n\n const start = j++;\n while (j < n) {\n c = src.charCodeAt(j);\n if (isWs(c) || c === 47 || c === 62 || c === 61) break;\n j++;\n }\n const attrName = src.slice(start, j);\n let k = j;\n while (k < n && isWs(src.charCodeAt(k))) k++;\n if (src.charCodeAt(k) !== 61) {\n attrs.push({ name: attrName, value: null, start, end: j });\n continue;\n }\n k++;\n while (k < n && isWs(src.charCodeAt(k))) k++;\n const q = src.charCodeAt(k);\n let raw;\n if (q === 34 || q === 39) {\n const close = src.indexOf(q === 34 ? '\"' : \"'\", k + 1);\n if (close === -1) return null;\n raw = src.slice(k + 1, close);\n j = close + 1;\n } else {\n const vs = k;\n while (k < n && !isWs(src.charCodeAt(k)) && src.charCodeAt(k) !== 62) k++;\n raw = src.slice(vs, k);\n j = k;\n }\n attrs.push({ name: attrName, value: decodeEntities(raw), start, end: j });\n }\n return null; // unterminated tag at end of input\n}\n\n/** @param {Attr[]} attrs @param {string} name */\nfunction findAttr(attrs, name) {\n for (const attr of attrs) if (attr.name.toLowerCase() === name) return attr;\n return undefined;\n}\n\n/**\n * Work out the changes for one start tag, recording them on the attrs.\n * @returns {boolean} whether anything changed\n */\nfunction transformTag(f, tag, ctx, state) {\n let changed = false;\n const { name, attrs } = tag;\n\n if (name === \"meta\") {\n const equiv = findAttr(attrs, \"http-equiv\");\n const kind = equiv && equiv.value ? equiv.value.trim().toLowerCase() : \"\";\n if (kind.startsWith(\"content-security-policy\")) {\n equiv.newName = \"data-butter-http-equiv\";\n return true;\n }\n if (kind === \"refresh\") {\n const content = findAttr(attrs, \"content\");\n if (content && content.value) {\n const value = rewriteRefresh(f, content.value, ctx.base);\n if (value !== content.value) {\n content.newValue = value;\n changed = true;\n }\n }\n }\n return changed;\n }\n\n if (name === \"base\" && !state.baseSeen) {\n const href = findAttr(attrs, \"href\");\n if (href && href.value !== null) {\n state.baseSeen = true;\n try {\n ctx.base = new URL(href.value.trim(), ctx.base).href;\n } catch {\n // keep the previous base\n }\n }\n }\n\n for (const attr of attrs) {\n if (attr.value === null) continue;\n const lower = attr.name.toLowerCase();\n if (lower === \"data-butter\") return false; // our own markup\n const rename = NEUTRALIZE[lower];\n if (rename && (lower !== \"sandbox\" || name === \"iframe\")) {\n attr.newName = rename;\n changed = true;\n continue;\n }\n const value = rewriteAttribute(f, name, attr.name, attr.value, ctx);\n if (value !== attr.value) {\n attr.newValue = value;\n changed = true;\n }\n }\n return changed;\n}\n\n/**\n * Rewrite the URL in a refresh value such as \"5; url=/next\".\n * @returns {string}\n */\nexport function rewriteRefresh(f, value, base) {\n const match = value.match(/^(\\s*[\\d.]*\\s*[;,]?\\s*(?:url\\s*=\\s*)?)(['\"]?)(.*?)\\2(\\s*)$/i);\n if (!match || !match[3]) return value;\n return match[1] + match[2] + f.rewriteUrl(match[3], base) + match[2] + match[4];\n}\n\nfunction serializeTag(src, tag, i) {\n let out = \"\";\n let last = i;\n for (const attr of tag.attrs) {\n if (attr.newName === undefined && attr.newValue === undefined) continue;\n const name = attr.newName ?? attr.name;\n const value = attr.newValue !== undefined ? attr.newValue : attr.value;\n out += src.slice(last, attr.start) + name + (value === null ? \"\" : `=\"${escapeAttribute(value)}\"`);\n last = attr.end;\n }\n return out + src.slice(last, tag.end);\n}\n\nconst closeTagCache = new Map();\nfunction findRawTextEnd(src, name, from) {\n let re = closeTagCache.get(name);\n if (!re) {\n re = new RegExp(`</${name}(?=[\\\\s/>])`, \"ig\");\n closeTagCache.set(name, re);\n }\n re.lastIndex = from;\n const match = re.exec(src);\n return match ? match.index : src.length;\n}\n\n/**\n * @param {string} html\n * @param {import(\"./index.js\").Formatter} f\n * @param {RewriteContext} options\n * @returns {string}\n */\nexport function rewriteHtml(html, f, options) {\n const ctx = { base: options.base, inject: options.inject };\n const state = { injected: !options.inject, baseSeen: false, foreign: 0, doctypeEnd: -1 };\n const n = html.length;\n let out = \"\";\n let i = 0;\n\n const inject = () => {\n state.injected = true;\n return ctx.inject || \"\";\n };\n\n while (i < n) {\n const lt = html.indexOf(\"<\", i);\n if (lt === -1) {\n out += html.slice(i);\n break;\n }\n out += html.slice(i, lt);\n i = lt;\n const next = html.charCodeAt(i + 1);\n\n // Comments, doctype, CDATA and other markup declarations.\n if (next === 33 || next === 63) {\n let end;\n if (html.startsWith(\"<!--\", i)) {\n if (html.startsWith(\"<!-->\", i)) end = i + 5;\n else if (html.startsWith(\"<!--->\", i)) end = i + 6;\n else {\n const close = html.indexOf(\"-->\", i + 4);\n end = close === -1 ? n : close + 3;\n }\n } else if (state.foreign && html.startsWith(\"<![CDATA[\", i)) {\n const close = html.indexOf(\"]]>\", i + 9);\n end = close === -1 ? n : close + 3;\n } else {\n const close = html.indexOf(\">\", i + 2);\n end = close === -1 ? n : close + 1;\n if (/^<!doctype/i.test(html.slice(i, i + 9))) state.doctypeEnd = out.length + (end - i);\n }\n out += html.slice(i, end);\n i = end;\n continue;\n }\n\n // End tags.\n if (next === 47) {\n const close = html.indexOf(\">\", i + 2);\n const end = close === -1 ? n : close + 1;\n if (isLetter(html.charCodeAt(i + 2))) {\n const name = html.slice(i + 2, end).match(/^[^\\s/>]*/)[0].toLowerCase();\n if ((name === \"svg\" || name === \"math\") && state.foreign > 0) state.foreign--;\n }\n out += html.slice(i, end);\n i = end;\n continue;\n }\n\n if (!isLetter(next)) {\n out += \"<\";\n i++;\n continue;\n }\n\n // Start tags.\n const tag = parseStartTag(html, i);\n if (!tag) {\n out += html.slice(i);\n break;\n }\n\n if (!state.injected && tag.name !== \"html\") {\n if (tag.name !== \"head\") out += inject();\n }\n\n out += transformTag(f, tag, ctx, state) ? serializeTag(html, tag, i) : html.slice(i, tag.end);\n i = tag.end;\n\n if (!state.injected && tag.name === \"head\") out += inject();\n if ((tag.name === \"svg\" || tag.name === \"math\") && !tag.selfClosing) state.foreign++;\n\n const raw = state.foreign\n ? (tag.name === \"script\" || tag.name === \"style\") && !tag.selfClosing\n : RAW_TEXT.has(tag.name);\n if (!raw) continue;\n\n if (tag.name === \"plaintext\") {\n out += html.slice(i);\n break;\n }\n const end = findRawTextEnd(html, tag.name, i);\n let content = html.slice(i, end);\n if (tag.name === \"script\" && !findAttr(tag.attrs, \"data-butter\")) {\n const type = findAttr(tag.attrs, \"type\");\n if (JS_TYPE.test(type && type.value ? type.value.trim() : \"\")) content = f.js(content);\n } else if (tag.name === \"style\") {\n content = f.css(content, ctx.base);\n }\n out += content;\n i = end;\n }\n\n if (!state.injected) {\n const markup = inject();\n if (state.doctypeEnd !== -1) out = out.slice(0, state.doctypeEnd) + markup + out.slice(state.doctypeEnd);\n else out = markup + out;\n }\n return out;\n}\n", "/**\n * butter-col formatter: everything that turns a target site's content into\n * content that keeps working when served from the proxy origin.\n *\n * It is shared by the service worker (src/sw) and the in-page runtime\n * (src/client) and has no dependencies on either environment beyond the\n * standard URL / TextEncoder APIs.\n */\n\nimport { createUrlRewriter, MODULE_WORKER_MARK } from \"./url.js\";\nimport { rewriteCss } from \"./css.js\";\nimport { rewriteJs, LOCATION, EVAL_WRAP, UNREWRITE } from \"./js.js\";\nimport { rewriteHtml, rewriteAttribute, rewriteRefresh, URL_ATTRS, decodeEntities, escapeAttribute } from \"./html.js\";\nimport { codecs, getCodec } from \"./codecs.js\";\n\n/**\n * @typedef {object} FormatterConfig\n * @property {string} origin Proxy origin\n * @property {string} prefix Prefix for proxied URLs, e.g. \"/butter/go/\"\n * @property {string} codec Codec name\n */\n\n/**\n * @param {FormatterConfig} config\n */\nexport function createFormatter(config) {\n const url = createUrlRewriter(config);\n\n const formatter = {\n config,\n url,\n /** @param {string} raw @param {string | URL} base @param {{ moduleWorker?: boolean }} [opts] */\n rewriteUrl: (raw, base, opts) => url.rewrite(raw, base, opts),\n /** @param {string} proxied */\n unrewriteUrl: (proxied) => url.unrewrite(proxied),\n /** @param {string} src @param {string | URL} base */\n css: (src, base) => rewriteCss(src, base, url.rewrite),\n /** @param {string} src */\n js: (src) => rewriteJs(src),\n /** @param {string} src @param {{ base: string, inject?: string }} options */\n html: (src, options) => rewriteHtml(src, formatter, options),\n /** @param {string} tag @param {string} name @param {string} value @param {{ base: string, inject?: string }} ctx */\n attr: (tag, name, value, ctx) => rewriteAttribute(formatter, tag, name, value, ctx),\n /** @param {string} value @param {string} base */\n refresh: (value, base) => rewriteRefresh(formatter, value, base),\n };\n return formatter;\n}\n\n/** @typedef {ReturnType<typeof createFormatter>} Formatter */\n\nexport {\n codecs,\n getCodec,\n rewriteCss,\n rewriteJs,\n rewriteHtml,\n decodeEntities,\n escapeAttribute,\n URL_ATTRS,\n MODULE_WORKER_MARK,\n LOCATION,\n EVAL_WRAP,\n UNREWRITE,\n};\n", "/**\n * Error codes butter-col understands. Transports may use their own codes too\n * (prefix them, e.g. \"BARE_...\"); they are shown to the visitor as-is.\n */\nexport const TRANSPORT_ERROR_CODES = {\n /** The transport's backend could not be reached. */\n UNREACHABLE: \"TRANSPORT_UNREACHABLE\",\n /** The backend answered with something the transport could not understand. */\n BAD_RESPONSE: \"BAD_TRANSPORT_RESPONSE\",\n /** The target's host name did not resolve. */\n DNS_FAILURE: \"DNS_FAILURE\",\n /** The target refused or reset the connection, or TLS failed. */\n UPSTREAM_UNREACHABLE: \"UPSTREAM_UNREACHABLE\",\n /** The target did not answer in time. */\n UPSTREAM_TIMEOUT: \"UPSTREAM_TIMEOUT\",\n /** The backend refused this target (policy). */\n BLOCKED: \"BLOCKED\",\n /** Anything else. */\n ERROR: \"TRANSPORT_ERROR\",\n} as const;\n\n/**\n * Throw this from request() to give the visitor a meaningful error page.\n * `status` is the HTTP status of that page (502 by default).\n */\nexport class TransportError extends Error {\n readonly code: string;\n readonly status: number;\n\n constructor(code: string, message: string, status = 502) {\n super(message);\n this.name = \"TransportError\";\n this.code = code;\n this.status = status;\n }\n\n /** Errors cross realms (service worker \u2192 page); recognise them by shape too. */\n static is(value: unknown): value is TransportError {\n return value instanceof TransportError ||\n (!!value && typeof value === \"object\" && (value as Error).name === \"TransportError\" &&\n typeof (value as TransportError).code === \"string\");\n }\n}\n", "import type { HeaderList } from \"./types.js\";\n\n/** Headers / object / list \u2192 HeaderList (names lower-cased). */\nexport function headersToList(headers: Headers | Record<string, string | string[]> | HeaderList): HeaderList {\n const list: HeaderList = [];\n if (Array.isArray(headers)) {\n for (const [name, value] of headers) list.push([name.toLowerCase(), value]);\n } else if (typeof Headers !== \"undefined\" && headers instanceof Headers) {\n headers.forEach((value, name) => list.push([name, value]));\n // Headers joins Set-Cookie values; getSetCookie() keeps them apart.\n const setCookies = typeof headers.getSetCookie === \"function\" ? headers.getSetCookie() : [];\n if (setCookies.length) {\n const rest = list.filter(([name]) => name !== \"set-cookie\");\n return [...rest, ...setCookies.map((value): [string, string] => [\"set-cookie\", value])];\n }\n } else {\n for (const [name, value] of Object.entries(headers)) {\n for (const v of Array.isArray(value) ? value : [value]) list.push([name.toLowerCase(), String(v)]);\n }\n }\n return list;\n}\n\n/** HeaderList \u2192 object, joining repeated names with \", \" (Set-Cookie kept as array). */\nexport function listToObject(list: HeaderList): Record<string, string | string[]> {\n const out: Record<string, string | string[]> = {};\n for (const [name, value] of list) {\n const key = name.toLowerCase();\n if (key === \"set-cookie\") {\n const prev = out[key];\n out[key] = Array.isArray(prev) ? [...prev, value] : [value];\n } else {\n out[key] = key in out ? `${out[key]}, ${value}` : value;\n }\n }\n return out;\n}\n\n/** Read any TransportResponse body into an ArrayBuffer. */\nexport async function readBody(body: ReadableStream<Uint8Array> | ArrayBuffer | Blob | string | null): Promise<ArrayBuffer> {\n if (body == null) return new ArrayBuffer(0);\n if (body instanceof ArrayBuffer) return body;\n return new Response(body as BodyInit).arrayBuffer();\n}\n", "/**\n * @axis-network/butter-transport: the transport API for butter-col.\n *\n * Transport authors import registerTransport() and the types from here and\n * ship a classic script that registers their factory. butter-col loads that\n * script in the service worker, in proxied pages and in workers, and creates\n * an instance in each realm that needs one.\n */\nimport type { ButterTransport, TransportEnvironment, TransportFactory } from \"./types.js\";\n\nexport * from \"./types.js\";\nexport { TransportError, TRANSPORT_ERROR_CODES } from \"./errors.js\";\nexport { headersToList, listToObject, readBody } from \"./util.js\";\n\ndeclare global {\n // eslint-disable-next-line no-var\n var __butter$transports: Map<string, TransportFactory> | undefined;\n}\n\n/** The registry is a global so separately bundled transports share it. */\nfunction registry(): Map<string, TransportFactory> {\n return (globalThis.__butter$transports ??= new Map());\n}\n\nconst NAME = /^[a-z0-9][a-z0-9._-]{0,63}$/;\n\n/**\n * Register a transport factory under `name`. Call it at the top level of your\n * transport's script.\n *\n * ```js\n * registerTransport(\"mine\", (options, env) => ({ meta: {...}, request(req) {...} }));\n * ```\n */\nexport function registerTransport<Options>(name: string, factory: TransportFactory<Options>): void {\n if (!NAME.test(name)) throw new TypeError(`butter-transport: invalid transport name \"${name}\"`);\n if (typeof factory !== \"function\") throw new TypeError(`butter-transport: factory for \"${name}\" is not a function`);\n if (registry().has(name)) console.warn(`[butter] transport \"${name}\" registered twice; the last one wins`);\n registry().set(name, factory as TransportFactory);\n}\n\nexport function getTransportFactory(name: string): TransportFactory | undefined {\n return registry().get(name);\n}\n\n/** Names of every registered transport in this realm. */\nexport function listTransports(): string[] {\n return [...registry().keys()];\n}\n\n/**\n * Create, validate and initialise a transport. Used by butter-col itself;\n * also handy in tests.\n */\nexport async function createTransport(name: string, options: unknown, env: TransportEnvironment): Promise<ButterTransport> {\n const factory = getTransportFactory(name);\n if (!factory) {\n throw new Error(`butter-transport: no transport named \"${name}\" is registered (loaded: ${listTransports().join(\", \") || \"none\"})`);\n }\n const transport = await factory(options, env);\n const problems = validateTransport(transport);\n if (problems.length) throw new TypeError(`butter-transport: \"${name}\" is invalid: ${problems.join(\"; \")}`);\n if (transport.meta.name !== name) {\n throw new TypeError(`butter-transport: \"${name}\" reports meta.name \"${transport.meta.name}\"`);\n }\n await transport.init?.();\n return transport;\n}\n\n/** Structural checks; returns a list of problems (empty when valid). */\nexport function validateTransport(transport: unknown): string[] {\n const problems: string[] = [];\n const t = transport as Partial<ButterTransport> | null;\n if (!t || typeof t !== \"object\") return [\"factory did not return an object\"];\n const meta = t.meta;\n if (!meta || typeof meta !== \"object\") problems.push(\"meta is missing\");\n else {\n if (typeof meta.name !== \"string\") problems.push(\"meta.name must be a string\");\n if (meta.cookies !== \"server\" && meta.cookies !== \"client\") problems.push('meta.cookies must be \"server\" or \"client\"');\n if (typeof meta.websockets !== \"boolean\") problems.push(\"meta.websockets must be a boolean\");\n if (meta.websockets && typeof t.connect !== \"function\") problems.push(\"meta.websockets is true but connect() is missing\");\n }\n if (typeof t.request !== \"function\") problems.push(\"request() is missing\");\n if (t.init !== undefined && typeof t.init !== \"function\") problems.push(\"init must be a function\");\n if (t.destroy !== undefined && typeof t.destroy !== \"function\") problems.push(\"destroy must be a function\");\n return problems;\n}\n", "/**\n * document.cookie mirror.\n *\n * The real cookie jar lives on the server (so HttpOnly cookies never reach\n * the page). Each document is served with the non-HttpOnly cookies visible\n * to it; writes update this local copy immediately and are sent back to the\n * server so the next request carries them.\n */\n\nfunction parsePairs(str) {\n const jar = new Map();\n for (const part of str.split(\";\")) {\n if (!part.trim()) continue;\n const eq = part.indexOf(\"=\");\n if (eq === -1) jar.set(\"\", part.trim());\n else jar.set(part.slice(0, eq).trim(), part.slice(eq + 1).trim());\n }\n return jar;\n}\n\nfunction isExpired(attributes) {\n for (const attr of attributes) {\n const eq = attr.indexOf(\"=\");\n const key = (eq === -1 ? attr : attr.slice(0, eq)).trim().toLowerCase();\n const value = eq === -1 ? \"\" : attr.slice(eq + 1).trim();\n if (key === \"max-age\" && /^-?\\d+$/.test(value)) return Number(value) <= 0;\n if (key === \"expires\") {\n const time = Date.parse(value);\n if (!Number.isNaN(time) && time <= Date.now()) return true;\n }\n }\n return false;\n}\n\n/**\n * @param {string} initial document.cookie string provided by the server\n * @param {string} endpoint write-back endpoint (POST)\n * @param {typeof fetch} fetchImpl an unhooked fetch\n */\nexport function createCookieMirror(initial, endpoint, fetchImpl) {\n const jar = parsePairs(initial || \"\");\n\n return {\n get() {\n const parts = [];\n for (const [name, value] of jar) parts.push(name ? `${name}=${value}` : value);\n return parts.join(\"; \");\n },\n /**\n * @param {string} cookie e.g. \"theme=dark; Max-Age=3600; Path=/\"\n * @param {string} url target URL of the document setting it\n */\n set(cookie, url) {\n const [pair, ...attributes] = String(cookie).split(\";\");\n if (/httponly/i.test(attributes.join(\";\"))) return; // scripts cannot create HttpOnly cookies\n const eq = pair.indexOf(\"=\");\n const name = eq === -1 ? \"\" : pair.slice(0, eq).trim();\n const value = eq === -1 ? pair.trim() : pair.slice(eq + 1).trim();\n if (isExpired(attributes)) jar.delete(name);\n else jar.set(name, value);\n\n fetchImpl(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ url, cookie: String(cookie) }),\n credentials: \"same-origin\",\n keepalive: true,\n }).catch(() => {});\n },\n };\n}\n", "/**\n * Shared state for one runtime: configuration, the formatter, the cookie\n * mirror, and helpers that answer \"what is the target URL of this realm?\".\n * One core can patch several realms (a page and its about:blank iframes).\n */\nimport { createTransport } from \"@axis-network/butter-transport\";\nimport { createCookieMirror } from \"./cookies.js\";\n\n/** U+2028 / U+2029 are valid in JSON but end a line in older JS engines. */\nconst LINE_SEPARATORS = new RegExp(\"[\" + String.fromCharCode(0x2028, 0x2029) + \"]\", \"g\");\n\n/** JSON safe to embed in an inline <script>. */\nconst scriptJson = (value) =>\n JSON.stringify(value).replace(/</g, \"\\\\u003c\").replace(LINE_SEPARATORS, (ch) => \"\\\\u\" + ch.charCodeAt(0).toString(16));\n\n/**\n * @typedef {object} Natives APIs captured before any hook is installed\n * @property {typeof fetch} fetch\n * @property {typeof WebSocket | undefined} WebSocket\n * @property {() => ServiceWorker | null} controller the real navigator.serviceWorker.controller\n */\n\n/**\n * @param {import(\"@axis-network/butter-transport\").ButterPublicConfig} config self.__butter$config\n * @param {import(\"../formatter/index.js\").Formatter} f\n * @param {{ url?: string, cookies?: string, transport?: { name: string, url: string, options?: unknown } }} boot\n * @param {Natives} natives\n */\nexport function createCore(config, f, boot, natives) {\n /** @type {Promise<import(\"@axis-network/butter-transport\").ButterTransport> | null} */\n let transport = null;\n const selected = boot.transport || { name: config.defaultTransport };\n\n const core = {\n config,\n f,\n natives,\n /** Proxy origin */\n origin: globalThis.location.origin,\n cookies: createCookieMirror(boot.cookies || \"\", config.transport.cookie, natives.fetch),\n /** The transport chosen by the service worker for this document or worker. */\n selectedTransport: selected,\n\n /**\n * This realm's instance of the active transport, created on first use\n * (only WebSockets need one in pages; HTTP goes through the service worker).\n */\n transport() {\n if (!transport) {\n const scope = globalThis.document ? \"window\" : \"worker\";\n transport = createTransport(selected.name, selected.options, {\n scope,\n origin: core.origin,\n config,\n fetch: natives.fetch,\n WebSocket: natives.WebSocket,\n });\n transport.catch(() => {\n transport = null;\n });\n }\n return transport;\n },\n\n /**\n * Ask the service worker something (see the message handler in\n * src/sw/index.ts). Resolves to null when there is no controller.\n */\n askServiceWorker(message, timeout = 3000) {\n const controller = natives.controller();\n if (!controller) return Promise.resolve(null);\n return new Promise((resolve) => {\n const channel = new MessageChannel();\n const timer = setTimeout(() => resolve(null), timeout);\n channel.port1.onmessage = (event) => {\n clearTimeout(timer);\n resolve(event.data && event.data.ok ? event.data.result : null);\n };\n controller.postMessage(message, [channel.port2]);\n });\n },\n\n /** Request headers for a WebSocket handshake to `target`. */\n async socketHeaders(target, win) {\n /** @type {Record<string, string>} */\n const headers = { origin: core.targetOrigin(win) };\n const ua = globalThis.navigator && globalThis.navigator.userAgent;\n if (ua) headers[\"user-agent\"] = ua;\n const reply = await core.askServiceWorker({ type: \"butter:socket-cookies\", url: target.href });\n if (reply && reply.cookie) headers.cookie = reply.cookie;\n return headers;\n },\n\n /** Set-Cookie values a transport saw on a WebSocket handshake. */\n storeSocketCookies(target, setCookies) {\n if (setCookies && setCookies.length) {\n core.askServiceWorker({ type: \"butter:store-cookies\", url: target.href, setCookies: [...setCookies] });\n }\n },\n\n /** What location.href should report for this realm. */\n hrefOf(win) {\n return f.unrewriteUrl(win.location.href);\n },\n\n /** Target URL of the document; about:blank / srcdoc frames inherit their parent's. */\n documentTargetOf(win) {\n const href = core.hrefOf(win);\n if (/^(?:about|blob):/i.test(href)) {\n try {\n if (win.parent && win.parent !== win) return core.documentTargetOf(win.parent);\n } catch {\n // cross-origin parent\n }\n if (boot.url) return boot.url;\n }\n return href;\n },\n\n /** Base URL for resolving relative URLs in this realm (honours <base href>). */\n baseOf(win) {\n return f.unrewriteUrl(win.document ? win.document.baseURI : win.location.href);\n },\n\n targetOrigin(win) {\n try {\n return new URL(core.documentTargetOf(win)).origin;\n } catch {\n return \"null\";\n }\n },\n\n rewrite(url, win, opts) {\n return f.rewriteUrl(String(url), core.baseOf(win), opts);\n },\n\n unrewrite(url) {\n return f.unrewriteUrl(String(url));\n },\n\n /** Like rewrite(), but also handles javascript: URLs. */\n rewriteNavigation(url, win) {\n const value = String(url);\n const js = value.match(/^\\s*javascript:/i);\n return js ? \"javascript:\" + f.js(value.slice(js[0].length)) : core.rewrite(value, win);\n },\n\n /** Rewrite one attribute value of `el`. */\n attr(el, name, value, win) {\n return f.attr(el.localName || \"\", name, value, {\n base: core.baseOf(win),\n get inject() {\n return core.injection(win);\n },\n });\n },\n\n /** Rewrite an HTML fragment (innerHTML, document.write, ...). */\n html(markup, win) {\n return f.html(markup, { base: core.baseOf(win) });\n },\n\n /** Markup that installs the runtime in a new document (iframe srcdoc). */\n injection(win) {\n const bootData = { url: core.documentTargetOf(win), cookies: core.cookies.get(), transport: selected };\n const urls = config.transports.map((t) => t.url);\n if (selected.url && !urls.includes(selected.url)) urls.push(selected.url);\n const transportScripts = urls.map((url) => `<script src=\"${url.replace(/\"/g, \"&quot;\")}\" data-butter></script>`).join(\"\");\n return (\n `<script data-butter>self.__butter$config=${scriptJson(config)};self.__butter$boot=${scriptJson(bootData)};</script>` +\n transportScripts +\n `<script src=\"${config.client}\" data-butter></script>`\n );\n },\n };\n return core;\n}\n\n/** @typedef {ReturnType<typeof createCore>} Core */\n", "/**\n * Fake Location objects. Rewritten scripts read `__butter$location` instead\n * of `location`; for windows and documents that resolves to one of these.\n */\n\nconst PARTS = [\"protocol\", \"host\", \"hostname\", \"port\", \"pathname\", \"search\", \"hash\", \"origin\", \"username\", \"password\"];\n\n/**\n * @param {import(\"./core.js\").Core} core\n * @param {Window} win\n */\nexport function createLocation(core, win) {\n const real = win.location;\n const current = () => new URL(core.hrefOf(win));\n\n const navigate = (url, method) => {\n const value = String(url);\n const base = core.baseOf(win);\n let next;\n try {\n next = new URL(value, base);\n } catch {\n next = null;\n }\n // Same document, different fragment: let the browser scroll without a reload.\n if (next && next.hash && next.href.split(\"#\")[0] === current().href.split(\"#\")[0]) {\n real.hash = next.hash;\n return;\n }\n real[method](core.rewriteNavigation(value, win));\n };\n\n class Location {\n get href() {\n return current().href;\n }\n set href(value) {\n navigate(value, \"assign\");\n }\n assign(url) {\n navigate(url, \"assign\");\n }\n replace(url) {\n navigate(url, \"replace\");\n }\n reload() {\n real.reload();\n }\n toString() {\n return current().href;\n }\n get ancestorOrigins() {\n return real.ancestorOrigins;\n }\n }\n\n for (const part of PARTS) {\n const descriptor = {\n configurable: true,\n enumerable: true,\n get() {\n return current()[part];\n },\n };\n if (part === \"hash\") {\n descriptor.set = (value) => {\n real.hash = value;\n };\n } else if (part !== \"origin\") {\n descriptor.set = (value) => {\n const url = current();\n url[part] = value;\n navigate(url.href, \"assign\");\n };\n }\n Object.defineProperty(Location.prototype, part, descriptor);\n }\n Object.defineProperty(Location.prototype, Symbol.toStringTag, { value: \"Location\", configurable: true });\n\n return new Location();\n}\n\n/**\n * WorkerLocation equivalent for worker realms.\n * @param {import(\"./core.js\").Core} core\n * @param {WorkerGlobalScope} scope\n */\nexport function createWorkerLocation(core, scope) {\n const current = () => new URL(core.hrefOf(scope));\n class WorkerLocation {\n get href() {\n return current().href;\n }\n toString() {\n return current().href;\n }\n }\n for (const part of PARTS.slice(0, 8)) {\n Object.defineProperty(WorkerLocation.prototype, part, {\n configurable: true,\n enumerable: true,\n get: () => current()[part],\n });\n }\n Object.defineProperty(WorkerLocation.prototype, Symbol.toStringTag, { value: \"WorkerLocation\", configurable: true });\n return new WorkerLocation();\n}\n", "/**\n * Helpers for patching browser APIs without making the patches obvious.\n */\n\n/** Wrapper function -> original native function, for Function.prototype.toString. */\nconst disguised = new WeakMap();\n\n/**\n * @template {Function} T\n * @param {T} fake\n * @param {Function} real\n * @returns {T}\n */\nexport function disguise(fake, real) {\n if (typeof fake === \"function\" && typeof real === \"function\") disguised.set(fake, real);\n return fake;\n}\n\n/** Make wrappers report the original function's source text. */\nexport function installToString(win) {\n const proto = win.Function.prototype;\n const original = proto.toString;\n const toString = function toString() {\n return original.call(disguised.get(this) || this);\n };\n disguise(toString, original);\n Object.defineProperty(proto, \"toString\", { value: toString, writable: true, configurable: true, enumerable: false });\n}\n\n/** Find a property descriptor on an object or its prototype chain. */\nfunction findDescriptor(obj, name) {\n for (let o = obj; o; o = Object.getPrototypeOf(o)) {\n const desc = Object.getOwnPropertyDescriptor(o, name);\n if (desc) return [o, desc];\n }\n return [null, null];\n}\n\nfunction copyNameAndLength(fake, real) {\n try {\n Object.defineProperty(fake, \"name\", { value: real.name, configurable: true });\n Object.defineProperty(fake, \"length\", { value: real.length, configurable: true });\n } catch {\n // non-configurable in some engines; cosmetic only\n }\n}\n\n/**\n * Replace a method: `wrap` receives the original and returns the replacement.\n * @param {object | undefined} obj\n * @param {string} name\n * @param {(original: Function) => Function} wrap\n */\nexport function wrapMethod(obj, name, wrap) {\n if (!obj) return;\n const [owner, desc] = findDescriptor(obj, name);\n if (!owner || !desc || typeof desc.value !== \"function\" || !desc.configurable && !desc.writable) return;\n const original = desc.value;\n const fake = wrap(original);\n copyNameAndLength(fake, original);\n disguise(fake, original);\n Object.defineProperty(owner, name, { ...desc, value: fake });\n}\n\n/**\n * Replace an accessor. `get` is called with `this` and the original getter;\n * `set` with `this`, the value and the original setter.\n * @param {object | undefined} obj\n * @param {string} name\n * @param {{ get?: (this: any, original: Function) => any, set?: (this: any, value: any, original: Function) => void }} hooks\n */\nexport function wrapAccessor(obj, name, hooks) {\n if (!obj) return;\n const [owner, desc] = findDescriptor(obj, name);\n if (!owner || !desc || !desc.configurable || (!desc.get && !desc.set)) return;\n const next = { configurable: true, enumerable: desc.enumerable };\n // Object literal accessors give the replacements the native \"get x\" / \"set x\" names.\n if (desc.get) {\n const origGet = desc.get;\n next.get = hooks.get\n ? disguise(Object.getOwnPropertyDescriptor({ get [name]() { return hooks.get.call(this, origGet); } }, name).get, origGet)\n : origGet;\n }\n if (desc.set) {\n const origSet = desc.set;\n next.set = hooks.set\n ? disguise(Object.getOwnPropertyDescriptor({ set [name](value) { hooks.set.call(this, value, origSet); } }, name).set, origSet)\n : origSet;\n }\n Object.defineProperty(owner, name, next);\n}\n\n/**\n * Replace a constructor with a Proxy that can rewrite its arguments.\n * @param {object} win\n * @param {string} name\n * @param {(args: any[]) => any[]} mapArgs\n */\nexport function wrapConstructor(win, name, mapArgs) {\n const Original = win[name];\n if (typeof Original !== \"function\") return;\n const proxy = new Proxy(Original, {\n construct(target, args, newTarget) {\n return Reflect.construct(target, mapArgs(args), newTarget === proxy ? target : newTarget);\n },\n });\n disguise(proxy, Original);\n Object.defineProperty(win, name, { value: proxy, writable: true, configurable: true, enumerable: false });\n}\n\n/** Define a hidden, non-enumerable value. */\nexport function hide(obj, name, value) {\n Object.defineProperty(obj, name, { value, writable: true, configurable: true, enumerable: false });\n}\n\n/** `obj === obj.window` without throwing on cross-origin windows. */\nexport function isWindow(obj) {\n try {\n return obj != null && obj.window === obj;\n } catch {\n return false;\n }\n}\n\nexport function isDocument(obj) {\n try {\n return obj != null && obj.nodeType === 9 && \"defaultView\" in obj;\n } catch {\n return false;\n }\n}\n\nexport const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);\n", "/**\n * Globals that rewritten code calls into, and the `__butter$location`\n * accessor on Object.prototype.\n */\nimport { LOCATION, EVAL_WRAP, UNREWRITE } from \"../../formatter/index.js\";\nimport { hide, isWindow, isDocument } from \"../util.js\";\n\n/**\n * @param {import(\"../core.js\").Core} core\n * @param {any} win\n * @param {(win: any) => { location: object }} ensure\n */\nexport function installGlobals(core, win, ensure) {\n hide(win, EVAL_WRAP, (code) => (typeof code === \"string\" ? core.f.js(code) : code));\n hide(win, UNREWRITE, (url) => core.unrewrite(url));\n\n const isWorkerScope = (obj) => typeof win.WorkerGlobalScope === \"function\" && obj instanceof win.WorkerGlobalScope;\n\n const locationOfWindow = (w) => {\n try {\n return ensure(w).location;\n } catch {\n return w.location; // cross-origin window: the real Location is all there is\n }\n };\n\n Object.defineProperty(win.Object.prototype, LOCATION, {\n configurable: true,\n enumerable: false,\n get() {\n if (isWindow(this)) return locationOfWindow(this);\n if (isDocument(this)) return this.defaultView ? locationOfWindow(this.defaultView) : null;\n if (isWorkerScope(this)) return ensure(this).location;\n return this.location;\n },\n set(value) {\n if (isWindow(this)) {\n const loc = locationOfWindow(this);\n if (loc === this.location) this.location = value;\n else loc.href = value;\n } else if (isDocument(this) && this.defaultView) {\n locationOfWindow(this.defaultView).href = value;\n } else {\n this.location = value;\n }\n },\n });\n}\n", "/**\n * A WebSocket implementation on top of the active transport's connect().\n *\n * Pages keep using `new WebSocket(url, protocols)`; this class looks and\n * behaves like the native one (readyState, binaryType, on* handlers, events,\n * close codes) while the bytes travel however the transport decides.\n */\nimport { disguise } from \"./util.js\";\n\nconst CONNECTING = 0;\nconst OPEN = 1;\nconst CLOSING = 2;\nconst CLOSED = 3;\n\n/**\n * @param {import(\"./core.js\").Core} core\n * @param {any} win\n */\nexport function createWebSocketClass(core, win) {\n const NativeWebSocket = win.WebSocket;\n /** @type {WeakMap<object, any>} */\n const internals = new WeakMap();\n const state = (ws) => {\n const s = internals.get(ws);\n if (!s) throw new win.TypeError(\"Illegal invocation\");\n return s;\n };\n const isBlob = (value) => value && typeof value === \"object\" && typeof value.arrayBuffer === \"function\" && typeof value.size === \"number\";\n\n async function connect(ws, s, target, protocols) {\n // Events are dispatched in order, even when a Blob must be converted first.\n const dispatch = (make) => {\n s.queue = s.queue.then(async () => {\n const event = await make();\n if (event) ws.dispatchEvent(event);\n });\n };\n const fail = (message) => {\n if (s.readyState === CLOSED) return;\n console.warn(`[butter] WebSocket to ${s.url} failed: ${message}`);\n s.readyState = CLOSED;\n dispatch(() => new win.Event(\"error\"));\n dispatch(() => new win.CloseEvent(\"close\", { code: 1006, reason: \"\", wasClean: false }));\n };\n\n try {\n const transport = await core.transport();\n if (!transport.meta.websockets || typeof transport.connect !== \"function\") {\n throw new Error(`the \"${transport.meta.name}\" transport does not support WebSockets`);\n }\n const headers = await core.socketHeaders(target, win);\n if (s.readyState === CLOSED) return;\n\n s.socket = transport.connect(new URL(target.href), protocols, headers, {\n open(protocol, extensions) {\n if (s.closeRequested) {\n s.socket.close(s.closeRequested.code, s.closeRequested.reason);\n return;\n }\n s.protocol = protocol || \"\";\n s.extensions = extensions || \"\";\n dispatch(() => {\n s.readyState = OPEN;\n return new win.Event(\"open\");\n });\n },\n message(data) {\n dispatch(async () => {\n if (s.readyState !== OPEN) return null;\n let value = data;\n if (typeof data !== \"string\") {\n if (s.binaryType === \"arraybuffer\" && isBlob(data)) value = await data.arrayBuffer();\n else if (s.binaryType === \"blob\" && !isBlob(data)) value = new win.Blob([data]);\n }\n return new win.MessageEvent(\"message\", { data: value, origin: new URL(s.url).origin });\n });\n },\n error(message) {\n console.warn(`[butter] WebSocket to ${s.url}: ${message}`);\n dispatch(() => new win.Event(\"error\"));\n },\n close(code, reason, wasClean) {\n if (s.closed) return;\n s.closed = true;\n dispatch(() => {\n s.readyState = CLOSED;\n return new win.CloseEvent(\"close\", { code: code || 1005, reason: reason || \"\", wasClean: !!wasClean });\n });\n },\n cookies(setCookies) {\n core.storeSocketCookies(target, setCookies);\n },\n });\n } catch (err) {\n fail(String((err && err.message) || err));\n }\n }\n\n class WebSocket extends win.EventTarget {\n constructor(url, protocols) {\n super();\n if (arguments.length === 0) throw new win.TypeError(\"Failed to construct 'WebSocket': 1 argument required, but only 0 present.\");\n let target;\n try {\n target = new URL(String(url), core.baseOf(win));\n } catch {\n throw new win.DOMException(`Failed to construct 'WebSocket': The URL '${url}' is invalid.`, \"SyntaxError\");\n }\n if (target.protocol === \"http:\") target.protocol = \"ws:\";\n else if (target.protocol === \"https:\") target.protocol = \"wss:\";\n if (target.protocol !== \"ws:\" && target.protocol !== \"wss:\") {\n throw new win.DOMException(`Failed to construct 'WebSocket': The URL's scheme must be either 'http', 'https', 'ws', or 'wss'. '${target.protocol}' is not allowed.`, \"SyntaxError\");\n }\n if (target.hash) {\n throw new win.DOMException(\"Failed to construct 'WebSocket': The URL contains a fragment identifier.\", \"SyntaxError\");\n }\n const list = protocols === undefined ? [] : typeof protocols === \"string\" ? [protocols] : Array.from(protocols, String);\n if (new Set(list).size !== list.length) {\n throw new win.DOMException(\"Failed to construct 'WebSocket': The subprotocol is duplicated.\", \"SyntaxError\");\n }\n\n const s = {\n url: target.href,\n readyState: CONNECTING,\n protocol: \"\",\n extensions: \"\",\n binaryType: \"blob\",\n socket: null,\n closeRequested: null,\n closed: false,\n queue: Promise.resolve(),\n handlers: {},\n };\n internals.set(this, s);\n connect(this, s, target, list);\n }\n\n get url() { return state(this).url; }\n get readyState() { return state(this).readyState; }\n get protocol() { return state(this).protocol; }\n get extensions() { return state(this).extensions; }\n get bufferedAmount() {\n const s = state(this);\n return (s.socket && s.socket.bufferedAmount) || 0;\n }\n get binaryType() { return state(this).binaryType; }\n set binaryType(value) {\n if (value === \"blob\" || value === \"arraybuffer\") state(this).binaryType = value;\n }\n\n send(data) {\n const s = state(this);\n if (s.readyState === CONNECTING) {\n throw new win.DOMException(\"Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.\", \"InvalidStateError\");\n }\n if (s.readyState !== OPEN || !s.socket) return;\n s.socket.send(data);\n }\n\n close(code, reason) {\n const s = state(this);\n if (code !== undefined && code !== 1000 && !(code >= 3000 && code <= 4999)) {\n throw new win.DOMException(`Failed to execute 'close' on 'WebSocket': The close code must be either 1000, or between 3000 and 4999. ${code} is neither.`, \"InvalidAccessError\");\n }\n if (reason !== undefined && new TextEncoder().encode(String(reason)).length > 123) {\n throw new win.DOMException(\"Failed to execute 'close' on 'WebSocket': The close reason must not be greater than 123 UTF-8 bytes.\", \"SyntaxError\");\n }\n if (s.readyState === CLOSING || s.readyState === CLOSED) return;\n const wasConnecting = s.readyState === CONNECTING;\n s.readyState = CLOSING;\n if (wasConnecting && !s.socket) {\n s.closeRequested = { code, reason };\n return;\n }\n if (s.socket) s.socket.close(code, reason === undefined ? undefined : String(reason));\n }\n }\n\n for (const [name, value] of Object.entries({ CONNECTING, OPEN, CLOSING, CLOSED })) {\n Object.defineProperty(WebSocket, name, { value, enumerable: true });\n Object.defineProperty(WebSocket.prototype, name, { value, enumerable: true });\n }\n\n // onopen / onmessage / onerror / onclose\n for (const type of [\"open\", \"message\", \"error\", \"close\"]) {\n Object.defineProperty(WebSocket.prototype, \"on\" + type, {\n configurable: true,\n enumerable: true,\n get() {\n return state(this).handlers[type]?.handler ?? null;\n },\n set(handler) {\n const s = state(this);\n const previous = s.handlers[type];\n if (previous) this.removeEventListener(type, previous.listener);\n if (typeof handler === \"function\") {\n const listener = (event) => handler.call(this, event);\n s.handlers[type] = { handler, listener };\n this.addEventListener(type, listener);\n } else {\n delete s.handlers[type];\n }\n },\n });\n }\n\n Object.defineProperty(WebSocket.prototype, Symbol.toStringTag, { value: \"WebSocket\", configurable: true });\n if (NativeWebSocket) disguise(WebSocket, NativeWebSocket);\n return WebSocket;\n}\n", "/**\n * Network APIs: fetch, XHR, WebSocket, EventSource, beacons and workers.\n *\n * Most requests would reach the service worker anyway; rewriting them here\n * makes relative URLs resolve against the target page rather than the proxy\n * URL. WebSockets are reimplemented on top of the active transport.\n */\nimport { wrapAccessor, wrapConstructor, wrapMethod } from \"../util.js\";\nimport { createWebSocketClass } from \"../websocket.js\";\n\n/**\n * @param {import(\"../core.js\").Core} core\n * @param {any} win\n */\nexport function hookNetwork(core, win) {\n const rewrite = (url) => core.rewrite(url, win);\n const isUrlLike = (input) => typeof input === \"string\" || (win.URL && input instanceof win.URL);\n const unrewriteGetter = {\n get(original) {\n return core.unrewrite(original.call(this));\n },\n };\n\n wrapConstructor(win, \"Request\", (args) => {\n if (isUrlLike(args[0])) args[0] = rewrite(args[0]);\n return args;\n });\n wrapMethod(win, \"fetch\", (original) =>\n function fetch(input, init) {\n return original.call(this, isUrlLike(input) ? rewrite(input) : input, init);\n });\n wrapAccessor(win.Request && win.Request.prototype, \"url\", unrewriteGetter);\n wrapAccessor(win.Response && win.Response.prototype, \"url\", unrewriteGetter);\n\n const XHR = win.XMLHttpRequest && win.XMLHttpRequest.prototype;\n wrapMethod(XHR, \"open\", (original) =>\n function open(method, url, ...rest) {\n return original.call(this, method, rewrite(url), ...rest);\n });\n wrapAccessor(XHR, \"responseURL\", unrewriteGetter);\n\n wrapConstructor(win, \"EventSource\", (args) => {\n if (args.length) args[0] = rewrite(args[0]);\n return args;\n });\n wrapAccessor(win.EventSource && win.EventSource.prototype, \"url\", unrewriteGetter);\n\n // WebSockets never pass through a service worker: they go through the\n // active transport's connect() instead.\n if (win.WebSocket && win.EventTarget) {\n Object.defineProperty(win, \"WebSocket\", {\n value: createWebSocketClass(core, win),\n writable: true,\n configurable: true,\n enumerable: false,\n });\n }\n\n wrapMethod(win.Navigator && win.Navigator.prototype, \"sendBeacon\", (original) =>\n function sendBeacon(url, ...rest) {\n return original.call(this, rewrite(url), ...rest);\n });\n\n const workerArgs = (args) => {\n if (!args.length) return args;\n const url = String(args[0]);\n if (/^\\s*(?:blob|data):/i.test(url)) return args;\n const options = args[1];\n const moduleWorker = !!options && typeof options === \"object\" && options.type === \"module\";\n args[0] = core.rewrite(url, win, { moduleWorker });\n return args;\n };\n wrapConstructor(win, \"Worker\", workerArgs);\n wrapConstructor(win, \"SharedWorker\", workerArgs);\n\n // Worker realms only.\n wrapMethod(win, \"importScripts\", (original) =>\n function importScripts(...urls) {\n return original.apply(this, urls.map(rewrite));\n });\n}\n", "/**\n * Window / global scope APIs: navigation, history, messaging, dynamic code,\n * origin and service worker registration.\n */\nimport { disguise, isWindow, wrapAccessor, wrapMethod } from \"../util.js\";\n\n/**\n * @param {import(\"../core.js\").Core} core\n * @param {any} win\n * @param {(win: any) => unknown} ensure\n */\nexport function hookWindow(core, win, ensure) {\n const isWindowRealm = !!win.document;\n const js = (code) => (typeof code === \"string\" ? core.f.js(code) : code);\n\n // self.origin\n wrapAccessor(win, \"origin\", {\n get() {\n return core.targetOrigin(win);\n },\n });\n\n // Dynamic code: setTimeout(\"code\"), new Function(\"code\").\n for (const name of [\"setTimeout\", \"setInterval\"]) {\n wrapMethod(win, name, (original) =>\n function (handler, ...rest) {\n return original.call(this, js(handler), ...rest);\n });\n }\n const NativeFunction = win.Function;\n const mapFunctionArgs = (args) => {\n if (args.length) args[args.length - 1] = core.f.js(String(args[args.length - 1]));\n return args;\n };\n const FunctionProxy = new Proxy(NativeFunction, {\n apply(target, thisArg, args) {\n return Reflect.apply(target, thisArg, mapFunctionArgs(args));\n },\n construct(target, args, newTarget) {\n return Reflect.construct(target, mapFunctionArgs(args), newTarget === FunctionProxy ? target : newTarget);\n },\n });\n disguise(FunctionProxy, NativeFunction);\n Object.defineProperty(win, \"Function\", { value: FunctionProxy, writable: true, configurable: true, enumerable: false });\n // Keep `(function () {}).constructor === Function` true.\n Object.defineProperty(NativeFunction.prototype, \"constructor\", { value: FunctionProxy, writable: true, configurable: true, enumerable: false });\n\n // Service workers: the page must not replace or unregister ours.\n const container = win.ServiceWorkerContainer && win.ServiceWorkerContainer.prototype;\n wrapMethod(container, \"register\", () =>\n function register() {\n return Promise.reject(new win.DOMException(\"Service workers are unavailable in proxied pages.\", \"SecurityError\"));\n });\n wrapMethod(container, \"getRegistration\", () =>\n function getRegistration() {\n return Promise.resolve(undefined);\n });\n wrapMethod(container, \"getRegistrations\", () =>\n function getRegistrations() {\n return Promise.resolve([]);\n });\n wrapAccessor(container, \"controller\", {\n get() {\n return null;\n },\n });\n wrapAccessor(container, \"ready\", {\n get() {\n return new Promise(() => {});\n },\n });\n\n if (!isWindowRealm) return;\n\n wrapMethod(win, \"open\", (original) =>\n function open(url, ...rest) {\n const next = url == null || String(url) === \"\" ? url : core.rewriteNavigation(url, win);\n const opened = original.call(this, next, ...rest);\n if (opened) {\n try {\n ensure(opened); // about:blank popups are written to directly\n } catch {\n // cross-origin or blocked popup\n }\n }\n return opened;\n });\n\n const History = win.History && win.History.prototype;\n for (const name of [\"pushState\", \"replaceState\"]) {\n wrapMethod(History, name, (original) =>\n function (state, title, url) {\n if (arguments.length < 3) return original.call(this, state, title);\n return original.call(this, state, title, url == null ? url : core.rewrite(url, win));\n });\n }\n\n const Navigation = win.Navigation && win.Navigation.prototype;\n wrapMethod(Navigation, \"navigate\", (original) =>\n function navigate(url, ...rest) {\n return original.call(this, core.rewriteNavigation(url, win), ...rest);\n });\n\n // All proxied frames share the proxy origin, so target origins never match.\n wrapMethod(win, \"postMessage\", (original) =>\n function postMessage(message, targetOrigin, ...rest) {\n if (typeof targetOrigin === \"string\" && targetOrigin !== \"*\") {\n targetOrigin = core.origin;\n } else if (targetOrigin && typeof targetOrigin === \"object\" && typeof targetOrigin.targetOrigin === \"string\" && targetOrigin.targetOrigin !== \"*\") {\n targetOrigin = { ...targetOrigin, targetOrigin: core.origin };\n }\n return original.call(this, message, targetOrigin, ...rest);\n });\n\n wrapAccessor(win.MessageEvent && win.MessageEvent.prototype, \"origin\", {\n get(original) {\n const origin = original.call(this);\n if (origin !== core.origin) return origin;\n try {\n const source = this.source;\n if (source && isWindow(source)) return core.targetOrigin(source);\n } catch {\n // fall through\n }\n return core.targetOrigin(win);\n },\n });\n}\n", "/**\n * Document-level APIs: URL, referrer, domain, baseURI, cookie, write().\n */\nimport { wrapAccessor, wrapMethod } from \"../util.js\";\n\n/**\n * @param {import(\"../core.js\").Core} core\n * @param {any} win\n */\nexport function hookDocument(core, win) {\n const Doc = win.Document.prototype;\n const unrewriteGetter = {\n get(original) {\n return core.unrewrite(original.call(this));\n },\n };\n\n wrapAccessor(Doc, \"URL\", unrewriteGetter);\n wrapAccessor(Doc, \"documentURI\", unrewriteGetter);\n wrapAccessor(win.Node.prototype, \"baseURI\", unrewriteGetter);\n\n wrapAccessor(Doc, \"referrer\", {\n get(original) {\n const referrer = original.call(this);\n if (!referrer) return referrer;\n const target = core.unrewrite(referrer);\n // Referred by butter-col's own pages (the launcher): no referrer.\n return target === referrer && referrer.startsWith(core.origin) ? \"\" : target;\n },\n });\n\n wrapAccessor(Doc, \"domain\", {\n get() {\n try {\n return new URL(core.documentTargetOf(win)).hostname;\n } catch {\n return \"\";\n }\n },\n set() {\n // Relaxing document.domain is meaningless when every site shares the proxy origin.\n },\n });\n\n wrapAccessor(Doc, \"cookie\", {\n get() {\n return core.cookies.get();\n },\n set(value) {\n core.cookies.set(String(value), core.documentTargetOf(win));\n },\n });\n\n for (const name of [\"write\", \"writeln\"]) {\n wrapMethod(Doc, name, (original) =>\n function (...markup) {\n return original.call(this, core.html(markup.join(\"\"), win));\n });\n }\n}\n", "/**\n * DOM APIs. Attributes in the DOM always hold rewritten (proxied) URLs;\n * getters hand the page the original URLs and setters rewrite on the way in.\n */\nimport { URL_ATTRS } from \"../../formatter/index.js\";\nimport { wrapAccessor, wrapMethod } from \"../util.js\";\n\nconst URL_PROPERTIES = [\n [\"HTMLAnchorElement\", \"href\"], [\"HTMLAreaElement\", \"href\"], [\"HTMLLinkElement\", \"href\"], [\"HTMLBaseElement\", \"href\"],\n [\"HTMLImageElement\", \"src\"], [\"HTMLScriptElement\", \"src\"], [\"HTMLIFrameElement\", \"src\"], [\"HTMLFrameElement\", \"src\"],\n [\"HTMLEmbedElement\", \"src\"], [\"HTMLSourceElement\", \"src\"], [\"HTMLTrackElement\", \"src\"], [\"HTMLMediaElement\", \"src\"],\n [\"HTMLInputElement\", \"src\"], [\"HTMLVideoElement\", \"poster\"], [\"HTMLFormElement\", \"action\"],\n [\"HTMLButtonElement\", \"formAction\"], [\"HTMLInputElement\", \"formAction\"], [\"HTMLObjectElement\", \"data\"],\n [\"HTMLModElement\", \"cite\"], [\"HTMLQuoteElement\", \"cite\"],\n];\nconst SRCSET_PROPERTIES = [[\"HTMLImageElement\", \"srcset\"], [\"HTMLSourceElement\", \"srcset\"], [\"HTMLLinkElement\", \"imageSrcset\"]];\nconst READONLY_URL_PROPERTIES = [[\"HTMLImageElement\", \"currentSrc\"], [\"HTMLMediaElement\", \"currentSrc\"]];\nconst HYPERLINK_PARTS = [\"protocol\", \"host\", \"hostname\", \"port\", \"pathname\", \"search\", \"hash\", \"origin\", \"username\", \"password\"];\n\n/** Attributes renamed so the browser ignores them (see formatter/html.js). */\nconst RENAMED = { integrity: \"data-butter-integrity\", sandbox: \"data-butter-sandbox\" };\n\n/** Attributes that can navigate away from the proxy, watched by the safety net. */\nconst NAVIGATION_ATTRS = { a: \"href\", area: \"href\", form: \"action\", button: \"formaction\", input: \"formaction\", iframe: \"src\", frame: \"src\" };\nconst NAVIGATION_SELECTOR = \"a[href],area[href],form[action],button[formaction],input[formaction],iframe[src],frame[src],[integrity],iframe[sandbox]\";\n\nconst JS_TYPE = /^(?:|module|(?:text|application)\\/(?:x-)?(?:javascript|ecmascript))$/i;\n\n/**\n * @param {import(\"../core.js\").Core} core\n * @param {any} win\n * @param {(win: any) => unknown} ensure\n */\nexport function hookDom(core, win, ensure) {\n const ElementProto = win.Element.prototype;\n const getAttr = ElementProto.getAttribute;\n const setAttr = ElementProto.setAttribute;\n const removeAttr = ElementProto.removeAttribute;\n\n const renamedFor = (el, attr) => (attr === \"sandbox\" && el.localName !== \"iframe\" ? undefined : RENAMED[attr]);\n\n // --- Attributes ---------------------------------------------------------\n\n wrapMethod(ElementProto, \"setAttribute\", (original) =>\n function setAttribute(name, value) {\n const attr = String(name).toLowerCase();\n const renamed = renamedFor(this, attr);\n if (renamed) return original.call(this, renamed, value);\n return original.call(this, name, core.attr(this, attr, String(value), win));\n });\n\n wrapMethod(ElementProto, \"getAttribute\", (original) =>\n function getAttribute(name) {\n const attr = String(name).toLowerCase();\n const value = original.call(this, name);\n if (value === null) {\n const renamed = renamedFor(this, attr);\n return renamed ? original.call(this, renamed) : null;\n }\n if (attr === \"srcset\" || attr === \"imagesrcset\") return core.f.url.unrewriteSrcset(value);\n if (URL_ATTRS.has(attr) || attr === \"data\") return core.unrewrite(value);\n return value;\n });\n\n wrapMethod(ElementProto, \"setAttributeNS\", (original) =>\n function setAttributeNS(ns, name, value) {\n const local = String(name).split(\":\").pop().toLowerCase();\n return original.call(this, ns, name, local === \"href\" ? core.attr(this, local, String(value), win) : value);\n });\n\n // --- Reflected URL properties --------------------------------------------\n\n for (const [iface, prop] of URL_PROPERTIES) {\n const attr = prop.toLowerCase();\n wrapAccessor(win[iface] && win[iface].prototype, prop, {\n get(original) {\n const raw = getAttr.call(this, attr);\n if (raw === null) return core.unrewrite(original.call(this));\n const target = core.unrewrite(raw);\n if (target !== raw) return target;\n try {\n return new URL(raw.trim(), core.baseOf(win)).href;\n } catch {\n return raw;\n }\n },\n set(value) {\n setAttr.call(this, attr, core.attr(this, attr, String(value), win));\n },\n });\n }\n\n for (const [iface, prop] of SRCSET_PROPERTIES) {\n const attr = prop.toLowerCase();\n wrapAccessor(win[iface] && win[iface].prototype, prop, {\n get() {\n return core.f.url.unrewriteSrcset(getAttr.call(this, attr) || \"\");\n },\n set(value) {\n setAttr.call(this, attr, core.attr(this, attr, String(value), win));\n },\n });\n }\n\n for (const [iface, prop] of READONLY_URL_PROPERTIES) {\n wrapAccessor(win[iface] && win[iface].prototype, prop, {\n get(original) {\n return core.unrewrite(original.call(this));\n },\n });\n }\n\n for (const iface of [\"HTMLAnchorElement\", \"HTMLAreaElement\"]) {\n const proto = win[iface] && win[iface].prototype;\n for (const part of HYPERLINK_PARTS) {\n wrapAccessor(proto, part, {\n get() {\n try {\n return new URL(this.href)[part];\n } catch {\n return \"\";\n }\n },\n set(value) {\n try {\n const url = new URL(this.href);\n url[part] = value;\n this.href = url.href;\n } catch {\n // invalid href: nothing to update\n }\n },\n });\n }\n }\n\n for (const iface of [\"HTMLScriptElement\", \"HTMLLinkElement\"]) {\n wrapAccessor(win[iface] && win[iface].prototype, \"integrity\", {\n get() {\n return getAttr.call(this, RENAMED.integrity) || \"\";\n },\n set(value) {\n setAttr.call(this, RENAMED.integrity, String(value));\n },\n });\n }\n\n // --- Markup and script text ------------------------------------------------\n\n const rawText = (el, text) => {\n if (el.localName === \"style\") return core.f.css(text, core.baseOf(win));\n if (el.localName === \"script\" && JS_TYPE.test((getAttr.call(el, \"type\") || \"\").trim())) return core.f.js(text);\n return null;\n };\n const markup = (el, value) => {\n const text = String(value);\n return rawText(el, text) ?? core.html(text, win);\n };\n\n for (const proto of [ElementProto, win.ShadowRoot && win.ShadowRoot.prototype]) {\n wrapAccessor(proto, \"innerHTML\", {\n set(value, original) {\n original.call(this, markup(this, value));\n },\n });\n }\n wrapAccessor(ElementProto, \"outerHTML\", {\n set(value, original) {\n original.call(this, core.html(String(value), win));\n },\n });\n wrapMethod(ElementProto, \"insertAdjacentHTML\", (original) =>\n function insertAdjacentHTML(position, value) {\n return original.call(this, position, core.html(String(value), win));\n });\n wrapMethod(ElementProto, \"setHTMLUnsafe\", (original) =>\n function setHTMLUnsafe(value, ...rest) {\n return original.call(this, markup(this, value), ...rest);\n });\n wrapMethod(win.Range && win.Range.prototype, \"createContextualFragment\", (original) =>\n function createContextualFragment(value) {\n return original.call(this, core.html(String(value), win));\n });\n\n const scriptText = {\n set(value, original) {\n const text = String(value);\n original.call(this, this.localName === \"script\" ? rawText(this, text) ?? text : text);\n },\n };\n wrapAccessor(win.HTMLScriptElement && win.HTMLScriptElement.prototype, \"text\", scriptText);\n wrapAccessor(win.Node.prototype, \"textContent\", scriptText);\n wrapAccessor(win.HTMLElement.prototype, \"innerText\", scriptText);\n\n // --- Frames: install the runtime into about:blank frames on first access ---\n\n for (const iface of [\"HTMLIFrameElement\", \"HTMLFrameElement\", \"HTMLObjectElement\"]) {\n const proto = win[iface] && win[iface].prototype;\n wrapAccessor(proto, \"contentWindow\", {\n get(original) {\n const frame = original.call(this);\n if (frame) {\n try {\n ensure(frame);\n } catch {\n // cross-origin\n }\n }\n return frame;\n },\n });\n wrapAccessor(proto, \"contentDocument\", {\n get(original) {\n const doc = original.call(this);\n if (doc && doc.defaultView) {\n try {\n ensure(doc.defaultView);\n } catch {\n // cross-origin\n }\n }\n return doc;\n },\n });\n }\n\n // --- Safety net --------------------------------------------------------------\n // Elements created through paths the hooks cannot see (DOMParser, cloned\n // templates, ...) could navigate straight to the real site. Rewrite the\n // attributes that can navigate before anyone gets to click them.\n\n const fixElement = (el) => {\n if (getAttr.call(el, \"data-butter\") !== null) return;\n const attr = NAVIGATION_ATTRS[el.localName];\n if (attr) {\n const value = getAttr.call(el, attr);\n if (value !== null) {\n const rewritten = core.attr(el, attr, value, win);\n if (rewritten !== value) setAttr.call(el, attr, rewritten);\n }\n }\n for (const old of [\"integrity\", \"sandbox\"]) {\n const renamed = renamedFor(el, old);\n const value = renamed && getAttr.call(el, old);\n if (renamed && value !== null) {\n removeAttr.call(el, old);\n setAttr.call(el, renamed, value);\n }\n }\n };\n\n const observer = new win.MutationObserver((records) => {\n for (const record of records) {\n if (record.type === \"attributes\") {\n fixElement(record.target);\n continue;\n }\n for (const node of record.addedNodes) {\n if (node.nodeType !== 1) continue;\n fixElement(node);\n for (const el of node.querySelectorAll(NAVIGATION_SELECTOR)) fixElement(el);\n }\n }\n });\n observer.observe(win.document, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [\"href\", \"action\", \"formaction\", \"src\", \"integrity\", \"sandbox\"],\n });\n}\n", "/**\n * Every proxied site shares the proxy origin, and with it one localStorage.\n * Give each target origin its own key namespace so sites don't collide.\n */\nimport { disguise, wrapMethod } from \"../util.js\";\n\nfunction scopeStorage(win, storage, prefix) {\n const proto = win.Storage.prototype;\n const { getItem, setItem, removeItem, key } = proto;\n\n const keys = () => {\n const out = [];\n for (let i = 0; i < storage.length; i++) {\n const k = key.call(storage, i);\n if (k !== null && k.startsWith(prefix)) out.push(k.slice(prefix.length));\n }\n return out;\n };\n\n const api = Object.create(proto, {\n getItem: { value: (k) => getItem.call(storage, prefix + k) },\n setItem: { value: (k, v) => setItem.call(storage, prefix + k, String(v)) },\n removeItem: { value: (k) => removeItem.call(storage, prefix + k) },\n clear: { value: () => keys().forEach((k) => removeItem.call(storage, prefix + k)) },\n key: { value: (i) => keys()[i] ?? null },\n length: { get: () => keys().length },\n });\n for (const name of [\"getItem\", \"setItem\", \"removeItem\", \"clear\", \"key\"]) disguise(api[name], proto[name]);\n\n const isItem = (target, prop) => typeof prop === \"string\" && !(prop in target);\n\n return new Proxy(api, {\n get(target, prop) {\n if (isItem(target, prop)) {\n const value = api.getItem(prop);\n return value === null ? undefined : value;\n }\n return Reflect.get(target, prop);\n },\n set(target, prop, value) {\n if (isItem(target, prop)) {\n api.setItem(prop, value);\n return true;\n }\n return Reflect.set(target, prop, value);\n },\n deleteProperty(target, prop) {\n if (isItem(target, prop)) api.removeItem(prop);\n return true;\n },\n has(target, prop) {\n return prop in target || (typeof prop === \"string\" && api.getItem(prop) !== null);\n },\n ownKeys() {\n return keys();\n },\n getOwnPropertyDescriptor(target, prop) {\n if (typeof prop !== \"string\") return undefined;\n const value = api.getItem(prop);\n return value === null ? undefined : { value, writable: true, enumerable: true, configurable: true };\n },\n });\n}\n\n/**\n * @param {import(\"../core.js\").Core} core\n * @param {any} win\n */\nexport function hookStorage(core, win) {\n if (!win.Storage) return;\n const prefix = `butter:${core.targetOrigin(win)}:`;\n for (const name of [\"localStorage\", \"sessionStorage\"]) {\n const desc = Object.getOwnPropertyDescriptor(win, name);\n if (!desc || !desc.configurable || !desc.get) continue;\n let storage;\n try {\n storage = desc.get.call(win);\n } catch {\n continue; // storage disabled\n }\n if (!storage) continue;\n const scoped = scopeStorage(win, storage, prefix);\n Object.defineProperty(win, name, {\n configurable: true,\n enumerable: desc.enumerable,\n get: disguise(Object.getOwnPropertyDescriptor({ get [name]() { return scoped; } }, name).get, desc.get),\n });\n }\n}\n\n/** The service worker's own database: cookies of \"client\" transports, the transport choice. */\nconst RESERVED_DB = \"butter-col\";\nconst PAGE_ALIAS = \"butter-col (page)\";\n\n/**\n * Proxied pages share the proxy origin with the service worker, so they\n * could open its IndexedDB and read every cookie (HttpOnly included).\n * Page code asking for that name gets a separate database instead, and the\n * real one is left out of indexedDB.databases().\n */\nexport function hookIndexedDB(win) {\n const proto = win.IDBFactory && win.IDBFactory.prototype;\n if (!proto) return;\n for (const method of [\"open\", \"deleteDatabase\"]) {\n wrapMethod(proto, method, (original) =>\n function (name, ...rest) {\n return original.call(this, String(name) === RESERVED_DB ? PAGE_ALIAS : name, ...rest);\n });\n }\n wrapMethod(proto, \"databases\", (original) =>\n function databases() {\n return original.call(this).then((list) =>\n list\n .filter((db) => db.name !== RESERVED_DB)\n .map((db) => (db.name === PAGE_ALIAS ? { ...db, name: RESERVED_DB } : db)));\n });\n}\n", "import { LOCATION } from \"../formatter/index.js\";\nimport { createLocation, createWorkerLocation } from \"./location.js\";\nimport { hide, hasOwn, installToString } from \"./util.js\";\nimport { installGlobals } from \"./hooks/globals.js\";\nimport { hookNetwork } from \"./hooks/network.js\";\nimport { hookWindow } from \"./hooks/window.js\";\nimport { hookDocument } from \"./hooks/document.js\";\nimport { hookDom } from \"./hooks/dom.js\";\nimport { hookIndexedDB, hookStorage } from \"./hooks/storage.js\";\n\n/** Fake locations for windows that must not be patched (see ensureRealm). */\nconst foreign = new WeakMap();\n\n/**\n * Is `win` a butter-col page of its own (a launcher or frontend embedding the\n * proxied page) rather than proxied content or an about:blank / blob: frame?\n * Those windows only get a fake Location, never the full set of hooks, which\n * would start rewriting the frontend's own requests.\n */\nfunction isForeign(core, win) {\n const href = win.location.href;\n if (/^(?:about|blob):/i.test(href)) return false;\n return core.f.unrewriteUrl(href) === href;\n}\n\n/** The runtime state of another same-origin realm, installing it if needed. */\nfunction ensureRealm(core, win) {\n if (hasOwn(win, \"__butter$runtime\")) return win.__butter$runtime;\n if (win.document && isForeign(core, win)) {\n let state = foreign.get(win);\n if (!state) {\n state = { core, location: createLocation(core, win) };\n foreign.set(win, state);\n }\n return state;\n }\n return install(core, win);\n}\n\n/**\n * Rewritten code reads `top.__butter$location`, `parent.__butter$location`...\n * When the proxied page is framed by a butter-col page (the frontend), that\n * ancestor has no runtime, so give it just the accessor.\n */\nfunction exposeToAncestors(core, win) {\n for (let w = win; ; ) {\n let parent;\n try {\n parent = w.parent;\n if (!parent || parent === w) return;\n if (!hasOwn(parent.Object.prototype, LOCATION)) installGlobals(core, parent, (other) => ensureRealm(core, other));\n } catch {\n return; // cross-origin ancestor: nothing to do (or possible)\n }\n w = parent;\n }\n}\n\n/**\n * Patch one realm (a window or a worker global scope). Safe to call more\n * than once; a realm that already has a runtime is returned as-is.\n *\n * @param {import(\"./core.js\").Core} core\n * @param {any} win\n * @returns {{ location: object }}\n */\nexport function install(core, win) {\n if (hasOwn(win, \"__butter$runtime\")) return win.__butter$runtime;\n\n const isWindowRealm = !!win.document;\n const runtime = { core, location: /** @type {object} */ (null) };\n hide(win, \"__butter$runtime\", runtime);\n runtime.location = isWindowRealm ? createLocation(core, win) : createWorkerLocation(core, win);\n\n const ensure = (other) => ensureRealm(core, other);\n const steps = [\n () => installToString(win),\n () => installGlobals(core, win, ensure),\n () => hookNetwork(core, win),\n () => hookWindow(core, win, ensure),\n () => hookIndexedDB(win),\n ];\n if (isWindowRealm) {\n steps.push(\n () => hookDocument(core, win),\n () => hookDom(core, win, ensure),\n () => hookStorage(core, win),\n () => exposeToAncestors(core, win),\n );\n }\n for (const step of steps) {\n try {\n step();\n } catch (err) {\n // A missing API in one browser must not take the rest of the runtime down.\n console.warn(\"[butter] hook failed:\", err);\n }\n }\n return runtime;\n}\n", "/**\n * butter-col in-page runtime. Loaded at the top of every proxied document\n * (injected by the service worker) and every proxied worker (prepended).\n *\n * Expects self.__butter$config (and, in documents, self.__butter$boot) to be\n * defined before it runs.\n */\nimport { createFormatter } from \"../formatter/index.js\";\nimport { createCore } from \"./core.js\";\nimport { install } from \"./install.js\";\n\n(() => {\n const scope = /** @type {any} */ (globalThis);\n if (Object.prototype.hasOwnProperty.call(scope, \"__butter$runtime\")) return;\n\n const config = scope.__butter$config;\n if (!config) {\n console.error(\"[butter] __butter$config is missing; the runtime was not installed.\");\n return;\n }\n const boot = scope.__butter$boot || {};\n delete scope.__butter$config;\n delete scope.__butter$boot;\n const formatter = createFormatter({ origin: scope.location.origin, prefix: config.prefix, codec: config.codec });\n\n // Transports and the runtime itself need the real APIs, captured before\n // the hooks replace them.\n const container = scope.navigator && scope.navigator.serviceWorker;\n const ContainerProto = scope.ServiceWorkerContainer && scope.ServiceWorkerContainer.prototype;\n const controllerGetter = ContainerProto && Object.getOwnPropertyDescriptor(ContainerProto, \"controller\")?.get;\n const natives = {\n fetch: scope.fetch.bind(scope),\n WebSocket: scope.WebSocket,\n controller: () => (container && controllerGetter ? controllerGetter.call(container) : null),\n };\n\n const core = createCore(config, formatter, boot, natives);\n install(core, scope);\n\n // Leave the page's DOM as the site authored it.\n if (scope.document) {\n for (const el of scope.document.querySelectorAll(\"script[data-butter]\")) el.remove();\n }\n})();\n"],
5
+ "mappings": "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",
6
+ "names": ["none", "url", "encoded", "plain", "xorString", "str", "out", "i", "xor", "base64", "bytes", "bin", "b64", "codecs", "getCodec", "name", "codec", "MODULE_WORKER_MARK", "PASSTHROUGH_SCHEMES", "TARGET_SCHEME", "createUrlRewriter", "origin", "prefix", "codecName", "codec", "getCodec", "absPrefix", "decodeTail", "tail", "decoded", "isProxied", "url", "rewrite", "raw", "base", "opts", "str", "trimmed", "abs", "hash", "mark", "unrewrite", "rest", "hashAt", "search", "searchAt", "target", "rewriteSrcset", "value", "map", "out", "i", "n", "wsStart", "urlStart", "trailing", "commas", "descStart", "depth", "ch", "URL_FUNCTION", "IMPORT_STRING", "rewriteCss", "css", "base", "rewriteUrl", "map", "raw", "url", "rewritten", "match", "dq", "sq", "bare", "LOCATION", "EVAL_WRAP", "UNREWRITE", "NEEDS_REWRITE", "EXPR_KEYWORDS", "OBJECT_AFTER_PUNC", "OBJECT_AFTER_KEYWORD", "IMPORT_META_URL", "isIdStart", "c", "isIdPart", "isWhitespace", "isLineTerminator", "rewriteJs", "src", "n", "edits", "prevType", "prevVal", "prev2Type", "prev2Val", "braces", "parens", "inImport", "push", "type", "val", "skipTrivia", "pos", "end", "peekWord", "j", "start", "regexAllowed", "scanString", "i", "quote", "scanTemplate", "scanRegex", "inClass", "handleTemplate", "opens", "handleLocation", "top", "importing", "next", "d", "value", "escaped", "cc", "close", "afterDot", "kind", "isEvalCall", "open", "e", "a", "b", "out", "last", "text", "RAW_TEXT", "JS_TYPE", "URL_ATTRS", "NEUTRALIZE", "NAMED_ENTITIES", "ENTITY", "decodeEntities", "value", "match", "dec", "hex", "named", "code", "escapeAttribute", "isWs", "c", "isLetter", "rewriteAttribute", "f", "tag", "name", "ctx", "attr", "part", "trimmed", "parseStartTag", "src", "i", "n", "j", "attrs", "selfClosing", "start", "attrName", "k", "q", "raw", "close", "vs", "findAttr", "transformTag", "state", "changed", "equiv", "kind", "content", "rewriteRefresh", "href", "lower", "rename", "base", "serializeTag", "out", "last", "closeTagCache", "findRawTextEnd", "from", "re", "rewriteHtml", "html", "options", "inject", "lt", "next", "end", "type", "markup", "createFormatter", "config", "url", "createUrlRewriter", "formatter", "raw", "base", "opts", "proxied", "src", "rewriteCss", "rewriteJs", "options", "rewriteHtml", "tag", "name", "value", "ctx", "rewriteAttribute", "rewriteRefresh", "registry", "getTransportFactory", "name", "registry", "listTransports", "createTransport", "options", "env", "factory", "transport", "problems", "validateTransport", "t", "meta", "parsePairs", "str", "jar", "part", "eq", "isExpired", "attributes", "attr", "key", "value", "time", "createCookieMirror", "initial", "endpoint", "fetchImpl", "parts", "name", "cookie", "url", "pair", "LINE_SEPARATORS", "scriptJson", "value", "ch", "createCore", "config", "f", "boot", "natives", "transport", "selected", "core", "createCookieMirror", "scope", "createTransport", "message", "timeout", "controller", "resolve", "channel", "timer", "event", "target", "win", "headers", "ua", "reply", "setCookies", "href", "url", "opts", "js", "el", "name", "markup", "bootData", "urls", "t", "transportScripts", "PARTS", "createLocation", "core", "win", "real", "current", "navigate", "url", "method", "value", "base", "next", "Location", "part", "descriptor", "createWorkerLocation", "scope", "WorkerLocation", "disguised", "disguise", "fake", "real", "installToString", "win", "proto", "original", "toString", "findDescriptor", "obj", "name", "o", "desc", "copyNameAndLength", "wrapMethod", "wrap", "owner", "wrapAccessor", "hooks", "next", "origGet", "origSet", "value", "wrapConstructor", "mapArgs", "Original", "proxy", "target", "args", "newTarget", "hide", "isWindow", "isDocument", "hasOwn", "key", "installGlobals", "core", "win", "ensure", "hide", "EVAL_WRAP", "code", "UNREWRITE", "url", "isWorkerScope", "obj", "locationOfWindow", "w", "LOCATION", "isWindow", "isDocument", "value", "loc", "CONNECTING", "OPEN", "CLOSING", "CLOSED", "createWebSocketClass", "core", "win", "NativeWebSocket", "internals", "state", "ws", "s", "isBlob", "value", "connect", "target", "protocols", "dispatch", "make", "event", "fail", "message", "transport", "headers", "protocol", "extensions", "data", "code", "reason", "wasClean", "setCookies", "err", "WebSocket", "url", "list", "wasConnecting", "name", "type", "handler", "previous", "listener", "disguise", "hookNetwork", "core", "win", "rewrite", "url", "isUrlLike", "input", "unrewriteGetter", "original", "wrapConstructor", "args", "wrapMethod", "init", "wrapAccessor", "XHR", "method", "rest", "createWebSocketClass", "workerArgs", "options", "moduleWorker", "urls", "hookWindow", "core", "win", "ensure", "isWindowRealm", "js", "code", "wrapAccessor", "name", "wrapMethod", "original", "handler", "rest", "NativeFunction", "mapFunctionArgs", "args", "FunctionProxy", "target", "thisArg", "newTarget", "disguise", "container", "url", "next", "opened", "History", "state", "title", "Navigation", "message", "targetOrigin", "origin", "source", "isWindow", "hookDocument", "core", "win", "Doc", "unrewriteGetter", "original", "wrapAccessor", "referrer", "target", "value", "name", "wrapMethod", "markup", "URL_PROPERTIES", "SRCSET_PROPERTIES", "READONLY_URL_PROPERTIES", "HYPERLINK_PARTS", "RENAMED", "NAVIGATION_ATTRS", "NAVIGATION_SELECTOR", "JS_TYPE", "hookDom", "core", "win", "ensure", "ElementProto", "getAttr", "setAttr", "removeAttr", "renamedFor", "el", "attr", "wrapMethod", "original", "name", "value", "renamed", "URL_ATTRS", "ns", "local", "iface", "prop", "wrapAccessor", "raw", "target", "proto", "part", "url", "rawText", "text", "markup", "position", "rest", "scriptText", "frame", "doc", "fixElement", "rewritten", "old", "records", "record", "node", "scopeStorage", "win", "storage", "prefix", "proto", "getItem", "setItem", "removeItem", "key", "keys", "out", "i", "k", "api", "v", "name", "disguise", "isItem", "target", "prop", "value", "hookStorage", "core", "desc", "scoped", "RESERVED_DB", "PAGE_ALIAS", "hookIndexedDB", "method", "wrapMethod", "original", "rest", "list", "db", "foreign", "isForeign", "core", "win", "href", "ensureRealm", "hasOwn", "state", "createLocation", "install", "exposeToAncestors", "w", "parent", "LOCATION", "installGlobals", "other", "isWindowRealm", "runtime", "hide", "createWorkerLocation", "ensure", "steps", "installToString", "hookNetwork", "hookWindow", "hookIndexedDB", "hookDocument", "hookDom", "hookStorage", "step", "err", "scope", "config", "boot", "formatter", "createFormatter", "container", "ContainerProto", "controllerGetter", "natives", "core", "createCore", "install", "el"]
7
+ }
@@ -0,0 +1,2 @@
1
+ var re={encode:e=>e,decode:e=>e},ie={encode:e=>encodeURIComponent(e),decode:e=>decodeURIComponent(e)};function q(e){let n="";for(let s=0;s<e.length;s++)n+=s%2?String.fromCharCode(e.charCodeAt(s)^2):e[s];return n}var oe={encode:e=>encodeURIComponent(q(e)),decode:e=>q(decodeURIComponent(e))},se={encode(e){let n=new TextEncoder().encode(e),s="";for(let t=0;t<n.length;t++)s+=String.fromCharCode(n[t]);return btoa(s).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")},decode(e){let n=e.replace(/-/g,"+").replace(/_/g,"/");for(;n.length%4;)n+="=";let s=atob(n),t=new Uint8Array(s.length);for(let i=0;i<s.length;i++)t[i]=s.charCodeAt(i);return new TextDecoder("utf-8",{fatal:!0}).decode(t)}},B={none:re,plain:ie,xor:oe,base64:se};function I(e){let n=B[e];if(!n)throw new Error(`butter: unknown codec "${e}"`);return n}var _="~m/",ae=/^(?:data|blob|about|mailto|tel|sms|javascript|intent|chrome|chrome-extension|moz-extension|file|filesystem):/i,ce=/^(?:https?|wss?):\/\//i;function F({origin:e,prefix:n,codec:s}){let t=I(s),i=e+n;function f(a){a.startsWith(_)&&(a=a.slice(_.length));let d;try{d=t.decode(a)}catch{return null}if(!ce.test(d))return null;try{return new URL(d).href}catch{return null}}function u(a){return a.startsWith(i)||a.startsWith(n)}function o(a,d,x){if(a==null)return a;let C=String(a),h=C.trim();if(!h||h.startsWith("#")||ae.test(h))return C;if(u(h))return h;let w;try{w=new URL(h,d)}catch{return C}if(w.protocol!=="http:"&&w.protocol!=="https:")return C;let b=w.hash;w.hash="";let T=x&&x.moduleWorker?_:"";return i+T+t.encode(w.href)+b}function A(a){if(a==null)return a;let d=String(a),x;if(d.startsWith(i))x=d.slice(i.length);else if(d.startsWith(n))x=d.slice(n.length);else return d;let C="",h=x.indexOf("#");h!==-1&&(C=x.slice(h),x=x.slice(0,h));let w="",b=x.indexOf("?");b!==-1&&(w=x.slice(b),x=x.slice(0,b));let T=f(x);if(T===null)return d;if(!w)return T+C;let E=new URL(T);return E.search=w,E.href+C}function g(a,d,x=o){let C="",h=0,w=a.length;for(;h<w;){let b=h;for(;h<w&&(/\s/.test(a[h])||a[h]===",");)h++;if(C+=a.slice(b,h),h>=w)break;let T=h;for(;h<w&&!/\s/.test(a[h]);)h++;let E=a.slice(T,h),c="",k=E.match(/,+$/);if(k&&(c=k[0],E=E.slice(0,-c.length)),C+=x(E,d)+c,c)continue;let y=h,l=0;for(;h<w;){let r=a[h];if(r==="(")l++;else if(r===")")l=Math.max(0,l-1);else if(r===","&&l===0)break;h++}C+=a.slice(y,h)}return C}return{origin:e,prefix:n,codec:t,decodeTail:f,isProxied:u,rewrite:o,unrewrite:A,rewriteSrcset:g,unrewriteSrcset:a=>g(a,"",d=>A(d))}}var le=/url\(\s*(?:"((?:[^"\\\n]|\\.)*)"|'((?:[^'\\\n]|\\.)*)'|((?:[^)\s"'\\]|\\.)*))\s*\)/gi,ue=/@import\s+(?:"((?:[^"\\\n]|\\.)*)"|'((?:[^'\\\n]|\\.)*)')/gi;function D(e,n,s){if(!e||e.indexOf("url(")===-1&&e.indexOf("URL(")===-1&&e.indexOf("@import")===-1)return e;let t=i=>{let f=i.replace(/\\([^0-9a-fA-F\n])/g,"$1");if(!f||f.startsWith("#")||/^data:/i.test(f))return null;let u=s(f,n);return u===f?null:u};return e.replace(le,(i,f,u,o)=>{let g=t(f??u??o??"");return g===null?i:`url("${g.replace(/["\\\n]/g,"\\$&")}")`}).replace(ue,(i,f,u)=>{let o=t(f??u??"");return o===null?i:`@import "${o.replace(/["\\\n]/g,"\\$&")}"`})}var v="__butter$location",H="__butter$js",J="__butter$unrewrite",fe=/location|eval|import\s*\.\s*meta/,V=new Set(["return","typeof","instanceof","in","of","new","delete","void","throw","case","do","else","yield","await","extends"]),de=new Set(["(","[",",","=",":","?","...","!","&","|","^","~","+","-","*","/","%","<",">","${","??","?."]),pe=new Set(["return","yield","await","typeof","void","in","of","case","throw","delete"]),L=/import\s*\.\s*meta\s*\.\s*url(?![\w$])/y;function K(e){return e>=97&&e<=122||e>=65&&e<=90||e===36||e===95||e>=128}function W(e){return K(e)||e>=48&&e<=57}function P(e){return e===32||e===9||e===10||e===13||e===11||e===12||e===160||e===65279||e===8232||e===8233||e===5760||e>=8192&&e<=8202||e===8239||e===8287||e===12288}function j(e){return e===10||e===13||e===8232||e===8233}function Y(e){if(typeof e!="string"||!fe.test(e))return e;let n=e.length,s=[],t="",i="",f="",u="",o=[],A=[],g=!1,a=(l,r)=>{f=t,u=i,t=l,i=r},d=l=>{for(;l<n;){let r=e.charCodeAt(l);if(P(r))l++;else if(r===47&&e.charCodeAt(l+1)===47)for(;l<n&&!j(e.charCodeAt(l));)l++;else if(r===47&&e.charCodeAt(l+1)===42){let p=e.indexOf("*/",l+2);l=p===-1?n:p+2}else break}return l},x=l=>{let r=d(l),p=r;for(;r<n&&W(e.charCodeAt(r));)r++;return e.slice(p,r)},C=()=>t?t==="punc"?i!==")"&&i!=="]"&&i!=="++"&&i!=="--":t==="id"?V.has(i):!1:!0,h=(l,r)=>{let p=l+1;for(;p<n;){let m=e.charCodeAt(p);if(m===92)p+=2;else{if(m===r)return p+1;if(m===10||m===13)return p;p++}}return n},w=l=>{for(;l<n;){let r=e.charCodeAt(l);if(r===92)l+=2;else{if(r===96)return[l+1,!1];if(r===36&&e.charCodeAt(l+1)===123)return[l+2,!0];l++}}return[n,!1]},b=l=>{let r=l+1,p=!1;for(;r<n;){let m=e.charCodeAt(r);if(j(m))return-1;if(m===92){if(r+1>=n||j(e.charCodeAt(r+1)))return-1;r+=2;continue}if(p)m===93&&(p=!1);else if(m===91)p=!0;else if(m===47){for(r++;r<n&&W(e.charCodeAt(r));)r++;return r}r++}return-1},T=l=>{let[r,p]=w(l);return p?(o.push("tmpl"),a("punc","${")):a("tmpl",""),r},E=(l,r)=>{if(t==="punc"&&(i==="."||i==="?.")){s.push([l,r,v]);return}let p=o[o.length-1];if(p==="ie-import"||p==="ie-export"){let m=p==="ie-import";t==="id"&&i==="as"?m&&s.push([l,r,v]):x(r)==="as"?m||s.push([l,r,v]):s.push([l,r,m?`location as ${v}`:`${v} as location`]);return}if(p==="obj"&&t==="punc"&&(i==="{"||i===",")){let m=e[d(r)];if(m===":")return;if(m===","||m==="}"){s.push([l,r,`location: ${v}`]);return}}s.push([l,r,v])},c=0;if(e.startsWith("#!"))for(;c<n&&!j(e.charCodeAt(c));)c++;for(;c<n;){let l=e.charCodeAt(c);if(P(l)){c++;continue}if(l===47){let r=e.charCodeAt(c+1);if(r===47||r===42){c=d(c);continue}if(C()){let p=b(c);if(p!==-1){c=p,a("regex","");continue}}c++,a("punc","/");continue}if(l===34||l===39){let r=h(c,l),p=e.slice(c+1,r-1);if(p==="location"&&t==="punc"&&i==="["&&(f==="id"&&!V.has(u)||u===")"||u==="]")&&e[d(r)]==="]"){let m=e[c];s.push([c,r,m+v+m])}c=r,a("str",p);continue}if(l===96){c=T(c+1);continue}if(K(l)||l===92){let r=c,p=!1;for(;r<n;){let R=e.charCodeAt(r);if(R===92)if(p=!0,e.charCodeAt(r+2)===123){let U=e.indexOf("}",r);r=U===-1?n:U+1}else r+=6;else if(W(R)&&!P(R))r++;else break}let m=e.slice(c,r),ne=t==="punc"&&(i==="."||i==="?.");if(!p)if(m==="location")E(c,r);else if(m==="import"&&!ne){if(L.lastIndex=c,L.test(e)){let U=L.lastIndex;s.push([c,U,`${J}(import.meta.url)`]),c=U,a("punc",")");continue}let R=e[d(r)];R!=="("&&R!=="."&&(g=!0)}else m==="from"&&g&&(g=!1);c=r,a("id",m);continue}if(l===35){let r=c+1;for(;r<n&&W(e.charCodeAt(r));)r++;a("id",e.slice(c,r)),c=r;continue}if(l>=48&&l<=57||l===46&&e.charCodeAt(c+1)>=48&&e.charCodeAt(c+1)<=57){let r=c+1;for(;r<n;){let p=e.charCodeAt(r);if(W(p)||p===46)r++;else break}c=r,a("num","");continue}switch(l){case 123:{let r="block";t==="id"&&(i==="import"||i==="export")&&u!=="."&&u!=="?."?r="ie-"+i:g&&t==="punc"&&i===","?r="ie-import":(t==="punc"&&de.has(i)||t==="id"&&pe.has(i))&&(r="obj"),o.push(r),c++,a("punc","{");continue}case 125:{if(o.pop()==="tmpl"){c=T(c+1);continue}c++,a("punc","}");continue}case 40:{let r=t==="id"&&i==="eval"&&u!=="."&&u!=="?."&&u!=="function";A.push(r?c:null),c++,a("punc","(");continue}case 41:{let r=A.pop();r!=null&&e[d(c+1)]!=="{"&&(s.push([r+1,r+1,H+"("]),s.push([c,c,")"])),c++,a("punc",")");continue}case 46:e.charCodeAt(c+1)===46&&e.charCodeAt(c+2)===46?(c+=3,a("punc","...")):(c++,a("punc","."));continue;case 63:{let r=e.charCodeAt(c+1),p=e.charCodeAt(c+2);r===46&&!(p>=48&&p<=57)?(c+=2,a("punc","?.")):r===63?(c+=2,a("punc","??")):(c++,a("punc","?"));continue}case 43:case 45:e.charCodeAt(c+1)===l?(c+=2,a("punc",l===43?"++":"--")):(c++,a("punc",e[c-1]));continue;case 61:e.charCodeAt(c+1)===62?(c+=2,a("punc","=>")):(c++,a("punc","="));continue;case 59:g=!1,c++,a("punc",";");continue;default:c++,a("punc",e[c-1])}}if(s.length===0)return e;s.sort((l,r)=>l[0]-r[0]||l[1]-l[0]-(r[1]-r[0]));let k="",y=0;for(let[l,r,p]of s)l<y||(k+=e.slice(y,l)+p,y=r);return k+e.slice(y)}var he=new Set(["script","style","textarea","title","xmp","iframe","noembed","noframes","plaintext"]),we=/^(?:|module|(?:text|application)\/(?:x-)?(?:javascript|ecmascript)|text\/jscript|text\/livescript|text\/javascript1\.[0-5])$/i,X=new Set(["href","src","action","formaction","poster","background","cite","longdesc","manifest","codebase","icon","lowsrc","dynsrc","xlink:href"]),ge={integrity:"data-butter-integrity",sandbox:"data-butter-sandbox"},me={amp:"&",lt:"<",gt:">",quot:'"',apos:"'",nbsp:"\xA0"},Ce=/&(?:#(\d{1,7});?|#[xX]([0-9a-fA-F]{1,6});?|(amp|lt|gt|quot|apos|nbsp)(?:;|(?![=\w])))/g;function Z(e){return e.indexOf("&")===-1?e:e.replace(Ce,(n,s,t,i)=>{if(i)return me[i];let f=s?parseInt(s,10):parseInt(t,16);return f>0&&f<=1114111?String.fromCodePoint(f):"\uFFFD"})}function Q(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;")}function S(e){return e===32||e===9||e===10||e===12||e===13}function z(e){return e>=97&&e<=122||e>=65&&e<=90}function $(e,n,s,t,i){let f=s.toLowerCase();if(f.length>2&&f.startsWith("on"))return e.js(t);switch(f){case"style":return e.css(t,i.base);case"srcset":case"imagesrcset":return e.url.rewriteSrcset(t,i.base);case"ping":return t.split(/(\s+)/).map(u=>u.trim()?e.rewriteUrl(u,i.base):u).join("");case"srcdoc":return n==="iframe"?e.html(t,{base:i.base,inject:i.inject}):t;case"data":return n==="object"?e.rewriteUrl(t,i.base):t}if(X.has(f)){let u=t.trim();if(/^javascript:/i.test(u)){let o=u.slice(11);return o.indexOf("%")===-1?"javascript:"+e.js(o):t}return e.rewriteUrl(t,i.base)}return t}function xe(e,n){let s=e.length,t=n+1;for(;t<s;){let o=e.charCodeAt(t);if(S(o)||o===47||o===62)break;t++}let i=e.slice(n+1,t).toLowerCase(),f=[],u=!1;for(;t<s;){let o=e.charCodeAt(t);if(S(o)){t++;continue}if(o===47){if(e.charCodeAt(t+1)===62)return u=!0,{name:i,attrs:f,selfClosing:u,end:t+2};t++;continue}if(o===62)return{name:i,attrs:f,selfClosing:u,end:t+1};let A=t++;for(;t<s&&(o=e.charCodeAt(t),!(S(o)||o===47||o===62||o===61));)t++;let g=e.slice(A,t),a=t;for(;a<s&&S(e.charCodeAt(a));)a++;if(e.charCodeAt(a)!==61){f.push({name:g,value:null,start:A,end:t});continue}for(a++;a<s&&S(e.charCodeAt(a));)a++;let d=e.charCodeAt(a),x;if(d===34||d===39){let C=e.indexOf(d===34?'"':"'",a+1);if(C===-1)return null;x=e.slice(a+1,C),t=C+1}else{let C=a;for(;a<s&&!S(e.charCodeAt(a))&&e.charCodeAt(a)!==62;)a++;x=e.slice(C,a),t=a}f.push({name:g,value:Z(x),start:A,end:t})}return null}function O(e,n){for(let s of e)if(s.name.toLowerCase()===n)return s}function be(e,n,s,t){let i=!1,{name:f,attrs:u}=n;if(f==="meta"){let o=O(u,"http-equiv"),A=o&&o.value?o.value.trim().toLowerCase():"";if(A.startsWith("content-security-policy"))return o.newName="data-butter-http-equiv",!0;if(A==="refresh"){let g=O(u,"content");if(g&&g.value){let a=N(e,g.value,s.base);a!==g.value&&(g.newValue=a,i=!0)}}return i}if(f==="base"&&!t.baseSeen){let o=O(u,"href");if(o&&o.value!==null){t.baseSeen=!0;try{s.base=new URL(o.value.trim(),s.base).href}catch{}}}for(let o of u){if(o.value===null)continue;let A=o.name.toLowerCase();if(A==="data-butter")return!1;let g=ge[A];if(g&&(A!=="sandbox"||f==="iframe")){o.newName=g,i=!0;continue}let a=$(e,f,o.name,o.value,s);a!==o.value&&(o.newValue=a,i=!0)}return i}function N(e,n,s){let t=n.match(/^(\s*[\d.]*\s*[;,]?\s*(?:url\s*=\s*)?)(['"]?)(.*?)\2(\s*)$/i);return!t||!t[3]?n:t[1]+t[2]+e.rewriteUrl(t[3],s)+t[2]+t[4]}function Ae(e,n,s){let t="",i=s;for(let f of n.attrs){if(f.newName===void 0&&f.newValue===void 0)continue;let u=f.newName??f.name,o=f.newValue!==void 0?f.newValue:f.value;t+=e.slice(i,f.start)+u+(o===null?"":`="${Q(o)}"`),i=f.end}return t+e.slice(i,n.end)}var G=new Map;function Te(e,n,s){let t=G.get(n);t||(t=new RegExp(`</${n}(?=[\\s/>])`,"ig"),G.set(n,t)),t.lastIndex=s;let i=t.exec(e);return i?i.index:e.length}function ee(e,n,s){let t={base:s.base,inject:s.inject},i={injected:!s.inject,baseSeen:!1,foreign:0,doctypeEnd:-1},f=e.length,u="",o=0,A=()=>(i.injected=!0,t.inject||"");for(;o<f;){let g=e.indexOf("<",o);if(g===-1){u+=e.slice(o);break}u+=e.slice(o,g),o=g;let a=e.charCodeAt(o+1);if(a===33||a===63){let w;if(e.startsWith("<!--",o))if(e.startsWith("<!-->",o))w=o+5;else if(e.startsWith("<!--->",o))w=o+6;else{let b=e.indexOf("-->",o+4);w=b===-1?f:b+3}else if(i.foreign&&e.startsWith("<![CDATA[",o)){let b=e.indexOf("]]>",o+9);w=b===-1?f:b+3}else{let b=e.indexOf(">",o+2);w=b===-1?f:b+1,/^<!doctype/i.test(e.slice(o,o+9))&&(i.doctypeEnd=u.length+(w-o))}u+=e.slice(o,w),o=w;continue}if(a===47){let w=e.indexOf(">",o+2),b=w===-1?f:w+1;if(z(e.charCodeAt(o+2))){let T=e.slice(o+2,b).match(/^[^\s/>]*/)[0].toLowerCase();(T==="svg"||T==="math")&&i.foreign>0&&i.foreign--}u+=e.slice(o,b),o=b;continue}if(!z(a)){u+="<",o++;continue}let d=xe(e,o);if(!d){u+=e.slice(o);break}if(!i.injected&&d.name!=="html"&&d.name!=="head"&&(u+=A()),u+=be(n,d,t,i)?Ae(e,d,o):e.slice(o,d.end),o=d.end,!i.injected&&d.name==="head"&&(u+=A()),(d.name==="svg"||d.name==="math")&&!d.selfClosing&&i.foreign++,!(i.foreign?(d.name==="script"||d.name==="style")&&!d.selfClosing:he.has(d.name)))continue;if(d.name==="plaintext"){u+=e.slice(o);break}let C=Te(e,d.name,o),h=e.slice(o,C);if(d.name==="script"&&!O(d.attrs,"data-butter")){let w=O(d.attrs,"type");we.test(w&&w.value?w.value.trim():"")&&(h=n.js(h))}else d.name==="style"&&(h=n.css(h,t.base));u+=h,o=C}if(!i.injected){let g=A();i.doctypeEnd!==-1?u=u.slice(0,i.doctypeEnd)+g+u.slice(i.doctypeEnd):u=g+u}return u}function te(e){let n=F(e),s={config:e,url:n,rewriteUrl:(t,i,f)=>n.rewrite(t,i,f),unrewriteUrl:t=>n.unrewrite(t),css:(t,i)=>D(t,i,n.rewrite),js:t=>Y(t),html:(t,i)=>ee(t,s,i),attr:(t,i,f,u)=>$(s,t,i,f,u),refresh:(t,i)=>N(s,t,i)};return s}var M=class{options;config=null;registration=null;#e=null;constructor(n={}){this.options={serviceWorker:n.serviceWorker??"/butter/sw.js",scope:n.scope??"/",config:n.config??"/butter/config.js",searchEngine:n.searchEngine??"https://duckduckgo.com/?q=%s"}}async init(){if(!("serviceWorker"in navigator))throw new Error("This browser has no service workers (private windows often disable them).");if(!window.isSecureContext)throw new Error("Service workers need HTTPS (or localhost).");let[n,s]=await Promise.all([this.#r(),this.#i()]);return this.config=n,this.registration=s,this.#e=te({origin:location.origin,prefix:n.prefix,codec:n.codec}),this}encodeUrl(n){return this.#n().rewriteUrl(String(n),location.href)}decodeUrl(n){return this.#n().unrewriteUrl(String(n))}resolveInput(n){let s=n.trim();return/^https?:\/\//i.test(s)?s:/^[^\s]+\.[a-z]{2,}(?::\d+)?(?:[/?#]\S*)?$/i.test(s)?"https://"+s:this.options.searchEngine.replace("%s",encodeURIComponent(s))}go(n){location.href=this.encodeUrl(this.resolveInput(n))}get transports(){return this.config?.transports??[]}async getTransport(){return await this.#t({type:"butter:get-transport"})}async setTransport(n,s){return(await this.#t({type:"butter:set-transport",name:n,options:s})).active}async resetTransport(){return(await this.#t({type:"butter:reset-transport"})).active}#n(){if(!this.#e)throw new Error("ButterController: call init() first");return this.#e}async#r(){let n=await fetch(this.options.config,{credentials:"same-origin",cache:"no-cache"});if(!n.ok)throw new Error(`Could not load ${this.options.config} (HTTP ${n.status}).`);let s=(await n.text()).match(/=\s*(\{[\s\S]*\})\s*;?\s*$/);if(!s)throw new Error(`${this.options.config} is not a butter-col configuration.`);return JSON.parse(s[1])}async#i(){let n=await navigator.serviceWorker.register(this.options.serviceWorker,{scope:this.options.scope}),s=n.installing||n.waiting||n.active;return s&&s.state!=="activated"&&await new Promise((t,i)=>{s.addEventListener("statechange",()=>{s.state==="activated"&&t(),s.state==="redundant"&&i(new Error("The butter-col service worker failed to install."))})}),n}async#t(n){let s=this.registration?.active;if(!s)throw new Error("ButterController: call init() first");return new Promise((t,i)=>{let f=new MessageChannel,u=setTimeout(()=>i(new Error("The service worker did not answer.")),1e4);f.port1.onmessage=o=>{clearTimeout(u),o.data?.ok?t(o.data.result):i(new Error(o.data?.error||"The service worker refused the request."))},s.postMessage(n,[f.port2])})}},Pe=M;export{M as ButterController,Pe as default};
2
+ //# sourceMappingURL=controller.mjs.map