langsys-js-typescript 0.6.4 → 0.7.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts","../src/identity.ts","../src/logger.ts","../src/locale.ts","../src/interpolate.ts","../src/legacy-value.ts","../src/legacy-keys.ts","../src/snapshot.ts","../src/server-messages.ts","../src/var-names.ts","../src/var-markers.ts"],"names":["x","c","a","b","d","i","key","branch","value","isRecord"],"mappings":"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","file":"pure.mjs","sourcesContent":["export const isEmpty = (data: unknown): boolean => {\n if (typeof data === 'number' || typeof data === 'boolean') return false;\n if (typeof data === 'undefined' || data === null) return true;\n if (typeof (data as { length?: number }).length !== 'undefined') {\n return (data as { length: number }).length === 0;\n }\n if (typeof data === 'object') return Object.keys(data as object).length === 0;\n return false;\n};\n\nexport function structuredCloneShim<T>(obj: T): T {\n if (typeof structuredClone === 'function') return structuredClone(obj);\n\n const clone = <V>(o: V): V => {\n if (typeof o !== 'object' || o === null) return o;\n if (Array.isArray(o)) return o.map((item) => clone(item)) as unknown as V;\n const out: Record<string, unknown> = {};\n for (const key in o as object) {\n if (Object.prototype.hasOwnProperty.call(o, key)) {\n out[key] = clone((o as Record<string, unknown>)[key]);\n }\n }\n return out as V;\n };\n return clone(obj);\n}\n\n/**\n * Encode a string to a \"byte string\" — one character per UTF-8 byte, each\n * ≤ 0xFF. The MD5 core packs `charCodeAt` values into byte lanes and takes\n * `length * 8` as the message bit-length, both of which are only correct when\n * every character IS a single byte. Running this first is what makes `md5`\n * agree with a standard UTF-8 MD5 for non-ASCII input.\n */\nfunction toUtf8ByteString(input: string): string {\n const bytes = new TextEncoder().encode(input);\n let out = '';\n // Chunked to avoid blowing the argument limit on very large content blocks.\n for (let i = 0; i < bytes.length; i += 8192) {\n out += String.fromCharCode(...bytes.subarray(i, i + 8192));\n }\n return out;\n}\n\n/**\n * MD5 of a string, matching a standard UTF-8 MD5 for all input.\n *\n * Content-block `custom_id`s are derived from this, so it's a wire identity —\n * see `generateCustomId`. Before 0.6.0 this packed UTF-16 code units directly\n * into byte lanes, which agreed with a real MD5 only for ASCII: non-ASCII\n * input both diverged from every other Langsys SDK and could collide (a\n * character's high byte was OR-ed into the neighbouring lane, vanishing\n * whenever that lane already carried those bits — so `éa` and `ǩa` hashed\n * alike). `md5Legacy` preserves the old behavior for migration lookups only.\n */\nexport function md5(inputString: string) {\n if (typeof inputString !== 'string') inputString = JSON.stringify(inputString);\n return md5Core(toUtf8ByteString(inputString));\n}\n\n/**\n * The pre-0.6.0 MD5, retained ONLY so existing content blocks stay resolvable:\n * ids minted by an older SDK are keyed by this. Lookup-only — never register\n * new content under it, or the colliding-id population keeps growing.\n *\n * @deprecated Migration aid; will be removed once catalogs have been rebased.\n */\nexport function md5Legacy(inputString: string) {\n if (typeof inputString !== 'string') inputString = JSON.stringify(inputString);\n return md5Core(inputString);\n}\n\n// prettier-ignore\nfunction md5Core(inputString: string) {\n const hc = '0123456789abcdef';\n function rh(n: number) { let j, s = ''; for (j = 0; j <= 3; j++) s += hc.charAt((n >> (j * 8 + 4)) & 0x0F) + hc.charAt((n >> (j * 8)) & 0x0F); return s; }\n function ad(x: number, y: number) { const l = (x & 0xFFFF) + (y & 0xFFFF); const m = (x >> 16) + (y >> 16) + (l >> 16); return (m << 16) | (l & 0xFFFF); }\n function rl(n: number, c: number) { return (n << c) | (n >>> (32 - c)); }\n function cm(q: number, a: number, b: number, x: number, s: number, t: number) { return ad(rl(ad(ad(a, q), ad(x, t)), s), b); }\n function ff(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { return cm((b & c) | ((~b) & d), a, b, x, s, t); }\n function gg(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { return cm((b & d) | (c & (~d)), a, b, x, s, t); }\n function hh(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { return cm(b ^ c ^ d, a, b, x, s, t); }\n function ii(a: number, b: number, c: number, d: number, x: number, s: number, t: number) { return cm(c ^ (b | (~d)), a, b, x, s, t); }\n function sb(x: string) {\n let i; const nblk = ((x.length + 8) >> 6) + 1; const blks = new Array(nblk * 16); for (i = 0; i < nblk * 16; i++) blks[i] = 0;\n for (i = 0; i < x.length; i++) blks[i >> 2] |= x.charCodeAt(i) << ((i % 4) * 8);\n blks[i >> 2] |= 0x80 << ((i % 4) * 8); blks[nblk * 16 - 2] = x.length * 8; return blks;\n }\n let i, x = sb('' + inputString), a = 1732584193, b = -271733879, c = -1732584194, d = 271733878, olda, oldb, oldc, oldd;\n for (i = 0; i < x.length; i += 16) {\n olda = a; oldb = b; oldc = c; oldd = d;\n a = ff(a, b, c, d, x[i + 0], 7, -680876936); d = ff(d, a, b, c, x[i + 1], 12, -389564586); c = ff(c, d, a, b, x[i + 2], 17, 606105819);\n b = ff(b, c, d, a, x[i + 3], 22, -1044525330); a = ff(a, b, c, d, x[i + 4], 7, -176418897); d = ff(d, a, b, c, x[i + 5], 12, 1200080426);\n c = ff(c, d, a, b, x[i + 6], 17, -1473231341); b = ff(b, c, d, a, x[i + 7], 22, -45705983); a = ff(a, b, c, d, x[i + 8], 7, 1770035416);\n d = ff(d, a, b, c, x[i + 9], 12, -1958414417); c = ff(c, d, a, b, x[i + 10], 17, -42063); b = ff(b, c, d, a, x[i + 11], 22, -1990404162);\n a = ff(a, b, c, d, x[i + 12], 7, 1804603682); d = ff(d, a, b, c, x[i + 13], 12, -40341101); c = ff(c, d, a, b, x[i + 14], 17, -1502002290);\n b = ff(b, c, d, a, x[i + 15], 22, 1236535329); a = gg(a, b, c, d, x[i + 1], 5, -165796510); d = gg(d, a, b, c, x[i + 6], 9, -1069501632);\n c = gg(c, d, a, b, x[i + 11], 14, 643717713); b = gg(b, c, d, a, x[i + 0], 20, -373897302); a = gg(a, b, c, d, x[i + 5], 5, -701558691);\n d = gg(d, a, b, c, x[i + 10], 9, 38016083); c = gg(c, d, a, b, x[i + 15], 14, -660478335); b = gg(b, c, d, a, x[i + 4], 20, -405537848);\n a = gg(a, b, c, d, x[i + 9], 5, 568446438); d = gg(d, a, b, c, x[i + 14], 9, -1019803690); c = gg(c, d, a, b, x[i + 3], 14, -187363961);\n b = gg(b, c, d, a, x[i + 8], 20, 1163531501); a = gg(a, b, c, d, x[i + 13], 5, -1444681467); d = gg(d, a, b, c, x[i + 2], 9, -51403784);\n c = gg(c, d, a, b, x[i + 7], 14, 1735328473); b = gg(b, c, d, a, x[i + 12], 20, -1926607734); a = hh(a, b, c, d, x[i + 5], 4, -378558);\n d = hh(d, a, b, c, x[i + 8], 11, -2022574463); c = hh(c, d, a, b, x[i + 11], 16, 1839030562); b = hh(b, c, d, a, x[i + 14], 23, -35309556);\n a = hh(a, b, c, d, x[i + 1], 4, -1530992060); d = hh(d, a, b, c, x[i + 4], 11, 1272893353); c = hh(c, d, a, b, x[i + 7], 16, -155497632);\n b = hh(b, c, d, a, x[i + 10], 23, -1094730640); a = hh(a, b, c, d, x[i + 13], 4, 681279174); d = hh(d, a, b, c, x[i + 0], 11, -358537222);\n c = hh(c, d, a, b, x[i + 3], 16, -722521979); b = hh(b, c, d, a, x[i + 6], 23, 76029189); a = hh(a, b, c, d, x[i + 9], 4, -640364487);\n d = hh(d, a, b, c, x[i + 12], 11, -421815835); c = hh(c, d, a, b, x[i + 15], 16, 530742520); b = hh(b, c, d, a, x[i + 2], 23, -995338651);\n a = ii(a, b, c, d, x[i + 0], 6, -198630844); d = ii(d, a, b, c, x[i + 7], 10, 1126891415); c = ii(c, d, a, b, x[i + 14], 15, -1416354905);\n b = ii(b, c, d, a, x[i + 5], 21, -57434055); a = ii(a, b, c, d, x[i + 12], 6, 1700485571); d = ii(d, a, b, c, x[i + 3], 10, -1894986606);\n c = ii(c, d, a, b, x[i + 10], 15, -1051523); b = ii(b, c, d, a, x[i + 1], 21, -2054922799); a = ii(a, b, c, d, x[i + 8], 6, 1873313359);\n d = ii(d, a, b, c, x[i + 15], 10, -30611744); c = ii(c, d, a, b, x[i + 6], 15, -1560198380); b = ii(b, c, d, a, x[i + 13], 21, 1309151649);\n a = ii(a, b, c, d, x[i + 4], 6, -145523070); d = ii(d, a, b, c, x[i + 11], 10, -1120210379); c = ii(c, d, a, b, x[i + 2], 15, 718787259);\n b = ii(b, c, d, a, x[i + 9], 21, -343485551); a = ad(a, olda); b = ad(b, oldb); c = ad(c, oldc); d = ad(d, oldd);\n }\n return rh(a) + rh(b) + rh(c) + rh(d);\n}\n","import { md5, md5Legacy } from './utils.js';\n\n/**\n * The IDENTITY CONTRACT — everything that decides a `custom_id`, with no DOM\n * and no module-scope side effects, so it can be imported from a server, a\n * worker or a build script.\n *\n * It lives apart from `content-block.ts` because that module reaches the API\n * client, the discovery lane and the persisted stores; importing it to hash a\n * string pulled a network client and a storage probe along. `langsys-js-server`\n * was sed-extracting these functions out of a published tarball under\n * `@ts-nocheck` for exactly that reason — a copy that silently predates every\n * id rule changed since. Re-exported by `content-block.ts`, so nothing that\n * already imports from there needs to move.\n *\n * Reachable as the `langsys-js-typescript/pure` subpath. Nothing here may touch\n * `window`, `document`, `navigator` or storage, at import time or on any call\n * path — `tests/pure-subpath.test.ts` enforces that under a trapping global.\n */\n\n/**\n * HTML attributes whose values should be harvested for translation.\n *\n * THE LIST IS NOW IDENTICAL TO `langsys-php`'s, all twenty-seven, in its order.\n *\n * It used to be a subset of fifteen, and this docstring used to argue that the\n * framework-convention attributes (Bootstrap `data-bs-*`, Rails `data-confirm`)\n * were deliberately not mirrored because a JS app renders those strings through\n * its own components. That reasoning is superseded and was left standing beside\n * the list that contradicted it — the twelve below are exactly the attributes it\n * said would never appear here.\n *\n * The reason it was wrong: on an SSR handoff the two SDKs tokenize the SAME\n * markup, so an attribute only one side harvests produces a different token\n * array and therefore a different `custom_id` for identical content. That is not\n * a coverage hole to be argued about, it is a split identity.\n *\n * ORDER IS IDENTITY. `custom_id` hashes the token array, and where an element\n * carries several of these the list order decides the sequence. The same set in\n * a different order agrees on every single-attribute element and diverges on\n * exactly the ones nobody notices, so the twelve are APPENDED — inserting would\n * have re-keyed every block using one of the original fifteen.\n */\nexport const TRANSLATABLE_ATTRIBUTES = [\n 'placeholder',\n 'alt',\n 'title',\n 'label', // <option>, <optgroup>, <track> — the text a user reads in the picker\n 'aria-label',\n 'aria-placeholder',\n 'aria-description',\n 'aria-valuetext', // the spoken value of a slider/meter\n 'aria-roledescription',\n 'data-error',\n 'data-error-message',\n 'data-validation-message',\n 'data-invalid-message',\n 'data-required-message',\n 'data-pattern-message',\n // The 12 below converge on langsys-php's list, verified against\n // `src/Html/HtmlParser.php` rather than taken on report. ORDER IS IDENTITY:\n // `custom_id` hashes the token array, so these must stay appended in PHP's\n // order — reordering them silently re-keys every block using one.\n 'data-confirm', // Rails-style confirmation dialogs\n 'data-tooltip',\n 'data-title',\n 'data-content',\n 'data-original-title', // Bootstrap 4 tooltip/popover\n 'data-bs-title', // Bootstrap 5\n 'data-bs-content',\n 'data-loading-text',\n 'data-success-message',\n 'data-warning-message',\n 'data-empty-message',\n 'data-placeholder', // editors that shadow the native attribute\n];\n\n/**\n * Elements holding code, inert content, or content no implementation can agree\n * on. Measured before this existed: `<style>.plan{color:#fff}</style>`\n * registered `.plan{color:#fff}` as a translatable phrase, and\n * `<script>window.dataLayer.push(1)</script>` registered the statement. Both\n * were then sent for machine translation.\n *\n * `<noscript>` IS HERE ON A REVERSAL, and the reasoning is worth keeping because\n * the obvious answer is the wrong one. An earlier reading excluded it from this\n * list: its text renders to a real visitor whenever scripting is off, so\n * skipping it would leave a visitor-visible sentence permanently untranslated.\n * That premise is true, and it does not survive two questions.\n *\n * - WHO COULD TRANSLATE IT. With scripting off, a browser SDK is not running,\n * so it can translate nothing on that page — including this.\n * - WHAT THE TOKEN ACTUALLY IS. With scripting ENABLED, the spec's default, a\n * parser makes a `noscript` body RAW TEXT rather than markup. Chromium and\n * parse5 both yield the single token `<p>Enable JavaScript</p>`. Registering\n * that sends MARKUP to machine translation, which is this family's own\n * failure mode arriving through the rule meant to prevent it.\n *\n * And the implementations could not be made to agree cheaply. The axis is the\n * parser's scripting flag, not browser-versus-server: Chromium and parse5 agree\n * because parse5 defaults to scripting enabled, while PHP's libxml2 has no such\n * flag and parses the children as elements. `happy-dom` and `jsdom` behave like\n * libxml2, so a lane measuring in a test environment reproduces a\n * browser-versus-server split that does not exist.\n *\n * `<template>` is named as intent and is NOT a vector HERE: its content lives on\n * `HTMLTemplateElement.content`, so a walker over `childNodes` never reaches it\n * and omitting it from this list changes nothing in a DOM or in parse5 — two\n * lanes measured that independently. It is load-bearing elsewhere, which is why\n * it stays named: libxml2 puts `<template>` children in the ordinary tree, so a\n * PHP or Ruby walker that omitted it registers the template's text, and Ruby\n * measured exactly that leak. 8.0.1 states the split rather than calling the\n * exclusion free.\n *\n * `<math>` is notation, not prose. Translating a variable name or an operator\n * corrupts the expression instead of localising it, and before this exclusion\n * `<p>Area <math><mi>x</mi><mo>+</mo><mn>2</mn></math> units</p>` tokenized to\n * `['Area','x','+','2','units']` — the operator and the bare variable registered\n * as translatable phrases and sent for machine translation. Added by spec 8.0.1\n * after v8 shipped without it.\n *\n * `<svg>` IS DELIBERATELY ABSENT and must stay absent. It is the exclusion people\n * expect that is wrong: an `<svg><text>` renders visible words to a reader, so its\n * text is translated like any other. 8.0.1 states that behaviourally because the\n * structural reading — \"walk `<svg>` as a block\" — regressed the commonest markup\n * there is when PHP implemented it: treating svg as a block dropped the PARENT's\n * direct text, so `<p>Click <svg><path/></svg> to continue</p>` registered nothing\n * and every icon-bearing heading, link and list item lost its words. Adding `svg`\n * here would reproduce that, which is what `tokenizer-convergence` now pins.\n */\nexport const NON_TRANSLATABLE_ELEMENTS = ['script', 'style', 'template', 'noscript', 'math'];\n\n/**\n * True when an element opts out of translation entirely — it and its subtree\n * are skipped by the tokenizer.\n *\n * Mirrors `langsys-php`'s `HtmlParser::isTranslationExcluded()` exactly:\n * - `translate=\"no\"` — the HTML standard attribute, matched case-insensitively.\n * - `data-notrans` — PHP's author-facing alias, for hosts whose templating\n * strips unknown bare attributes or where `translate` collides with another\n * tool. Presence is intent; an explicit `\"false\"`/`\"0\"` opts out of the\n * opt-out, compared after trimming.\n *\n * Honoring PHP's alias matters for the same reason as the phrase marker: on SSR\n * handoff there is ONE DOM, and content an author marked \"do not translate\"\n * must not be extracted and registered by whichever SDK happens to walk it.\n *\n * Both this and `isPhraseMarked` trim before comparing. They briefly differed\n * — PHP's phrase check predated the trim its exclusion check gained — and the\n * gap was resolved by asking rather than tidying: mirror exactly, flag the\n * wart, let the owner decide. Divergence-by-tidying is the same failure class\n * as divergence-by-oversight, just better intentioned.\n */\nexport function isTranslationExcluded(element: AttributeReader): boolean {\n if ((element.getAttribute('translate') ?? '').toLowerCase() === 'no') return true;\n if (!element.hasAttribute('data-notrans')) return false;\n const value = (element.getAttribute('data-notrans') ?? '').trim().toLowerCase();\n return value !== 'false' && value !== '0';\n}\n\n/** The element shape the exclusion reads: the DOM's, or a tree view's. */\nexport interface AttributeReader {\n readonly tagName: string;\n getAttribute(name: string): string | null;\n hasAttribute(name: string): boolean;\n}\n\n/**\n * Whether an element is opaque in a rich phrase (TOK-1): an author's own exclusion,\n * or code and notation. It is one markup pair with nothing between, `{mNo}{mNc}`,\n * whatever it holds, so no text or value inside it enters the phrase, and it renders\n * its source content as given.\n */\nexport function isOpaqueInPhrase(element: AttributeReader): boolean {\n return isTranslationExcluded(element) || NON_TRANSLATABLE_ELEMENTS.includes(element.tagName.toLowerCase());\n}\n\n/**\n * THE definition. `phrase.ts` re-exports this rather than restating it — the\n * literal used to appear in both files, so renaming one side left the other\n * silently stale: the tokenizer would stop recognising the marker `Phrase`\n * emits and would re-tokenize a subtree that manages itself.\n */\nexport const PHRASE_MARKER_ATTR = 'data-ls-phrase';\n\n/** PHP's spelling. Recognised so a catalog shared with langsys-php round-trips. */\nexport const PHRASE_MARKER_ATTR_LEGACY = 'data-langsys-phrase';\n\nexport const PHRASE_MARKER_ATTRS = [PHRASE_MARKER_ATTR, PHRASE_MARKER_ATTR_LEGACY] as const;\n\n/**\n * Marker the `Translate` host element carries, holding the resolved\n * `custom_id` of the block rendered inside it.\n *\n * Mirrors how a `Phrase` host carries `PHRASE_MARKER_ATTR`, and exists so a\n * server-rendered page can be read back: the id is otherwise derivable only by\n * re-running the tokenizer over the same subtree, which a reader that only has\n * the HTML cannot do identically.\n */\nexport const CONTENT_BLOCK_MARKER_ATTR = 'data-ls-contentblock';\n\n/** PHP's spelling, accepted on read for the same reason the phrase marker's is. */\nexport const CONTENT_BLOCK_MARKER_ATTR_LEGACY = 'data-langsys-contentblock';\n\nexport const CONTENT_BLOCK_MARKER_ATTRS = [\n CONTENT_BLOCK_MARKER_ATTR,\n CONTENT_BLOCK_MARKER_ATTR_LEGACY,\n] as const;\n\n/**\n * A producer's statement that text inside this element is ALREADY RESOLVED: rendered by\n * a server SDK in the visitor's language, not authored as source. A reader records no\n * miss for it — neither a registration nor a discovery hint — because the catalog is\n * keyed by source text and this is a translation.\n *\n * Distinct from the identity markers on purpose, and agreed that way with the PHP and\n * Laravel lanes. A MARK stamp answers \"which block is this\", and a stamped block inside a\n * resolved scope keeps its id and still translates on a later render; this attribute says\n * only \"never treated as source\". It is also not `translate=\"no\"`, which tells a browser\n * not to machine-translate and would block a legitimate later render.\n *\n * The value is the locale it was resolved into, canonical lowercase, and is informational:\n * presence decides. A bare attribute means the same, because a binding writing it into a\n * layout often does not know the locale at that point. `=\"false\"` and `=\"0\"` opt a subtree\n * back out, the convention `isPhraseMarked` already uses in both SDKs; `=\"no\"` and\n * `=\"off\"` are NOT opt-outs under that shared rule.\n */\nexport const RESOLVED_MARKER_ATTR = 'data-ls-resolved';\n\n/** PHP's spelling, accepted on read for the same reason the other markers' is (MARK-2). */\nexport const RESOLVED_MARKER_ATTR_LEGACY = 'data-langsys-resolved';\n\nexport const RESOLVED_MARKER_ATTRS = [RESOLVED_MARKER_ATTR, RESOLVED_MARKER_ATTR_LEGACY] as const;\n\n/**\n * Canonical form of one token's text, applied identically to a TEXT NODE and to\n * an ATTRIBUTE VALUE.\n *\n * It used to differ: text nodes collapsed internal whitespace while attributes\n * were only trimmed. So the same authored sentence produced two different ids\n * depending on where it sat —\n *\n * <p>A long\\n description</p> -> \"A long description\"\n * <img alt=\"A long\\n description\"> -> \"A long\\n description\"\n *\n * — which also put this SDK and `langsys-php` on different ids for the same\n * markup. One function now, used by both, so \"the same content yields the same\n * id\" is true by construction rather than by two call sites agreeing.\n *\n * `\\s` in JavaScript already covers U+00A0, so a non-breaking space collapses\n * like any other whitespace without special handling. The C0 controls are\n * removed first (`stripC0Controls`), so VT and FF never reach the collapse.\n */\nexport function normalizeTokenText(value: string): string {\n return stripC0Controls(value).replace(/\\s+/g, ' ').trim();\n}\n\n/**\n * Remove the 28 C0 control characters TOK-2 deletes before anything collapses:\n * U+0001–U+0008, U+000B, U+000C and U+000E–U+001F. Applied to every string that becomes an\n * id input or a catalog key — text nodes, translatable attributes, `t()` keys — on register\n * and on lookup alike, and first: strip, then collapse, then trim.\n *\n * Removed rather than mapped to a space, because that is the only treatment every parser can\n * agree with: libxml2 before 2.14 deletes these from DOM text before any SDK code runs, while\n * libxml2 2.14+, parse5 and happy-dom keep them. So VT and FF, which are also in the collapse\n * set, are deleted here before the collapse can see them: `a` VT `b` is `ab`, not `a b`.\n *\n * TAB, LF and CR are not in the set; they reach the collapse and become one space. NUL, U+007F\n * and the C1 range, U+0085 included, are kept.\n */\nexport function stripC0Controls(value: string): string {\n return value.replace(/[\\u0001-\\u0008\\u000B\\u000C\\u000E-\\u001F]/g, '');\n}\n\n/**\n * Normalize `%name%` markup placeholders to canonical `{name}`.\n *\n * Framework compilers consume bare `{name}` written in markup before the DOM\n * walker ever sees it (Svelte compiles it to an expression; JSX evaluates it),\n * so DOM content accepts `%name%` as a collision-free authoring escape.\n * Normalization runs at every markup capture boundary (content-block\n * tokenizer, `Translate` original-value snapshots, `Phrase` encoding), so the\n * catalog, the wire, and translators only ever see the canonical `{name}`\n * form — and plain `{name}` keeps working for vanilla-HTML authors.\n *\n * Keys must be identifiers (`[A-Za-z_][A-Za-z0-9_]*`), so literal `%` in\n * prose (\"20% off\", \"50% to 60%\") can't match. `t()` phrases are JS strings\n * with no compiler collision and stay `{name}`-only.\n *\n * It lives HERE, beside `normalizeTokenText`, because it decides a stored key:\n * every capture boundary runs it, so the same authored content must pass through\n * the same rewrite in every SDK or the key splits. It was in `interpolate.ts`,\n * which is where the RENDER-time counterpart belongs, and where its docstring\n * had drifted onto `adoptPercentPlaceholders` — two functions with one doc\n * between them. `interpolate.ts` re-exports it, so no importer moves.\n */\nexport function normalizeMarkupPlaceholders(text: string): string {\n return text.replace(/%([A-Za-z_][A-Za-z0-9_]*)%/g, '{$1}');\n}\n\n/**\n * Compute the deterministic content-block id from a `(category, tokens)` pair.\n *\n * JSON-stringifies the tuple so each token is unambiguously delimited\n * (the previous `tokens.join('-')` was collision-prone for tokens\n * containing a hyphen, e.g. `'e-mail'`).\n *\n * Pure function — same inputs always produce the same id. Exported so\n * framework wrappers can compute the id themselves before deciding\n * whether to call `registerContentBlock`.\n */\nexport function generateCustomId(category: string, tokens: string[]): string {\n // Coalesce at runtime, not just in the type. This is public API, so an\n // untyped or plain-JS caller can pass `undefined` — which serializes to\n // `[null, …]` and yields an id no wire path ever stores. Every shipping\n // caller already coalesces; this enforces \"no-category is '', never null\"\n // at the reference implementation rather than merely documenting it.\n //\n // `generateLegacyCustomId` deliberately does NOT do this: it must reproduce\n // what was actually stored, including ids an untyped caller produced.\n return md5(canonicalContentBlockJson(category, tokens));\n}\n\n/**\n * The exact string whose UTF-8 bytes are hashed to produce a `custom_id`.\n *\n * Extracted so the cross-implementation assertion can compare the SAME bytes\n * the id function hashes, rather than a second expression that happens to look\n * the same. The PHP lane found four separate sites re-deriving their\n * serialization, one of them inside the test that was supposed to be checking\n * it — a parallel reimplementation agrees with itself, and would keep agreeing\n * after this function changed.\n *\n * Deliberately NOT re-exported from `src/index.ts`: this is the reference\n * implementation's internals, not public API. `generateCustomId` is the\n * contract.\n */\n/**\n * CID-2's input prohibition, applied where the value enters the hash.\n *\n * No-category is `''` — never `null`, never `undefined`, and never the\n * `'__uncategorized__'` sentinel. That sentinel is a CACHE-LOOKUP namespace: it\n * names the bucket an uncategorised phrase lives in inside `sTranslations`, and\n * it is a natural thing for a caller to have in hand. Hashing it produces an id\n * no wire path stores.\n *\n * Found by comparing ids against `langsys-php` over a shared fixture: tokens\n * byte-identical, ids different, because PHP normalised the sentinel and this\n * SDK did not. PHP was conformant and this side was not. No internal caller ever\n * passed it — `Translate` destructures `const { category = '' }` — so no stored\n * id changes; the hole was in the public export, and `/pure` had just widened\n * the audience for it.\n */\nfunction hashableCategory(category: string): string {\n return !category || category === '__uncategorized__' ? '' : category;\n}\n\nexport function canonicalContentBlockJson(category: string, tokens: string[]): string {\n return JSON.stringify([hashableCategory(category), tokens]);\n}\n\n/**\n * The id this block would have had before the 0.6.0 MD5 fix.\n *\n * **Lookup only — never register under this.** Blocks registered by an older\n * SDK are keyed by it, so `Translate` falls back to it when the corrected id\n * misses, which keeps existing translations resolving instead of orphaning\n * them. Registering under it would keep minting ids from a hash that both\n * diverges across SDKs and can collide.\n *\n * Note the collision is a property of the FINAL hashed string, not the phrase:\n * `JSON.stringify` shifts every character's offset, so the same phrase pair can\n * collide standalone and not collide here — and changing `category` moves every\n * character into different lanes. Always reason at this level, not at `md5()`.\n *\n * @deprecated Migration aid; will be removed once catalogs have been rebased.\n */\nexport function generateLegacyCustomId(category: string, tokens: string[]): string {\n return md5Legacy(JSON.stringify([category, tokens]));\n}\n\n/**\n * One node of a rich-phrase tree, in the host-neutral shape `encodeRichPhrase`\n * walks.\n *\n * `{ text }` carries a text node's value VERBATIM — uncollapsed, untrimmed,\n * because collapse runs once over the assembled string and not per node (see\n * `encodeRichPhrase`). An element contributes its `children` plus an opaque\n * `payload` handed straight back in `slots`, so a host keeps its own node handle\n * without this module knowing what one is.\n *\n * Anything that is NEITHER text nor element — a comment, a CDATA section, a\n * processing instruction — must contribute NO text and NO slot. The DOM adapter\n * drops them outright.\n *\n * Measured, because the obvious wording here was wrong: mapping one to\n * `{ text: '' }` is HARMLESS (`'a' + '' + 'b'` is still `'ab'`), so an adapter may\n * do that freely. What splits the key is mapping it to its own DATA\n * (`a<!-- note -->b` becoming `'a note b'`) or giving it a slot (`'a{m0o}{m0c}b'`,\n * which also shifts every later slot index). Those two are the mistakes worth\n * naming; \"must be omitted\" overstates the rule.\n */\nexport type RichTextNode<T> =\n | { readonly text: string }\n /** A marked value (VAR-3): its placeholder, `{NAME}`, never its text. */\n | { readonly param: string }\n | { readonly children: readonly RichTextNode<T>[]; readonly payload: T };\n\nexport interface EncodedRichPhrase<T> {\n /** The phrase string: the lookup key, and therefore the identity. */\n phrase: string;\n /** Each element's `payload`, in the order its markup token was assigned. */\n slots: T[];\n}\n\n/**\n * The `<Phrase>` identity rule, with no DOM in it.\n *\n * `<Phrase>` keys by a STRING, not by a token array and not by a `custom_id`:\n * inline elements become neutral `{mNo}`/`{mNc}` markup-token pairs and the\n * whole thing collapses to one sentence, which is then the catalog key. So this\n * string is as load-bearing as `generateCustomId`'s output, and a second\n * implementation of it re-keys every rich phrase the moment the two drift —\n * silently, as a cache miss and a re-registration rather than an error.\n *\n * That is why it is here and generic over the host's node type: `langsys-js-server`\n * renders `<Phrase>` from parse5 nodes and was otherwise going to write its own\n * encoder. The DOM adapter is `encodeRichText` in `richtext.ts`, which is now\n * nothing but a node-shape mapping over this function.\n *\n * Three details are identity and every adapter has to match them:\n *\n * 1. **Slot indices are assigned in pre-order**, parent before its children,\n * which is why `slots` comes back from here rather than being built by the\n * caller's walk. An adapter that numbered its own slots would have to\n * independently reproduce this order, and a nested phrase is where it would\n * not.\n * 2. **Whitespace collapses ONCE, over the assembled string**, markup tokens\n * included — never per text node. `<p>a <em> b</em></p>` keeps the space\n * before `b` inside the markers; a per-node trim moves it outside them and\n * changes the key. This is the same mistake the attribute path made against\n * the text path, which is what split `custom_id` between this SDK and PHP.\n * 3. **`%name%` normalizes after the collapse**, not before. The two orders\n * happen to agree today (an identifier cannot contain whitespace, so no\n * collapse creates or destroys a match) — stated because \"it doesn't matter\"\n * is not something a second implementation can verify, while \"this order\" is.\n *\n * The whitespace collapse is `normalizeTokenText`, deliberately SHARED with the\n * token path so the disputed set (U+FEFF, U+0085, U+180E — see CONFORMANCE) has\n * one definition to change when the spec rules. That sharing is about the\n * whitespace set only: COALESCING adjacent text nodes stays opposite between the\n * two paths, on purpose, and `content-block.ts` says so from its side.\n */\nexport function encodeRichPhrase<T>(nodes: readonly RichTextNode<T>[]): EncodedRichPhrase<T> {\n const slots: T[] = [];\n const assembled = _encodeRichNodes(nodes, slots);\n return { phrase: normalizeMarkupPlaceholders(normalizeTokenText(assembled)), slots };\n}\n\nfunction _encodeRichNodes<T>(nodes: readonly RichTextNode<T>[], slots: T[]): string {\n let out = '';\n for (const node of nodes) {\n if ('text' in node) {\n out += node.text;\n continue;\n }\n if ('param' in node) {\n out += `{${node.param}}`;\n continue;\n }\n // Index taken and payload pushed BEFORE recursing: pre-order.\n const index = slots.length;\n slots.push(node.payload);\n out += `{m${index}o}` + _encodeRichNodes(node.children, slots) + `{m${index}c}`;\n }\n return out;\n}\n\nconst UNCATEGORIZED_SLOT = '__uncategorized__';\n\nfunction sameTokenList(a: readonly string[], b: readonly string[]): boolean {\n return a.length === b.length && a.every((token, i) => token === b[i]);\n}\n\n/**\n * CID-3: every historical id a block with this content could be stored under.\n * LOOKUP ONLY. Never register or emit any of these.\n *\n * The authoritative list is the fleet's shared legacy fixture (vendored as\n * `tests/fixtures/legacy-custom-id-reference.json`, blob dc555646), and every row\n * of it must resolve. That takes three families of shape:\n *\n * 1. the corrected hash over the PRE-FIX token list, which the published JS SDK\n * registered from 0.6.0 to 0.6.2, before the duplicated `<option>` fix;\n * 2. the JS code-unit hash (`generateLegacyCustomId`, which does not coalesce its\n * category), which published JS SDKs registered before 0.6.0;\n * 3. the PHP pipe-join form, `md5` over `[slot, ...phrases].join('|')`.\n *\n * An uncategorised block could have been written under several spellings of its\n * category. Python lists the code-unit hash under `''` and `'__uncategorized__'`;\n * PHP lists it under `''` and a genuine `null` from an untyped JS caller. The\n * fixture has a row for each, and the spec test is that every row resolves, so this\n * takes the UNION rather than either SDK's subset. The pipe-join form covers `''`\n * and `'__uncategorized__'`, which is all PHP ever wrote. Every extra candidate is\n * safe because none is attached without the CID-4 content check.\n *\n * Most likely first, de-duplicated, and never including the current id.\n */\nexport function historicalCustomIds(\n category: string | null | undefined,\n tokens: readonly string[],\n legacyTokens: readonly string[] = tokens\n): string[] {\n const uncategorised =\n category === null || category === undefined || category === '' || category === UNCATEGORIZED_SLOT;\n const named = uncategorised ? '' : (category as string);\n const codeUnitSlots: Array<string | null> = uncategorised ? ['', UNCATEGORIZED_SLOT, null] : [named];\n const pipeSlots: string[] = uncategorised ? ['', UNCATEGORIZED_SLOT] : [named];\n const differ = !sameTokenList(tokens, legacyTokens);\n const lists: ReadonlyArray<readonly string[]> = differ ? [legacyTokens, tokens] : [tokens];\n\n const ids: string[] = [];\n if (differ) ids.push(generateCustomId(named, [...legacyTokens]));\n for (const list of lists) {\n for (const slot of codeUnitSlots) {\n ids.push(generateLegacyCustomId(slot as string, [...list]));\n }\n }\n for (const list of lists) {\n for (const slot of pipeSlots) {\n ids.push(md5([slot, ...list].join('|')));\n }\n }\n const current = generateCustomId(named, [...tokens]);\n return [...new Set(ids)].filter((id) => id !== current);\n}\n\n/**\n * CID-4: whether a block found under a historical id holds THIS block's content.\n *\n * None of the historical id spaces is injective. The UTF-16 packing loses a byte at\n * every fourth position, and joining on an unescaped delimiter loses the field\n * boundary, so an id alone does not identify a block, and attaching on the id being\n * present can file one block's translations under another.\n *\n * Compared as normalised for hashing, not as stored: a phrase stored by an older SDK\n * may carry whitespace or a `%name%` spelling that today's tokenizer canonicalises,\n * and a raw comparison would decline those correct matches. Compared as SETS, which\n * the rule allows where the representation has lost order, and the catalog returns a\n * block as a map keyed by source phrase. A set still defeats every collision mode,\n * since each is a collision over DIFFERING content. Matches langsys-python.\n */\nexport function blockContentMatches(storedPhrases: Iterable<string>, tokens: readonly string[]): boolean {\n const canonical = (phrase: string) => normalizeMarkupPlaceholders(normalizeTokenText(phrase));\n const stored = new Set(Array.from(storedPhrases, canonical));\n const current = new Set(tokens.map(canonical));\n if (stored.size !== current.size) return false;\n for (const phrase of stored) if (!current.has(phrase)) return false;\n return true;\n}\n\n","/**\n * Lightweight debug logger. Styled in browsers (via %c), plain text in Node.\n * Replaces the pre-existing `echo` module from the Svelte SDK with a simpler,\n * SSR-safe equivalent.\n */\n\nconst STYLES = {\n log: 'display:inline-block;background:rgb(239,239,244);color:black;font-weight:bold;padding:3px 7px;border-radius:3px',\n warn: 'display:inline-block;background:gold;color:black;font-weight:bold;padding:3px 7px;border-radius:3px',\n error: 'display:inline-block;background:#e0005a;color:#fff;font-weight:bold;padding:3px 7px;border-radius:3px',\n};\n\n/**\n * React Native defines `window`, so a bare `typeof window` check treats it as a\n * browser — and its console does not render `%c`, so every line comes out as a\n * literal \"%cLangsys Debug\" followed by an unrendered CSS string. Nothing\n * breaks, so nothing reports it; it just looks broken forever.\n * `navigator.product === 'ReactNative'` is the standard discriminator.\n *\n * Evaluated per call rather than once at module load: this module is commonly\n * imported before a host finishes installing its globals, and a value latched\n * at import time cannot be corrected afterwards — nor observed by a test,\n * which is how the browser branch would go unverified.\n */\nfunction supportsStyle(): boolean {\n // Guarded because the probe itself can throw. A host that wraps `globalThis`\n // in a Proxy to assert DOM-freeness — which is how the `/pure` subpath is\n // tested, and how some sandboxes are built — makes `typeof window` raise\n // rather than return 'undefined'. A logger that throws because it looked for\n // a browser is worse than a logger that prints plainly.\n try {\n if (typeof window === 'undefined') return false;\n return !(typeof navigator !== 'undefined' && navigator.product === 'ReactNative');\n } catch {\n return false;\n }\n}\n\nfunction emit(level: 'log' | 'warn' | 'error', label: string, args: unknown[]) {\n // Browsers render %c style. Node just gets the plain string.\n if (supportsStyle()) {\n // eslint-disable-next-line no-console\n console[level](`%c${label}`, STYLES[level], ...args);\n } else {\n // eslint-disable-next-line no-console\n console[level](`[${label}]`, ...args);\n }\n}\n\nexport class Logger {\n debugEnabled: boolean;\n\n constructor(debugEnabled = false) {\n this.debugEnabled = debugEnabled;\n }\n\n log(...args: unknown[]) {\n if (!this.debugEnabled) return;\n emit('log', 'Langsys Debug', args);\n }\n\n warn(...args: unknown[]) {\n emit('warn', 'Langsys Warning', args);\n }\n\n error(...args: unknown[]) {\n emit('error', 'Langsys Error', args);\n }\n}\n\nexport const logger = new Logger(false);\n","import { logger } from './logger.js';\n/**\n * Locale-identifier handling, CLDR/BCP 47 flavored. Everything here rides on\n * the platform's native `Intl` — no bundled locale data.\n *\n * The SDK's convention: normalise once at every input boundary (init config,\n * user-locale store emissions, detectPreferredLocale, API routes) and treat the\n * normalised string as the identity everywhere downstream — cache keys,\n * equality checks, and the wire format all use it.\n *\n * That form is LOWERCASE `xx-yy` (`en-us`, `zh-hant-tw`). It is what every\n * locale in the backend's database already is — script subtags included, stored\n * `az-cyrl` / `bs-latn` — and what the API's request middleware produces. It is\n * therefore the only form guaranteed to behave identically on a route that does\n * NOT mount that middleware, and the routes most likely to miss it are the\n * legacy ones carrying the oldest clients: exactly the clients least likely to\n * send a canonical form. Sending lowercase costs nothing; relying on a\n * normalisation we cannot see, cannot version, and will not be told about when\n * a route stops mounting it does.\n *\n * This does not weaken CLDR handling. `Intl` canonicalises its own input, so\n * `new Intl.Locale('zh-tw').maximize()` still yields `zh-Hant-TW` whether the\n * input was cased or not — likely-subtags matching is unaffected by the form we\n * hold. Validity is a separate axis from casing, which is why the invalid-tag\n * warning below is retained unchanged.\n */\n\n/** A locale's language, script and region subtags, ahead of its variants and extensions. */\nconst LANGUAGE_SCRIPT_REGION = /^(?:[a-z]{2,3}|[a-z]{5,8})(?:-[a-z]{4})?(?:-(?:[a-z]{2}|\\d{3}))?(?=-|$)/i;\n\n/**\n * Normalise a locale identifier to the SDK's single internal form: lowercase\n * `xx-yy` — `en-US` → `en-us`, `zh-Hant-TW` → `zh-hant-tw`. Underscores are\n * accepted and converted (`en_US` → `en-us`). Legacy aliases in the language,\n * script and region are resolved through `Intl.getCanonicalLocales` (`iw` → `he`,\n * `in-ID` → `id-id`, `sh-BA` → `sr-latn-ba`) BEFORE casing is flattened —\n * lowercasing first would lose them, since the alias table is keyed on canonical\n * tags.\n *\n * Variants and extensions are kept as written, lowercased: `en-US-POSIX` is\n * `en-us-posix`. The API's locale codes are ICU locale ids (`en_US_POSIX`), and\n * BCP 47 canonicalisation rewrites some of their variants into a code the API\n * does not hold (`POSIX` becomes the extension `-u-va-posix`).\n *\n * Structurally invalid tags fall back to lowercasing rather than throwing, so a\n * bad config value degrades to a failed catalog lookup instead of a crash — and\n * warns, because that failure is otherwise indistinguishable from a legitimately\n * untranslated locale.\n */\nexport function canonicalizeLocale(locale: string): string {\n if (!locale || typeof locale !== 'string') return locale;\n const cleaned = locale.trim().replace(/_/g, '-');\n try {\n // The whole tag is validated, then only its language, script and region are\n // canonicalised. A valid tag always starts with a language subtag.\n Intl.getCanonicalLocales(cleaned);\n const [head] = LANGUAGE_SCRIPT_REGION.exec(cleaned)!;\n return (Intl.getCanonicalLocales(head)[0] + cleaned.slice(head.length)).toLowerCase();\n } catch {\n // Not a valid BCP 47 tag. The return value cannot signal this — a\n // best-effort cased string is indistinguishable from a successfully\n // canonicalized one, so a typo'd config locale degrades to a silent\n // failed catalog lookup: the app renders base language, which is\n // exactly what a legitimately-untranslated locale looks like. Say so\n // when debug is on, since nothing downstream can.\n if (logger.debugEnabled) logger.warn(\n `\"${locale}\" is not a valid BCP 47 locale tag. Falling back to lowercasing it as-is,` +\n ` which will very likely miss the catalog and render base language with no other symptom.`,\n );\n // Lowercase anyway so the identity stays consistent — an invalid tag\n // must still compare equal to itself across boundaries.\n return cleaned.toLowerCase();\n }\n}\n\n/**\n * The `language-script` key of a locale after CLDR likely-subtags expansion\n * (`Intl.Locale.maximize()`): `zh` → `zh-Hans`, `zh-TW` → `zh-Hant`,\n * `sr` → `sr-Cyrl`. Two locales with the same key are mutually intelligible\n * at the script level; two with different keys must not fall back to each\n * other (a `zh-Hant` reader must never receive a `zh-Hans` catalog).\n *\n * Returns `null` when the tag can't be parsed — callers should treat that\n * as \"no match\" rather than guessing.\n */\nexport function maximizedLangScript(locale: string): string | null {\n try {\n const max = new Intl.Locale(canonicalizeLocale(locale)).maximize();\n // Intl canonicalises its own input, so the lowercase form we hold\n // maximises identically to a cased one. Lowercased for the same reason\n // everything else is: one internal form, compared only against itself.\n return `${max.language}-${max.script ?? ''}`.toLowerCase();\n } catch {\n return null;\n }\n}\n","import { IntlMessageFormat } from 'intl-messageformat';\nimport { normalizeMarkupPlaceholders } from './identity.js';\nimport { logger } from './logger.js';\n\n/**\n * Re-exported, not defined here: the CAPTURE-time rewrite is an identity rule\n * and lives in `identity.ts` with the other one. Kept on this module's surface\n * because eight call sites and both entry points import it from here.\n */\nexport { normalizeMarkupPlaceholders };\n\n/**\n * Detects ICU MessageFormat syntax in a translation string.\n *\n * - Matches `{var, plural, …}`, `{var, select, …}`, `{var, selectordinal, …}`,\n * `{var, number, …}`, `{var, date, …}`, `{var, time, …}`.\n * - Also matches the style-less forms `{var, number}`, `{var, date}`,\n * `{var, time}` — valid ICU with the locale-default style.\n * - Doesn't match plain interpolation slots like `{name}` or `{count}`.\n *\n * Exported because the Translation Manager UI needs the same detection logic\n * to decide whether to render a plural-slot editor vs. a single text field.\n */\nexport function isICU(template: string): boolean {\n return ICU_PATTERN.test(template);\n}\n\n// `[,}]` after the keyword: a style argument may follow (`{n, number, ::…}`)\n// or the argument may close immediately (`{n, number}` — locale-default style).\nconst ICU_PATTERN = /\\{[^{}]+,\\s*(plural|select|selectordinal|number|date|time)\\s*[,}]/;\n\n/**\n * Accept `%name%` at RENDER time, not only at capture time.\n *\n * `normalizeMarkupPlaceholders` has always converted `%name%` to `{name}` where\n * content is captured, because Svelte and JSX consume a bare `{name}` in markup\n * and `%name%` is what an author can actually type there. But nothing applied it\n * on the way out, so a translation stored with `%name%` rendered the percent\n * signs to the reader verbatim: `interpolate('Hi %name%', { name: 'Ada' })`\n * returned `'Hi %name%'`.\n *\n * Conversion is CONDITIONAL on the key being supplied, which matters: a blanket\n * rewrite would treat any `%word%` as a placeholder, so `'Save 20% %off%'` or\n * prose containing `%s` patterns could be mangled into a `{…}` that then renders\n * as a literal brace expression. Requiring a matching param means a string is\n * only reinterpreted when the caller demonstrably meant it as a placeholder.\n */\nfunction adoptPercentPlaceholders(template: string, params: Record<string, unknown>): string {\n if (!template.includes('%') || !params) return template;\n return template.replace(/%([A-Za-z_][A-Za-z0-9_]*)%/g, (whole, name: string) =>\n Object.prototype.hasOwnProperty.call(params, name) ? `{${name}}` : whole\n );\n}\n\n\n/** Keys `%name%` can carry — the same shape `adoptPercentPlaceholders` matches. */\nconst IDENTIFIER_KEY = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/** `name_gender` → `name`: the gender companion of a placeholder (see `findUnusedParamKeys`). */\nconst GENDER_COMPANION = /^(.+)_gender$/;\n\n/** Escape a params key for literal use inside a RegExp. */\nfunction escapeForRegExp(key: string): string {\n return key.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Params keys that have NO matching placeholder in `texts`.\n *\n * A key counts as used when it appears as `{key}`, as the argument of an ICU\n * slot (`{key, plural, …}`), or as `%key%`. Surrounding whitespace is tolerated\n * in the brace forms.\n *\n * BOTH SPELLINGS, because `interpolate` resolves both. It used to accept the\n * brace forms only, on the stated assumption that texts arrive canonical\n * (post-`normalizeMarkupPlaceholders`). That held for the two internal callers\n * and still does — `<Translate>` normalizes its tokens at capture and\n * `<Phrase>`'s string comes out of `encodeRichText` already rewritten — but it\n * stopped being true of the function itself once `interpolate` began adopting\n * `%name%` at render time. A caller passing a raw stored translation then got\n * `name` reported unused for a param that renders perfectly, and\n * `warnUnmatchedParams` told them to \"write %name% instead\" — which is what they\n * had written. This predicate and `adoptPercentPlaceholders` have to agree about\n * what a placeholder is; they are two halves of one rule.\n *\n * The percent spelling is accepted only for keys that are IDENTIFIERS, matching\n * `adoptPercentPlaceholders` exactly. A key like `a.b` never resolves from\n * `%a.b%` — accepting it here would suppress a warning that is correct.\n *\n * A `<name>_gender` key counts as used wherever `name` is a placeholder. Langsys\n * promotes a plain `{name}` to `{name_gender, select, …}` in gendered target\n * locales, so an app passes the gender beside the value (`GenderParamsFor` types\n * it), and the source text a caller checks never names it. Only a placeholder's\n * companion: `team_gender` with no `{team}` in the text is still reported.\n */\nexport function findUnusedParamKeys(texts: string[], params: Record<string, unknown> | undefined): string[] {\n if (!params) return [];\n const keys = Object.keys(params);\n if (!keys.length || !texts.length) return keys;\n\n // The separator is a literal NUL, written as an ESCAPE and never as the byte\n // itself. A raw 0x00 in a source file makes git classify it as binary: no\n // diff, no blame, no 3-way merge, and every change to this file becomes\n // invisible to review while still shipping. It hid here once already.\n const haystack = texts.join('\\0');\n const isPlaceholder = (key: string): boolean => {\n const escaped = escapeForRegExp(key);\n const percent = IDENTIFIER_KEY.test(key) ? `|%${escaped}%` : '';\n return new RegExp(`\\\\{\\\\s*${escaped}\\\\s*[,}]${percent}`).test(haystack);\n };\n return keys.filter((key) => {\n if (isPlaceholder(key)) return false;\n const genderOf = GENDER_COMPANION.exec(key)?.[1];\n return !(genderOf && isPlaceholder(genderOf));\n });\n}\n\n/**\n * Debug-time warning for the single most common markup-interpolation mistake:\n * writing `{name}` instead of `%name%` inside `<Translate>`/`<Phrase>` content.\n *\n * We can't see the mistake directly — Svelte and JSX substitute `{name}` at\n * compile time, so the SDK only ever receives the already-substituted text.\n * But the fingerprint is unmistakable: params were supplied and NONE of their\n * keys survive as placeholders in the captured content. Left undetected this\n * fails silently (the base locale still looks right), so it's worth naming\n * explicitly.\n *\n * Only emits when debug logging is on — silent in production.\n */\nexport function warnUnmatchedParams(\n source: string,\n texts: string[],\n params: Record<string, unknown> | undefined,\n context?: string,\n): void {\n if (!logger.debugEnabled) return;\n\n const unused = findUnusedParamKeys(texts, params);\n if (!unused.length) return;\n\n const keyList = unused.map((key) => `%${key}%`).join(', ');\n // Framework-neutral wording: the brace spelling that gets eaten differs by\n // framework (Svelte/JSX consume `{key}`, Vue consumes `{{ key }}`), and the\n // SDK has no idea which one it's running under.\n logger.warn(\n `${source} received params with no matching placeholder in its content: ${keyList}.` +\n ` If you wrote {${unused[0]}} or {{ ${unused[0]} }} in markup, your framework's template` +\n ` compiler substituted it before Langsys saw the text — write %${unused[0]}% instead.` +\n (context ? ` [${context}]` : ''),\n );\n}\n\n/**\n * Substitute placeholders in a translated string with values from `params`.\n *\n * Two paths:\n * - ICU MessageFormat (target string contains `{var, plural|select|…, …}`):\n * parsed and formatted via `intl-messageformat`, which knows every\n * target locale's plural rules (Arabic's 6 categories, Russian's 4,\n * etc.) and gender-select branches.\n * - Simple `{name}` interpolation: cheap regex replacement. Unknown\n * placeholders are left untouched so missing data is visible to the\n * developer rather than silently rendering empty strings. Number and\n * Date values are formatted per the target locale's CLDR rules\n * (`Intl.NumberFormat` / `Intl.DateTimeFormat`) — pass numbers as\n * strings to opt out (e.g. IDs and codes that must not get grouping\n * separators).\n *\n * Malformed ICU falls through to simple interpolation rather than throwing,\n * so the developer sees a broken-but-visible string instead of a runtime crash.\n * Backend-side validation in langsys-ai is supposed to prevent this — the\n * fall-through is defense in depth.\n *\n * `locale` is required for ICU formatting (drives plural-rule selection).\n * Falls back to `'en'` if absent — simple-interpolation path ignores it.\n *\n * `params` may be omitted, and behaves as an empty map: a select or plural renders\n * its `other` branch (ICU-1). Omitting it used to throw a TypeError inside recovery.\n *\n * `options` routes the two notices to the caller instead of this module's logger,\n * for a host with a logger of its own — a server with a per-instance debug\n * setting, where this module's process-wide logger is the wrong switch. See\n * `InterpolateOptions`.\n */\nexport function interpolate(\n template: string,\n params: Record<string, unknown> = {},\n locale?: string,\n options: InterpolateOptions = {},\n): string {\n template = adoptPercentPlaceholders(template, params);\n\n if (isICU(template)) {\n const resolved = locale || 'en';\n // A null value does NOT throw — `intl-messageformat` coerces it (null\n // becomes 0, so `{count, plural…}` renders \"0 items\"). That would make a\n // bug indistinguishable from valid data: a real empty cart and a failure\n // to pass the count would render identically. So null is routed straight\n // to recovery, where it is treated as missing — matching langsys-php,\n // which tests this explicitly. A genuine 0 is untouched and still\n // renders \"0 items\".\n const hasNullParam = !!params && Object.values(params).some((value) => value === null);\n let formatterError: unknown;\n if (!hasNullParam) {\n try {\n return formatIcu(new IntlMessageFormat(template, resolved), params, resolved);\n } catch (error) {\n formatterError = error;\n }\n }\n // `.ast` is typed private but is the parsed message the library formats\n // from, and `IntlMessageFormat` accepts an AST in place of a string.\n // Reaching for it avoids taking a second runtime dependency on the\n // parser just to re-parse what's already parsed. A phrase that does not\n // parse has no branches to select, so it takes the simple path.\n let ast: unknown;\n try {\n ast = (new IntlMessageFormat(template, resolved) as unknown as { ast?: unknown }).ast;\n } catch {\n return simpleInterpolate(template, params, locale);\n }\n if (!Array.isArray(ast)) return simpleInterpolate(template, params, locale);\n\n // A missing argument throws. Recover the sentence rather than dumping\n // ICU source to the page — see `_recoverMissingArgs`.\n const defaulted: string[] = [];\n const recovered = _recoverMissingArgs(JSON.parse(JSON.stringify(ast)) as IcuNode[], params, defaulted);\n if (defaulted.length) {\n if (options.onDefaulted) options.onDefaulted([...new Set(defaulted)], template, resolved);\n else noteDefaultedArgs(template, resolved, defaulted);\n }\n if (defaulted.length || formatterError === undefined) {\n try {\n return formatIcu(new IntlMessageFormat(recovered as never, resolved), params, resolved);\n } catch (error) {\n formatterError = error;\n }\n }\n\n // Nothing was missing, or the recovered message still would not format:\n // the formatter itself failed on this phrase (ICU-6). Render it without\n // the formatter, and say so at every log level.\n if (options.onFormatterFailure) options.onFormatterFailure(formatterError, template, resolved);\n else noteFormatterFailure(template, resolved, formatterError);\n return renderWithoutFormatter(ast as IcuNode[], params, resolved);\n }\n return simpleInterpolate(template, params, locale);\n}\n\n/**\n * The argument names `interpolate` would default for these params (ICU-4): each\n * `select`, `plural` or plain argument the template uses and `params` does not\n * supply (`null` counts as not supplied), once each, in the order the recovery\n * meets them. Empty for a plain template or one that does not parse.\n *\n * The same walk `interpolate` recovers with, so a host that emits the notice\n * through its own logger names exactly the arguments the render defaulted.\n */\nexport function defaultedArguments(template: string, params: Record<string, unknown> = {}, locale = 'en'): string[] {\n template = adoptPercentPlaceholders(template, params);\n if (!isICU(template)) return [];\n let ast: unknown;\n try {\n ast = (new IntlMessageFormat(template, locale) as unknown as { ast?: unknown }).ast;\n } catch {\n return [];\n }\n if (!Array.isArray(ast)) return [];\n const defaulted: string[] = [];\n _recoverMissingArgs(JSON.parse(JSON.stringify(ast)) as IcuNode[], params, defaulted);\n return [...new Set(defaulted)];\n}\n\n/**\n * Where `interpolate` reports what it recovered from. Each handler, when given,\n * replaces this module's logger for that notice and is called on EVERY\n * occurrence: gating and deduplication are then the caller's, so a host applies\n * its own debug switch and its own `(template, locale)` dedupe. What the core\n * logger does, and what a handler should reproduce:\n *\n * - `onDefaulted` (ICU-4): a missing argument was recovered with its neutral\n * branch. Debug level only; names every defaulted argument, once each, and the\n * locale.\n * - `onFormatterFailure` (ICU-6): the formatter failed and the SDK's own branch\n * selection rendered the phrase. At every log level, naming the phrase, the\n * locale and the error.\n */\nexport interface InterpolateOptions {\n onDefaulted?: (names: string[], template: string, locale: string) => void;\n onFormatterFailure?: (error: unknown, template: string, locale: string) => void;\n}\n\n/** ICU AST node types we care about (from `@formatjs/icu-messageformat-parser`). */\nconst ICU_LITERAL = 0;\nconst ICU_ARGUMENT = 1;\nconst ICU_NUMBER = 2;\nconst ICU_DATE = 3;\nconst ICU_TIME = 4;\nconst ICU_SELECT = 5;\nconst ICU_PLURAL = 6;\nconst ICU_POUND = 7;\nconst ICU_TAG = 8;\n\ninterface IcuNode {\n type: number;\n value?: string;\n options?: Record<string, { value: IcuNode[] }>;\n children?: IcuNode[];\n offset?: number;\n pluralType?: 'cardinal' | 'ordinal';\n}\n\n/**\n * Rewrite an ICU AST so a MISSING argument degrades gracefully instead of\n * taking the whole message down.\n *\n * Why this is reachable without any caller mistake: langsys-ai's ICU promoter\n * can *introduce* a select argument the source phrase never had — a plain\n * `{name}` becomes `{name_gender, select, …}` in gendered target locales. An\n * application may pass `name_gender` beside `name`, and most never do: the\n * argument appears nowhere in the phrase the developer wrote, and few apps know\n * the user's gender. Every app translating into a gendered locale hits this.\n *\n * The recovery, agreed with `langsys-php` so a shared catalog can't render two\n * different sentences for the same input:\n *\n * - **`select`** → take the `other` branch. Recoverable: `other` is exactly\n * what an unknown gender should render, so the sentence comes out correct.\n * - **`plural`** → take the `other` branch, rendering `#` as `{argName}`.\n * Nothing can be inferred for a count, so this is only made less bad: the\n * sentence survives with a visible gap.\n * - **plain arguments** (`{name}`, `{n, number}`, dates) → render as\n * `{argName}`, matching the simple path's rule that unknown keys stay\n * visible rather than blanking.\n *\n * Elements whose argument IS supplied are left untouched and recursed into, so\n * a missing argument nested inside a satisfied branch is still recovered.\n * `plural`/`select` without an `other` branch is malformed ICU — left alone, so\n * it falls through to the simple path as before.\n */\n/**\n * Templates already reported on, keyed by template+locale.\n *\n * Recovery is silent by design in production — that is the whole point — but\n * silence is also what makes the argument undiscoverable: it does not appear in\n * the source phrase, so a developer has no way to learn that `{name}` became\n * `{name_gender, select, …}` in Spanish and that their app could be supplying\n * it. Debug mode is the one place they can be told. Deduped because this runs\n * on every render of every string.\n */\nconst notifiedDefaults = new Set<string>();\n\nfunction noteDefaultedArgs(template: string, locale: string, names: string[]): void {\n if (!logger.debugEnabled) return;\n\n const key = `${locale}\\0${template}`;\n if (notifiedDefaults.has(key)) return;\n notifiedDefaults.add(key);\n\n const unique = [...new Set(names)];\n logger.warn(\n `Interpolation defaulted ${unique.length === 1 ? 'argument' : 'arguments'} ${unique\n .map((n) => `\"${n}\"`)\n .join(', ')} while rendering a '${locale}' string. The translated phrase asks for ` +\n `${unique.length === 1 ? 'it' : 'them'} but the source phrase does not, which is normal — a gendered ` +\n `target locale can introduce an argument the source never had. The neutral branch was used. Pass ` +\n `${unique.length === 1 ? 'the value' : 'the values'} in \\`params\\` if your app knows ${unique.length === 1 ? 'it' : 'them'}.`\n );\n}\n\nfunction _recoverMissingArgs(\n nodes: IcuNode[],\n params: Record<string, unknown>,\n defaulted: string[]\n): IcuNode[] {\n const out: IcuNode[] = [];\n\n for (const node of nodes) {\n const name = node.value;\n // `null` counts as missing, matching the simple path where a present-\n // but-null value is left visible rather than rendered as 0 or \"null\".\n const value = name !== undefined && name in params ? params[name] : undefined;\n const supplied = value !== undefined && value !== null;\n\n if (node.type === ICU_TAG) {\n out.push({ ...node, children: _recoverMissingArgs(node.children ?? [], params, defaulted) });\n continue;\n }\n\n if (node.type === ICU_SELECT || node.type === ICU_PLURAL) {\n if (supplied) {\n const options: Record<string, { value: IcuNode[] }> = {};\n for (const [key, branch] of Object.entries(node.options ?? {})) {\n options[key] = { value: _recoverMissingArgs(branch.value, params, defaulted) };\n }\n out.push({ ...node, options });\n continue;\n }\n const other = node.options?.other;\n if (!other) {\n out.push(node); // malformed — let the simple path handle it\n continue;\n }\n if (name) defaulted.push(name);\n const branch = _recoverMissingArgs(other.value, params, defaulted);\n // `#` has no count to render, so show the argument name instead.\n out.push(\n ...branch.map((child) =>\n child.type === ICU_POUND ? { type: ICU_LITERAL, value: `{${name}}` } : child,\n ),\n );\n continue;\n }\n\n if (\n !supplied &&\n (node.type === ICU_ARGUMENT ||\n node.type === ICU_NUMBER ||\n node.type === ICU_DATE ||\n node.type === ICU_TIME)\n ) {\n if (name) defaulted.push(name);\n out.push({ type: ICU_LITERAL, value: `{${name}}` });\n continue;\n }\n\n out.push(node);\n }\n\n return out;\n}\n\n/** Templates whose formatter failure has been reported, keyed by template+locale. */\nconst notifiedFailures = new Set<string>();\n\n/**\n * A formatter failure warns whether or not debug logging is on, unlike the\n * defaulted-argument notice above: a missing argument is normal, while a phrase\n * the formatter cannot render is a defect somebody has to fix. Deduped per\n * (template, locale) because this runs on every render.\n */\nfunction noteFormatterFailure(template: string, locale: string, error: unknown): void {\n const key = `${locale}\\0${template}`;\n if (notifiedFailures.has(key)) return;\n notifiedFailures.add(key);\n\n const reason = error instanceof Error ? error.message : String(error);\n logger.warn(\n `The message formatter failed on a '${locale}' phrase, so it was rendered by the SDK's own branch ` +\n `selection. Fix the phrase: ${JSON.stringify(template)}. Formatter error: ${reason}`\n );\n}\n\n/**\n * Render a parsed ICU message without the formatter (ICU-6), the way\n * `_recoverMissingArgs` treats a missing argument: each `select` or `plural`\n * takes the branch for its supplied value and the construct itself is dropped,\n * supplied values are filled in, and an unsupplied one stays visible as\n * `{argName}`. Never returns the raw construct.\n *\n * Plural branch order is ICU's: an exact `=N` on the value first, then the\n * value's CLDR category in the render locale (after the offset), then `other`.\n */\nfunction renderWithoutFormatter(nodes: IcuNode[], params: Record<string, unknown>, locale: string, pound?: number | string): string {\n let out = '';\n for (const node of nodes) {\n const name = node.value;\n const value = name !== undefined && params && name in params ? params[name] : undefined;\n const supplied = value !== undefined && value !== null;\n\n switch (node.type) {\n case ICU_LITERAL:\n out += node.value ?? '';\n break;\n case ICU_POUND:\n out += pound === undefined ? '#' : typeof pound === 'string' ? pound : formatScalar(pound, locale);\n break;\n case ICU_TAG:\n out += `<${name}>${renderWithoutFormatter(node.children ?? [], params, locale, pound)}</${name}>`;\n break;\n case ICU_SELECT: {\n const options = node.options ?? {};\n const branch = (supplied ? options[String(value)] : undefined) ?? options.other;\n out += branch ? renderWithoutFormatter(branch.value, params, locale, pound) : `{${name}}`;\n break;\n }\n case ICU_PLURAL: {\n const options = node.options ?? {};\n const count = supplied ? Number(value) : NaN;\n if (Number.isNaN(count)) {\n const other = options.other;\n // `#` has no count to render, so show the argument name instead.\n out += other ? renderWithoutFormatter(other.value, params, locale, `{${name}}`) : `{${name}}`;\n break;\n }\n const adjusted = count - (node.offset ?? 0);\n let branch = options[`=${count}`];\n if (!branch) {\n try {\n branch = options[new Intl.PluralRules(locale, { type: node.pluralType ?? 'cardinal' }).select(adjusted)];\n } catch {\n // no CLDR rules for this locale: `other` below\n }\n }\n branch = branch ?? options.other;\n out += branch ? renderWithoutFormatter(branch.value, params, locale, adjusted) : `{${name}}`;\n break;\n }\n default:\n // Plain, number, date and time arguments.\n out += supplied ? formatScalar(value, locale) : `{${name}}`;\n }\n }\n return out;\n}\n\n/**\n * An ICU message formatted to one string. When a plain argument is neither a string nor a\n * number (a Date, or `true`), the formatter returns its parts instead, or that one value\n * when it is the whole output, and it writes `false` as nothing. So a boolean goes in as\n * `true` or `false`, and any value that is not a string is written as the simple path\n * writes it (`formatScalar`).\n */\nfunction formatIcu(message: IntlMessageFormat, params: Record<string, unknown>, locale: string): string {\n const scalars = Object.fromEntries(Object.entries(params ?? {}).map(([name, value]) => [name, typeof value === 'boolean' ? String(value) : value]));\n const out: unknown = message.format(scalars as never);\n if (typeof out === 'string') return out;\n return Array.isArray(out) ? out.map((part) => (typeof part === 'string' ? part : formatScalar(part, locale))).join('') : formatScalar(out, locale);\n}\n\n/** A supplied value as the simple path renders it: CLDR numbers and medium dates. */\nfunction formatScalar(value: unknown, locale: string): string {\n try {\n if (value instanceof Date) return new Intl.DateTimeFormat(locale, { dateStyle: 'medium' }).format(value);\n if (typeof value === 'number' || typeof value === 'bigint') return new Intl.NumberFormat(locale).format(value);\n } catch {\n // an invalid locale tag: the locale-blind rendering below\n }\n return value instanceof Date ? value.toISOString() : String(value);\n}\n\nfunction simpleInterpolate(template: string, params: Record<string, unknown>, locale?: string): string {\n // The `[^{},]` character class excludes `{`, `}`, and `,` from placeholder\n // names so we don't accidentally consume ICU-shaped slots that somehow\n // routed through this path (e.g. malformed ICU after fall-through).\n return template.replace(/\\{([^{},]+)\\}/g, (match, rawKey: string) => {\n const key = rawKey.trim();\n if (!(key in params)) return match;\n const value = params[key];\n if (value === undefined || value === null) return match;\n // CLDR-formatted output for numbers and dates, mirroring what the ICU\n // defaults (`{n, number}`, `{d, date}` → medium) would produce. The\n // try/catch guards against invalid locale tags — fall back to the\n // locale-blind rendering rather than throwing mid-render.\n if (value instanceof Date) {\n try {\n return new Intl.DateTimeFormat(locale || 'en', { dateStyle: 'medium' }).format(value);\n } catch {\n return value.toISOString();\n }\n }\n if (typeof value === 'number' || typeof value === 'bigint') {\n try {\n return new Intl.NumberFormat(locale || 'en').format(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n });\n}\n","/**\n * Legacy i18n values to Langsys/ICU source text (spec MIG-4).\n *\n * A migrated app keeps its source-language file and its keys; a key's value\n * becomes the registered phrase after this conversion. The conversion decides\n * the phrase, so it is identity: every JS entry point — the browser `t()`\n * mode, a server `t()`, a vue-i18n or i18next bridge — converts through these\n * functions, never a copy of them.\n *\n * Placeholders convert the same way whatever the file's format. Plurals\n * convert by the format the file declares, because frameworks read the same\n * characters differently: vue-i18n reserves `|`, i18next pairs suffixed keys.\n * The conversion preserves the source framework's own selection. Anything a\n * format does not recognise comes back exactly as written, with `recognised`\n * false and the reason in `issue`, so it registers verbatim and is reported\n * rather than silently mangled.\n */\n\n/** The formats a file can declare anywhere in the fleet (MIG-7). */\nexport const LEGACY_FORMATS = ['laravel', 'vue-i18n', 'i18next', 'gettext', 'rails-i18n', 'plain'] as const;\n\n/** The formats this core reads (MIG-7). Any other configured format is refused at load. */\nexport const SUPPORTED_LEGACY_FORMATS = ['i18next', 'vue-i18n', 'plain'] as const;\n\nexport type LegacyFormat = (typeof SUPPORTED_LEGACY_FORMATS)[number];\n\n/** A converted value. `text` is the phrase to register; when `recognised` is false it is the value as written. */\nexport interface LegacyConversion {\n text: string;\n recognised: boolean;\n issue: string | null;\n}\n\n/** CLDR plural categories, in ICU's customary order. */\nexport const PLURAL_CATEGORIES = ['zero', 'one', 'two', 'few', 'many', 'other'] as const;\n\n/**\n * Every placeholder spelling the fleet converts, scanned left to right in one\n * pass so a `%%` is consumed before its second `%` can start another match.\n * The spellings that carry formatting `{name}` cannot express, and positional\n * `%s`, are matched so they can be refused rather than half-converted.\n */\nconst PLACEHOLDER =\n /%%|%\\{([A-Za-z_][A-Za-z0-9_]*)\\}|%\\(([A-Za-z_][A-Za-z0-9_]*)\\)[sd]|%\\([A-Za-z_][A-Za-z0-9_]*\\)[-+ #0-9.]*[a-zA-Z]|%<[A-Za-z_][A-Za-z0-9_]*>[-+ #0-9.]*[a-zA-Z]|%(?:\\.\\d+)?[sdif](?![A-Za-z])|\\{\\{\\s*([A-Za-z_][A-Za-z0-9_]*)\\s*\\}\\}|(?<![\\w:]):([a-z][a-z0-9_]*)/g;\n\n/** Laravel's `:Name` / `:NAME` upper-case the value, which `{name}` cannot express. */\nconst CASE_TRANSFORM = /(?<![\\w:]):[A-Z][A-Za-z0-9_]*/;\n\nclass Unconvertible extends Error {}\n\n/**\n * Convert a value under a format.\n *\n * `plain` converts placeholders and nothing else; a `|` in it is text, so such\n * a value is returned verbatim and reported. `vue-i18n` reads any `|` as a\n * plural selected by count. `i18next` has no in-string plural — its plurals are\n * suffix-paired keys, see `convertLegacyPluralForms` — so a `|` is reported.\n */\nexport function convertLegacyValue(value: string, format: LegacyFormat = 'plain'): LegacyConversion {\n value = String(value);\n\n if (CASE_TRANSFORM.test(value)) {\n return unrecognised(value, 'uses a case-transforming placeholder (:Name or :NAME), which ICU cannot express');\n }\n\n if (!value.includes('|')) return convertPlaceholders(value);\n\n if (format === 'vue-i18n') return convertVuePipes(value);\n\n return unrecognised(\n value,\n format === 'i18next'\n ? 'holds a \"|\", which i18next does not read as a plural'\n : 'holds a \"|\" in a file with no plural format declared; declare the file\\'s format to convert it'\n );\n}\n\n/**\n * One ICU plural from forms keyed by CLDR category — i18next's `key_one` /\n * `key_other` (and its older `key` / `key_plural` pair, as `one` / `other`).\n * i18next selects by locale, so the forms keep their CLDR categories.\n */\nexport function convertLegacyPluralForms(forms: Partial<Record<(typeof PLURAL_CATEGORIES)[number], string>>): LegacyConversion {\n const raw = PLURAL_CATEGORIES.filter((c) => forms[c] !== undefined)\n .map((c) => forms[c])\n .join(' | ');\n if (forms.other === undefined) return unrecognised(raw, 'is a plural with no \"other\" form');\n\n const branches: Array<[string, string]> = [];\n for (const category of PLURAL_CATEGORIES) {\n const text = forms[category];\n if (text === undefined) continue;\n if (CASE_TRANSFORM.test(text)) {\n return unrecognised(raw, 'uses a case-transforming placeholder (:Name or :NAME), which ICU cannot express');\n }\n branches.push([category, text]);\n }\n return plural(branches, raw);\n}\n\n/** A JS entry point that can receive legacy text (MIG-2). */\nexport type LegacyEntryPoint = 't' | 'vue-i18n' | 'i18next';\n\n/**\n * Convert the text a call passed when it is not a key — a literal miss\n * (MIG-2) — by the entry point that received it, not by any file: the text is\n * written in the calling framework's syntax.\n *\n * Langsys `t()` converts nothing; its argument is already Langsys syntax. A\n * vue-i18n `$t` or i18next `t` bridge converts under its own format's row.\n */\nexport function convertLegacyCall(text: string, entryPoint: LegacyEntryPoint): LegacyConversion {\n if (entryPoint === 't') return { text: String(text), recognised: true, issue: null };\n if (entryPoint === 'vue-i18n' || entryPoint === 'i18next') return convertLegacyValue(text, entryPoint);\n throw new Error(`Unknown entry point \"${String(entryPoint)}\"; expected t, vue-i18n or i18next`);\n}\n\n/**\n * vue-i18n reserves `|` and selects by count, not by locale: with two forms, 1\n * picks the first and anything else the second; with three, 0, 1, then the\n * rest. Exact values keep that selection in every source language, where CLDR\n * `one` would not (in French it covers 0).\n */\nfunction convertVuePipes(value: string): LegacyConversion {\n const segments = value.split('|').map((s) => s.trim());\n if (segments.length === 2) return plural([['=1', segments[0]!], ['other', segments[1]!]], value);\n if (segments.length === 3) return plural([['=0', segments[0]!], ['=1', segments[1]!], ['other', segments[2]!]], value);\n return unrecognised(value, `is a vue-i18n plural with ${segments.length} forms; only 2 or 3 map to ICU`);\n}\n\n/**\n * `{count, plural, <branches>}` with one space between parts, exact branches\n * first as given, then the CLDR categories in order — the string is the\n * phrase's identity, so it has exactly one spelling. The number inside a branch\n * is ICU's `#`, never `{count}`: some ICU builds accept `{count}` in a branch\n * of its own plural and then fail to format it.\n */\nfunction plural(branches: Array<[string, string]>, raw: string): LegacyConversion {\n const parts: string[] = [];\n for (const [selector, text] of branches) {\n const converted = convertPlaceholders(text);\n if (!converted.recognised) return unrecognised(raw, converted.issue!);\n parts.push(`${selector} {${converted.text.replace(/\\{(?:count|n)\\}/g, '#')}}`);\n }\n return { text: `{count, plural, ${parts.join(' ')}}`, recognised: true, issue: null };\n}\n\nfunction convertPlaceholders(value: string): LegacyConversion {\n try {\n const text = value.replace(PLACEHOLDER, (match, rails?: string, python?: string, braces?: string, laravel?: string) => {\n if (match === '%%') return '%';\n const name = rails ?? python ?? braces ?? laravel;\n if (name !== undefined) return `{${name}}`;\n throw new Unconvertible(\n match.startsWith('%(') || match.startsWith('%<')\n ? `uses a formatted placeholder (${match}), which {name} cannot express`\n : `uses a positional placeholder (${match}), which names no argument`\n );\n });\n return { text, recognised: true, issue: null };\n } catch (error) {\n if (error instanceof Unconvertible) return unrecognised(value, error.message);\n throw error;\n }\n}\n\nfunction unrecognised(value: string, issue: string): LegacyConversion {\n return { text: value, recognised: false, issue };\n}\n","import {\n convertLegacyPluralForms,\n convertLegacyValue,\n LEGACY_FORMATS,\n PLURAL_CATEGORIES,\n SUPPORTED_LEGACY_FORMATS,\n type LegacyConversion,\n type LegacyFormat,\n} from './legacy-value.js';\n\n/**\n * Legacy i18n keys resolved against an app's kept source-language files\n * (spec MIG-2, MIG-5, MIG-7).\n *\n * Pure and fs-free: each file is passed already parsed, as `{ name, format?,\n * namespace?, data }`, so the browser `t()` mode and a server `t()` read one\n * configuration through one resolver and register one phrase per key.\n *\n * - **Formats.** This core reads `i18next`, `vue-i18n` and `plain`, all JSON. A\n * file with no declared format is `plain`. A file declaring any other format,\n * or whose name marks it as another ecosystem's (`.php`, `.yml`, `.po`,\n * `.mo`), is refused when the resolver is built, with an error naming the\n * format and the file.\n * - **Lookup.** A key is read as written first, then by dotted path. The first\n * configured file that holds it answers, and a key held by more than one file\n * is reported by `duplicates()`.\n * - **Category.** A key shaped like a path (`checkout.submit`) contributes its\n * first segment; a file with a `namespace` answers only keys under it\n * (`checkout.submit` in a file with namespace `checkout`) and contributes the\n * namespace. A sentence used as its own key has none.\n * - **Plurals.** In an `i18next` file, suffix-paired keys (`items_one`,\n * `items_other`, or the older `items` / `items_plural`) resolve together as\n * one plural under their base key.\n */\n\n/** One configured source file. `data` is its parsed JSON object. */\nexport interface LegacyKeyFile {\n /** The file's path or name, as errors and reports should name it. */\n name: string;\n /** `i18next`, `vue-i18n` or `plain`. Defaults to `plain`. */\n format?: string;\n /** When set, the file answers only keys prefixed `namespace.`, and the namespace is their category. */\n namespace?: string;\n data: unknown;\n}\n\n/** A key the files hold, converted. */\nexport interface LegacyKeyHit extends LegacyConversion {\n /** The phrase to register: the converted value, or the value as written when not `recognised`. */\n phrase: string;\n /** The category the key contributes, or null for none (MIG-5). */\n category: string | null;\n key: string;\n /** The file that answered. */\n file: string;\n}\n\n/** What cannot be migrated as it stands, for a listing command (MIG-4, MIG-7). */\nexport interface LegacyKeyProblem {\n file: string;\n key: string | null;\n issue: string;\n fix: string;\n}\n\nexport interface LegacyKeys {\n /** The key's converted source value, or null when no file holds it (the MIG-2 miss). */\n resolve(key: string): LegacyKeyHit | null;\n /** Keys held by more than one file, with those files in configured order; the first answers. */\n duplicates(): Record<string, string[]>;\n /** Every value that converts to nothing recognised, and every file that is not a JSON object. */\n problems(): LegacyKeyProblem[];\n}\n\n/** Thrown when the configuration names a file this core cannot read (MIG-7). */\nexport class LegacyFormatError extends Error {\n constructor(\n message: string,\n readonly file: string,\n readonly format: string\n ) {\n super(message);\n this.name = 'LegacyFormatError';\n }\n}\n\ninterface NormalizedFile {\n name: string;\n format: LegacyFormat;\n namespace: string | null;\n data: Record<string, unknown> | null;\n}\n\ntype PluralForms = Partial<Record<(typeof PLURAL_CATEGORIES)[number], string>>;\n\n/** The format another ecosystem's file type implies, so it is refused by name rather than read as JSON. */\nconst FOREIGN_EXTENSIONS: Record<string, string> = {\n php: 'laravel',\n yml: 'rails-i18n',\n yaml: 'rails-i18n',\n po: 'gettext',\n mo: 'gettext',\n};\n\n/**\n * Build a resolver over configured files. Throws `LegacyFormatError` for a file\n * this core does not read — never silently, since a skipped file would turn\n * every one of its keys into a literal phrase named after the key.\n */\nexport function createLegacyKeys(files: LegacyKeyFile[]): LegacyKeys {\n const normalized = files.map(normalize);\n\n return {\n resolve(key) {\n if (typeof key !== 'string' || key === '') return null;\n for (const file of normalized) {\n const found = lookup(file, key);\n if (!found) continue;\n const converted = convert(found.value, file.format);\n return { ...converted, phrase: converted.text, category: found.category, key, file: file.name };\n }\n return null;\n },\n\n duplicates() {\n const seen: Record<string, string[]> = {};\n for (const file of normalized) {\n for (const key of Object.keys(leaves(file))) (seen[key] ??= []).push(file.name);\n }\n return Object.fromEntries(Object.entries(seen).filter(([, names]) => names.length > 1));\n },\n\n problems() {\n const problems: LegacyKeyProblem[] = [];\n for (const file of normalized) {\n if (file.data === null) {\n problems.push({ file: file.name, key: null, issue: 'is not a JSON object', fix: 'pass the parsed contents of the file' });\n continue;\n }\n for (const [key, value] of Object.entries(leaves(file))) {\n const converted = convert(value, file.format);\n if (!converted.recognised) {\n problems.push({\n file: file.name,\n key,\n issue: converted.issue!,\n fix: \"rewrite the value as Langsys source text, or declare the file's format\",\n });\n }\n }\n }\n return problems;\n },\n };\n}\n\nfunction normalize(file: LegacyKeyFile): NormalizedFile {\n const name = String(file?.name ?? '');\n const extension = name.includes('.') ? name.slice(name.lastIndexOf('.') + 1).toLowerCase() : '';\n\n if (extension === 'mo') {\n const po = name.slice(0, -3) + '.po';\n throw new LegacyFormatError(\n `The legacy file ${name} is a compiled gettext catalog. gettext reads .po only (${po}), and gettext is not a format this core reads; it reads ${SUPPORTED_LEGACY_FORMATS.join(', ')}.`,\n name,\n 'gettext'\n );\n }\n\n const declared = file?.format;\n const format = declared ?? FOREIGN_EXTENSIONS[extension] ?? 'plain';\n if (!(SUPPORTED_LEGACY_FORMATS as readonly string[]).includes(format)) {\n const known = (LEGACY_FORMATS as readonly string[]).includes(format);\n throw new LegacyFormatError(\n `The legacy file ${name} is in the ${known ? '' : 'unknown '}format \"${format}\", which this core does not read. It reads ${SUPPORTED_LEGACY_FORMATS.join(', ')}.`,\n name,\n format\n );\n }\n\n const data = isRecord(file?.data) ? file.data : null;\n return { name, format: format as LegacyFormat, namespace: file?.namespace ? String(file.namespace) : null, data };\n}\n\nfunction lookup(file: NormalizedFile, key: string): { value: string | PluralForms; category: string | null } | null {\n if (!file.data) return null;\n const pairs = file.format === 'i18next';\n\n if (file.namespace !== null) {\n if (!key.startsWith(file.namespace + '.')) return null;\n const value = valueAt(file.data, key.slice(file.namespace.length + 1).split('.'), pairs);\n return value === null ? null : { value, category: file.namespace };\n }\n\n if (!key.includes('.')) {\n // Read through the pairing, so an i18next plural base (`items` for\n // `items_one`, `item` for `item_plural`) resolves as its plural.\n const value = valueAt(file.data, [key], pairs);\n return value === null ? null : { value, category: null };\n }\n\n const flat = file.data[key];\n if (typeof flat === 'string') return { value: flat, category: looksLikeAPath(key) ? key.slice(0, key.indexOf('.')) : null };\n\n const value = valueAt(file.data, key.split('.'), pairs);\n return value === null ? null : { value, category: key.slice(0, key.indexOf('.')) };\n}\n\n/** A string at a path, or — in an i18next file — plural forms when the key is suffix-paired. */\nfunction valueAt(data: Record<string, unknown>, segments: string[], pairs: boolean): string | PluralForms | null {\n const last = segments.pop()!;\n let container: unknown = data;\n for (const segment of segments) {\n if (!isRecord(container) || !(segment in container)) return null;\n container = container[segment];\n }\n if (!isRecord(container)) return null;\n\n if (pairs) {\n const forms: PluralForms = {};\n for (const category of PLURAL_CATEGORIES) {\n const value = container[`${last}_${category}`];\n if (typeof value === 'string') forms[category] = value;\n }\n if (Object.keys(forms).length > 0) return forms;\n const singular = container[last];\n const pluralForm = container[`${last}_plural`];\n if (typeof singular === 'string' && typeof pluralForm === 'string') return { one: singular, other: pluralForm };\n }\n\n const value = container[last];\n return typeof value === 'string' ? value : null;\n}\n\n/** Every leaf by its full key: strings, and — in an i18next file — plural forms under their base key. */\nfunction leaves(file: NormalizedFile): Record<string, string | PluralForms> {\n const out: Record<string, string | PluralForms> = {};\n if (!file.data) return out;\n const prefix = file.namespace !== null ? file.namespace + '.' : '';\n collect(file.data, prefix, out, file.format === 'i18next');\n return out;\n}\n\nconst SUFFIXES = [...PLURAL_CATEGORIES.map((c) => `_${c}`), '_plural'];\n\nfunction collect(node: Record<string, unknown>, prefix: string, out: Record<string, string | PluralForms>, pairs: boolean): void {\n for (const [key, value] of Object.entries(node)) {\n if (isRecord(value)) {\n collect(value, `${prefix}${key}.`, out, pairs);\n continue;\n }\n if (typeof value !== 'string') continue;\n\n if (pairs) {\n const suffix = SUFFIXES.find((s) => key.endsWith(s) && key.length > s.length);\n if (suffix) {\n const base = key.slice(0, -suffix.length);\n const forms = valueAt(node, [base], true);\n if (forms !== null && typeof forms !== 'string') {\n out[prefix + base] = forms;\n continue;\n }\n }\n }\n if (!(prefix + key in out)) out[prefix + key] = value;\n }\n}\n\nfunction convert(value: string | PluralForms, format: LegacyFormat): LegacyConversion {\n return typeof value === 'string' ? convertLegacyValue(value, format) : convertLegacyPluralForms(value);\n}\n\n/** A flat key names a category only when it is shaped like a key path; a sentence used as its own key has none. */\nfunction looksLikeAPath(key: string): boolean {\n return /^[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)+$/.test(key);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","/**\n * Catalog snapshots (spec SNAP family): one file format every Langsys SDK\n * writes and reads, so a snapshot exported by any core loads in any other.\n *\n * A snapshot is the flat catalog (`GET /translations`) for chosen locales and\n * categories, carried as a file so a first render, a mobile bundle or an\n * offline session has translations with no network call. It is a cache, never\n * a source: Langsys produces it, a checksum over its canonical serialisation\n * catches an edited one, and the refresh path is a new export.\n *\n * Everything here is pure. Seeding a loaded snapshot into the SDK is\n * `LangsysApp.loadSnapshot`, on the main entry.\n */\n\n/** The `format` member every snapshot carries. */\nexport const SNAPSHOT_FORMAT = 'langsys-catalog-snapshot';\n\n/** The only `version` this SDK reads and writes. */\nexport const SNAPSHOT_VERSION = 1;\n\n/** A category's flat entries as `GET /translations` returns them: phrase → translation or null, or a block id → its phrase map. */\nexport type SnapshotCategory = Record<string, string | null | Record<string, string | null>>;\n\n/** locale → category → entries. A category the locale does not hold is absent; one it holds empty is `{}`. */\nexport type SnapshotCatalog = Record<string, Record<string, SnapshotCategory>>;\n\n/** The members the checksum covers. */\nexport interface SnapshotPayload {\n project_id: string;\n /** UTC, `YYYY-MM-DDTHH:MM:SSZ`. */\n generated_at: string;\n base_locale: string;\n /** Lowercase `xx-yy`, sorted ascending. */\n locales: string[];\n /** Sorted ascending. */\n categories: string[];\n catalog: SnapshotCatalog;\n}\n\n/** A whole snapshot document. */\nexport interface CatalogSnapshot extends SnapshotPayload {\n format: typeof SNAPSHOT_FORMAT;\n version: typeof SNAPSHOT_VERSION;\n /** `sha256:` and the lowercase hex digest of the canonical serialisation of the payload. */\n checksum: string;\n}\n\n/** Why a snapshot was refused. */\nexport type SnapshotRefusal = 'not-json' | 'format' | 'version' | 'missing-member' | 'checksum';\n\n/** Thrown when a snapshot cannot be loaded. `reason` names why; the message says what to do. */\nexport class SnapshotError extends Error {\n constructor(\n message: string,\n readonly reason: SnapshotRefusal\n ) {\n super(message);\n this.name = 'SnapshotError';\n }\n}\n\nconst PAYLOAD_MEMBERS = ['project_id', 'generated_at', 'base_locale', 'locales', 'categories', 'catalog'] as const;\n\n/**\n * The canonical serialisation the checksum is taken over, byte for byte the\n * same in every SDK:\n *\n * - strings escaped as CID-1 serialises them — `\"`, `\\` and U+0000–U+001F only,\n * everything else (`/`, non-ASCII, U+2028) raw — which is `JSON.stringify`'s\n * own string escaping;\n * - no whitespace;\n * - object members sorted by key in Unicode code point order. Neither\n * `Object.keys` order (integer-like keys first) nor the default `sort()`\n * (UTF-16 code units, which puts a key above U+FFFF before one in\n * U+E000–U+FFFF) is that order, so both are avoided;\n * - a map is `{}` even when empty; `null` is `null`.\n */\nexport function canonicalSnapshotJson(value: unknown): string {\n if (value === null) return 'null';\n if (typeof value === 'string') return JSON.stringify(value);\n if (typeof value === 'number' || typeof value === 'boolean') return JSON.stringify(value);\n if (Array.isArray(value)) return `[${value.map(canonicalSnapshotJson).join(',')}]`;\n if (typeof value === 'object') {\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).filter((key) => record[key] !== undefined).sort(compareCodePoints);\n return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalSnapshotJson(record[key])}`).join(',')}}`;\n }\n throw new TypeError(`A snapshot cannot hold a ${typeof value}.`);\n}\n\n/** `sha256:` and the lowercase hex SHA-256 of the canonical serialisation of the payload members. */\nexport function snapshotChecksum(payload: SnapshotPayload): string {\n const hashed: Record<string, unknown> = {};\n for (const member of PAYLOAD_MEMBERS) hashed[member] = payload[member];\n return 'sha256:' + sha256Hex(canonicalSnapshotJson(hashed));\n}\n\n/**\n * Build a snapshot document from catalogs already fetched — the writing half,\n * for an export tool. `catalogs` is locale → the catalog `GET /translations`\n * returned; only the chosen categories are kept, and a category a locale does\n * not hold stays absent for that locale. Locales are lowercased; both lists are\n * sorted.\n */\nexport function buildSnapshot(options: {\n projectId: string;\n baseLocale: string;\n catalogs: Record<string, Record<string, SnapshotCategory>>;\n categories: string[];\n generatedAt?: Date;\n}): CatalogSnapshot {\n const categories = [...new Set(options.categories.map(String))].sort(compareCodePoints);\n const catalog: SnapshotCatalog = {};\n for (const [locale, categoriesForLocale] of Object.entries(options.catalogs)) {\n const kept: Record<string, SnapshotCategory> = {};\n for (const category of categories) {\n if (Object.prototype.hasOwnProperty.call(categoriesForLocale, category)) kept[category] = categoriesForLocale[category]!;\n }\n catalog[locale.toLowerCase()] = kept;\n }\n const payload: SnapshotPayload = {\n project_id: String(options.projectId),\n generated_at: (options.generatedAt ?? new Date()).toISOString().replace(/\\.\\d{3}Z$/, 'Z'),\n base_locale: options.baseLocale.toLowerCase(),\n locales: Object.keys(catalog).sort(compareCodePoints),\n categories,\n catalog,\n };\n return { format: SNAPSHOT_FORMAT, version: SNAPSHOT_VERSION, ...payload, checksum: snapshotChecksum(payload) };\n}\n\n/**\n * Read a snapshot from its JSON text or parsed document, refusing — with an\n * error naming the reason — a different `format`, an unsupported `version`, a\n * missing member, or a checksum the contents no longer match. The file may be\n * any JSON encoding of the document; the checksum is recomputed from the\n * canonical serialisation, never compared against the file's bytes.\n */\nexport function parseSnapshot(input: string | unknown): CatalogSnapshot {\n let document: unknown = input;\n if (typeof input === 'string') {\n try {\n document = JSON.parse(input);\n } catch {\n throw new SnapshotError('This is not a Langsys catalog snapshot: it is not JSON.', 'not-json');\n }\n }\n if (typeof document !== 'object' || document === null || Array.isArray(document)) {\n throw new SnapshotError('This is not a Langsys catalog snapshot: it is not a JSON object.', 'not-json');\n }\n const doc = document as Record<string, unknown>;\n\n if (doc.format !== SNAPSHOT_FORMAT) {\n throw new SnapshotError(`This is not a Langsys catalog snapshot: its format is ${JSON.stringify(doc.format)}, not \"${SNAPSHOT_FORMAT}\".`, 'format');\n }\n if (doc.version !== SNAPSHOT_VERSION) {\n throw new SnapshotError(`This snapshot is version ${JSON.stringify(doc.version)}; this SDK reads version ${SNAPSHOT_VERSION}. Export it again.`, 'version');\n }\n for (const member of [...PAYLOAD_MEMBERS, 'checksum']) {\n if (!Object.prototype.hasOwnProperty.call(doc, member)) {\n throw new SnapshotError(`This snapshot has no \"${member}\". Export it again.`, 'missing-member');\n }\n }\n if (doc.checksum !== snapshotChecksum(doc as unknown as SnapshotPayload)) {\n throw new SnapshotError(\n 'This snapshot was changed after it was exported: its checksum does not match. A snapshot is a cache and is never edited; export it again.',\n 'checksum'\n );\n }\n return doc as unknown as CatalogSnapshot;\n}\n\n/** Compare two strings by Unicode code point, which is UTF-8 byte order. */\nfunction compareCodePoints(a: string, b: string): number {\n const ia = a[Symbol.iterator]();\n const ib = b[Symbol.iterator]();\n for (;;) {\n const ca = ia.next();\n const cb = ib.next();\n if (ca.done || cb.done) return ca.done && cb.done ? 0 : ca.done ? -1 : 1;\n const diff = ca.value.codePointAt(0)! - cb.value.codePointAt(0)!;\n if (diff !== 0) return diff;\n }\n}\n\n/**\n * SHA-256 of a string's UTF-8 bytes, synchronously. Loading a snapshot is\n * synchronous by contract (SNAP-2) and the platform's digest is async, so the\n * hash is computed here — FIPS 180-4, no dependency.\n */\nexport function sha256Hex(text: string): string {\n const bytes = new TextEncoder().encode(text);\n const length = bytes.length;\n const blocks = Math.ceil((length + 9) / 64);\n const words = new Uint32Array(blocks * 16);\n for (let i = 0; i < length; i++) words[i >> 2]! |= bytes[i]! << (24 - (i % 4) * 8);\n words[length >> 2]! |= 0x80 << (24 - (length % 4) * 8);\n // The bit length, as a 64-bit big-endian integer in the last two words.\n words[words.length - 2] = Math.floor((length * 8) / 0x100000000);\n words[words.length - 1] = (length * 8) >>> 0;\n\n const h = new Uint32Array([0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]);\n const w = new Uint32Array(64);\n for (let block = 0; block < words.length; block += 16) {\n for (let t = 0; t < 16; t++) w[t] = words[block + t]!;\n for (let t = 16; t < 64; t++) {\n const s0 = rotr(w[t - 15]!, 7) ^ rotr(w[t - 15]!, 18) ^ (w[t - 15]! >>> 3);\n const s1 = rotr(w[t - 2]!, 17) ^ rotr(w[t - 2]!, 19) ^ (w[t - 2]! >>> 10);\n w[t] = (w[t - 16]! + s0 + w[t - 7]! + s1) >>> 0;\n }\n let [a, b, c, d, e, f, g, hh] = [h[0]!, h[1]!, h[2]!, h[3]!, h[4]!, h[5]!, h[6]!, h[7]!];\n for (let t = 0; t < 64; t++) {\n const t1 = (hh + (rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)) + ((e & f) ^ (~e & g)) + K[t]! + w[t]!) >>> 0;\n const t2 = ((rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)) + ((a & b) ^ (a & c) ^ (b & c))) >>> 0;\n hh = g;\n g = f;\n f = e;\n e = (d + t1) >>> 0;\n d = c;\n c = b;\n b = a;\n a = (t1 + t2) >>> 0;\n }\n h[0] = (h[0]! + a) >>> 0;\n h[1] = (h[1]! + b) >>> 0;\n h[2] = (h[2]! + c) >>> 0;\n h[3] = (h[3]! + d) >>> 0;\n h[4] = (h[4]! + e) >>> 0;\n h[5] = (h[5]! + f) >>> 0;\n h[6] = (h[6]! + g) >>> 0;\n h[7] = (h[7]! + hh) >>> 0;\n }\n return Array.from(h, (word) => word.toString(16).padStart(8, '0')).join('');\n}\n\nfunction rotr(value: number, bits: number): number {\n return (value >>> bits) | (value << (32 - bits));\n}\n\nconst K = new Uint32Array([\n 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,\n 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,\n 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,\n 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n","/**\n * Server messages (spec MSG family): the entries a server attaches to its\n * framework's own error response, and how a client finds and renders them.\n *\n * What translation needs is small: the `template` — the framework's own\n * sentence, unfilled, with the field's label written in — and the `params`\n * that fill its `{name}` markers. `message` is the template already filled, the\n * fallback a client shows when it cannot look the template up. Everything else\n * is the framework's and passes through unchanged: `field` in the framework's\n * own path format (a dotted string, Pydantic's `loc` array), and `code`, the\n * framework's own identifier for the failure (Laravel's rule name, Pydantic's\n * error `type`, Django's `code`), or none. The error body is the framework's\n * too, so where the entries sit and what their pieces are called are the\n * app's configuration.\n *\n * Everything here is pure except `renderServerMessage`, which renders through\n * `t()`; that one is exported from the main entry only.\n */\n\n/** One server message entry (MSG-1), in the SDK's own piece names. */\nexport interface ServerMessage {\n template?: string;\n params?: Record<string, unknown>;\n message?: string;\n /** The field, in the framework's own path format, unchanged. */\n field?: unknown;\n /** The framework's own identifier for the failure, unchanged. Absent where the framework has none. */\n code?: unknown;\n}\n\n/** The piece names an app's entries use, where they differ from the SDK's. */\nexport type ServerMessagePieces = Partial<Record<'template' | 'params' | 'message' | 'field' | 'code', string>>;\n\n/** Where the entries sit in a response body (MSG-1). One of `key` or `resolver` is required. */\nexport interface ResolveServerMessagesOptions {\n /**\n * The dotted path the server attached the entries under, beside the\n * framework's own error body — Laravel's package default is `langsys_errors`.\n */\n key?: string;\n /** Maps a body to entries itself, for an app whose failures are carried some other way. */\n resolver?: (body: unknown) => unknown;\n /** The entries' piece names, when the server was configured with names of its own. */\n pieces?: ServerMessagePieces;\n}\n\n/** The category templates are registered and rendered under unless configured otherwise (MSG-6). */\nexport const DEFAULT_SERVER_MESSAGE_CATEGORY = 'Errors';\n\n/**\n * A marker is a lowercase snake_case name in braces (MSG-3). `{Name}`, `{ min }`\n * and `{1x}` are not markers and are never filled. Byte-compatible with the\n * server's grammar: the server fills `message` from the template with it, and a\n * client that disagreed about what a marker is would fill a different sentence.\n */\nconst MARKER = /\\{([a-z][a-z0-9_]*)\\}/g;\n\n/** The marker names in a template, once each, in the order they first appear. */\nexport function templateMarkers(template: string): string[] {\n if (typeof template !== 'string' || template === '') return [];\n const names: string[] = [];\n for (const match of template.matchAll(MARKER)) {\n if (!names.includes(match[1]!)) names.push(match[1]!);\n }\n return names;\n}\n\n/**\n * Fill a template's markers from params (MSG-4). A marker with no param stays\n * as its literal marker rather than going blank, so a missing value is visible\n * instead of producing a sentence that reads as complete. A structure is never\n * printed into the sentence; its marker stays too.\n */\nexport function fillTemplate(template: string, params: Record<string, unknown> = {}): string {\n return String(template).replace(MARKER, (marker, name: string) => {\n if (!Object.prototype.hasOwnProperty.call(params, name)) return marker;\n const value = params[name];\n // `typeof null` is 'object', so null keeps its marker here too.\n if (value === undefined || typeof value === 'object' || typeof value === 'function') return marker;\n return String(value);\n });\n}\n\n/**\n * An entry from its wire form, or null when it is not one. An entry needs a\n * `template` to look up or a `message` to show; either is a string. `params`\n * is kept when it is an object; `field` and `code` pass through as they are.\n */\nexport function toServerMessage(value: unknown, pieces: ServerMessagePieces = {}): ServerMessage | null {\n if (!isRecord(value)) return null;\n const read = (piece: keyof ServerMessagePieces) => value[pieces[piece] ?? piece];\n const template = read('template');\n const message = read('message');\n const params = read('params');\n const field = read('field');\n const code = read('code');\n const hasTemplate = typeof template === 'string';\n const hasMessage = typeof message === 'string';\n if (!hasTemplate && !hasMessage) return null;\n\n return {\n ...(hasTemplate ? { template } : {}),\n ...(isRecord(params) ? { params } : {}),\n ...(hasMessage ? { message } : {}),\n ...(field !== undefined && field !== null && field !== '' ? { field } : {}),\n ...(code !== undefined && code !== null ? { code } : {}),\n };\n}\n\n/**\n * The entries a response carries, found where the app's configuration says\n * they are (MSG-1). The body is the framework's own and is never searched by\n * shape: `key` names the dotted path the server attached the entries under,\n * and `resolver` maps the body to entries itself. Throws when neither is given,\n * since there is nowhere to look. `pieces` renames the entries' pieces.\n *\n * Accepts the decoded body or its JSON text, and never changes the body.\n * Unreadable JSON, or a key the body does not carry, resolves to no entries:\n * this runs in an error path already.\n */\nexport function resolveServerMessages(body: unknown, options: ResolveServerMessagesOptions): ServerMessage[] {\n const { key, resolver, pieces } = options ?? {};\n if (typeof resolver !== 'function' && (typeof key !== 'string' || key === '')) {\n throw new TypeError(\n 'resolveServerMessages needs to know where the entries sit: pass { key } with the path your server attaches them under (Laravel: \"langsys_errors\"), or { resolver }.'\n );\n }\n\n if (typeof body === 'string') {\n try {\n body = JSON.parse(body);\n } catch {\n return [];\n }\n }\n\n const found = typeof resolver === 'function' ? resolver(body) : dig(body, key!);\n return toItems(found)\n .map((item) => toServerMessage(item, pieces))\n .filter((entry): entry is ServerMessage => entry !== null);\n}\n\n/** A list of entries, a single entry, or a field → entries map, as items. */\nfunction toItems(found: unknown): unknown[] {\n if (Array.isArray(found)) return found;\n if (!isRecord(found)) return [];\n const values = Object.values(found);\n return values.every((value) => Array.isArray(value)) && values.length > 0 ? values.flat() : [found];\n}\n\nfunction dig(body: unknown, path: string): unknown {\n let node = body;\n for (const segment of path.split('.')) {\n if (typeof node !== 'object' || node === null || !Object.prototype.hasOwnProperty.call(node, segment)) {\n return undefined;\n }\n node = (node as Record<string, unknown>)[segment];\n }\n return node;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","/**\n * Placeholder names from source expressions (spec VAR-2). A name matches\n * `[a-z][a-z0-9_]*`, so it is a valid ICU argument, and it is derived the same way\n * by every SDK, because the name is part of the phrase: two SDKs naming the same\n * expression differently register two phrases.\n *\n * Expressions are given as a language-neutral shape, the one the shared naming\n * vectors (`var-naming-vectors.json`) use, so a binding maps its own AST onto it.\n */\n\n/** An expression that produced a value, as the naming rules see it. */\nexport type ExpressionShape =\n | { identifier: string }\n | { member: string[] }\n | { call: { callee: string; args: ExpressionShape[] } }\n | { other: 'binary' | 'conditional' | 'template' | 'computed' | 'call-multi' | string };\n\n/** One value in a phrase: its expression, and the name the developer wrote, if any. */\nexport interface NamedExpression {\n shape: ExpressionShape;\n /** An explicit name always wins. */\n explicit?: string;\n}\n\nconst GRAMMAR = /^[a-z][a-z0-9_]*$/;\n/** `<Phrase>`'s markup tokens. */\nconst RESERVED = /^m\\d+[oc]$/;\nconst COUNT = new Set(['length', 'size', 'count']);\nconst VALUE = new Set(['value', 'current']);\n\n/** A segment in snake_case, within the grammar, or null when nothing of it survives. */\nexport function snakeCase(segment: string): string | null {\n const snake = segment\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')\n .toLowerCase()\n .replace(/[^a-z0-9_]+/g, '_')\n .replace(/_+/g, '_')\n .replace(/^[^a-z]+/, '')\n .replace(/_+$/, '');\n return snake && GRAMMAR.test(snake) ? snake : null;\n}\n\n/** The name an expression derives on its own, and the segment before it, for a collision's prefix. */\nfunction derive(shape: ExpressionShape): { name: string; prev: string | null } | null {\n if ('identifier' in shape) {\n const name = snakeCase(shape.identifier);\n return name ? { name, prev: null } : null;\n }\n if ('member' in shape) {\n const segments = shape.member;\n if (segments.length === 0) return null;\n const last = segments[segments.length - 1]!;\n if (segments.length >= 2 && (COUNT.has(last) || VALUE.has(last))) {\n const base = snakeCase(segments[segments.length - 2]!);\n if (!base) return null;\n const prev = segments.length >= 3 ? snakeCase(segments[segments.length - 3]!) : null;\n return { name: COUNT.has(last) ? `${base}_count` : base, prev };\n }\n const name = snakeCase(last);\n if (!name) return null;\n return { name, prev: segments.length >= 2 ? snakeCase(segments[segments.length - 2]!) : null };\n }\n if ('call' in shape) {\n return shape.call.args.length === 1 ? derive(shape.call.args[0]!) : null;\n }\n return null;\n}\n\nconst key = (shape: ExpressionShape) => JSON.stringify(shape);\n\n/**\n * Whether a shape identifies its expression, so that an equal shape is the same\n * expression. An `other` shape, anywhere in it, does not: `a + b` and `c * d` are both\n * `{ other: 'binary' }`, and so are the arguments of `fmt(a + b)` and `fmt(c * d)`. Nor\n * does a call whose callee cannot be spelled (`''`): `getA()(n)` and `getB()(n)` are\n * both a call over `n`.\n */\nfunction identifies(shape: ExpressionShape): boolean {\n if ('call' in shape) return shape.call.callee !== '' && shape.call.args.every(identifies);\n return !('other' in shape);\n}\n\n/**\n * The placeholder name of each value in one phrase, in order (VAR-2):\n *\n * - an explicit name wins;\n * - an identifier is itself in snake_case; a member chain its last segment; a\n * chain ending in `length`, `size` or `count` the segment before plus `_count`;\n * one ending in `value` or `current` the segment before; a call with one\n * argument the argument's name;\n * - the same expression twice is the same placeholder, where the shape identifies\n * it: two shapes containing `other` are two placeholders, however equal;\n * - names that collide are prefixed with their previous segment, then suffixed\n * `_2`, `_3`, and a reserved name (`m0o`) counts as taken;\n * - anything else is `value`, `value_2`, ….\n */\nexport function derivePlaceholderNames(expressions: readonly NamedExpression[]): string[] {\n const names: Array<string | null> = expressions.map((e) => (e.explicit ? snakeCase(e.explicit) ?? e.explicit : null));\n const taken = new Set(names.filter((n): n is string => n !== null));\n const derived = expressions.map((e, i) => (names[i] === null ? derive(e.shape) : null));\n\n // The same expression is one placeholder: its later occurrences take the first's name.\n // Only a shape that identifies its expression can be the same as another.\n const firstOf = new Map<string, number>();\n const sameAs = expressions.map((e, i) => {\n if (names[i] !== null || !identifies(e.shape)) return i;\n const k = key(e.shape);\n if (!firstOf.has(k)) firstOf.set(k, i);\n return firstOf.get(k)!;\n });\n\n // Derived names wanted by more than one distinct expression, or taken already, collide.\n const wanted = new Map<string, number[]>();\n derived.forEach((d, i) => {\n if (d && sameAs[i] === i) wanted.set(d.name, [...(wanted.get(d.name) ?? []), i]);\n });\n const claim = (name: string): string => {\n let candidate = name;\n for (let n = 2; taken.has(candidate) || RESERVED.test(candidate); n++) candidate = `${name}_${n}`;\n taken.add(candidate);\n return candidate;\n };\n for (let i = 0; i < expressions.length; i++) {\n if (names[i] !== null || sameAs[i] !== i) continue;\n const d = derived[i];\n if (!d) continue;\n const collides = (wanted.get(d.name)?.length ?? 0) > 1 || taken.has(d.name) || RESERVED.test(d.name);\n names[i] = claim(collides && d.prev ? `${d.prev}_${d.name}` : d.name);\n }\n for (let i = 0; i < expressions.length; i++) {\n if (names[i] === null && sameAs[i] === i) names[i] = claim('value');\n }\n return expressions.map((_, i) => names[sameAs[i]!]!);\n}\n","import { encodeRichPhrase, isOpaqueInPhrase, normalizeMarkupPlaceholders, normalizeTokenText, type AttributeReader, type RichTextNode } from './identity.js';\nimport { interpolate, isICU } from './interpolate.js';\nimport type { ParamPrimitive } from './types/translation-fn.js';\n\n/**\n * Value markers (spec VAR-3): how an emitter tells a reader which printed text\n * was a variable, and what it was called, so the reader registers a placeholder\n * instead of one phrase per value (VAR-1).\n *\n * <p>Hello <!--ls:name-->Ana<!--/ls-->, welcome back</p>\n * <p>Hello <span data-ls-param=\"name\">Ana</span>, welcome back</p>\n * [{ text: 'Hello ' }, { comment: 'ls:name' }, { text: 'Ana' }, { comment: '/ls' }, { text: ', welcome back' }]\n *\n * all read as the one token `Hello {name}, welcome back`, with param `name` =\n * `Ana`. The value is text only: an element inside the pair voids the marker,\n * and its comments then split text as any comment does.\n *\n * Within one parent, the text on both sides of a marker, and every marker in\n * between, merge into one run. Everything without a marker splits exactly as\n * before, so no id derived from unmarked markup changes.\n */\n\n/** The attribute form's attribute, for an emitter that cannot write comments. */\nexport const VAR_PARAM_ATTR = 'data-ls-param';\n\n/** A placeholder name (VAR-2's grammar). */\nconst NAME = /^[a-z][a-z0-9_]*$/;\nconst OPEN = /^ls:([a-z][a-z0-9_]*)$/;\nconst CLOSE = '/ls';\n\nconst ELEMENT = 1;\nconst TEXT = 3;\nconst COMMENT = 8;\n\n/** What the grouping reads from a node: the DOM's shape, or a tree view's. */\nexport interface MarkerNode {\n nodeType: number;\n nodeValue: string | null;\n childNodes: ArrayLike<MarkerNode>;\n getAttribute?(name: string): string | null;\n}\n\n/** A marked value: its name, the text nodes holding the value, and the nodes that mark it. */\nexport interface VarMarker<N> {\n name: string;\n value: N[];\n /** The nodes that are the marker itself: a comment pair, or the `data-ls-param` element. */\n frame: N[];\n}\n\nexport type RunPart<N> = { text: N } | { marker: VarMarker<N> };\n\n/** One merged run: text nodes and markers, in order, holding at least one marker. */\nexport interface VarRun<N> {\n parts: RunPart<N>[];\n}\n\nexport type RunItem<N> = { node: N } | { run: VarRun<N> };\n\n/** The name an element marks as a value (`data-ls-param`, holding text only), or null when it is no marker. */\nexport function paramElementName(node: MarkerNode): string | null {\n if (node.nodeType !== ELEMENT || !node.getAttribute) return null;\n const name = node.getAttribute(VAR_PARAM_ATTR)?.trim();\n if (!name || !NAME.test(name)) return null;\n return Array.from(node.childNodes).every((child) => child.nodeType === TEXT) ? name : null;\n}\n\n/** The marker starting at `children[i]`, and the index after it; null when there is none there. */\nfunction markerAt<N extends MarkerNode>(children: readonly N[], i: number): { marker: VarMarker<N>; next: number } | null {\n const node = children[i]!;\n if (node.nodeType === COMMENT) {\n const open = OPEN.exec((node.nodeValue ?? '').trim());\n if (!open) return null;\n const value: N[] = [];\n let j = i + 1;\n while (j < children.length && children[j]!.nodeType === TEXT) value.push(children[j++]!);\n const close = children[j];\n // Anything but text before the close voids the pair (an element inside, or no close).\n if (!close || close.nodeType !== COMMENT || (close.nodeValue ?? '').trim() !== CLOSE) return null;\n return { marker: { name: open[1]!, value, frame: [node, close] }, next: j + 1 };\n }\n const name = paramElementName(node);\n if (name !== null) return { marker: { name, value: Array.from(node.childNodes) as N[], frame: [node] }, next: i + 1 };\n return null;\n}\n\n/**\n * A parent's children as items: each run of text and markers that holds a\n * marker, and every other node as itself. Adjacent text with no marker among it\n * stays separate nodes, as the walks have always seen it.\n */\nexport function groupRuns<N extends MarkerNode>(children: ArrayLike<N>): RunItem<N>[] {\n const list = Array.from(children);\n const items: RunItem<N>[] = [];\n let parts: RunPart<N>[] = [];\n const flush = () => {\n if (parts.some((part) => 'marker' in part)) items.push({ run: { parts } });\n else for (const part of parts) items.push({ node: (part as { text: N }).text });\n parts = [];\n };\n for (let i = 0; i < list.length; i++) {\n const node = list[i]!;\n if (node.nodeType === TEXT) {\n parts.push({ text: node });\n continue;\n }\n const found = markerAt(list, i);\n if (found) {\n parts.push({ marker: found.marker });\n i = found.next - 1;\n continue;\n }\n flush();\n items.push({ node });\n }\n flush();\n return items;\n}\n\n/** A run's text, with `{NAME}` for each marker; `text` reads a text node (its original, where one is kept). */\nexport function runSource<N extends MarkerNode>(run: VarRun<N>, text: (node: N) => string = (n) => n.nodeValue ?? ''): string {\n return run.parts.map((part) => ('text' in part ? text(part.text) : `{${part.marker.name}}`)).join('');\n}\n\n/** The siblings a run spans, in order: its text nodes, and each marker's own nodes with the value between. */\nexport function runNodes<N extends MarkerNode>(run: VarRun<N>): N[] {\n return run.parts.flatMap((part) => {\n if ('text' in part) return [part.text];\n const [open, close] = part.marker.frame;\n return close ? [open!, ...part.marker.value, close] : [open!];\n });\n}\n\n/** A run's token, normalised as a text node's token is. Empty when the run holds only whitespace and markers. */\nexport function runToken<N extends MarkerNode>(run: VarRun<N>, text?: (node: N) => string): string {\n return normalizeMarkupPlaceholders(normalizeTokenText(runSource(run, text)));\n}\n\n/** Whether a run has no text of its own: only markers, and whitespace. */\nexport function isMarkerOnly<N extends MarkerNode>(run: VarRun<N>, text: (node: N) => string = (n) => n.nodeValue ?? ''): boolean {\n return run.parts.every((part) => 'marker' in part || !normalizeTokenText(text(part.text)));\n}\n\n/** The value each marker carries, by name: the text it holds now. */\nexport function runValues<N extends MarkerNode>(run: VarRun<N>, value: (node: N) => string = (n) => n.nodeValue ?? ''): Record<string, string> {\n const values: Record<string, string> = {};\n for (const part of run.parts) {\n if ('marker' in part && !(part.marker.name in values)) {\n values[part.marker.name] = normalizeTokenText(part.marker.value.map(value).join(''));\n }\n }\n return values;\n}\n\n/**\n * The text each node of a run shows for `template` (the run's translation, or its\n * source): what to write into each text node, and into each marked value's nodes.\n *\n * In place when the template keeps every marker's placeholder exactly once, in\n * the markers' order, and is not ICU: the text between the markers goes into the\n * text nodes between them, and the value nodes keep the value, so a framework's\n * later update to them stays live. Otherwise the whole sentence, with the values\n * interpolated, goes into the run's first text node, and every other text node\n * and value node is emptied; a later value update then needs a re-render.\n *\n * `params` are the caller's; a marker's value is its param only when the caller\n * does not name that param itself. A param the caller names is written into the\n * value's nodes, in place as in a whole sentence.\n */\nexport function renderRun<N extends MarkerNode>(\n run: VarRun<N>,\n template: string,\n params: Record<string, ParamPrimitive>,\n locale: string,\n source: { text: (node: N) => string; value: (marker: VarMarker<N>) => string }\n): Array<[N, string]> {\n const groups: N[][] = [[]];\n const markers: VarMarker<N>[] = [];\n for (const part of run.parts) {\n if ('text' in part) groups[groups.length - 1]!.push(part.text);\n else {\n markers.push(part.marker);\n groups.push([]);\n }\n }\n const texts = groups.flat();\n const leadOf = (node: N | undefined) => (node ? /^\\s*/.exec(source.text(node))![0] : '');\n const trailOf = (node: N | undefined) => (node ? /\\s*$/.exec(source.text(node))![0] : '');\n const lastGroup = groups[groups.length - 1]!;\n // The run's own outer whitespace stays where it was, as a text node's does.\n const edge = (i: number, segment: string) =>\n (i === 0 ? leadOf(groups[0]![0]) : '') + segment + (i === groups.length - 1 ? trailOf(lastGroup[lastGroup.length - 1]) : '');\n\n const segments = splitAtMarkers(template, markers.map((m) => m.name));\n const inPlace = segments !== null && segments.every((segment, i) => groups[i]!.length > 0 || segment === '');\n const writes: Array<[N, string]> = [];\n if (inPlace) {\n segments!.forEach((segment, i) => {\n groups[i]!.forEach((node, k) => writes.push([node, k === 0 ? edge(i, interpolate(segment, params, locale)) : '']));\n });\n for (const marker of markers) {\n const node = marker.value[0];\n if (!node) continue;\n if (marker.name in params) {\n // The caller names the param itself, so it is the value shown (VAR-3).\n const text = interpolate(`{${marker.name}}`, params, locale);\n marker.value.forEach((n, k) => writes.push([n, k === 0 ? text : '']));\n } else if (!marker.value.map((n) => n.nodeValue ?? '').join('')) {\n // A value an earlier whole-sentence render emptied is shown again.\n writes.push([node, source.value(marker)]);\n }\n }\n return writes;\n }\n const values: Record<string, ParamPrimitive> = {};\n for (const marker of markers) if (!(marker.name in values)) values[marker.name] = source.value(marker);\n const whole = interpolate(template, { ...values, ...params }, locale);\n const first = texts[0];\n if (!first) return writes;\n const text = leadOf(first) + whole + trailOf(texts[texts.length - 1]);\n for (const node of texts) writes.push([node, node === first ? text : '']);\n for (const marker of markers) for (const node of marker.value) writes.push([node, '']);\n return writes;\n}\n\n/** The template's text between the markers' placeholders, or null unless each appears once, in order, outside ICU. */\nfunction splitAtMarkers(template: string, names: string[]): string[] | null {\n if (isICU(template) || new Set(names).size !== names.length) return null;\n const segments: string[] = [];\n let rest = template;\n for (const name of names) {\n const token = `{${name}}`;\n const at = rest.indexOf(token);\n if (at < 0 || rest.indexOf(token, at + token.length) >= 0) return null;\n segments.push(rest.slice(0, at));\n rest = rest.slice(at + token.length);\n }\n segments.push(rest);\n // A placeholder of a marker must not also appear in an earlier segment.\n if (segments.some((segment) => names.some((name) => segment.includes(`{${name}}`)))) return null;\n return segments;\n}\n\n/**\n * A rich phrase's nodes (`encodeRichPhrase`), reading value markers: each marked\n * value is its `{NAME}` placeholder, its value goes into `values`, and a comment\n * that marks nothing is dropped. Every other element is a markup slot. An element\n * opaque in a phrase (`isOpaqueInPhrase`) is a slot with nothing inside, and nothing\n * in it is read (TOK-1). `payload` is told whether its element is opaque.\n *\n * `exclude: false` walks into opaque elements, as the reader did before TOK-1 bound\n * this path: the earlier key a phrase holding one was registered under (`earlierRichPhrase`).\n *\n * With `marker`, each marked value is a markup slot holding its placeholder, with\n * `marker`'s payload: how a phrase served as its source renders inside its markers.\n */\nexport function toRichNodes<N extends MarkerNode, T>(\n children: ArrayLike<N>,\n payload: (element: N, opaque: boolean) => T,\n values: Record<string, string> = {},\n exclude = true,\n marker?: (marker: VarMarker<N>) => T\n): RichTextNode<T>[] {\n const out: RichTextNode<T>[] = [];\n for (const item of groupRuns(children)) {\n if ('run' in item) {\n for (const part of item.run.parts) {\n if ('text' in part) out.push({ text: part.text.nodeValue ?? '' });\n else {\n out.push(marker ? { children: [{ param: part.marker.name }], payload: marker(part.marker) } : { param: part.marker.name });\n if (!(part.marker.name in values)) {\n values[part.marker.name] = normalizeTokenText(part.marker.value.map((node) => node.nodeValue ?? '').join(''));\n }\n }\n }\n continue;\n }\n const node = item.node;\n if (node.nodeType === TEXT) out.push({ text: node.nodeValue ?? '' });\n else if (node.nodeType === ELEMENT) {\n const opaque = isOpaqueInPhrase(node as unknown as AttributeReader);\n const children = opaque && exclude ? [] : toRichNodes(node.childNodes as ArrayLike<N>, payload, values, exclude, marker);\n out.push({ children, payload: payload(node, opaque) });\n }\n }\n return out;\n}\n\n/**\n * The key a phrase holding an opaque element was registered under before TOK-1 bound\n * this path, with its slots and values, or null when it holds none and so has one key.\n * Lookup only: a phrase renders a translation found under it and registers only its\n * current key.\n */\nexport function earlierRichPhrase<N extends MarkerNode, T>(\n children: ArrayLike<N>,\n payload: (element: N, opaque: boolean) => T\n): { phrase: string; slots: T[]; values: Record<string, string> } | null {\n let holds = false;\n const values: Record<string, string> = {};\n const nodes = toRichNodes(children, (element, opaque) => ((holds ||= opaque), payload(element, opaque)), values, false);\n return holds ? { ...encodeRichPhrase(nodes), values } : null;\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "langsys-js-typescript",
3
- "version": "0.6.4",
4
- "description": "Framework-agnostic TypeScript SDK for Langsys translation management — realtime continuous translations with automatic token discovery.",
3
+ "version": "0.7.0",
4
+ "description": "Framework-agnostic TypeScript SDK for Langsys translation management \u2014 realtime continuous translations with automatic token discovery.",
5
5
  "author": "Langsys",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/langsys/langsys-js-typescript",
@@ -23,7 +23,17 @@
23
23
  "types": "./dist/index.d.ts",
24
24
  "import": "./dist/index.mjs",
25
25
  "require": "./dist/index.js"
26
- }
26
+ },
27
+ "./pure": {
28
+ "types": "./dist/pure.d.ts",
29
+ "import": "./dist/pure.mjs",
30
+ "require": "./dist/pure.js"
31
+ },
32
+ "./browser": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/langsys.browser.mjs"
35
+ },
36
+ "./package.json": "./package.json"
27
37
  },
28
38
  "files": [
29
39
  "dist",
@@ -37,8 +47,12 @@
37
47
  "typecheck": "tsc --noEmit",
38
48
  "test": "vitest run",
39
49
  "test:watch": "vitest",
50
+ "test:no-clone": "vitest run --project no-clone",
40
51
  "prepublishOnly": "npm run build",
41
- "release": "./_dev_/publish.sh"
52
+ "release": "./_dev_/publish.sh",
53
+ "verify:spec": "./_dev_/verify-spec-blob.sh",
54
+ "tally:conformance": "node _dev_/tally-conformance.mjs",
55
+ "pretest": "npm run build"
42
56
  },
43
57
  "keywords": [
44
58
  "i18n",