@spintax/core 0.1.6 → 0.2.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.
- package/CHANGELOG.md +79 -0
- package/dist/index.cjs +58 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +94 -1
- package/dist/index.d.ts +94 -1
- package/dist/index.js +57 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/ast.ts","../src/internal/parser.ts","../src/internal/plurals.ts","../src/internal/validator.ts","../src/internal/extract.ts","../src/internal/errors.ts","../src/internal/neutralize.ts","../src/internal/render.ts","../src/internal/postprocess.ts","../src/internal/pipeline.ts","../src/internal/rng.ts","../src/index.ts"],"names":["PLURAL_PREFIX","INCLUDE_RE","VARIABLE_RE","phpTrim","PHP_LTRIM_RE","PHP_RTRIM_RE","resolveAst","neutralize"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Internal AST for @spintax/core. The public `Ast` (spec §9.2) is the opaque,\n * versioned view; `ParsedAst` is the internal shape carrying the node tree that\n * render/validate/extract/analyze walk. Not a serialization format — never\n * persisted across engine versions.\n *\n * Tree nodes: literal / variable / enumeration / permutation / conditional /\n * plural. Directives are NOT tree nodes (plugin parity):\n * - `#set` is extracted GLOBALLY before the tree is built (line-anchored, like\n * `extract_set_directives`) → {@link ParsedAst.setDefs}; its lines are\n * stripped from the body, so a `#set` on its own line even INSIDE a group is\n * a global definition, not literal text.\n * - `#include` is resolved by the renderer as a post-tree string pass (the\n * plugin's `resolve_includes` runs after enum/perm), so it stays literal in\n * the AST here.\n * Permutation's `<config>` + per-element separators are fully parsed (PR-11b).\n */\n\n/** Bumped only on a breaking change to the node shape (independent of syntax v1). */\nexport const AST_VERSION = 1;\n\n/** Opaque public handle (re-exported as `Ast` from the package index). */\nexport interface Ast {\n readonly astVersion: typeof AST_VERSION;\n}\n\n/** Internal parsed tree. Carries the original source so validate(Ast) can do\n * the raw-text checks (bracket balance etc.) and future offset diagnostics, and\n * the globally-extracted `#set` definitions (name → raw value, name lowercased). */\nexport interface ParsedAst extends Ast {\n readonly source: string;\n readonly setDefs: Readonly<Record<string, string>>;\n readonly nodes: readonly Node[];\n}\n\nexport type Node =\n | LiteralNode\n | VariableNode\n | EnumerationNode\n | PermutationNode\n | ConditionalNode\n | PluralNode;\n\n/** Verbatim text. */\nexport interface LiteralNode {\n readonly type: 'literal';\n readonly value: string;\n}\n\n/** `%name%` reference (name stored verbatim; lookup is case-insensitive at render). */\nexport interface VariableNode {\n readonly type: 'variable';\n readonly name: string;\n}\n\n/** `{a|b|c}` — pick one option. Each option is a node sequence. */\nexport interface EnumerationNode {\n readonly type: 'enumeration';\n readonly options: readonly (readonly Node[])[];\n}\n\n/**\n * `[<config>a|b|c]` — select/shuffle/join. PR-10 captures the raw inner\n * verbatim; PR-11 extracts the `<config>` prefix FIRST (before splitting, so a\n * `|` inside a quoted separator like `sep=\"|\"` isn't a false split — matching\n * the plugin's `extract_permutation_config` → `split_top_level` order) and\n * parses the per-element separators + option node sequences.\n */\n/** Permutation `<config>` (parsed in PR-11b). `null` size ⇒ default rules at render (§4.2). */\nexport interface PermConfig {\n readonly minsize: number | null;\n readonly maxsize: number | null;\n readonly sep: string;\n readonly lastsep: string | null;\n}\n\n/** One permutation element + its per-element separator (a trailing `<sep>` from the PREVIOUS part). */\nexport interface PermOption {\n readonly nodes: readonly Node[];\n readonly separator: string | null;\n}\n\nexport interface PermutationNode {\n readonly type: 'permutation';\n readonly config: PermConfig;\n readonly options: readonly PermOption[];\n}\n\n/**\n * `{?VAR?then|else}` / `{?!VAR?then}` — show `then` when VAR is truthy (or falsy\n * if `inverted`), else `else`. A malformed `{?…}` is NOT a conditional: the\n * parser falls back to treating the braces as an enumeration (matching the\n * plugin, where a bad conditional survives the conditional pass unchanged and\n * is then consumed by the enumeration pass).\n */\nexport interface ConditionalNode {\n readonly type: 'conditional';\n readonly name: string;\n readonly inverted: boolean;\n readonly then: readonly Node[];\n readonly else: readonly Node[];\n}\n\n/**\n * `{plural <count>: one|few|many}`. Both slots are kept RAW (they may hold\n * `%var%`): the renderer expands variables in them first (plurals run after\n * var-expansion, before enum/perm), then splits/checks/pick. The lenient path\n * (nested `{}`/`[]` in a form, or arity mismatch) re-emits\n * `{plural <countRaw>:<formsRaw>}` with fullwidth braces (U+FF5B/FF5D).\n * Discriminated by the literal `{plural ` prefix + a `:`.\n */\nexport interface PluralNode {\n readonly type: 'plural';\n readonly countRaw: string;\n readonly formsRaw: string;\n}\n\n/** Depth-first walk over every node, descending into all child sequences. */\nexport function walk(nodes: readonly Node[], visit: (n: Node) => void): void {\n for (const n of nodes) {\n visit(n);\n switch (n.type) {\n case 'enumeration':\n for (const opt of n.options) walk(opt, visit);\n break;\n case 'conditional':\n walk(n.then, visit);\n walk(n.else, visit);\n break;\n case 'permutation':\n for (const opt of n.options) walk(opt.nodes, visit);\n break;\n default:\n break; // literal / variable / plural (raw slots): no child nodes\n }\n }\n}\n\n/** Type guard: is this an internal ParsedAst produced by this engine version? */\nexport function isParsedAst(value: unknown): value is ParsedAst {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { astVersion?: unknown }).astVersion === AST_VERSION &&\n typeof (value as { source?: unknown }).source === 'string' &&\n Array.isArray((value as { nodes?: unknown }).nodes)\n );\n}\n","/**\n * Recursive-descent parser: template string → {@link ParsedAst}.\n *\n * Lenient by contract (spec §9.2): never throws on malformed markup. Unmatched\n * brackets, malformed `{?…}` / `{plural …}`, and bare `%` degrade gracefully\n * (bad conditional/plural fall back to an enumeration, exactly as the plugin's\n * later passes would consume them). Structural *diagnostics* are the validator's\n * job (PR-12), not the parser's.\n *\n * `#set` is extracted GLOBALLY before the tree is built ({@link extractSetDirectives},\n * line-anchored like the plugin's `extract_set_directives`), so a `#set` on its\n * own line even inside a `{…}`/`[…]` group is a global definition — matching the\n * plugin's brace-oblivious `/m` extraction — not literal text. `#include` stays\n * literal here; the renderer resolves it as a post-tree string pass (like the\n * plugin's post-enum `resolve_includes`).\n */\nimport { AST_VERSION, type Node, type ParsedAst, type PermConfig, type PermOption } from './ast';\n\nconst VARIABLE_RE = /^%(\\w+)%/;\n// `\\r?` before the multiline `$` so a CRLF line strips cleanly (JS `.` excludes \\r).\nconst SET_DIRECTIVE_RE = /^[ \\t]*#set[ \\t]+%(\\w+)%[ \\t]*=[ \\t]*(.*?)[ \\t]*\\r?$/gmu;\nconst CONDITIONAL_NAME_RE = /^[A-Za-z_]\\w*/;\nconst PLURAL_PREFIX = 'plural ';\n\n/** Parse a full template into an AST (comments stripped + `#set` extracted first). */\nexport function parseTemplate(src: string): ParsedAst {\n const { body, setDefs } = extractSetDirectives(stripComments(src));\n return { astVersion: AST_VERSION, source: src, setDefs, nodes: parseSequence(body) };\n}\n\n/**\n * Global `#set` extraction (parity with `extract_set_directives`): pull every\n * line-anchored `#set %name% = value` out of the text — regardless of brace\n * nesting — collecting name→value (name lowercased), strip the lines, then\n * collapse `\\n{3,}`→`\\n\\n`. Whitespace is `[ \\t]` (not `\\s`) so a directive is a\n * single line.\n */\nexport function extractSetDirectives(text: string): { body: string; setDefs: Record<string, string> } {\n const setDefs: Record<string, string> = {};\n SET_DIRECTIVE_RE.lastIndex = 0;\n const stripped = text.replace(SET_DIRECTIVE_RE, (_full: string, name: string, value: string): string => {\n setDefs[name.toLowerCase()] = value;\n return '';\n });\n return { body: stripped.replace(/\\n{3,}/gu, '\\n\\n'), setDefs };\n}\n\n/** Remove `/# … #/` block comments (non-greedy, spans newlines). */\nexport function stripComments(text: string): string {\n return text.replace(/\\/#[\\s\\S]*?#\\//g, '');\n}\n\n/** Parse a run of text into a node sequence (construct parsing only — no comment\n * strip / #set extraction; the renderer uses this to re-process variable values). */\nexport function parseSequence(text: string): Node[] {\n const nodes: Node[] = [];\n let literal = '';\n let i = 0;\n\n const flushLiteral = (): void => {\n if (literal !== '') {\n nodes.push({ type: 'literal', value: literal });\n literal = '';\n }\n };\n\n while (i < text.length) {\n const ch = text.charAt(i);\n\n if (ch === '{') {\n const end = findMatchingClose(text, i, '{', '}');\n if (end === -1) {\n literal += ch;\n i += 1;\n continue;\n }\n const content = text.slice(i + 1, end);\n flushLiteral();\n nodes.push(parseBraceConstruct(content));\n i = end + 1;\n continue;\n }\n\n if (ch === '[') {\n const end = findMatchingClose(text, i, '[', ']');\n if (end === -1) {\n literal += ch;\n i += 1;\n continue;\n }\n flushLiteral();\n nodes.push(parsePermutation(text.slice(i + 1, end)));\n i = end + 1;\n continue;\n }\n\n if (ch === '%') {\n const name = VARIABLE_RE.exec(text.slice(i))?.[1];\n if (name !== undefined) {\n flushLiteral();\n nodes.push({ type: 'variable', name });\n i += name.length + 2; // \"%\" + name + \"%\"\n continue;\n }\n }\n\n literal += ch;\n i += 1;\n }\n\n flushLiteral();\n return nodes;\n}\n\n/**\n * Decide what a `{…}` (content between the braces) is: a conditional (`?…`), a\n * plural (`plural …:` …), or — the default and the fallback for a malformed\n * conditional — an enumeration.\n */\nfunction parseBraceConstruct(content: string): Node {\n if (content.charAt(0) === '?') {\n const cond = tryParseConditional(content);\n if (cond) return cond;\n // Malformed conditional ⇒ fall back to enumeration (plugin parity).\n } else if (content.startsWith(PLURAL_PREFIX) && content.slice(PLURAL_PREFIX.length).includes(':')) {\n return parsePlural(content.slice(PLURAL_PREFIX.length));\n }\n return { type: 'enumeration', options: splitTopLevel(content).map((o) => parseSequence(o)) };\n}\n\n/** Parse `?VAR?then|else` / `?!VAR?then` (content starts with `?`), or null if malformed. */\nfunction tryParseConditional(content: string): Node | null {\n let p = 1; // past the leading '?'\n let inverted = false;\n if (content.charAt(p) === '!') {\n inverted = true;\n p += 1;\n }\n\n const name = CONDITIONAL_NAME_RE.exec(content.slice(p))?.[0];\n if (name === undefined) return null;\n p += name.length;\n\n if (content.charAt(p) !== '?') return null; // required '?' after the name\n p += 1;\n\n const body = content.slice(p);\n const sep = firstTopLevelPipe(body);\n const thenRaw = sep < 0 ? body : body.slice(0, sep);\n const elseRaw = sep < 0 ? '' : body.slice(sep + 1);\n\n return {\n type: 'conditional',\n name,\n inverted,\n then: parseSequence(thenRaw),\n else: parseSequence(elseRaw),\n };\n}\n\n/** Parse `<count>: forms` (the part after the `plural ` prefix). */\nfunction parsePlural(afterPrefix: string): Node {\n const colon = afterPrefix.indexOf(':');\n // Count + raw forms are kept as strings; the renderer expands variables in them\n // FIRST (Stage 6d runs after var-expansion, before enum/perm), then splits/checks.\n return { type: 'plural', countRaw: afterPrefix.slice(0, colon), formsRaw: afterPrefix.slice(colon + 1) };\n}\n\n// ─── Permutation parsing (config + per-element separators) ────────────────────\n\nconst CONFIG_KEY_RE = /\\b(?:minsize|maxsize|sep|lastsep)\\s*=/i;\nconst MINSIZE_RE = /minsize\\s*=\\s*(\\d+)/i;\nconst MAXSIZE_RE = /maxsize\\s*=\\s*(\\d+)/i;\nconst SEP_RE = /(?<!last)sep\\s*=\\s*\"([^\"]*)\"/i; // negative lookbehind excludes \"lastsep\"\nconst LASTSEP_RE = /lastsep\\s*=\\s*\"([^\"]*)\"/i;\nconst HTML_TAG_RE = /^([a-zA-Z][a-zA-Z0-9-]*)(?:\\s+[^>]*)?\\/?$/;\nconst PER_ELEM_HTML_RE = /^[a-zA-Z][a-zA-Z0-9]*\\s/;\n\nfunction defaultPermConfig(): PermConfig {\n return { minsize: null, maxsize: null, sep: ' ', lastsep: null };\n}\n\n/** Parse a permutation body `[<config>a|b|c]` inner → config + options with per-element seps. */\nfunction parsePermutation(rawInner: string): Node {\n const { config, content } = extractPermutationConfig(rawInner);\n const options = extractPerElementSeparators(splitTopLevel(content));\n return { type: 'permutation', config, options };\n}\n\n/** Split a leading `<config>` off the body (config is extracted BEFORE the top-level split). */\nfunction extractPermutationConfig(content: string): { config: PermConfig; content: string } {\n const trimmed = phpLtrim(content);\n if (trimmed === '' || trimmed.charAt(0) !== '<') {\n return { config: defaultPermConfig(), content };\n }\n const end = findConfigEnd(trimmed);\n if (end === -1) return { config: defaultPermConfig(), content };\n\n const configStr = trimmed.slice(1, end);\n const remaining = trimmed.slice(end + 1);\n // A leading `<li>…</li>`-style tag is HTML, not config.\n if (looksLikeHtmlStartTag(configStr, remaining)) {\n return { config: defaultPermConfig(), content };\n }\n return { config: parseConfigString(configStr), content: remaining };\n}\n\n/** Index of the closing `>` of a `<…>` config, respecting quoted strings; -1 if none. */\nfunction findConfigEnd(text: string): number {\n let inQuote = false;\n for (let i = 1; i < text.length; i += 1) {\n const ch = text.charAt(i);\n if (ch === '\"') inQuote = !inQuote;\n if (ch === '>' && !inQuote) return i;\n }\n return -1;\n}\n\nfunction parseConfigString(str: string): PermConfig {\n if (!CONFIG_KEY_RE.test(str)) {\n // Single-separator form: the whole string is sep (and lastsep).\n return { minsize: null, maxsize: null, sep: str, lastsep: str };\n }\n return {\n minsize: intGroup(MINSIZE_RE.exec(str)),\n maxsize: intGroup(MAXSIZE_RE.exec(str)),\n sep: strGroup(SEP_RE.exec(str)) ?? ' ',\n lastsep: strGroup(LASTSEP_RE.exec(str)),\n };\n}\n\nfunction looksLikeHtmlStartTag(tagText: string, remaining: string): boolean {\n const trimmed = phpTrim(tagText);\n if (trimmed === '') return false;\n const m = HTML_TAG_RE.exec(trimmed);\n if (!m) return false;\n if (trimmed.endsWith('/')) return true; // self-closing\n const tagName = (m[1] ?? '').toLowerCase();\n return new RegExp(`</${escapeRegExp(tagName)}\\\\s*>`, 'iu').test(remaining);\n}\n\n/**\n * Turn raw split parts into elements, moving a trailing `<sep>` on part[i] to be\n * the per-element separator of the element from part[i+1]. Each element's text is\n * trimmed; empty elements are dropped (plugin `extract_per_element_separators`).\n */\nfunction extractPerElementSeparators(rawParts: string[]): PermOption[] {\n const options: PermOption[] = [];\n let pendingSep: string | null = null;\n\n rawParts.forEach((part, i) => {\n let text = part;\n let trailingSep: string | null = null;\n if (i < rawParts.length - 1) {\n const extracted = extractTrailingSep(part);\n if (extracted) {\n text = extracted.text;\n trailingSep = extracted.sep;\n }\n }\n const trimmed = phpTrim(text);\n if (trimmed !== '') {\n options.push({ nodes: parseSequence(trimmed), separator: pendingSep });\n }\n pendingSep = trailingSep;\n });\n\n return options;\n}\n\n/** Detect a trailing `< sep >` on a part (not an HTML tag). Returns {text, sep} or null. */\nfunction extractTrailingSep(part: string): { text: string; sep: string } | null {\n const trimmed = phpRtrim(part);\n const len = trimmed.length;\n if (len === 0 || trimmed.charAt(len - 1) !== '>') return null;\n\n let openPos = -1;\n for (let i = len - 2; i >= 0; i -= 1) {\n const ch = trimmed.charAt(i);\n if (ch === '<') {\n openPos = i;\n break;\n }\n if (ch === '>') return null; // nested/complex, bail\n }\n if (openPos === -1) return null;\n\n const inner = trimmed.slice(openPos + 1, len - 1);\n const innerTrimmed = phpTrim(inner);\n // HTML tag → not a separator: closing </x>, self-closing <x/>, or tag-with-attrs `<x …>`.\n if (innerTrimmed.startsWith('/') || innerTrimmed.endsWith('/') || PER_ELEM_HTML_RE.test(innerTrimmed)) {\n return null;\n }\n return { text: trimmed.slice(0, openPos), sep: inner };\n}\n\nfunction intGroup(m: RegExpExecArray | null): number | null {\n return m && m[1] !== undefined ? Number.parseInt(m[1], 10) : null;\n}\nfunction strGroup(m: RegExpExecArray | null): string | null {\n return m && m[1] !== undefined ? m[1] : null;\n}\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/gu, '\\\\$&');\n}\n\n// PHP trim strips only [ \\t\\n\\r\\0\\x0B] — NOT the full JS Unicode whitespace set —\n// so use these for byte-exact parity wherever the plugin trims (permutation\n// config / element text / separators, plural forms).\nconst PHP_LTRIM_RE = /^[ \\t\\n\\r\\0\\x0B]+/u;\nconst PHP_RTRIM_RE = /[ \\t\\n\\r\\0\\x0B]+$/u;\nfunction phpTrim(s: string): string {\n return s.replace(PHP_LTRIM_RE, '').replace(PHP_RTRIM_RE, '');\n}\nfunction phpLtrim(s: string): string {\n return s.replace(PHP_LTRIM_RE, '');\n}\nfunction phpRtrim(s: string): string {\n return s.replace(PHP_RTRIM_RE, '');\n}\n\n/**\n * Index of the `close` that matches the `open` at `openPos`, tracking depth of\n * this bracket pair only. Returns -1 if unmatched.\n */\nfunction findMatchingClose(text: string, openPos: number, open: string, close: string): number {\n let depth = 0;\n for (let i = openPos; i < text.length; i += 1) {\n const ch = text.charAt(i);\n if (ch === open) {\n depth += 1;\n } else if (ch === close) {\n depth -= 1;\n if (depth === 0) return i;\n }\n }\n return -1;\n}\n\n/**\n * Split on top-level `|` — mirrors the plugin's `split_top_level`: brace and\n * bracket depths tracked INDEPENDENTLY and decremented UNCONDITIONALLY (may go\n * negative), split only when BOTH are exactly 0. So `a]|b` stays one option.\n */\nexport function splitTopLevel(inner: string): string[] {\n const parts: string[] = [];\n let brace = 0;\n let bracket = 0;\n let cur = '';\n for (const ch of inner) {\n if (ch === '{') brace += 1;\n else if (ch === '}') brace -= 1;\n else if (ch === '[') bracket += 1;\n else if (ch === ']') bracket -= 1;\n\n if (ch === '|' && brace === 0 && bracket === 0) {\n parts.push(cur);\n cur = '';\n } else {\n cur += ch;\n }\n }\n parts.push(cur);\n return parts;\n}\n\n/**\n * Index of the first top-level `|` in a conditional body, or -1. Uses a single\n * depth counter CLAMPED at 0 (matching the plugin's `parse_conditional` body\n * split, which differs from `split_top_level`'s signed dual counters).\n */\nfunction firstTopLevelPipe(body: string): number {\n let depth = 0;\n for (let j = 0; j < body.length; j += 1) {\n const ch = body.charAt(j);\n if (ch === '{' || ch === '[') {\n depth += 1;\n } else if (ch === '}' || ch === ']') {\n if (depth > 0) depth -= 1;\n } else if (ch === '|' && depth === 0) {\n return j;\n }\n }\n return -1;\n}\n","/**\n * Locale plural rules — ported from the plugin's `Plurals` (parity item §3.1).\n * Shared by the validator (arity check, PR-12) and the renderer (bucket pick, M2).\n */\n\nconst PLURAL_PREFIX = '{plural ';\n\nexport interface PluralBlock {\n readonly start: number;\n /** Exclusive end offset — one past the block's closing `}` (for diagnostics). */\n readonly end: number;\n readonly countSlot: string;\n readonly formsRaw: string;\n}\n\n/**\n * Raw brace-aware scan for `{plural …}` blocks — ported from the plugin's\n * `find_plural_blocks`. Used by the validator (and available to the renderer).\n * Scans the whole text, so it finds plurals nested inside `[…]` permutations too\n * (the AST leaves a permutation body unparsed until PR-11b). A block without a\n * `:` is not a plural (left to the enumeration path).\n */\nexport function findPluralBlocks(text: string): PluralBlock[] {\n const blocks: PluralBlock[] = [];\n let i = 0;\n while (i < text.length) {\n const start = text.indexOf(PLURAL_PREFIX, i);\n if (start === -1) break;\n\n let depth = 1;\n let j = start + PLURAL_PREFIX.length;\n while (j < text.length) {\n const ch = text.charAt(j);\n if (ch === '{') depth += 1;\n else if (ch === '}') {\n depth -= 1;\n if (depth === 0) break;\n }\n j += 1;\n }\n if (depth !== 0) {\n i = start + PLURAL_PREFIX.length; // unmatched opening — skip past prefix\n continue;\n }\n\n const inner = text.slice(start + PLURAL_PREFIX.length, j);\n const colon = inner.indexOf(':');\n if (colon === -1) {\n i = j + 1; // no colon ⇒ not a plural\n continue;\n }\n blocks.push({ start, end: j + 1, countSlot: inner.slice(0, colon), formsRaw: inner.slice(colon + 1) });\n i = j + 1;\n }\n return blocks;\n}\n\n/** Normalise a locale to its base language tag: `pt-BR`→`pt`, `uk_UA`→`uk`, `RU`→`ru`. */\nexport function normalizeBaseLang(locale: string): string {\n const first = locale.toLowerCase().split(/[-_]/, 1)[0];\n return first ?? '';\n}\n\n/** Expected number of plural forms: 3 for East Slavic (ru/uk/be), else 2 (EN-style). */\nexport function pluralArity(baseLang: string): number {\n switch (baseLang) {\n case 'ru':\n case 'uk':\n case 'be':\n return 3;\n default:\n return 2;\n }\n}\n\n/**\n * Pick the plural form for a count by the locale's grammar.\n * - East Slavic: one (1,21,31… not 11), few (2-4,22-24… not 12-14), many (rest, incl. 0).\n * - EN-style: one (n=1), many (rest). Negative counts use abs().\n */\nexport function pluralFor(baseLang: string, n: number, forms: readonly string[]): string {\n const abs = Math.abs(n);\n const mod10 = abs % 10;\n const mod100 = abs % 100;\n\n switch (baseLang) {\n case 'ru':\n case 'uk':\n case 'be':\n if (mod10 === 1 && mod100 !== 11) return forms[0] ?? '';\n if (mod10 >= 2 && mod10 <= 4 && (mod100 < 12 || mod100 > 14)) return forms[1] ?? '';\n return forms[2] ?? '';\n default:\n return (abs === 1 ? forms[0] : forms[1]) ?? '';\n }\n}\n","/**\n * Static validator — ported from the plugin's `Validator` (parity gate §3.1).\n * Produces {@link Diagnostic}[] with the canonical, stable codes documented in\n * `@spintax/conformance`'s README. \"Valid\" ⇔ no `severity:'error'`.\n *\n * Bracket balance is a raw char scan (the lenient AST doesn't represent\n * imbalance). Plural and #include checks walk the AST. Positions are best-effort\n * — not parity-gated (§3.1): only `code` (+ severity) is.\n *\n * Circular `#include` is NOT a verdict here — it is a render-time maxDepth guard\n * (the plugin's validator never resolves includes).\n */\nimport type { Diagnostic, ValidateOptions } from '../index';\nimport { stripComments } from './parser';\nimport { findPluralBlocks, normalizeBaseLang, pluralArity } from './plurals';\n\nconst KNOWN_CONFIG_KEYS = new Set(['minsize', 'maxsize', 'sep', 'lastsep']);\nconst INCLUDE_RE = /^[ \\t]*#include[ \\t\\n\\r\\f\\x0B]+\"([^\"]+)\"[ \\t\\n\\r\\f\\x0B]*$/gmu; // ASCII \\s (PHP parity)\n\n/**\n * Pure raw-text validation — exactly like the plugin's `Validator` (which does\n * NOT build an AST). Scanning the raw text (not the lenient AST) is what lets\n * bracket imbalance and constructs nested inside `[…]` permutations be seen.\n */\nexport function validateTemplate(src: string, opts: ValidateOptions = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const text = stripComments(src);\n\n checkBrackets(text, diagnostics);\n checkSetDirectives(text, diagnostics);\n checkPermutationConfigs(text, diagnostics);\n checkPlurals(text, opts.locale, diagnostics);\n checkVariableReferences(text, opts.knownVariables, diagnostics);\n if (opts.knownIncludes && opts.knownIncludes.length > 0) {\n checkIncludeTargets(text, opts.knownIncludes, diagnostics);\n }\n\n return diagnostics;\n}\n\n/** Position (+ optional end and structured data) attached to a Diagnostic. */\ninterface Pos { line: number; column: number; endLine?: number; endColumn?: number; data?: Record<string, unknown> }\n\nfunction err(code: string, message: string, pos: Pos): Diagnostic {\n return { severity: 'error', code, message, ...pos };\n}\nfunction warn(code: string, message: string, pos: Pos): Diagnostic {\n return { severity: 'warning', code, message, ...pos };\n}\n\n/** 1-based (line, column) of a character offset. */\nfunction offsetToLineCol(text: string, offset: number): { line: number; column: number } {\n let line = 1;\n let lineStart = 0;\n const end = Math.min(Math.max(offset, 0), text.length);\n for (let i = 0; i < end; i += 1) {\n if (text.charAt(i) === '\\n') { line += 1; lineStart = i + 1; }\n }\n return { line, column: end - lineStart + 1 };\n}\n\n/** A full [offset, offset+length) span as start + end positions. */\nfunction span(text: string, offset: number, length: number): Pos {\n const s = offsetToLineCol(text, offset);\n const e = offsetToLineCol(text, offset + length);\n return { line: s.line, column: s.column, endLine: e.line, endColumn: e.column };\n}\n\n/** Balanced `{}`/`[]` with proper nesting (raw char scan, real line/col). */\nfunction checkBrackets(text: string, out: Diagnostic[]): void {\n const close: Record<string, string> = { '{': '}', '[': ']' };\n const stack: Array<{ char: string; expect: string; line: number; column: number }> = [];\n let line = 1;\n let column = 1;\n\n for (const ch of text) {\n if (ch === '\\n') {\n line += 1;\n column = 1;\n continue;\n }\n if (ch === '{' || ch === '[') {\n stack.push({ char: ch, expect: close[ch]!, line, column });\n } else if (ch === '}' || ch === ']') {\n const top = stack.pop();\n if (top === undefined) {\n out.push(err('bracket.unexpected-closing', `Unexpected closing '${ch}'.`, { line, column, endLine: line, endColumn: column + 1, data: { bracket: ch } }));\n } else if (top.expect !== ch) {\n out.push(err('bracket.mismatched', `'${top.char}' closed by '${ch}'.`, { line, column, endLine: line, endColumn: column + 1, data: { open: top.char, close: ch } }));\n }\n }\n column += 1;\n }\n\n for (const unclosed of stack) {\n out.push(err('bracket.unclosed', `Unclosed '${unclosed.char}'.`, { line: unclosed.line, column: unclosed.column, endLine: unclosed.line, endColumn: unclosed.column + 1, data: { bracket: unclosed.char } }));\n }\n}\n\n/** `#set` lines must match `#set %name% = value`. */\nfunction checkSetDirectives(text: string, out: Diagnostic[]): void {\n const lines = text.split('\\n');\n lines.forEach((lineText, idx) => {\n const trimmed = lineText.replace(/^[ \\t]+/, '');\n if (!trimmed.startsWith('#set ') && !trimmed.startsWith('#set\\t')) return;\n if (!/^#set\\s+%(\\w+)%\\s*=\\s*(.+)$/u.test(trimmed)) {\n const column = lineText.length - trimmed.length + 1; // first non-space char\n const line = idx + 1;\n out.push(err('set.malformed', 'Malformed #set. Expected: #set %name% = value', { line, column, endLine: line, endColumn: lineText.length + 1 }));\n }\n });\n}\n\n/** `[<config>]` prefixes: known keys only, minsize/maxsize must be digit runs. */\nfunction checkPermutationConfigs(text: string, out: Diagnostic[]): void {\n for (const m of text.matchAll(/\\[<([^>]*?)>/gu)) {\n const configStr = m[1] ?? '';\n if (!/\\w+\\s*=/.test(configStr)) continue; // not a key=value config\n const configBase = (m.index ?? 0) + 2; // offset of configStr in text (past \"[<\")\n\n for (const km of configStr.matchAll(/(\\w+)\\s*=/gu)) {\n const key = (km[1] ?? '').toLowerCase();\n if (!KNOWN_CONFIG_KEYS.has(key)) {\n out.push(err('permutation.unknown-key', `Unknown permutation config key: '${km[1]}'.`,\n { ...span(text, configBase + (km.index ?? 0), (km[1] ?? '').length), data: { key: km[1] } }));\n }\n }\n const min = /minsize\\s*=\\s*([^;>\\s]+)/i.exec(configStr);\n if (min && !/^\\d+$/.test(min[1] ?? '')) {\n out.push(err('permutation.minsize-not-integer', `minsize must be a positive integer, got '${min[1]}'.`,\n { ...span(text, configBase + min.index, min[0].length), data: { value: min[1] } }));\n }\n const max = /maxsize\\s*=\\s*([^;>\\s]+)/i.exec(configStr);\n if (max && !/^\\d+$/.test(max[1] ?? '')) {\n out.push(err('permutation.maxsize-not-integer', `maxsize must be a positive integer, got '${max[1]}'.`,\n { ...span(text, configBase + max.index, max[0].length), data: { value: max[1] } }));\n }\n }\n}\n\n/** `{plural …}`: no nested brackets in forms; form count matches locale arity. */\nfunction checkPlurals(text: string, locale: string | undefined, out: Diagnostic[]): void {\n // Guard on the NORMALIZED base (like the plugin): a non-empty locale that\n // normalizes to '' (e.g. \"_en\") skips the arity check.\n const base = locale && locale !== '' ? normalizeBaseLang(locale) : '';\n const arity = base !== '' ? pluralArity(base) : 0;\n\n for (const block of findPluralBlocks(text)) {\n const at = span(text, block.start, block.end - block.start);\n if (/[{}[\\]]/.test(block.formsRaw)) {\n out.push(err('plural.nested-brackets', '{plural ...}: forms must not contain nested spintax brackets.', at));\n continue;\n }\n if (arity > 0) {\n const count = block.formsRaw.split('|').length;\n if (count !== arity) {\n out.push(err('plural.arity', `{plural ...}: expected ${arity} forms, got ${count}.`,\n { ...at, data: { expected: arity, got: count } }));\n }\n }\n }\n}\n\n/** Self-reference + circular `#set` (errors) and undefined `%var%`/conditional refs (warnings). */\nfunction checkVariableReferences(text: string, known: readonly string[] | undefined, out: Diagnostic[]): void {\n const knownSet = new Set((known ?? []).map((n) => n.toLowerCase()));\n // `[ \\t]` (single-line), uniform with the parser's extract_set_directives and\n // extract.ts — so a malformed cross-line `#set` isn't treated as a definition.\n const defs = new Map<string, string>();\n const defPos = new Map<string, Pos>(); // %name% token span in its #set line\n for (const m of text.matchAll(/^[ \\t]*#set[ \\t]+%(\\w+)%[ \\t]*=[ \\t]*(.*?)$/gmu)) {\n const name = (m[1] ?? '').toLowerCase();\n defs.set(name, m[2] ?? '');\n const nameOffset = (m.index ?? 0) + m[0].indexOf('%');\n defPos.set(name, span(text, nameOffset, name.length + 2));\n }\n\n const somewhere: Pos = { line: 1, column: 1 };\n for (const [name, value] of defs) {\n if (value.toLowerCase().includes(`%${name}%`)) {\n out.push(err('variable.self-reference', `Variable '${name}' references itself.`, defPos.get(name) ?? somewhere));\n }\n }\n for (const name of defs.keys()) {\n detectCycle(name, defs, [name], defPos.get(name) ?? somewhere, out);\n }\n\n // Blank #set lines to same-length whitespace so ref offsets still map to `text`\n // (a bare removal would shift every later column).\n const body = text.replace(/^[ \\t]*#set[ \\t]+%\\w+%[ \\t]*=[ \\t]*.*?$/gmu, (m) => m.replace(/[^\\n]/g, ' '));\n const seen = new Set<string>();\n const undefinedAt = (name: string, offset: number, length: number): void => {\n const key = name.toLowerCase();\n if (defs.has(key) || knownSet.has(key) || seen.has(key)) return;\n seen.add(key);\n out.push(warn('variable.undefined', `Variable '${name}' is not defined — may be a runtime variable.`,\n { ...span(text, offset, length), data: { name } }));\n };\n for (const m of body.matchAll(/%(\\w+)%/gu)) undefinedAt(m[1] ?? '', m.index ?? 0, m[0].length);\n for (const m of body.matchAll(/\\{\\?!?([A-Za-z_]\\w*)\\?/gu)) {\n undefinedAt(m[1] ?? '', (m.index ?? 0) + m[0].indexOf(m[1] ?? ''), (m[1] ?? '').length);\n }\n}\n\nfunction detectCycle(current: string, defs: Map<string, string>, visited: string[], rootPos: Pos, out: Diagnostic[]): void {\n const value = defs.get(current) ?? '';\n for (const m of value.matchAll(/%(\\w+)%/gu)) {\n const ref = (m[1] ?? '').toLowerCase();\n if (ref === current) continue; // self-reference already reported\n if (visited.includes(ref)) {\n out.push(err('variable.circular-reference', `Circular variable reference: ${[...visited, ref].join(' → ')}.`, rootPos));\n return;\n }\n if (defs.has(ref)) detectCycle(ref, defs, [...visited, ref], rootPos, out);\n }\n}\n\n/** Unknown `#include` targets — only when a slug list is supplied. Raw `/m` scan. */\nfunction checkIncludeTargets(text: string, known: readonly string[], out: Diagnostic[]): void {\n const set = new Set(known);\n INCLUDE_RE.lastIndex = 0;\n for (const m of text.matchAll(INCLUDE_RE)) {\n const ref = m[1] ?? '';\n if (!set.has(ref)) {\n const refOffset = (m.index ?? 0) + m[0].indexOf('\"') + 1; // inside the quotes\n out.push(err('include.unknown-target', `#include target '${ref}' does not match any known template.`,\n { ...span(text, refOffset, ref.length), data: { target: ref } }));\n }\n }\n}\n","/**\n * Variable / #set / #include enumeration for `extract()` (spec §9.2).\n *\n * Raw-text scan (like the validator) rather than an AST walk, so it is complete:\n * it catches `%var%` inside a `{plural <count>: …}` count slot and inside a\n * `[…]` permutation body — both of which the AST leaves as raw strings. The\n * `#set` definition target (`#set %name% =` LHS) is a *definition*, not a\n * reference, so it is stripped before collecting `refs`.\n *\n * Variable names (`refs`, `sets`) are LOWER-CASED — the engine's variable\n * identity is case-insensitive, so cross-referencing sets against refs (the\n * two-phase-include / host-provisioning use) works. `includes` slugs are left\n * as authored (host-resolved, not case-folded). Arrays are de-duplicated;\n * order is insertion (the corpus compares order-normalized).\n *\n * NOTE (best-effort on malformed input): the conditional-name scan keys off the\n * `{?NAME?` prefix without requiring the brace to close, so an unclosed\n * `{?foo?…` yields a phantom `foo` ref. Acceptable for an extraction API.\n */\nimport { stripComments } from './parser';\n\nexport interface ExtractResult {\n refs: string[];\n sets: string[];\n includes: string[];\n}\n\n// `#set` uses [ \\t] (single-line), matching the parser / extract_set_directives —\n// NOT \\s, which would let a malformed multi-line `#set` be read as a definition.\nconst SET_DEF_RE = /^[ \\t]*#set[ \\t]+%(\\w+)%[ \\t]*=/gmu;\nconst SET_LHS_RE = /^[ \\t]*#set[ \\t]+%\\w+%[ \\t]*=/gmu;\nconst INCLUDE_RE = /^[ \\t]*#include[ \\t\\n\\r\\f\\x0B]+\"([^\"]+)\"[ \\t\\n\\r\\f\\x0B]*$/gmu; // ASCII \\s (PHP parity)\nconst VARIABLE_RE = /%(\\w+)%/gu;\nconst CONDITIONAL_REF_RE = /\\{\\?!?([A-Za-z_]\\w*)\\?/gu;\n\nexport function extractFromSource(src: string): ExtractResult {\n const text = stripComments(src);\n\n const sets = collect(text, SET_DEF_RE, true);\n const includes = collect(text, INCLUDE_RE, false);\n\n // Drop the `#set … =` LHS (keep the value) so a definition target is not a ref.\n const body = text.replace(SET_LHS_RE, '');\n const refs = new Set<string>();\n addAll(refs, body, VARIABLE_RE, true);\n addAll(refs, body, CONDITIONAL_REF_RE, true);\n\n return { refs: [...refs], sets, includes };\n}\n\nfunction collect(text: string, re: RegExp, fold: boolean): string[] {\n const seen = new Set<string>();\n addAll(seen, text, re, fold);\n return [...seen];\n}\n\nfunction addAll(target: Set<string>, text: string, re: RegExp, fold: boolean): void {\n for (const m of text.matchAll(re)) {\n const value = m[1];\n if (value !== undefined && value !== '') target.add(fold ? value.toLowerCase() : value);\n }\n}\n","/**\n * Error hierarchy for @spintax/core (spec §9.3 — minimal, not a taxonomy).\n * `render()` throws these only on programmer error, never on template content.\n */\n\n/** Base class for programmer-error throws from render(). */\nexport class SpintaxError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SpintaxError';\n }\n}\n\n/** A host-injected includeResolver itself threw. */\nexport class IncludeResolverError extends SpintaxError {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = 'IncludeResolverError';\n if (options && 'cause' in options) {\n (this as { cause?: unknown }).cause = options.cause;\n }\n }\n}\n\n// NOTE: there is deliberately NO MaxDepthExceededError. Exceeding maxDepth\n// (circular / too-deep #include, runaway variable recursion) is LENIENT — the\n// guard resolves to '' rather than throwing, matching the plugin (which logs +\n// returns ''). render() throwing on a depth breach would break the lenient\n// contract, so no such error type is part of the public surface (§9.2/§9.3).\n\n/** An Ast produced by an incompatible engine version was passed back in. */\nexport class AstVersionError extends SpintaxError {\n constructor(message: string) {\n super(message);\n this.name = 'AstVersionError';\n }\n}\n\n/** Thrown by not-yet-implemented ops / node kinds until the engine lands. */\nexport class NotImplementedError extends SpintaxError {\n constructor(what: string) {\n super(`${what} is not implemented yet.`);\n this.name = 'NotImplementedError';\n }\n}\n","/**\n * T2 shielding (§6). Text-safe / context-agnostic — NOT the plugin's HTML-entity\n * encoding (that only round-trips in an HTML sink; this engine targets Telegram /\n * plaintext / CLI too). Structural chars `{ } [ ] % #` map to Private-Use-Area\n * sentinels (U+E000–U+E005) the engine's passes never interpret as markup; the\n * mandatory {@link safetyRestore} (always run, even with postProcess:false) maps\n * them back to their literal glyphs. PUA (not the `\\x00…` scheme post-process\n * uses) so the two shielding mechanisms can't collide.\n *\n * \"Text-safe\" = safe against re-interpretation as spintax markup, NOT against an\n * HTML/JS sink — neutralize does not touch `< > &`, so it is not XSS mitigation\n * (an HTML-entity variant is a host concern, §6).\n *\n * RESERVED RANGE: U+E000–U+E005 are engine sentinels. `render()` strips them from\n * author markup (template source + #include results) via {@link stripSentinels}\n * and rewrites them in output, so a RAW (non-neutralized) context value carrying\n * these code points will be altered — hosts should neutralize/strip such data.\n */\nconst STRUCTURAL = ['{', '}', '[', ']', '%', '#'] as const;\nconst SENTINEL_BASE = 0xe000;\n\nconst SHIELD = new Map<string, string>();\nconst RESTORE = new Map<string, string>();\nSTRUCTURAL.forEach((ch, i) => {\n const sentinel = String.fromCharCode(SENTINEL_BASE + i);\n SHIELD.set(ch, sentinel);\n RESTORE.set(sentinel, ch);\n});\n\nconst SHIELD_RE = /[{}[\\]%#]/gu;\nconst RESTORE_RE = new RegExp(\n `[${String.fromCharCode(SENTINEL_BASE)}-${String.fromCharCode(SENTINEL_BASE + STRUCTURAL.length - 1)}]`,\n 'gu',\n);\n\n/** Shield data-derived (T2) input so it can't be re-interpreted as spintax markup. */\nexport function neutralize(value: string): string {\n return value.replace(SHIELD_RE, (ch) => SHIELD.get(ch) ?? ch);\n}\n\n/** Mandatory final stage: restore shielded structural chars to literal glyphs. */\nexport function safetyRestore(text: string): string {\n return text.replace(RESTORE_RE, (ch) => RESTORE.get(ch) ?? ch);\n}\n\n/** Remove stray sentinels from author markup (template / #include) so only\n * neutralize() can introduce them — otherwise safetyRestore would rewrite them. */\nexport function stripSentinels(text: string): string {\n return text.replace(RESTORE_RE, '');\n}\n","/**\n * Tree-walk renderer with the plugin's staged semantics layered on (parity with\n * Renderer::process_template). Not a naive walk — the deterministic stages are\n * reproduced in order:\n * - #set is a global pre-pass (parser) → setDefs; those enum values are\n * COLLAPSED ONCE here (buildVars), skipping values with `{?`/`{plural ` (they\n * reference vars and defer to the body) — plugin Stage 4b.\n * - variables resolve against the merged map (runtime context > #set); a value\n * that itself contains constructs is re-parsed and rendered (recursive, depth\n * capped) — this covers conditionals/plurals introduced by a variable value\n * (Stages 6b–6c), so a separate pre/post conditional pass isn't needed.\n * - conditionals test truthiness against the raw var map; plurals resolve the\n * count (vars already expanded) then pick the bucket, lenient fullwidth\n * fallback (Stage 6d, after vars).\n * - #include (post-tree string pass) and post-process are later PRs.\n *\n * RNG note: cross-engine RNG-sequence parity is a non-goal (§3.2). Enumerations\n * render outer-first and LAZILY (only the picked branch's nested RNG is used) vs\n * the plugin's eager innermost-out; corpus-safe because deterministic nested-enum\n * cases use order-independent sequences. Permutation matches the plugin's exact\n * pick→Fisher-Yates, so its rng-strategy cases are exact.\n */\nimport type { Node, ParsedAst, PermutationNode, PluralNode, ConditionalNode } from './ast';\nimport { IncludeResolverError } from './errors';\nimport { stripSentinels } from './neutralize';\nimport { parseSequence, parseTemplate } from './parser';\nimport { normalizeBaseLang, pluralArity, pluralFor } from './plurals';\nimport type { Rng } from './rng';\n\nconst MAX_VARIABLE_DEPTH = 50;\n// ASCII whitespace only — PHP `\\s` under /u is ASCII; JS `\\s` matches Unicode\n// whitespace (NBSP etc.), which would diverge on exotic input. Parity.\nconst INCLUDE_LINE_RE = /^[ \\t]*#include[ \\t\\n\\r\\f\\x0B]+\"([^\"]+)\"[ \\t\\n\\r\\f\\x0B]*$/gmu;\n\n/** Document-level render context (threads through nested #include resolution). */\nexport interface RenderCtx {\n /** Runtime/host variable map — inherited by child #includes (NOT parent #set). */\n readonly runtimeContext: Readonly<Record<string, string>>;\n readonly rng: Rng;\n readonly locale: string;\n readonly resolver: ((ref: string) => string | null) | undefined;\n readonly maxDepth: number;\n /** #include ref chain for circular-reference detection. */\n readonly includeStack: readonly string[];\n}\n\n/**\n * Render a parsed template: collapse-once #set → tree-walk → resolve #includes\n * (post-tree string pass, like the plugin's Stage 9 resolve_nested, AFTER\n * enum/perm). Post-process (Stage 10) is layered on by the public render().\n */\nexport function renderAst(ast: ParsedAst, ctx: RenderCtx): string {\n const vars = buildVars(ast.setDefs, ctx.runtimeContext, ctx.rng);\n const text = renderNodes(ast.nodes, { vars, rng: ctx.rng, locale: ctx.locale, depth: 0 });\n return ctx.resolver ? resolveIncludes(text, ctx) : text;\n}\n\n/**\n * Replace each `#include \"ref\"` (line-anchored) with the host-resolved child\n * template, rendered with a CHILD scope: inherits runtime context but NOT the\n * parent's #set locals (plugin `for_child_render`). Circular refs / runaway\n * depth resolve to '' (lenient); a resolver that throws surfaces as\n * IncludeResolverError (programmer error).\n *\n * NOTE: cycles are detected by the ref STRING (the engine has no template\n * identity beyond the host-supplied ref, §4.1), so two aliased refs for one\n * template aren't seen as a cycle and recurse until `maxDepth`. `maxDepth` also\n * caps deep ACYCLIC chains (silently → ''), a guard the plugin lacks.\n */\nfunction resolveIncludes(text: string, ctx: RenderCtx): string {\n INCLUDE_LINE_RE.lastIndex = 0;\n return text.replace(INCLUDE_LINE_RE, (_m, ref: string): string => {\n if (ctx.includeStack.includes(ref) || ctx.includeStack.length >= ctx.maxDepth) return '';\n let included: string | null;\n try {\n included = ctx.resolver!(ref);\n } catch (cause) {\n throw new IncludeResolverError(`includeResolver threw for \"${ref}\"`, { cause });\n }\n if (included === null) return '';\n return renderAst(parseTemplate(stripSentinels(included)), {\n ...ctx,\n runtimeContext: ctx.runtimeContext, // child inherits runtime, not parent #set\n includeStack: [...ctx.includeStack, ref],\n });\n });\n}\n\nexport interface RenderInternalOptions {\n /** Merged variable map, keys LOWER-CASED (runtime context wins over #set). */\n readonly vars: Readonly<Record<string, string>>;\n readonly rng: Rng;\n /** Plural-bucket locale (raw; normalized per lookup). Empty ⇒ default 2-form. */\n readonly locale: string;\n /** Variable re-processing depth (guards runaway/circular expansion). */\n readonly depth: number;\n}\n\n/**\n * Build the merged variable map: collapse-once each `#set` value (Stage 4b) then\n * overlay the runtime context (which wins). Context keys are lowercased.\n */\nexport function buildVars(\n setDefs: Readonly<Record<string, string>>,\n context: Readonly<Record<string, string>>,\n rng: Rng,\n): Record<string, string> {\n const vars: Record<string, string> = {};\n for (const [name, value] of Object.entries(setDefs)) {\n vars[name] = collapseSetValue(value, rng);\n }\n for (const [name, value] of Object.entries(context)) {\n vars[name.toLowerCase()] = value;\n }\n return vars;\n}\n\n/** Stage 4b: resolve ONLY enumerations in a #set value once; skip {? / {plural values. */\nfunction collapseSetValue(value: string, rng: Rng): string {\n if (!value.includes('{')) return value;\n if (value.includes('{?') || value.includes('{plural ')) return value;\n return resolveEnumerationsString(value, rng);\n}\n\n/** Innermost-out `{a|b}` resolution over a raw string (perms / %vars% untouched). */\nfunction resolveEnumerationsString(text: string, rng: Rng): string {\n let out = text;\n for (let guard = 0; guard < 1000; guard += 1) {\n let changed = false;\n out = out.replace(/\\{([^{}]*)\\}/gu, (_m, inner: string): string => {\n changed = true;\n const options = splitTopLevelPipes(inner);\n return options.length === 0 ? '' : (options[randomInt(rng, 0, options.length - 1)] ?? '');\n });\n if (!changed) break;\n }\n return out;\n}\n\nexport function renderNodes(nodes: readonly Node[], opts: RenderInternalOptions): string {\n let out = '';\n for (const node of nodes) out += renderNode(node, opts);\n return out;\n}\n\nfunction renderNode(node: Node, opts: RenderInternalOptions): string {\n switch (node.type) {\n case 'literal':\n return node.value;\n case 'variable':\n return resolveVariable(node.name, opts);\n case 'enumeration':\n return renderEnumeration(node.options, opts);\n case 'permutation':\n return renderPermutation(node, opts);\n case 'conditional':\n return renderConditional(node, opts);\n case 'plural':\n return renderPlural(node, opts);\n }\n}\n\n/** `min === max` short-circuits WITHOUT consuming the RNG (plugin `random_int`). */\nfunction randomInt(rng: Rng, min: number, max: number): number {\n return min === max ? min : rng(min, max);\n}\n\n/**\n * Resolve a `%var%`. A value containing constructs is re-parsed and rendered\n * (recursive, depth-capped) so nested vars / conditionals / plurals introduced by\n * the value are resolved; a plain value is returned as-is; unresolved ⇒ verbatim.\n */\nfunction resolveVariable(name: string, opts: RenderInternalOptions): string {\n const value = opts.vars[name.toLowerCase()];\n if (value === undefined) return `%${name}%`;\n // At the cap, stop expanding (lenient: partial output, never throws — unlike the\n // plugin which throws→'' on runaway; §9.2 render never throws on content).\n if (opts.depth >= MAX_VARIABLE_DEPTH || !/[{[%]/u.test(value)) return value;\n // parseSequence, NOT parseTemplate: a value must not be re-comment-stripped or\n // re-#set-extracted (those are one-time body passes in the plugin).\n return renderNodes(parseSequence(value), { ...opts, depth: opts.depth + 1 });\n}\n\n/** Variable-expansion ONLY (plugin `expand_variables` fixpoint) — leaves enums/perms literal. */\nfunction expandVarsOnly(text: string, opts: RenderInternalOptions): string {\n let out = text;\n for (let i = 0; i < MAX_VARIABLE_DEPTH; i += 1) {\n let changed = false;\n out = out.replace(/%(\\w+)%/gu, (m, name: string): string => {\n const value = opts.vars[name.toLowerCase()];\n if (value === undefined) return m;\n changed = true;\n return value;\n });\n if (!changed) break;\n }\n return out;\n}\n\n/** Truthy = the raw var value is set and has a non-whitespace char (plugin is_truthy). */\nfunction renderConditional(node: ConditionalNode, opts: RenderInternalOptions): string {\n const value = opts.vars[node.name.toLowerCase()];\n const baseTruthy = value !== undefined && /\\S/u.test(value);\n const truthy = node.inverted ? !baseTruthy : baseTruthy;\n return renderNodes(truthy ? node.then : node.else, opts);\n}\n\n/**\n * Plural agreement (Stage 6d — after variable-expansion, before enum/perm). The\n * count/forms are expanded with VARIABLES ONLY, so the checks (nested-bracket,\n * numeric erase, arity) see the same state the plugin does — enums/perms still\n * literal. Order: bracket check → numeric erase → arity → bucket pick. The two\n * error paths emit the (var-expanded) construct verbatim with fullwidth braces.\n */\nfunction renderPlural(node: PluralNode, opts: RenderInternalOptions): string {\n const countRaw = expandVarsOnly(node.countRaw, opts);\n const formsRaw = expandVarsOnly(node.formsRaw, opts);\n\n if (/[{}[\\]]/u.test(formsRaw)) return fullwidthVerbatim(countRaw, formsRaw);\n\n const count = phpTrim(countRaw);\n if (!/^-?\\d+$/u.test(count)) return ''; // empty / non-numeric ⇒ erase the block\n\n const base = normalizeBaseLang(opts.locale);\n const forms = formsRaw.split('|').map((f) => phpTrim(f));\n if (forms.length !== pluralArity(base)) return fullwidthVerbatim(countRaw, formsRaw);\n\n // The picked form re-enters the pipeline (its enums/perms resolve after plurals).\n const picked = pluralFor(base, Number.parseInt(count, 10), forms);\n return renderNodes(parseSequence(picked), opts);\n}\n\n/** Emit the plural construct verbatim with fullwidth braces so later passes leave it alone. */\nfunction fullwidthVerbatim(countRaw: string, formsRaw: string): string {\n return `{plural ${countRaw}:${formsRaw}}`.replace(/\\{/gu, '{').replace(/\\}/gu, '}');\n}\n\n/** Pick one option (outer-first) and render it. */\nfunction renderEnumeration(options: readonly (readonly Node[])[], opts: RenderInternalOptions): string {\n if (options.length === 0) return '';\n const picked = options[randomInt(opts.rng, 0, options.length - 1)];\n return picked ? renderNodes(picked, opts) : '';\n}\n\ninterface Element {\n text: string;\n sep: string | null;\n}\n\nfunction renderPermutation(node: PermutationNode, opts: RenderInternalOptions): string {\n const elements: Element[] = node.options.map((o) => ({\n text: renderNodes(o.nodes, opts),\n sep: o.separator,\n }));\n const total = elements.length;\n if (total === 0) return '';\n\n const { config } = node;\n const hasMin = config.minsize !== null;\n const hasMax = config.maxsize !== null;\n let min: number;\n let max: number;\n if (hasMin && hasMax) {\n min = config.minsize as number;\n max = config.maxsize as number;\n } else if (hasMin) {\n min = config.minsize as number;\n max = total;\n } else if (hasMax) {\n min = 1;\n max = config.maxsize as number;\n } else {\n min = total;\n max = total;\n }\n min = Math.max(1, Math.min(min, total));\n max = Math.max(min, Math.min(max, total));\n\n const pick = randomInt(opts.rng, min, max);\n shuffle(elements, opts.rng);\n return joinWithSeparators(elements.slice(0, pick), config.sep, config.lastsep ?? config.sep);\n}\n\n/** Fisher-Yates, matching the plugin: i = n-1 … 1, j = randomInt(0, i), swap. */\nfunction shuffle(arr: Element[], rng: Rng): void {\n for (let i = arr.length - 1; i > 0; i -= 1) {\n const j = randomInt(rng, 0, i);\n const tmp = arr[i] as Element;\n arr[i] = arr[j] as Element;\n arr[j] = tmp;\n }\n}\n\nfunction joinWithSeparators(elements: readonly Element[], globalSep: string, globalLastsep: string): string {\n const count = elements.length;\n if (count === 0) return '';\n if (count === 1) return (elements[0] as Element).text;\n\n let out = (elements[0] as Element).text;\n for (let i = 1; i < count; i += 1) {\n const el = elements[i] as Element;\n const sep = el.sep ?? (i === count - 1 ? globalLastsep : globalSep);\n out += padSeparator(sep) + el.text;\n }\n return out;\n}\n\n/** Purely-alphabetic separators get space-padded; others pass through (plugin). */\nfunction padSeparator(sep: string): string {\n const trimmed = phpTrim(sep);\n if (trimmed === '') return sep;\n if (/^\\p{L}+$/u.test(trimmed)) return ` ${trimmed} `;\n return sep;\n}\n\n/** Split on top-level `|` (brace/bracket-depth aware) — for the collapse-once enum resolver. */\nfunction splitTopLevelPipes(inner: string): string[] {\n const parts: string[] = [];\n let brace = 0;\n let bracket = 0;\n let cur = '';\n for (const ch of inner) {\n if (ch === '{') brace += 1;\n else if (ch === '}') brace -= 1;\n else if (ch === '[') bracket += 1;\n else if (ch === ']') bracket -= 1;\n if (ch === '|' && brace === 0 && bracket === 0) {\n parts.push(cur);\n cur = '';\n } else {\n cur += ch;\n }\n }\n parts.push(cur);\n return parts;\n}\n\nconst PHP_LTRIM_RE = /^[ \\t\\n\\r\\0\\x0B]+/u;\nconst PHP_RTRIM_RE = /[ \\t\\n\\r\\0\\x0B]+$/u;\nfunction phpTrim(s: string): string {\n return s.replace(PHP_LTRIM_RE, '').replace(PHP_RTRIM_RE, '');\n}\n","/**\n * Cosmetic post-process — faithful port of the plugin's `Parser::post_process`\n * (parity-target §5). Order matters: URLs / emails / domains / decimals /\n * abbreviations are shielded to `\\x00…\\x00` placeholders FIRST so the\n * spacing/capitalization passes don't corrupt them, then restored + trimmed.\n *\n * This is the COSMETIC stage (gated by `postProcess`). The mandatory neutralize\n * safety-restore (§6) is separate (M2e) and always runs.\n */\n\n// Single-token abbreviations (case-insensitive) that would otherwise look like a\n// sentence end. Multi-dot forms (т.д.) are handled by the 5a regex.\nconst SINGLE_ABBREVS = [\n // Russian editorial / address / unit shorthands.\n 'соц', 'эл', 'см', 'ср', 'ст', 'ул', 'пр', 'пер', 'г', 'р', 'руб', 'коп',\n 'тыс', 'млн', 'млрд', 'трлн', 'доп', 'напр', 'прим', 'изд', 'обл', 'респ',\n 'стр', 'табл', 'рис', 'мин', 'макс', 'тел', 'факс',\n // English titles / business suffixes / editorial.\n 'etc', 'vs', 'Mr', 'Mrs', 'Ms', 'Dr', 'Prof', 'Sr', 'Jr', 'Inc', 'Ltd', 'Co',\n 'Corp', 'No', 'St', 'Ave', 'Blvd',\n];\n\n// ASCII whitespace only — PHP `\\s`/`\\b` under /u (no PCRE_UCP) are ASCII, while\n// JS `\\s` is Unicode. Using `\\s` would diverge around NBSP / thin spaces, so every\n// whitespace class below is the explicit ASCII set. (`\\b` in JS is already ASCII.)\nconst WS = ' \\\\t\\\\r\\\\n\\\\f\\\\x0B';\nconst S = `[${WS}]`;\n\nconst DOMAIN_PART =\n '(?:(?:(?:xn--)?[\\\\p{L}\\\\p{N}]+(?:-[\\\\p{L}\\\\p{N}]+)*)\\\\.)+(?:xn--[a-z0-9\\\\-]{2,59}|[\\\\p{L}][\\\\p{L}\\\\p{N}-]{1,62})';\nconst URL_RE = new RegExp(`(?:https?|ftp):\\\\/\\\\/[^${WS}<>\"')\\\\]]+`, 'giu');\n// `mailto:`/`tel:` URIs have no `//` authority, so URL_RE misses them. Without\n// this shield the EMAIL/DOMAIN passes swallow the address, the bare `mailto:` /\n// `tel:` prefix is left behind, and the \"space after :\" rule splits it into a\n// malformed `mailto: contact@…` href (spintax-js#41).\nconst MAILTEL_RE = new RegExp(`(?:mailto|tel):[^${WS}<>\"')\\\\]]+`, 'giu');\nconst EMAIL_RE = new RegExp(`[a-z0-9._%+\\\\-]+@${DOMAIN_PART}\\\\b`, 'giu');\nconst DOMAIN_RE = new RegExp(`\\\\b${DOMAIN_PART}\\\\b`, 'giu');\nconst DECIMAL_RE = /\\b\\d+\\.\\d+\\b/gu;\nconst MULTI_ABBR_RE = new RegExp(`\\\\b(?:\\\\p{L}{1,2}\\\\.${S}*){2,}`, 'gu');\nconst SINGLE_ABBR_RE = new RegExp(`(?<![\\\\p{L}\\\\p{N}])(?:${SINGLE_ABBREVS.join('|')})\\\\.(?=${S}|$|<)`, 'giu');\nconst TRAILING_PUNCT_RE = /([.,;:!]+)$/u;\n\n/**\n * SENTENCE OPENERS — the inverted marks that OPEN a Spanish question/exclamation.\n *\n * Every other European language only ever *closes* with punctuation, which is why the spacing and\n * capitalization passes below were written as if a sentence always begins with a letter. In Spanish\n * it does not: `¿cómo estás?` begins with `¿`, and the capitalizer — which upper-cases the first\n * *character* after a boundary — hits a mark that has no uppercase form and silently leaves the\n * real first letter lowercase.\n *\n * Named explicitly, and deliberately NOT widened to quotes/brackets/«»: those both open and close,\n * and capitalizing after them would mangle list markers (\"Elige. (a) primero\" → \"(A) primero\").\n * This constant encodes the language semantics of Spanish punctuation, not a general \"skip anything\n * that isn't a letter\" rule.\n */\nconst SENTENCE_OPENERS = '¿¡';\n/**\n * The LEAD — everything that can sit between a sentence boundary and the first letter: HTML tags,\n * sentence openers and whitespace, in any order and any number.\n *\n * A single optional opener is not enough. `¡¿Qué haces?!` — RAE's form for a sentence that is both\n * a question and an exclamation — opens with TWO marks, and the opened word is routinely wrapped in\n * markup (`<p>¿<a href=\"/ayuda\">Necesitas ayuda</a>?</p>`), which puts a tag AFTER the opener.\n * Whatever the lead fails to cover silently keeps a lowercase first letter.\n */\nconst LEAD = `(?:<[^>]+>|[${SENTENCE_OPENERS}]|${S})*`;\n\n// Spacing + capitalization (all ASCII-whitespace).\nconst SPACE_BEFORE_PUNCT_RE = new RegExp(`${S}+([,;:!?.])`, 'gu');\nconst SPACE_AFTER_COMMA_RE = new RegExp(`([,;:])(?!\\\\d)(?!${S}|$|<)`, 'gu');\n// A run of sentence punctuation is ONE sentence end, not several: \"...\" and \"?!\" have to survive\n// intact, so the space goes after the whole run. `(?![.!?])` is what completes the run — a greedy\n// `+` on its own still backtracks INTO it to satisfy the lookaheads, turning \"Wow!!!\" into\n// \"Wow!! !\". (JS has no possessive quantifiers, and PHP must match this shape exactly.)\nconst SPACE_AFTER_SENTENCE_RE = new RegExp(`([.!?]+)(?![.!?])(?!\\\\d)(?!${S}|$|<)`, 'gu');\n// An opener binds to the word it opens: \"¿ qué tal ?\" → \"¿qué tal?\". MUST run before the\n// capitalization passes, so they see the real first letter instead of a space.\nconst SPACE_AFTER_OPENER_RE = new RegExp(`([${SENTENCE_OPENERS}])${S}+`, 'gu');\nconst CAP_FIRST_RE = new RegExp(`^(${LEAD})(\\\\p{Ll})`, 'u');\nconst CAP_AFTER_SENTENCE_RE = new RegExp(`([.!?…])(${LEAD})(\\\\p{Ll})`, 'gu');\nconst CAP_AFTER_BLOCK_RE = new RegExp(\n `(<\\\\/?(?:p|h[1-6]|li|blockquote|div|td|th)[^>]*>${LEAD})(\\\\p{Ll})`,\n 'giu',\n);\nconst CAP_AFTER_BREAK_RE = new RegExp(`(\\\\n${LEAD})(\\\\p{Ll})`, 'gu');\n\nconst up = (ch: string): string => ch.toUpperCase();\n\nexport function postProcess(input: string): string {\n const placeholders = new Map<string, string>();\n let counter = 0;\n\n const store = (value: string, prefix: string): string => {\n const key = `\\x00${prefix}_${counter}\\x00`;\n placeholders.set(key, value);\n counter += 1;\n return key;\n };\n const storeWithTrailingPunct = (value: string, prefix: string): string => {\n const m = TRAILING_PUNCT_RE.exec(value);\n if (m) {\n const suffix = m[1] ?? '';\n const body = value.slice(0, value.length - suffix.length);\n return body === '' ? suffix : store(body, prefix) + suffix;\n }\n return store(value, prefix);\n };\n\n let text = input;\n\n // 1-5: shield. mailto:/tel: shielded before EMAIL/DOMAIN so the whole URI\n // survives instead of the address being carved out from under its prefix.\n text = text.replace(URL_RE, (m) => storeWithTrailingPunct(m, 'URL'));\n text = text.replace(MAILTEL_RE, (m) => storeWithTrailingPunct(m, 'URI'));\n text = text.replace(EMAIL_RE, (m) => store(m, 'EMAIL'));\n text = text.replace(DOMAIN_RE, (m) => store(m, 'DOM'));\n text = text.replace(DECIMAL_RE, (m) => store(m, 'NUM'));\n text = text.replace(MULTI_ABBR_RE, (m) => store(m, 'ABBR'));\n text = text.replace(SINGLE_ABBR_RE, (m) => store(m, 'ABBR'));\n\n // 6: collapse duplicate spaces/tabs.\n text = text.replace(/[ \\t]{2,}/gu, ' ');\n\n // 7: punctuation spacing. Remove whitespace before punctuation, then add a\n // space after ,;: and after a RUN of .!? unless followed by a digit / space / end / tag.\n text = text.replace(SPACE_BEFORE_PUNCT_RE, '$1');\n text = text.replace(SPACE_AFTER_COMMA_RE, '$1 ');\n text = text.replace(SPACE_AFTER_SENTENCE_RE, '$1 ');\n // 7a: a Spanish opener binds to the word it opens. Before capitalization, deliberately.\n text = text.replace(SPACE_AFTER_OPENER_RE, '$1');\n\n // 8: capitalize the first letter (skipping leading HTML tags and sentence openers).\n text = text.replace(CAP_FIRST_RE, (_m, lead: string, ch: string) => lead + up(ch));\n // 9: capitalize after sentence punctuation (through HTML tags).\n text = text.replace(CAP_AFTER_SENTENCE_RE, (_m, p: string, gap: string, ch: string) => p + gap + up(ch));\n // 10: capitalize after block-level HTML tags.\n text = text.replace(CAP_AFTER_BLOCK_RE, (_m, tag: string, ch: string) => tag + up(ch));\n // 11: capitalize after line breaks.\n text = text.replace(CAP_AFTER_BREAK_RE, (_m, br: string, ch: string) => br + up(ch));\n\n // 12: restore placeholders, then trim.\n for (const [key, value] of placeholders) {\n text = text.split(key).join(value);\n }\n return text.trim();\n}\n","/**\n * The full render pipeline with an INJECTED rng — the seam shared by the public\n * render() (which seeds the rng from RenderOptions.seed) and the corpus harness\n * (which injects a fixture's `rng` strategy). Keeping the rng a parameter is what\n * lets the deterministic parity fixtures assert exact output.\n *\n * Order: strip stray sentinels → collapse-once #set + tree-walk (+ #include) →\n * cosmetic post-process (if on) → mandatory neutralize safety-restore (always).\n */\nimport { renderAst, type RenderCtx } from './render';\nimport { postProcess } from './postprocess';\nimport { safetyRestore, stripSentinels } from './neutralize';\nimport { parseTemplate } from './parser';\nimport { isParsedAst, type Ast, type ParsedAst } from './ast';\nimport { AstVersionError } from './errors';\nimport type { Rng } from './rng';\n\n/** Default for {@link PipelineOptions.maxDepth} (#include + parse-nesting guard). */\nexport const DEFAULT_MAX_DEPTH = 20;\n\nexport interface PipelineOptions {\n context?: Record<string, string>;\n locale?: string;\n includeResolver?: (ref: string) => string | null;\n postProcess?: boolean;\n maxDepth?: number;\n}\n\nexport function renderWith(input: string | Ast, rng: Rng, opts: PipelineOptions = {}): string {\n const ctx: RenderCtx = {\n runtimeContext: opts.context ?? {},\n rng,\n locale: opts.locale ?? '',\n resolver: opts.includeResolver,\n maxDepth: opts.maxDepth ?? DEFAULT_MAX_DEPTH,\n includeStack: [],\n };\n // Strip stray engine sentinels from author markup so only neutralize() introduces them.\n const ast = resolveAst(typeof input === 'string' ? stripSentinels(input) : input);\n let out = renderAst(ast, ctx);\n // Cosmetic post-process defaults ON (§0.1); false skips it. It runs on the still-\n // shielded form (neutralize sentinels are inert here).\n if (opts.postProcess !== false) out = postProcess(out);\n // Mandatory neutralize safety-restore (§6) — ALWAYS runs, even with postProcess:false.\n return safetyRestore(out);\n}\n\n/** Resolve a `string | Ast` input to a parsed AST (parses a string fresh). */\nfunction resolveAst(input: string | Ast): ParsedAst {\n if (typeof input === 'string') return parseTemplate(input);\n if (isParsedAst(input)) return input;\n throw new AstVersionError('Ast was not produced by this engine version.');\n}\n","/**\n * RNG seam. Signature `(min, max) => int` inclusive — mirrors the plugin's\n * injectable `$random_fn`. The engine short-circuits `min === max` (see\n * `randomInt` in render.ts), so this is only invoked when a real choice exists.\n */\nexport type Rng = (min: number, max: number) => number;\n\n/**\n * Build an RNG from a `seed` (deterministic PRNG — reproducible within THIS\n * engine; cross-engine sequence parity is a non-goal §3.2) or, when omitted,\n * from `Math.random` (universal on Workers / Node / browser).\n */\nexport function makeRng(seed: number | string | undefined): Rng {\n const next =\n seed === undefined\n ? Math.random\n : mulberry32(typeof seed === 'number' ? seed >>> 0 : hashString(seed));\n return (min, max) => min + Math.floor(next() * (max - min + 1));\n}\n\n/** mulberry32 — tiny, fast, well-distributed 32-bit PRNG. */\nfunction mulberry32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) | 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/** FNV-1a hash of a string seed → 32-bit uint. */\nfunction hashString(s: string): number {\n let h = 2166136261;\n for (let i = 0; i < s.length; i += 1) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n return h >>> 0;\n}\n","/**\n * @spintax/core — framework-agnostic Spintax engine (parse / render / validate /\n * extract / analyze / neutralize). Public API contract per spec §9.2 / §9.3.\n *\n * STATUS: M3. The full §9.2 surface — parse / render / validate / extract /\n * analyze / neutralize — is implemented.\n */\n\nimport { parseTemplate } from './internal/parser';\nimport { validateTemplate } from './internal/validator';\nimport { extractFromSource } from './internal/extract';\nimport { renderWith } from './internal/pipeline';\nimport { neutralize as neutralizeValue } from './internal/neutralize';\nimport { makeRng } from './internal/rng';\nimport { AstVersionError } from './internal/errors';\nimport { isParsedAst, walk, type Ast, type ParsedAst } from './internal/ast';\n\n// ─── Public types (§9.2) ─────────────────────────────────────────────────────\n\n/**\n * Opaque, versioned parse result. NOT a public data contract in v1 — consumers\n * pass it back to render/validate/extract/analyze, they do not introspect it.\n * An in-memory perf handle, not a serialization format (do not persist across\n * engine versions).\n */\nexport type { Ast };\n\nexport interface RenderOptions {\n /** Variable map (T1, author-controlled by default — §6). */\n context?: Record<string, string>;\n /** Deterministic RNG seed; omit ⇒ nondeterministic. */\n seed?: number | string;\n /** Plural-bucket locale (§3.1); omit ⇒ default EN-style 2-form. */\n locale?: string;\n /** Host-injected, SYNCHRONOUS #include resolver (§4.1); omit ⇒ #include disabled. */\n includeResolver?: (ref: string) => string | null;\n /** Default TRUE (§0.1). false skips cosmetic post-process only; the mandatory neutralize safety-restore still runs (§6). */\n postProcess?: boolean;\n /** #include + parse-nesting guard; defaults to {@link DEFAULT_MAX_DEPTH}. */\n maxDepth?: number;\n}\n\nexport interface ValidateOptions {\n /** Plural-bucket locale for arity verdicts (§3.1); omit ⇒ default 2-form. */\n locale?: string;\n /** Slug/id allow-list; enables \"unknown #include target\" verdicts. */\n knownIncludes?: readonly string[];\n /**\n * Variable names the host will supply at render (globals / context keys).\n * Suppresses the `variable.undefined` WARNING for them — verdict is unaffected\n * (an undefined var is never an error). Case-insensitive.\n */\n knownVariables?: readonly string[];\n}\n\nexport interface Diagnostic {\n severity: 'error' | 'warning';\n /** Stable machine code — parity-gated (wording/position are not). */\n code: string;\n message: string;\n /** 1-based. */\n line: number;\n /** 1-based. */\n column: number;\n endLine?: number;\n endColumn?: number;\n /** Structured specifics keyed off `code`, e.g. { expected: 3, got: 2 }. */\n data?: Record<string, unknown>;\n}\n\nexport interface ExtractResult {\n refs: string[];\n sets: string[];\n includes: string[];\n}\n\nexport interface Analysis extends ExtractResult {\n diagnostics: Diagnostic[];\n /** Best-effort construct counts — NOT a variant-cardinality promise (§9.3). */\n constructs: Record<string, number>;\n}\n\n/** Default value for {@link RenderOptions.maxDepth}. */\nexport { DEFAULT_MAX_DEPTH } from './internal/pipeline';\n\n// ─── Errors (§9.3 — minimal, not a taxonomy) ─────────────────────────────────\n\nexport { SpintaxError, IncludeResolverError, AstVersionError, NotImplementedError } from './internal/errors';\n\n// ─── Public API surface (§9.2) ───────────────────────────────────────────────\n\nexport function parse(src: string): Ast {\n return parseTemplate(src);\n}\n\nexport function render(input: string | Ast, opts: RenderOptions = {}): string {\n // Public entry: seed the rng, then run the shared pipeline (internal/pipeline).\n return renderWith(input, makeRng(opts.seed), opts);\n}\n\nexport function validate(input: string | Ast, opts: ValidateOptions = {}): Diagnostic[] {\n return validateTemplate(resolveSource(input), opts);\n}\n\n/** Resolve a `string | Ast` input to its source text (for the raw-text checks). */\nfunction resolveSource(input: string | Ast): string {\n if (typeof input === 'string') return input;\n if (isParsedAst(input)) return input.source;\n throw new AstVersionError('Ast was not produced by this engine version.');\n}\n\nexport function extract(input: string | Ast): ExtractResult {\n return extractFromSource(resolveSource(input));\n}\n\nexport function analyze(input: string | Ast, opts: ValidateOptions = {}): Analysis {\n const ast = resolveAst(input);\n const extracted = extractFromSource(ast.source);\n return {\n ...extracted,\n diagnostics: validateTemplate(ast.source, opts),\n constructs: countConstructs(ast, extracted.includes.length),\n };\n}\n\n/** Resolve a `string | Ast` input to a parsed AST (parses a string fresh). */\nfunction resolveAst(input: string | Ast): ParsedAst {\n if (typeof input === 'string') return parseTemplate(input);\n if (isParsedAst(input)) return input;\n throw new AstVersionError('Ast was not produced by this engine version.');\n}\n\n/**\n * Best-effort construct census (§9.3) — counts author-visible constructs, NOT a\n * variant-cardinality promise. `set`/`include` are directive counts; the rest are\n * AST node types (nested nodes included; literals excluded).\n */\nfunction countConstructs(ast: ParsedAst, includeCount: number): Record<string, number> {\n const counts: Record<string, number> = {\n enumeration: 0,\n permutation: 0,\n variable: 0,\n conditional: 0,\n plural: 0,\n };\n walk(ast.nodes, (n) => {\n if (n.type in counts) counts[n.type] = (counts[n.type] ?? 0) + 1;\n });\n counts.set = Object.keys(ast.setDefs).length;\n counts.include = includeCount;\n return counts;\n}\n\nexport function neutralize(value: string): string {\n return neutralizeValue(value);\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/ast.ts","../src/internal/parser.ts","../src/internal/plurals.ts","../src/internal/validator.ts","../src/internal/extract.ts","../src/internal/errors.ts","../src/internal/neutralize.ts","../src/internal/render.ts","../src/internal/postprocess.ts","../src/internal/pipeline.ts","../src/internal/rng.ts","../src/index.ts"],"names":["PLURAL_PREFIX","INCLUDE_RE","VARIABLE_RE","phpTrim","PHP_LTRIM_RE","PHP_RTRIM_RE","normalizeBaseLang","pluralArity","resolveAst","neutralize"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Internal AST for @spintax/core. The public `Ast` (spec §9.2) is the opaque,\n * versioned view; `ParsedAst` is the internal shape carrying the node tree that\n * render/validate/extract/analyze walk. Not a serialization format — never\n * persisted across engine versions.\n *\n * Tree nodes: literal / variable / enumeration / permutation / conditional /\n * plural. Directives are NOT tree nodes (plugin parity):\n * - `#set` is extracted GLOBALLY before the tree is built (line-anchored, like\n * `extract_set_directives`) → {@link ParsedAst.setDefs}; its lines are\n * stripped from the body, so a `#set` on its own line even INSIDE a group is\n * a global definition, not literal text.\n * - `#include` is resolved by the renderer as a post-tree string pass (the\n * plugin's `resolve_includes` runs after enum/perm), so it stays literal in\n * the AST here.\n * Permutation's `<config>` + per-element separators are fully parsed (PR-11b).\n */\n\n/** Bumped only on a breaking change to the node shape (independent of syntax v1). */\nexport const AST_VERSION = 1;\n\n/** Opaque public handle (re-exported as `Ast` from the package index). */\nexport interface Ast {\n readonly astVersion: typeof AST_VERSION;\n}\n\n/** Internal parsed tree. Carries the original source so validate(Ast) can do\n * the raw-text checks (bracket balance etc.) and future offset diagnostics, and\n * the globally-extracted `#set` definitions (name → raw value, name lowercased). */\nexport interface ParsedAst extends Ast {\n readonly source: string;\n readonly setDefs: Readonly<Record<string, string>>;\n readonly nodes: readonly Node[];\n}\n\nexport type Node =\n | LiteralNode\n | VariableNode\n | EnumerationNode\n | PermutationNode\n | ConditionalNode\n | PluralNode;\n\n/** Verbatim text. */\nexport interface LiteralNode {\n readonly type: 'literal';\n readonly value: string;\n}\n\n/** `%name%` reference (name stored verbatim; lookup is case-insensitive at render). */\nexport interface VariableNode {\n readonly type: 'variable';\n readonly name: string;\n}\n\n/** `{a|b|c}` — pick one option. Each option is a node sequence. */\nexport interface EnumerationNode {\n readonly type: 'enumeration';\n readonly options: readonly (readonly Node[])[];\n}\n\n/**\n * `[<config>a|b|c]` — select/shuffle/join. PR-10 captures the raw inner\n * verbatim; PR-11 extracts the `<config>` prefix FIRST (before splitting, so a\n * `|` inside a quoted separator like `sep=\"|\"` isn't a false split — matching\n * the plugin's `extract_permutation_config` → `split_top_level` order) and\n * parses the per-element separators + option node sequences.\n */\n/** Permutation `<config>` (parsed in PR-11b). `null` size ⇒ default rules at render (§4.2). */\nexport interface PermConfig {\n readonly minsize: number | null;\n readonly maxsize: number | null;\n readonly sep: string;\n readonly lastsep: string | null;\n}\n\n/** One permutation element + its per-element separator (a trailing `<sep>` from the PREVIOUS part). */\nexport interface PermOption {\n readonly nodes: readonly Node[];\n readonly separator: string | null;\n}\n\nexport interface PermutationNode {\n readonly type: 'permutation';\n readonly config: PermConfig;\n readonly options: readonly PermOption[];\n}\n\n/**\n * `{?VAR?then|else}` / `{?!VAR?then}` — show `then` when VAR is truthy (or falsy\n * if `inverted`), else `else`. A malformed `{?…}` is NOT a conditional: the\n * parser falls back to treating the braces as an enumeration (matching the\n * plugin, where a bad conditional survives the conditional pass unchanged and\n * is then consumed by the enumeration pass).\n */\nexport interface ConditionalNode {\n readonly type: 'conditional';\n readonly name: string;\n readonly inverted: boolean;\n readonly then: readonly Node[];\n readonly else: readonly Node[];\n}\n\n/**\n * `{plural <count>: one|few|many}`. Both slots are kept RAW (they may hold\n * `%var%`): the renderer expands variables in them first (plurals run after\n * var-expansion, before enum/perm), then splits/checks/pick. The lenient path\n * (nested `{}`/`[]` in a form, or arity mismatch) re-emits\n * `{plural <countRaw>:<formsRaw>}` with fullwidth braces (U+FF5B/FF5D).\n * Discriminated by the literal `{plural ` prefix + a `:`.\n */\nexport interface PluralNode {\n readonly type: 'plural';\n readonly countRaw: string;\n readonly formsRaw: string;\n}\n\n/** Depth-first walk over every node, descending into all child sequences. */\nexport function walk(nodes: readonly Node[], visit: (n: Node) => void): void {\n for (const n of nodes) {\n visit(n);\n switch (n.type) {\n case 'enumeration':\n for (const opt of n.options) walk(opt, visit);\n break;\n case 'conditional':\n walk(n.then, visit);\n walk(n.else, visit);\n break;\n case 'permutation':\n for (const opt of n.options) walk(opt.nodes, visit);\n break;\n default:\n break; // literal / variable / plural (raw slots): no child nodes\n }\n }\n}\n\n/** Type guard: is this an internal ParsedAst produced by this engine version? */\nexport function isParsedAst(value: unknown): value is ParsedAst {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { astVersion?: unknown }).astVersion === AST_VERSION &&\n typeof (value as { source?: unknown }).source === 'string' &&\n Array.isArray((value as { nodes?: unknown }).nodes)\n );\n}\n","/**\n * Recursive-descent parser: template string → {@link ParsedAst}.\n *\n * Lenient by contract (spec §9.2): never throws on malformed markup. Unmatched\n * brackets, malformed `{?…}` / `{plural …}`, and bare `%` degrade gracefully\n * (bad conditional/plural fall back to an enumeration, exactly as the plugin's\n * later passes would consume them). Structural *diagnostics* are the validator's\n * job (PR-12), not the parser's.\n *\n * `#set` is extracted GLOBALLY before the tree is built ({@link extractSetDirectives},\n * line-anchored like the plugin's `extract_set_directives`), so a `#set` on its\n * own line even inside a `{…}`/`[…]` group is a global definition — matching the\n * plugin's brace-oblivious `/m` extraction — not literal text. `#include` stays\n * literal here; the renderer resolves it as a post-tree string pass (like the\n * plugin's post-enum `resolve_includes`).\n */\nimport { AST_VERSION, type Node, type ParsedAst, type PermConfig, type PermOption } from './ast';\n\nconst VARIABLE_RE = /^%(\\w+)%/;\n// `\\r?` before the multiline `$` so a CRLF line strips cleanly (JS `.` excludes \\r).\nconst SET_DIRECTIVE_RE = /^[ \\t]*#set[ \\t]+%(\\w+)%[ \\t]*=[ \\t]*(.*?)[ \\t]*\\r?$/gmu;\nconst CONDITIONAL_NAME_RE = /^[A-Za-z_]\\w*/;\nconst PLURAL_PREFIX = 'plural ';\n\n/** Parse a full template into an AST (comments stripped + `#set` extracted first). */\nexport function parseTemplate(src: string): ParsedAst {\n const { body, setDefs } = extractSetDirectives(stripComments(src));\n return { astVersion: AST_VERSION, source: src, setDefs, nodes: parseSequence(body) };\n}\n\n/**\n * Global `#set` extraction (parity with `extract_set_directives`): pull every\n * line-anchored `#set %name% = value` out of the text — regardless of brace\n * nesting — collecting name→value (name lowercased), strip the lines, then\n * collapse `\\n{3,}`→`\\n\\n`. Whitespace is `[ \\t]` (not `\\s`) so a directive is a\n * single line.\n */\nexport function extractSetDirectives(text: string): { body: string; setDefs: Record<string, string> } {\n const setDefs: Record<string, string> = {};\n SET_DIRECTIVE_RE.lastIndex = 0;\n const stripped = text.replace(SET_DIRECTIVE_RE, (_full: string, name: string, value: string): string => {\n setDefs[name.toLowerCase()] = value;\n return '';\n });\n return { body: stripped.replace(/\\n{3,}/gu, '\\n\\n'), setDefs };\n}\n\n/** Remove `/# … #/` block comments (non-greedy, spans newlines). */\nexport function stripComments(text: string): string {\n return text.replace(/\\/#[\\s\\S]*?#\\//g, '');\n}\n\n/** Parse a run of text into a node sequence (construct parsing only — no comment\n * strip / #set extraction; the renderer uses this to re-process variable values). */\nexport function parseSequence(text: string): Node[] {\n const nodes: Node[] = [];\n let literal = '';\n let i = 0;\n\n const flushLiteral = (): void => {\n if (literal !== '') {\n nodes.push({ type: 'literal', value: literal });\n literal = '';\n }\n };\n\n while (i < text.length) {\n const ch = text.charAt(i);\n\n if (ch === '{') {\n const end = findMatchingClose(text, i, '{', '}');\n if (end === -1) {\n literal += ch;\n i += 1;\n continue;\n }\n const content = text.slice(i + 1, end);\n flushLiteral();\n nodes.push(parseBraceConstruct(content));\n i = end + 1;\n continue;\n }\n\n if (ch === '[') {\n const end = findMatchingClose(text, i, '[', ']');\n if (end === -1) {\n literal += ch;\n i += 1;\n continue;\n }\n flushLiteral();\n nodes.push(parsePermutation(text.slice(i + 1, end)));\n i = end + 1;\n continue;\n }\n\n if (ch === '%') {\n const name = VARIABLE_RE.exec(text.slice(i))?.[1];\n if (name !== undefined) {\n flushLiteral();\n nodes.push({ type: 'variable', name });\n i += name.length + 2; // \"%\" + name + \"%\"\n continue;\n }\n }\n\n literal += ch;\n i += 1;\n }\n\n flushLiteral();\n return nodes;\n}\n\n/**\n * Decide what a `{…}` (content between the braces) is: a conditional (`?…`), a\n * plural (`plural …:` …), or — the default and the fallback for a malformed\n * conditional — an enumeration.\n */\nfunction parseBraceConstruct(content: string): Node {\n if (content.charAt(0) === '?') {\n const cond = tryParseConditional(content);\n if (cond) return cond;\n // Malformed conditional ⇒ fall back to enumeration (plugin parity).\n } else if (content.startsWith(PLURAL_PREFIX) && content.slice(PLURAL_PREFIX.length).includes(':')) {\n return parsePlural(content.slice(PLURAL_PREFIX.length));\n }\n return { type: 'enumeration', options: splitTopLevel(content).map((o) => parseSequence(o)) };\n}\n\n/** Parse `?VAR?then|else` / `?!VAR?then` (content starts with `?`), or null if malformed. */\nfunction tryParseConditional(content: string): Node | null {\n let p = 1; // past the leading '?'\n let inverted = false;\n if (content.charAt(p) === '!') {\n inverted = true;\n p += 1;\n }\n\n const name = CONDITIONAL_NAME_RE.exec(content.slice(p))?.[0];\n if (name === undefined) return null;\n p += name.length;\n\n if (content.charAt(p) !== '?') return null; // required '?' after the name\n p += 1;\n\n const body = content.slice(p);\n const sep = firstTopLevelPipe(body);\n const thenRaw = sep < 0 ? body : body.slice(0, sep);\n const elseRaw = sep < 0 ? '' : body.slice(sep + 1);\n\n return {\n type: 'conditional',\n name,\n inverted,\n then: parseSequence(thenRaw),\n else: parseSequence(elseRaw),\n };\n}\n\n/** Parse `<count>: forms` (the part after the `plural ` prefix). */\nfunction parsePlural(afterPrefix: string): Node {\n const colon = afterPrefix.indexOf(':');\n // Count + raw forms are kept as strings; the renderer expands variables in them\n // FIRST (Stage 6d runs after var-expansion, before enum/perm), then splits/checks.\n return { type: 'plural', countRaw: afterPrefix.slice(0, colon), formsRaw: afterPrefix.slice(colon + 1) };\n}\n\n// ─── Permutation parsing (config + per-element separators) ────────────────────\n\nconst CONFIG_KEY_RE = /\\b(?:minsize|maxsize|sep|lastsep)\\s*=/i;\nconst MINSIZE_RE = /minsize\\s*=\\s*(\\d+)/i;\nconst MAXSIZE_RE = /maxsize\\s*=\\s*(\\d+)/i;\nconst SEP_RE = /(?<!last)sep\\s*=\\s*\"([^\"]*)\"/i; // negative lookbehind excludes \"lastsep\"\nconst LASTSEP_RE = /lastsep\\s*=\\s*\"([^\"]*)\"/i;\nconst HTML_TAG_RE = /^([a-zA-Z][a-zA-Z0-9-]*)(?:\\s+[^>]*)?\\/?$/;\nconst PER_ELEM_HTML_RE = /^[a-zA-Z][a-zA-Z0-9]*\\s/;\n\nfunction defaultPermConfig(): PermConfig {\n return { minsize: null, maxsize: null, sep: ' ', lastsep: null };\n}\n\n/** Parse a permutation body `[<config>a|b|c]` inner → config + options with per-element seps. */\nfunction parsePermutation(rawInner: string): Node {\n const { config, content } = extractPermutationConfig(rawInner);\n const options = extractPerElementSeparators(splitTopLevel(content));\n return { type: 'permutation', config, options };\n}\n\n/** Split a leading `<config>` off the body (config is extracted BEFORE the top-level split). */\nfunction extractPermutationConfig(content: string): { config: PermConfig; content: string } {\n const trimmed = phpLtrim(content);\n if (trimmed === '' || trimmed.charAt(0) !== '<') {\n return { config: defaultPermConfig(), content };\n }\n const end = findConfigEnd(trimmed);\n if (end === -1) return { config: defaultPermConfig(), content };\n\n const configStr = trimmed.slice(1, end);\n const remaining = trimmed.slice(end + 1);\n // A leading `<li>…</li>`-style tag is HTML, not config.\n if (looksLikeHtmlStartTag(configStr, remaining)) {\n return { config: defaultPermConfig(), content };\n }\n return { config: parseConfigString(configStr), content: remaining };\n}\n\n/** Index of the closing `>` of a `<…>` config, respecting quoted strings; -1 if none. */\nfunction findConfigEnd(text: string): number {\n let inQuote = false;\n for (let i = 1; i < text.length; i += 1) {\n const ch = text.charAt(i);\n if (ch === '\"') inQuote = !inQuote;\n if (ch === '>' && !inQuote) return i;\n }\n return -1;\n}\n\nfunction parseConfigString(str: string): PermConfig {\n if (!CONFIG_KEY_RE.test(str)) {\n // Single-separator form: the whole string is sep (and lastsep).\n return { minsize: null, maxsize: null, sep: str, lastsep: str };\n }\n return {\n minsize: intGroup(MINSIZE_RE.exec(str)),\n maxsize: intGroup(MAXSIZE_RE.exec(str)),\n sep: strGroup(SEP_RE.exec(str)) ?? ' ',\n lastsep: strGroup(LASTSEP_RE.exec(str)),\n };\n}\n\nfunction looksLikeHtmlStartTag(tagText: string, remaining: string): boolean {\n const trimmed = phpTrim(tagText);\n if (trimmed === '') return false;\n const m = HTML_TAG_RE.exec(trimmed);\n if (!m) return false;\n if (trimmed.endsWith('/')) return true; // self-closing\n const tagName = (m[1] ?? '').toLowerCase();\n return new RegExp(`</${escapeRegExp(tagName)}\\\\s*>`, 'iu').test(remaining);\n}\n\n/**\n * Turn raw split parts into elements, moving a trailing `<sep>` on part[i] to be\n * the per-element separator of the element from part[i+1]. Each element's text is\n * trimmed; empty elements are dropped (plugin `extract_per_element_separators`).\n */\nfunction extractPerElementSeparators(rawParts: string[]): PermOption[] {\n const options: PermOption[] = [];\n let pendingSep: string | null = null;\n\n rawParts.forEach((part, i) => {\n let text = part;\n let trailingSep: string | null = null;\n if (i < rawParts.length - 1) {\n const extracted = extractTrailingSep(part);\n if (extracted) {\n text = extracted.text;\n trailingSep = extracted.sep;\n }\n }\n const trimmed = phpTrim(text);\n if (trimmed !== '') {\n options.push({ nodes: parseSequence(trimmed), separator: pendingSep });\n }\n pendingSep = trailingSep;\n });\n\n return options;\n}\n\n/** Detect a trailing `< sep >` on a part (not an HTML tag). Returns {text, sep} or null. */\nfunction extractTrailingSep(part: string): { text: string; sep: string } | null {\n const trimmed = phpRtrim(part);\n const len = trimmed.length;\n if (len === 0 || trimmed.charAt(len - 1) !== '>') return null;\n\n let openPos = -1;\n for (let i = len - 2; i >= 0; i -= 1) {\n const ch = trimmed.charAt(i);\n if (ch === '<') {\n openPos = i;\n break;\n }\n if (ch === '>') return null; // nested/complex, bail\n }\n if (openPos === -1) return null;\n\n const inner = trimmed.slice(openPos + 1, len - 1);\n const innerTrimmed = phpTrim(inner);\n // HTML tag → not a separator: closing </x>, self-closing <x/>, or tag-with-attrs `<x …>`.\n if (innerTrimmed.startsWith('/') || innerTrimmed.endsWith('/') || PER_ELEM_HTML_RE.test(innerTrimmed)) {\n return null;\n }\n return { text: trimmed.slice(0, openPos), sep: inner };\n}\n\nfunction intGroup(m: RegExpExecArray | null): number | null {\n return m && m[1] !== undefined ? Number.parseInt(m[1], 10) : null;\n}\nfunction strGroup(m: RegExpExecArray | null): string | null {\n return m && m[1] !== undefined ? m[1] : null;\n}\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/gu, '\\\\$&');\n}\n\n// PHP trim strips only [ \\t\\n\\r\\0\\x0B] — NOT the full JS Unicode whitespace set —\n// so use these for byte-exact parity wherever the plugin trims (permutation\n// config / element text / separators, plural forms).\nconst PHP_LTRIM_RE = /^[ \\t\\n\\r\\0\\x0B]+/u;\nconst PHP_RTRIM_RE = /[ \\t\\n\\r\\0\\x0B]+$/u;\nfunction phpTrim(s: string): string {\n return s.replace(PHP_LTRIM_RE, '').replace(PHP_RTRIM_RE, '');\n}\nfunction phpLtrim(s: string): string {\n return s.replace(PHP_LTRIM_RE, '');\n}\nfunction phpRtrim(s: string): string {\n return s.replace(PHP_RTRIM_RE, '');\n}\n\n/**\n * Index of the `close` that matches the `open` at `openPos`, tracking depth of\n * this bracket pair only. Returns -1 if unmatched.\n */\nfunction findMatchingClose(text: string, openPos: number, open: string, close: string): number {\n let depth = 0;\n for (let i = openPos; i < text.length; i += 1) {\n const ch = text.charAt(i);\n if (ch === open) {\n depth += 1;\n } else if (ch === close) {\n depth -= 1;\n if (depth === 0) return i;\n }\n }\n return -1;\n}\n\n/**\n * Split on top-level `|` — mirrors the plugin's `split_top_level`: brace and\n * bracket depths tracked INDEPENDENTLY and decremented UNCONDITIONALLY (may go\n * negative), split only when BOTH are exactly 0. So `a]|b` stays one option.\n */\nexport function splitTopLevel(inner: string): string[] {\n const parts: string[] = [];\n let brace = 0;\n let bracket = 0;\n let cur = '';\n for (const ch of inner) {\n if (ch === '{') brace += 1;\n else if (ch === '}') brace -= 1;\n else if (ch === '[') bracket += 1;\n else if (ch === ']') bracket -= 1;\n\n if (ch === '|' && brace === 0 && bracket === 0) {\n parts.push(cur);\n cur = '';\n } else {\n cur += ch;\n }\n }\n parts.push(cur);\n return parts;\n}\n\n/**\n * Index of the first top-level `|` in a conditional body, or -1. Uses a single\n * depth counter CLAMPED at 0 (matching the plugin's `parse_conditional` body\n * split, which differs from `split_top_level`'s signed dual counters).\n */\nfunction firstTopLevelPipe(body: string): number {\n let depth = 0;\n for (let j = 0; j < body.length; j += 1) {\n const ch = body.charAt(j);\n if (ch === '{' || ch === '[') {\n depth += 1;\n } else if (ch === '}' || ch === ']') {\n if (depth > 0) depth -= 1;\n } else if (ch === '|' && depth === 0) {\n return j;\n }\n }\n return -1;\n}\n","/**\n * Locale plural rules — ported from the plugin's `Plurals` (parity item §3.1).\n * Shared by the validator (arity check, PR-12) and the renderer (bucket pick, M2).\n */\n\nconst PLURAL_PREFIX = '{plural ';\n\nexport interface PluralBlock {\n readonly start: number;\n /** Exclusive end offset — one past the block's closing `}` (for diagnostics). */\n readonly end: number;\n readonly countSlot: string;\n readonly formsRaw: string;\n}\n\n/**\n * Raw brace-aware scan for `{plural …}` blocks — ported from the plugin's\n * `find_plural_blocks`. Used by the validator (and available to the renderer).\n * Scans the whole text, so it finds plurals nested inside `[…]` permutations too\n * (the AST leaves a permutation body unparsed until PR-11b). A block without a\n * `:` is not a plural (left to the enumeration path).\n */\nexport function findPluralBlocks(text: string): PluralBlock[] {\n const blocks: PluralBlock[] = [];\n let i = 0;\n while (i < text.length) {\n const start = text.indexOf(PLURAL_PREFIX, i);\n if (start === -1) break;\n\n let depth = 1;\n let j = start + PLURAL_PREFIX.length;\n while (j < text.length) {\n const ch = text.charAt(j);\n if (ch === '{') depth += 1;\n else if (ch === '}') {\n depth -= 1;\n if (depth === 0) break;\n }\n j += 1;\n }\n if (depth !== 0) {\n i = start + PLURAL_PREFIX.length; // unmatched opening — skip past prefix\n continue;\n }\n\n const inner = text.slice(start + PLURAL_PREFIX.length, j);\n const colon = inner.indexOf(':');\n if (colon === -1) {\n i = j + 1; // no colon ⇒ not a plural\n continue;\n }\n blocks.push({ start, end: j + 1, countSlot: inner.slice(0, colon), formsRaw: inner.slice(colon + 1) });\n i = j + 1;\n }\n return blocks;\n}\n\n/** Normalise a locale to its base language tag: `pt-BR`→`pt`, `uk_UA`→`uk`, `RU`→`ru`. */\nexport function normalizeBaseLang(locale: string): string {\n const first = locale.toLowerCase().split(/[-_]/, 1)[0];\n return first ?? '';\n}\n\n/**\n * Expected number of plural forms: 3 for the Slavic one/few/other family\n * (East Slavic ru/uk/be + BCS sr/hr/bs), else 2 (EN-style).\n *\n * BCS shares the East-Slavic integer rule exactly, so it reuses that bucket; CLDR\n * names the third slot \"other\" rather than \"many\", positionally the same.\n */\nexport function pluralArity(baseLang: string): number {\n switch (baseLang) {\n case 'ru':\n case 'uk':\n case 'be':\n case 'sr':\n case 'hr':\n case 'bs':\n return 3;\n default:\n return 2;\n }\n}\n\n/**\n * Pick the plural form for a count by the locale's grammar.\n * - Slavic 3-form (ru/uk/be + sr/hr/bs): one (1,21,31… not 11), few (2-4,22-24…\n * not 12-14), many (rest, incl. 0).\n * - EN-style: one (n=1), many (rest). Negative counts use abs().\n *\n * Counts are integers here (§3.1 erases a non-numeric slot), so the BCS/East-Slavic\n * split on fractions — CLDR gives BCS a fraction-digit rule — cannot be reached.\n */\nexport function pluralFor(baseLang: string, n: number, forms: readonly string[]): string {\n const abs = Math.abs(n);\n const mod10 = abs % 10;\n const mod100 = abs % 100;\n\n switch (baseLang) {\n case 'ru':\n case 'uk':\n case 'be':\n case 'sr':\n case 'hr':\n case 'bs':\n if (mod10 === 1 && mod100 !== 11) return forms[0] ?? '';\n if (mod10 >= 2 && mod10 <= 4 && (mod100 < 12 || mod100 > 14)) return forms[1] ?? '';\n return forms[2] ?? '';\n default:\n return (abs === 1 ? forms[0] : forms[1]) ?? '';\n }\n}\n","/**\n * Static validator — ported from the plugin's `Validator` (parity gate §3.1).\n * Produces {@link Diagnostic}[] with the canonical, stable codes documented in\n * `@spintax/conformance`'s README. \"Valid\" ⇔ no `severity:'error'`.\n *\n * Bracket balance is a raw char scan (the lenient AST doesn't represent\n * imbalance). Plural and #include checks walk the AST. Positions are best-effort\n * — not parity-gated (§3.1): only `code` (+ severity) is.\n *\n * Circular `#include` is NOT a verdict here — it is a render-time maxDepth guard\n * (the plugin's validator never resolves includes).\n */\nimport type { Diagnostic, ValidateOptions } from '../index';\nimport { stripComments } from './parser';\nimport { findPluralBlocks, normalizeBaseLang, pluralArity } from './plurals';\n\nconst KNOWN_CONFIG_KEYS = new Set(['minsize', 'maxsize', 'sep', 'lastsep']);\nconst INCLUDE_RE = /^[ \\t]*#include[ \\t\\n\\r\\f\\x0B]+\"([^\"]+)\"[ \\t\\n\\r\\f\\x0B]*$/gmu; // ASCII \\s (PHP parity)\n\n/**\n * Pure raw-text validation — exactly like the plugin's `Validator` (which does\n * NOT build an AST). Scanning the raw text (not the lenient AST) is what lets\n * bracket imbalance and constructs nested inside `[…]` permutations be seen.\n */\nexport function validateTemplate(src: string, opts: ValidateOptions = {}): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const text = stripComments(src);\n\n checkBrackets(text, diagnostics);\n checkSetDirectives(text, diagnostics);\n checkPermutationConfigs(text, diagnostics);\n checkPlurals(text, opts.locale, diagnostics);\n checkVariableReferences(text, opts.knownVariables, diagnostics);\n if (opts.knownIncludes && opts.knownIncludes.length > 0) {\n checkIncludeTargets(text, opts.knownIncludes, diagnostics);\n }\n\n return diagnostics;\n}\n\n/** Position (+ optional end and structured data) attached to a Diagnostic. */\ninterface Pos { line: number; column: number; endLine?: number; endColumn?: number; data?: Record<string, unknown> }\n\nfunction err(code: string, message: string, pos: Pos): Diagnostic {\n return { severity: 'error', code, message, ...pos };\n}\nfunction warn(code: string, message: string, pos: Pos): Diagnostic {\n return { severity: 'warning', code, message, ...pos };\n}\n\n/** 1-based (line, column) of a character offset. */\nfunction offsetToLineCol(text: string, offset: number): { line: number; column: number } {\n let line = 1;\n let lineStart = 0;\n const end = Math.min(Math.max(offset, 0), text.length);\n for (let i = 0; i < end; i += 1) {\n if (text.charAt(i) === '\\n') { line += 1; lineStart = i + 1; }\n }\n return { line, column: end - lineStart + 1 };\n}\n\n/** A full [offset, offset+length) span as start + end positions. */\nfunction span(text: string, offset: number, length: number): Pos {\n const s = offsetToLineCol(text, offset);\n const e = offsetToLineCol(text, offset + length);\n return { line: s.line, column: s.column, endLine: e.line, endColumn: e.column };\n}\n\n/** Balanced `{}`/`[]` with proper nesting (raw char scan, real line/col). */\nfunction checkBrackets(text: string, out: Diagnostic[]): void {\n const close: Record<string, string> = { '{': '}', '[': ']' };\n const stack: Array<{ char: string; expect: string; line: number; column: number }> = [];\n let line = 1;\n let column = 1;\n\n for (const ch of text) {\n if (ch === '\\n') {\n line += 1;\n column = 1;\n continue;\n }\n if (ch === '{' || ch === '[') {\n stack.push({ char: ch, expect: close[ch]!, line, column });\n } else if (ch === '}' || ch === ']') {\n const top = stack.pop();\n if (top === undefined) {\n out.push(err('bracket.unexpected-closing', `Unexpected closing '${ch}'.`, { line, column, endLine: line, endColumn: column + 1, data: { bracket: ch } }));\n } else if (top.expect !== ch) {\n out.push(err('bracket.mismatched', `'${top.char}' closed by '${ch}'.`, { line, column, endLine: line, endColumn: column + 1, data: { open: top.char, close: ch } }));\n }\n }\n column += 1;\n }\n\n for (const unclosed of stack) {\n out.push(err('bracket.unclosed', `Unclosed '${unclosed.char}'.`, { line: unclosed.line, column: unclosed.column, endLine: unclosed.line, endColumn: unclosed.column + 1, data: { bracket: unclosed.char } }));\n }\n}\n\n/** `#set` lines must match `#set %name% = value`. */\nfunction checkSetDirectives(text: string, out: Diagnostic[]): void {\n const lines = text.split('\\n');\n lines.forEach((lineText, idx) => {\n const trimmed = lineText.replace(/^[ \\t]+/, '');\n if (!trimmed.startsWith('#set ') && !trimmed.startsWith('#set\\t')) return;\n if (!/^#set\\s+%(\\w+)%\\s*=\\s*(.+)$/u.test(trimmed)) {\n const column = lineText.length - trimmed.length + 1; // first non-space char\n const line = idx + 1;\n out.push(err('set.malformed', 'Malformed #set. Expected: #set %name% = value', { line, column, endLine: line, endColumn: lineText.length + 1 }));\n }\n });\n}\n\n/** `[<config>]` prefixes: known keys only, minsize/maxsize must be digit runs. */\nfunction checkPermutationConfigs(text: string, out: Diagnostic[]): void {\n for (const m of text.matchAll(/\\[<([^>]*?)>/gu)) {\n const configStr = m[1] ?? '';\n if (!/\\w+\\s*=/.test(configStr)) continue; // not a key=value config\n const configBase = (m.index ?? 0) + 2; // offset of configStr in text (past \"[<\")\n\n for (const km of configStr.matchAll(/(\\w+)\\s*=/gu)) {\n const key = (km[1] ?? '').toLowerCase();\n if (!KNOWN_CONFIG_KEYS.has(key)) {\n out.push(err('permutation.unknown-key', `Unknown permutation config key: '${km[1]}'.`,\n { ...span(text, configBase + (km.index ?? 0), (km[1] ?? '').length), data: { key: km[1] } }));\n }\n }\n const min = /minsize\\s*=\\s*([^;>\\s]+)/i.exec(configStr);\n if (min && !/^\\d+$/.test(min[1] ?? '')) {\n out.push(err('permutation.minsize-not-integer', `minsize must be a positive integer, got '${min[1]}'.`,\n { ...span(text, configBase + min.index, min[0].length), data: { value: min[1] } }));\n }\n const max = /maxsize\\s*=\\s*([^;>\\s]+)/i.exec(configStr);\n if (max && !/^\\d+$/.test(max[1] ?? '')) {\n out.push(err('permutation.maxsize-not-integer', `maxsize must be a positive integer, got '${max[1]}'.`,\n { ...span(text, configBase + max.index, max[0].length), data: { value: max[1] } }));\n }\n }\n}\n\n/** `{plural …}`: no nested brackets in forms; form count matches locale arity. */\nfunction checkPlurals(text: string, locale: string | undefined, out: Diagnostic[]): void {\n // Guard on the NORMALIZED base (like the plugin): a non-empty locale that\n // normalizes to '' (e.g. \"_en\") skips the arity check.\n const base = locale && locale !== '' ? normalizeBaseLang(locale) : '';\n const arity = base !== '' ? pluralArity(base) : 0;\n\n for (const block of findPluralBlocks(text)) {\n const at = span(text, block.start, block.end - block.start);\n if (/[{}[\\]]/.test(block.formsRaw)) {\n out.push(err('plural.nested-brackets', '{plural ...}: forms must not contain nested spintax brackets.', at));\n continue;\n }\n if (arity > 0) {\n const count = block.formsRaw.split('|').length;\n if (count !== arity) {\n out.push(err('plural.arity', `{plural ...}: expected ${arity} forms, got ${count}.`,\n { ...at, data: { expected: arity, got: count } }));\n }\n }\n }\n}\n\n/** Self-reference + circular `#set` (errors) and undefined `%var%`/conditional refs (warnings). */\nfunction checkVariableReferences(text: string, known: readonly string[] | undefined, out: Diagnostic[]): void {\n const knownSet = new Set((known ?? []).map((n) => n.toLowerCase()));\n // `[ \\t]` (single-line), uniform with the parser's extract_set_directives and\n // extract.ts — so a malformed cross-line `#set` isn't treated as a definition.\n const defs = new Map<string, string>();\n const defPos = new Map<string, Pos>(); // %name% token span in its #set line\n for (const m of text.matchAll(/^[ \\t]*#set[ \\t]+%(\\w+)%[ \\t]*=[ \\t]*(.*?)$/gmu)) {\n const name = (m[1] ?? '').toLowerCase();\n defs.set(name, m[2] ?? '');\n const nameOffset = (m.index ?? 0) + m[0].indexOf('%');\n defPos.set(name, span(text, nameOffset, name.length + 2));\n }\n\n const somewhere: Pos = { line: 1, column: 1 };\n for (const [name, value] of defs) {\n if (value.toLowerCase().includes(`%${name}%`)) {\n out.push(err('variable.self-reference', `Variable '${name}' references itself.`, defPos.get(name) ?? somewhere));\n }\n }\n for (const name of defs.keys()) {\n detectCycle(name, defs, [name], defPos.get(name) ?? somewhere, out);\n }\n\n // Blank #set lines to same-length whitespace so ref offsets still map to `text`\n // (a bare removal would shift every later column).\n const body = text.replace(/^[ \\t]*#set[ \\t]+%\\w+%[ \\t]*=[ \\t]*.*?$/gmu, (m) => m.replace(/[^\\n]/g, ' '));\n const seen = new Set<string>();\n const undefinedAt = (name: string, offset: number, length: number): void => {\n const key = name.toLowerCase();\n if (defs.has(key) || knownSet.has(key) || seen.has(key)) return;\n seen.add(key);\n out.push(warn('variable.undefined', `Variable '${name}' is not defined — may be a runtime variable.`,\n { ...span(text, offset, length), data: { name } }));\n };\n for (const m of body.matchAll(/%(\\w+)%/gu)) undefinedAt(m[1] ?? '', m.index ?? 0, m[0].length);\n for (const m of body.matchAll(/\\{\\?!?([A-Za-z_]\\w*)\\?/gu)) {\n undefinedAt(m[1] ?? '', (m.index ?? 0) + m[0].indexOf(m[1] ?? ''), (m[1] ?? '').length);\n }\n}\n\nfunction detectCycle(current: string, defs: Map<string, string>, visited: string[], rootPos: Pos, out: Diagnostic[]): void {\n const value = defs.get(current) ?? '';\n for (const m of value.matchAll(/%(\\w+)%/gu)) {\n const ref = (m[1] ?? '').toLowerCase();\n if (ref === current) continue; // self-reference already reported\n if (visited.includes(ref)) {\n out.push(err('variable.circular-reference', `Circular variable reference: ${[...visited, ref].join(' → ')}.`, rootPos));\n return;\n }\n if (defs.has(ref)) detectCycle(ref, defs, [...visited, ref], rootPos, out);\n }\n}\n\n/** Unknown `#include` targets — only when a slug list is supplied. Raw `/m` scan. */\nfunction checkIncludeTargets(text: string, known: readonly string[], out: Diagnostic[]): void {\n const set = new Set(known);\n INCLUDE_RE.lastIndex = 0;\n for (const m of text.matchAll(INCLUDE_RE)) {\n const ref = m[1] ?? '';\n if (!set.has(ref)) {\n const refOffset = (m.index ?? 0) + m[0].indexOf('\"') + 1; // inside the quotes\n out.push(err('include.unknown-target', `#include target '${ref}' does not match any known template.`,\n { ...span(text, refOffset, ref.length), data: { target: ref } }));\n }\n }\n}\n","/**\n * Variable / #set / #include enumeration for `extract()` (spec §9.2).\n *\n * Raw-text scan (like the validator) rather than an AST walk, so it is complete:\n * it catches `%var%` inside a `{plural <count>: …}` count slot and inside a\n * `[…]` permutation body — both of which the AST leaves as raw strings. The\n * `#set` definition target (`#set %name% =` LHS) is a *definition*, not a\n * reference, so it is stripped before collecting `refs`.\n *\n * Variable names (`refs`, `sets`) are LOWER-CASED — the engine's variable\n * identity is case-insensitive, so cross-referencing sets against refs (the\n * two-phase-include / host-provisioning use) works. `includes` slugs are left\n * as authored (host-resolved, not case-folded). Arrays are de-duplicated;\n * order is insertion (the corpus compares order-normalized).\n *\n * NOTE (best-effort on malformed input): the conditional-name scan keys off the\n * `{?NAME?` prefix without requiring the brace to close, so an unclosed\n * `{?foo?…` yields a phantom `foo` ref. Acceptable for an extraction API.\n */\nimport { stripComments } from './parser';\n\nexport interface ExtractResult {\n refs: string[];\n sets: string[];\n includes: string[];\n}\n\n// `#set` uses [ \\t] (single-line), matching the parser / extract_set_directives —\n// NOT \\s, which would let a malformed multi-line `#set` be read as a definition.\nconst SET_DEF_RE = /^[ \\t]*#set[ \\t]+%(\\w+)%[ \\t]*=/gmu;\nconst SET_LHS_RE = /^[ \\t]*#set[ \\t]+%\\w+%[ \\t]*=/gmu;\nconst INCLUDE_RE = /^[ \\t]*#include[ \\t\\n\\r\\f\\x0B]+\"([^\"]+)\"[ \\t\\n\\r\\f\\x0B]*$/gmu; // ASCII \\s (PHP parity)\nconst VARIABLE_RE = /%(\\w+)%/gu;\nconst CONDITIONAL_REF_RE = /\\{\\?!?([A-Za-z_]\\w*)\\?/gu;\n\nexport function extractFromSource(src: string): ExtractResult {\n const text = stripComments(src);\n\n const sets = collect(text, SET_DEF_RE, true);\n const includes = collect(text, INCLUDE_RE, false);\n\n // Drop the `#set … =` LHS (keep the value) so a definition target is not a ref.\n const body = text.replace(SET_LHS_RE, '');\n const refs = new Set<string>();\n addAll(refs, body, VARIABLE_RE, true);\n addAll(refs, body, CONDITIONAL_REF_RE, true);\n\n return { refs: [...refs], sets, includes };\n}\n\nfunction collect(text: string, re: RegExp, fold: boolean): string[] {\n const seen = new Set<string>();\n addAll(seen, text, re, fold);\n return [...seen];\n}\n\nfunction addAll(target: Set<string>, text: string, re: RegExp, fold: boolean): void {\n for (const m of text.matchAll(re)) {\n const value = m[1];\n if (value !== undefined && value !== '') target.add(fold ? value.toLowerCase() : value);\n }\n}\n","/**\n * Error hierarchy for @spintax/core (spec §9.3 — minimal, not a taxonomy).\n * `render()` throws these only on programmer error, never on template content.\n */\n\n/** Base class for programmer-error throws from render(). */\nexport class SpintaxError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'SpintaxError';\n }\n}\n\n/** A host-injected includeResolver itself threw. */\nexport class IncludeResolverError extends SpintaxError {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message);\n this.name = 'IncludeResolverError';\n if (options && 'cause' in options) {\n (this as { cause?: unknown }).cause = options.cause;\n }\n }\n}\n\n// NOTE: there is deliberately NO MaxDepthExceededError. Exceeding maxDepth\n// (circular / too-deep #include, runaway variable recursion) is LENIENT — the\n// guard resolves to '' rather than throwing, matching the plugin (which logs +\n// returns ''). render() throwing on a depth breach would break the lenient\n// contract, so no such error type is part of the public surface (§9.2/§9.3).\n\n/** An Ast produced by an incompatible engine version was passed back in. */\nexport class AstVersionError extends SpintaxError {\n constructor(message: string) {\n super(message);\n this.name = 'AstVersionError';\n }\n}\n\n/** Thrown by not-yet-implemented ops / node kinds until the engine lands. */\nexport class NotImplementedError extends SpintaxError {\n constructor(what: string) {\n super(`${what} is not implemented yet.`);\n this.name = 'NotImplementedError';\n }\n}\n","/**\n * T2 shielding (§6). Text-safe / context-agnostic — NOT the plugin's HTML-entity\n * encoding (that only round-trips in an HTML sink; this engine targets Telegram /\n * plaintext / CLI too). Structural chars `{ } [ ] % #` map to Private-Use-Area\n * sentinels (U+E000–U+E005) the engine's passes never interpret as markup; the\n * mandatory {@link safetyRestore} (always run, even with postProcess:false) maps\n * them back to their literal glyphs. PUA (not the `\\x00…` scheme post-process\n * uses) so the two shielding mechanisms can't collide.\n *\n * \"Text-safe\" = safe against re-interpretation as spintax markup, NOT against an\n * HTML/JS sink — neutralize does not touch `< > &`, so it is not XSS mitigation\n * (an HTML-entity variant is a host concern, §6).\n *\n * RESERVED RANGE: U+E000–U+E005 are engine sentinels. `render()` strips them from\n * author markup (template source + #include results) via {@link stripSentinels}\n * and rewrites them in output, so a RAW (non-neutralized) context value carrying\n * these code points will be altered — hosts should neutralize/strip such data.\n */\nconst STRUCTURAL = ['{', '}', '[', ']', '%', '#'] as const;\nconst SENTINEL_BASE = 0xe000;\n\nconst SHIELD = new Map<string, string>();\nconst RESTORE = new Map<string, string>();\nSTRUCTURAL.forEach((ch, i) => {\n const sentinel = String.fromCharCode(SENTINEL_BASE + i);\n SHIELD.set(ch, sentinel);\n RESTORE.set(sentinel, ch);\n});\n\nconst SHIELD_RE = /[{}[\\]%#]/gu;\nconst RESTORE_RE = new RegExp(\n `[${String.fromCharCode(SENTINEL_BASE)}-${String.fromCharCode(SENTINEL_BASE + STRUCTURAL.length - 1)}]`,\n 'gu',\n);\n\n/** Shield data-derived (T2) input so it can't be re-interpreted as spintax markup. */\nexport function neutralize(value: string): string {\n return value.replace(SHIELD_RE, (ch) => SHIELD.get(ch) ?? ch);\n}\n\n/** Mandatory final stage: restore shielded structural chars to literal glyphs. */\nexport function safetyRestore(text: string): string {\n return text.replace(RESTORE_RE, (ch) => RESTORE.get(ch) ?? ch);\n}\n\n/** Remove stray sentinels from author markup (template / #include) so only\n * neutralize() can introduce them — otherwise safetyRestore would rewrite them. */\nexport function stripSentinels(text: string): string {\n return text.replace(RESTORE_RE, '');\n}\n","/**\n * Tree-walk renderer with the plugin's staged semantics layered on (parity with\n * Renderer::process_template). Not a naive walk — the deterministic stages are\n * reproduced in order:\n * - #set is a global pre-pass (parser) → setDefs; those enum values are\n * COLLAPSED ONCE here (buildVars), skipping values with `{?`/`{plural ` (they\n * reference vars and defer to the body) — plugin Stage 4b.\n * - variables resolve against the merged map (runtime context > #set); a value\n * that itself contains constructs is re-parsed and rendered (recursive, depth\n * capped) — this covers conditionals/plurals introduced by a variable value\n * (Stages 6b–6c), so a separate pre/post conditional pass isn't needed.\n * - conditionals test truthiness against the raw var map; plurals resolve the\n * count (vars already expanded) then pick the bucket, lenient fullwidth\n * fallback (Stage 6d, after vars).\n * - #include (post-tree string pass) and post-process are later PRs.\n *\n * RNG note: cross-engine RNG-sequence parity is a non-goal (§3.2). Enumerations\n * render outer-first and LAZILY (only the picked branch's nested RNG is used) vs\n * the plugin's eager innermost-out; corpus-safe because deterministic nested-enum\n * cases use order-independent sequences. Permutation matches the plugin's exact\n * pick→Fisher-Yates, so its rng-strategy cases are exact.\n */\nimport type { Node, ParsedAst, PermutationNode, PluralNode, ConditionalNode } from './ast';\nimport { IncludeResolverError } from './errors';\nimport { stripSentinels } from './neutralize';\nimport { parseSequence, parseTemplate } from './parser';\nimport { normalizeBaseLang, pluralArity, pluralFor } from './plurals';\nimport type { Rng } from './rng';\n\nconst MAX_VARIABLE_DEPTH = 50;\n// ASCII whitespace only — PHP `\\s` under /u is ASCII; JS `\\s` matches Unicode\n// whitespace (NBSP etc.), which would diverge on exotic input. Parity.\nconst INCLUDE_LINE_RE = /^[ \\t]*#include[ \\t\\n\\r\\f\\x0B]+\"([^\"]+)\"[ \\t\\n\\r\\f\\x0B]*$/gmu;\n\n/** Document-level render context (threads through nested #include resolution). */\n/**\n * A `{plural …}` block the renderer could not resolve, reported through\n * {@link RenderCtx.onPluralError}. Observation only — the render still degrades\n * exactly as it always has (§0.1 lenient contract); the host decides whether a\n * report is fatal. Mirrors the plugin's `on_error` callable.\n */\nexport interface PluralIssue {\n /**\n * `plural.nested-brackets` and `plural.arity` are the same codes `validate()`\n * emits. `plural.count` has no validate counterpart on purpose — an unresolved\n * count is a runtime-value fact, invisible to static analysis.\n */\n readonly code: 'plural.nested-brackets' | 'plural.arity' | 'plural.count';\n readonly message: string;\n /** The construct as the renderer saw it, AFTER variable expansion. */\n readonly construct: string;\n /** Normalized base language the arity was judged against. */\n readonly locale: string;\n /** Arity verdicts only. */\n readonly expected?: number;\n readonly got?: number;\n}\n\nexport interface RenderCtx {\n /** Runtime/host variable map — inherited by child #includes (NOT parent #set). */\n readonly runtimeContext: Readonly<Record<string, string>>;\n readonly rng: Rng;\n readonly locale: string;\n readonly resolver: ((ref: string) => string | null) | undefined;\n readonly maxDepth: number;\n /** #include ref chain for circular-reference detection. */\n readonly includeStack: readonly string[];\n /** Optional observer for unresolvable plural blocks; never affects output. */\n readonly onPluralError: ((issue: PluralIssue) => void) | undefined;\n}\n\n/**\n * Render a parsed template: collapse-once #set → tree-walk → resolve #includes\n * (post-tree string pass, like the plugin's Stage 9 resolve_nested, AFTER\n * enum/perm). Post-process (Stage 10) is layered on by the public render().\n */\nexport function renderAst(ast: ParsedAst, ctx: RenderCtx): string {\n const vars = buildVars(ast.setDefs, ctx.runtimeContext, ctx.rng);\n const text = renderNodes(ast.nodes, {\n vars,\n rng: ctx.rng,\n locale: ctx.locale,\n depth: 0,\n onPluralError: ctx.onPluralError,\n });\n return ctx.resolver ? resolveIncludes(text, ctx) : text;\n}\n\n/**\n * Replace each `#include \"ref\"` (line-anchored) with the host-resolved child\n * template, rendered with a CHILD scope: inherits runtime context but NOT the\n * parent's #set locals (plugin `for_child_render`). Circular refs / runaway\n * depth resolve to '' (lenient); a resolver that throws surfaces as\n * IncludeResolverError (programmer error).\n *\n * NOTE: cycles are detected by the ref STRING (the engine has no template\n * identity beyond the host-supplied ref, §4.1), so two aliased refs for one\n * template aren't seen as a cycle and recurse until `maxDepth`. `maxDepth` also\n * caps deep ACYCLIC chains (silently → ''), a guard the plugin lacks.\n */\nfunction resolveIncludes(text: string, ctx: RenderCtx): string {\n INCLUDE_LINE_RE.lastIndex = 0;\n return text.replace(INCLUDE_LINE_RE, (_m, ref: string): string => {\n if (ctx.includeStack.includes(ref) || ctx.includeStack.length >= ctx.maxDepth) return '';\n let included: string | null;\n try {\n included = ctx.resolver!(ref);\n } catch (cause) {\n throw new IncludeResolverError(`includeResolver threw for \"${ref}\"`, { cause });\n }\n if (included === null) return '';\n return renderAst(parseTemplate(stripSentinels(included)), {\n ...ctx,\n runtimeContext: ctx.runtimeContext, // child inherits runtime, not parent #set\n includeStack: [...ctx.includeStack, ref],\n });\n });\n}\n\nexport interface RenderInternalOptions {\n /** Merged variable map, keys LOWER-CASED (runtime context wins over #set). */\n readonly vars: Readonly<Record<string, string>>;\n readonly rng: Rng;\n /** Plural-bucket locale (raw; normalized per lookup). Empty ⇒ default 2-form. */\n readonly locale: string;\n /** Variable re-processing depth (guards runaway/circular expansion). */\n readonly depth: number;\n /** Optional observer for unresolvable plural blocks; never affects output. */\n readonly onPluralError: ((issue: PluralIssue) => void) | undefined;\n}\n\n/**\n * Build the merged variable map: collapse-once each `#set` value (Stage 4b) then\n * overlay the runtime context (which wins). Context keys are lowercased.\n */\nexport function buildVars(\n setDefs: Readonly<Record<string, string>>,\n context: Readonly<Record<string, string>>,\n rng: Rng,\n): Record<string, string> {\n const vars: Record<string, string> = {};\n for (const [name, value] of Object.entries(setDefs)) {\n vars[name] = collapseSetValue(value, rng);\n }\n for (const [name, value] of Object.entries(context)) {\n vars[name.toLowerCase()] = value;\n }\n return vars;\n}\n\n/** Stage 4b: resolve ONLY enumerations in a #set value once; skip {? / {plural values. */\nfunction collapseSetValue(value: string, rng: Rng): string {\n if (!value.includes('{')) return value;\n if (value.includes('{?') || value.includes('{plural ')) return value;\n return resolveEnumerationsString(value, rng);\n}\n\n/** Innermost-out `{a|b}` resolution over a raw string (perms / %vars% untouched). */\nfunction resolveEnumerationsString(text: string, rng: Rng): string {\n let out = text;\n for (let guard = 0; guard < 1000; guard += 1) {\n let changed = false;\n out = out.replace(/\\{([^{}]*)\\}/gu, (_m, inner: string): string => {\n changed = true;\n const options = splitTopLevelPipes(inner);\n return options.length === 0 ? '' : (options[randomInt(rng, 0, options.length - 1)] ?? '');\n });\n if (!changed) break;\n }\n return out;\n}\n\nexport function renderNodes(nodes: readonly Node[], opts: RenderInternalOptions): string {\n let out = '';\n for (const node of nodes) out += renderNode(node, opts);\n return out;\n}\n\nfunction renderNode(node: Node, opts: RenderInternalOptions): string {\n switch (node.type) {\n case 'literal':\n return node.value;\n case 'variable':\n return resolveVariable(node.name, opts);\n case 'enumeration':\n return renderEnumeration(node.options, opts);\n case 'permutation':\n return renderPermutation(node, opts);\n case 'conditional':\n return renderConditional(node, opts);\n case 'plural':\n return renderPlural(node, opts);\n }\n}\n\n/** `min === max` short-circuits WITHOUT consuming the RNG (plugin `random_int`). */\nfunction randomInt(rng: Rng, min: number, max: number): number {\n return min === max ? min : rng(min, max);\n}\n\n/**\n * Resolve a `%var%`. A value containing constructs is re-parsed and rendered\n * (recursive, depth-capped) so nested vars / conditionals / plurals introduced by\n * the value are resolved; a plain value is returned as-is; unresolved ⇒ verbatim.\n */\nfunction resolveVariable(name: string, opts: RenderInternalOptions): string {\n const value = opts.vars[name.toLowerCase()];\n if (value === undefined) return `%${name}%`;\n // At the cap, stop expanding (lenient: partial output, never throws — unlike the\n // plugin which throws→'' on runaway; §9.2 render never throws on content).\n if (opts.depth >= MAX_VARIABLE_DEPTH || !/[{[%]/u.test(value)) return value;\n // parseSequence, NOT parseTemplate: a value must not be re-comment-stripped or\n // re-#set-extracted (those are one-time body passes in the plugin).\n return renderNodes(parseSequence(value), { ...opts, depth: opts.depth + 1 });\n}\n\n/** Variable-expansion ONLY (plugin `expand_variables` fixpoint) — leaves enums/perms literal. */\nfunction expandVarsOnly(text: string, opts: RenderInternalOptions): string {\n let out = text;\n for (let i = 0; i < MAX_VARIABLE_DEPTH; i += 1) {\n let changed = false;\n out = out.replace(/%(\\w+)%/gu, (m, name: string): string => {\n const value = opts.vars[name.toLowerCase()];\n if (value === undefined) return m;\n changed = true;\n return value;\n });\n if (!changed) break;\n }\n return out;\n}\n\n/** Truthy = the raw var value is set and has a non-whitespace char (plugin is_truthy). */\nfunction renderConditional(node: ConditionalNode, opts: RenderInternalOptions): string {\n const value = opts.vars[node.name.toLowerCase()];\n const baseTruthy = value !== undefined && /\\S/u.test(value);\n const truthy = node.inverted ? !baseTruthy : baseTruthy;\n return renderNodes(truthy ? node.then : node.else, opts);\n}\n\n/**\n * Plural agreement (Stage 6d — after variable-expansion, before enum/perm). The\n * count/forms are expanded with VARIABLES ONLY, so the checks (nested-bracket,\n * numeric erase, arity) see the same state the plugin does — enums/perms still\n * literal. Order: bracket check → numeric erase → arity → bucket pick. The two\n * error paths emit the (var-expanded) construct verbatim with fullwidth braces.\n */\nfunction renderPlural(node: PluralNode, opts: RenderInternalOptions): string {\n const countRaw = expandVarsOnly(node.countRaw, opts);\n const formsRaw = expandVarsOnly(node.formsRaw, opts);\n const base = normalizeBaseLang(opts.locale);\n const report = (issue: PluralIssue): void => opts.onPluralError?.(issue);\n\n if (/[{}[\\]]/u.test(formsRaw)) {\n report({\n code: 'plural.nested-brackets',\n message: 'Plural form slot contains nested spintax brackets; extract via #set first.',\n construct: rawConstruct(countRaw, formsRaw),\n locale: base,\n });\n return fullwidthVerbatim(countRaw, formsRaw);\n }\n\n const count = phpTrim(countRaw);\n if (!/^-?\\d+$/u.test(count)) {\n // Erasing leaves no trace in the output, so this report is the ONLY way a\n // host can tell an intentionally-empty sentence from an unsubstituted %Var%.\n report({\n code: 'plural.count',\n message: `Plural count slot is empty or non-numeric (${JSON.stringify(count)}); block erased.`,\n construct: rawConstruct(countRaw, formsRaw),\n locale: base,\n });\n return '';\n }\n\n const forms = formsRaw.split('|').map((f) => phpTrim(f));\n if (forms.length !== pluralArity(base)) {\n report({\n code: 'plural.arity',\n message: `Plural has ${forms.length} form(s); locale \"${base}\" takes ${pluralArity(base)}.`,\n construct: rawConstruct(countRaw, formsRaw),\n locale: base,\n expected: pluralArity(base),\n got: forms.length,\n });\n return fullwidthVerbatim(countRaw, formsRaw);\n }\n\n // The picked form re-enters the pipeline (its enums/perms resolve after plurals).\n const picked = pluralFor(base, Number.parseInt(count, 10), forms);\n return renderNodes(parseSequence(picked), opts);\n}\n\n/** The construct as the renderer saw it — ASCII braces, for reports and logs. */\nfunction rawConstruct(countRaw: string, formsRaw: string): string {\n return `{plural ${countRaw}:${formsRaw}}`;\n}\n\n/** Emit the plural construct verbatim with fullwidth braces so later passes leave it alone. */\nfunction fullwidthVerbatim(countRaw: string, formsRaw: string): string {\n return rawConstruct(countRaw, formsRaw).replace(/\\{/gu, '{').replace(/\\}/gu, '}');\n}\n\n/** Pick one option (outer-first) and render it. */\nfunction renderEnumeration(options: readonly (readonly Node[])[], opts: RenderInternalOptions): string {\n if (options.length === 0) return '';\n const picked = options[randomInt(opts.rng, 0, options.length - 1)];\n return picked ? renderNodes(picked, opts) : '';\n}\n\ninterface Element {\n text: string;\n sep: string | null;\n}\n\nfunction renderPermutation(node: PermutationNode, opts: RenderInternalOptions): string {\n const elements: Element[] = node.options.map((o) => ({\n text: renderNodes(o.nodes, opts),\n sep: o.separator,\n }));\n const total = elements.length;\n if (total === 0) return '';\n\n const { config } = node;\n const hasMin = config.minsize !== null;\n const hasMax = config.maxsize !== null;\n let min: number;\n let max: number;\n if (hasMin && hasMax) {\n min = config.minsize as number;\n max = config.maxsize as number;\n } else if (hasMin) {\n min = config.minsize as number;\n max = total;\n } else if (hasMax) {\n min = 1;\n max = config.maxsize as number;\n } else {\n min = total;\n max = total;\n }\n min = Math.max(1, Math.min(min, total));\n max = Math.max(min, Math.min(max, total));\n\n const pick = randomInt(opts.rng, min, max);\n shuffle(elements, opts.rng);\n return joinWithSeparators(elements.slice(0, pick), config.sep, config.lastsep ?? config.sep);\n}\n\n/** Fisher-Yates, matching the plugin: i = n-1 … 1, j = randomInt(0, i), swap. */\nfunction shuffle(arr: Element[], rng: Rng): void {\n for (let i = arr.length - 1; i > 0; i -= 1) {\n const j = randomInt(rng, 0, i);\n const tmp = arr[i] as Element;\n arr[i] = arr[j] as Element;\n arr[j] = tmp;\n }\n}\n\nfunction joinWithSeparators(elements: readonly Element[], globalSep: string, globalLastsep: string): string {\n const count = elements.length;\n if (count === 0) return '';\n if (count === 1) return (elements[0] as Element).text;\n\n let out = (elements[0] as Element).text;\n for (let i = 1; i < count; i += 1) {\n const el = elements[i] as Element;\n const sep = el.sep ?? (i === count - 1 ? globalLastsep : globalSep);\n out += padSeparator(sep) + el.text;\n }\n return out;\n}\n\n/** Purely-alphabetic separators get space-padded; others pass through (plugin). */\nfunction padSeparator(sep: string): string {\n const trimmed = phpTrim(sep);\n if (trimmed === '') return sep;\n if (/^\\p{L}+$/u.test(trimmed)) return ` ${trimmed} `;\n return sep;\n}\n\n/** Split on top-level `|` (brace/bracket-depth aware) — for the collapse-once enum resolver. */\nfunction splitTopLevelPipes(inner: string): string[] {\n const parts: string[] = [];\n let brace = 0;\n let bracket = 0;\n let cur = '';\n for (const ch of inner) {\n if (ch === '{') brace += 1;\n else if (ch === '}') brace -= 1;\n else if (ch === '[') bracket += 1;\n else if (ch === ']') bracket -= 1;\n if (ch === '|' && brace === 0 && bracket === 0) {\n parts.push(cur);\n cur = '';\n } else {\n cur += ch;\n }\n }\n parts.push(cur);\n return parts;\n}\n\nconst PHP_LTRIM_RE = /^[ \\t\\n\\r\\0\\x0B]+/u;\nconst PHP_RTRIM_RE = /[ \\t\\n\\r\\0\\x0B]+$/u;\nfunction phpTrim(s: string): string {\n return s.replace(PHP_LTRIM_RE, '').replace(PHP_RTRIM_RE, '');\n}\n","/**\n * Cosmetic post-process — faithful port of the plugin's `Parser::post_process`\n * (parity-target §5). Order matters: URLs / emails / domains / decimals /\n * abbreviations are shielded to `\\x00…\\x00` placeholders FIRST so the\n * spacing/capitalization passes don't corrupt them, then restored + trimmed.\n *\n * This is the COSMETIC stage (gated by `postProcess`). The mandatory neutralize\n * safety-restore (§6) is separate (M2e) and always runs.\n */\n\n// Single-token abbreviations (case-insensitive) that would otherwise look like a\n// sentence end. Multi-dot forms (т.д.) are handled by the 5a regex.\nconst SINGLE_ABBREVS = [\n // Russian editorial / address / unit shorthands.\n 'соц', 'эл', 'см', 'ср', 'ст', 'ул', 'пр', 'пер', 'г', 'р', 'руб', 'коп',\n 'тыс', 'млн', 'млрд', 'трлн', 'доп', 'напр', 'прим', 'изд', 'обл', 'респ',\n 'стр', 'табл', 'рис', 'мин', 'макс', 'тел', 'факс',\n // English titles / business suffixes / editorial.\n 'etc', 'vs', 'Mr', 'Mrs', 'Ms', 'Dr', 'Prof', 'Sr', 'Jr', 'Inc', 'Ltd', 'Co',\n 'Corp', 'No', 'St', 'Ave', 'Blvd',\n];\n\n// ASCII whitespace only — PHP `\\s`/`\\b` under /u (no PCRE_UCP) are ASCII, while\n// JS `\\s` is Unicode. Using `\\s` would diverge around NBSP / thin spaces, so every\n// whitespace class below is the explicit ASCII set. (`\\b` in JS is already ASCII.)\nconst WS = ' \\\\t\\\\r\\\\n\\\\f\\\\x0B';\nconst S = `[${WS}]`;\n\nconst DOMAIN_PART =\n '(?:(?:(?:xn--)?[\\\\p{L}\\\\p{N}]+(?:-[\\\\p{L}\\\\p{N}]+)*)\\\\.)+(?:xn--[a-z0-9\\\\-]{2,59}|[\\\\p{L}][\\\\p{L}\\\\p{N}-]{1,62})';\nconst URL_RE = new RegExp(`(?:https?|ftp):\\\\/\\\\/[^${WS}<>\"')\\\\]]+`, 'giu');\n// `mailto:`/`tel:` URIs have no `//` authority, so URL_RE misses them. Without\n// this shield the EMAIL/DOMAIN passes swallow the address, the bare `mailto:` /\n// `tel:` prefix is left behind, and the \"space after :\" rule splits it into a\n// malformed `mailto: contact@…` href (spintax-js#41).\nconst MAILTEL_RE = new RegExp(`(?:mailto|tel):[^${WS}<>\"')\\\\]]+`, 'giu');\nconst EMAIL_RE = new RegExp(`[a-z0-9._%+\\\\-]+@${DOMAIN_PART}\\\\b`, 'giu');\nconst DOMAIN_RE = new RegExp(`\\\\b${DOMAIN_PART}\\\\b`, 'giu');\nconst DECIMAL_RE = /\\b\\d+\\.\\d+\\b/gu;\nconst MULTI_ABBR_RE = new RegExp(`\\\\b(?:\\\\p{L}{1,2}\\\\.${S}*){2,}`, 'gu');\nconst SINGLE_ABBR_RE = new RegExp(`(?<![\\\\p{L}\\\\p{N}])(?:${SINGLE_ABBREVS.join('|')})\\\\.(?=${S}|$|<)`, 'giu');\nconst TRAILING_PUNCT_RE = /([.,;:!]+)$/u;\n\n/**\n * SENTENCE OPENERS — the inverted marks that OPEN a Spanish question/exclamation.\n *\n * Every other European language only ever *closes* with punctuation, which is why the spacing and\n * capitalization passes below were written as if a sentence always begins with a letter. In Spanish\n * it does not: `¿cómo estás?` begins with `¿`, and the capitalizer — which upper-cases the first\n * *character* after a boundary — hits a mark that has no uppercase form and silently leaves the\n * real first letter lowercase.\n *\n * Named explicitly, and deliberately NOT widened to quotes/brackets/«»: those both open and close,\n * and capitalizing after them would mangle list markers (\"Elige. (a) primero\" → \"(A) primero\").\n * This constant encodes the language semantics of Spanish punctuation, not a general \"skip anything\n * that isn't a letter\" rule.\n */\nconst SENTENCE_OPENERS = '¿¡';\n/**\n * The LEAD — everything that can sit between a sentence boundary and the first letter: HTML tags,\n * sentence openers and whitespace, in any order and any number.\n *\n * A single optional opener is not enough. `¡¿Qué haces?!` — RAE's form for a sentence that is both\n * a question and an exclamation — opens with TWO marks, and the opened word is routinely wrapped in\n * markup (`<p>¿<a href=\"/ayuda\">Necesitas ayuda</a>?</p>`), which puts a tag AFTER the opener.\n * Whatever the lead fails to cover silently keeps a lowercase first letter.\n */\nconst LEAD = `(?:<[^>]+>|[${SENTENCE_OPENERS}]|${S})*`;\n\n// Spacing + capitalization (all ASCII-whitespace).\nconst SPACE_BEFORE_PUNCT_RE = new RegExp(`${S}+([,;:!?.])`, 'gu');\nconst SPACE_AFTER_COMMA_RE = new RegExp(`([,;:])(?!\\\\d)(?!${S}|$|<)`, 'gu');\n// A run of sentence punctuation is ONE sentence end, not several: \"...\" and \"?!\" have to survive\n// intact, so the space goes after the whole run. `(?![.!?])` is what completes the run — a greedy\n// `+` on its own still backtracks INTO it to satisfy the lookaheads, turning \"Wow!!!\" into\n// \"Wow!! !\". (JS has no possessive quantifiers, and PHP must match this shape exactly.)\nconst SPACE_AFTER_SENTENCE_RE = new RegExp(`([.!?]+)(?![.!?])(?!\\\\d)(?!${S}|$|<)`, 'gu');\n// An opener binds to the word it opens: \"¿ qué tal ?\" → \"¿qué tal?\". MUST run before the\n// capitalization passes, so they see the real first letter instead of a space.\nconst SPACE_AFTER_OPENER_RE = new RegExp(`([${SENTENCE_OPENERS}])${S}+`, 'gu');\nconst CAP_FIRST_RE = new RegExp(`^(${LEAD})(\\\\p{Ll})`, 'u');\nconst CAP_AFTER_SENTENCE_RE = new RegExp(`([.!?…])(${LEAD})(\\\\p{Ll})`, 'gu');\nconst CAP_AFTER_BLOCK_RE = new RegExp(\n `(<\\\\/?(?:p|h[1-6]|li|blockquote|div|td|th)[^>]*>${LEAD})(\\\\p{Ll})`,\n 'giu',\n);\nconst CAP_AFTER_BREAK_RE = new RegExp(`(\\\\n${LEAD})(\\\\p{Ll})`, 'gu');\n\nconst up = (ch: string): string => ch.toUpperCase();\n\nexport function postProcess(input: string): string {\n const placeholders = new Map<string, string>();\n let counter = 0;\n\n const store = (value: string, prefix: string): string => {\n const key = `\\x00${prefix}_${counter}\\x00`;\n placeholders.set(key, value);\n counter += 1;\n return key;\n };\n const storeWithTrailingPunct = (value: string, prefix: string): string => {\n const m = TRAILING_PUNCT_RE.exec(value);\n if (m) {\n const suffix = m[1] ?? '';\n const body = value.slice(0, value.length - suffix.length);\n return body === '' ? suffix : store(body, prefix) + suffix;\n }\n return store(value, prefix);\n };\n\n let text = input;\n\n // 1-5: shield. mailto:/tel: shielded before EMAIL/DOMAIN so the whole URI\n // survives instead of the address being carved out from under its prefix.\n text = text.replace(URL_RE, (m) => storeWithTrailingPunct(m, 'URL'));\n text = text.replace(MAILTEL_RE, (m) => storeWithTrailingPunct(m, 'URI'));\n text = text.replace(EMAIL_RE, (m) => store(m, 'EMAIL'));\n text = text.replace(DOMAIN_RE, (m) => store(m, 'DOM'));\n text = text.replace(DECIMAL_RE, (m) => store(m, 'NUM'));\n text = text.replace(MULTI_ABBR_RE, (m) => store(m, 'ABBR'));\n text = text.replace(SINGLE_ABBR_RE, (m) => store(m, 'ABBR'));\n\n // 6: collapse duplicate spaces/tabs.\n text = text.replace(/[ \\t]{2,}/gu, ' ');\n\n // 7: punctuation spacing. Remove whitespace before punctuation, then add a\n // space after ,;: and after a RUN of .!? unless followed by a digit / space / end / tag.\n text = text.replace(SPACE_BEFORE_PUNCT_RE, '$1');\n text = text.replace(SPACE_AFTER_COMMA_RE, '$1 ');\n text = text.replace(SPACE_AFTER_SENTENCE_RE, '$1 ');\n // 7a: a Spanish opener binds to the word it opens. Before capitalization, deliberately.\n text = text.replace(SPACE_AFTER_OPENER_RE, '$1');\n\n // 8: capitalize the first letter (skipping leading HTML tags and sentence openers).\n text = text.replace(CAP_FIRST_RE, (_m, lead: string, ch: string) => lead + up(ch));\n // 9: capitalize after sentence punctuation (through HTML tags).\n text = text.replace(CAP_AFTER_SENTENCE_RE, (_m, p: string, gap: string, ch: string) => p + gap + up(ch));\n // 10: capitalize after block-level HTML tags.\n text = text.replace(CAP_AFTER_BLOCK_RE, (_m, tag: string, ch: string) => tag + up(ch));\n // 11: capitalize after line breaks.\n text = text.replace(CAP_AFTER_BREAK_RE, (_m, br: string, ch: string) => br + up(ch));\n\n // 12: restore placeholders, then trim.\n for (const [key, value] of placeholders) {\n text = text.split(key).join(value);\n }\n return text.trim();\n}\n","/**\n * The full render pipeline with an INJECTED rng — the seam shared by the public\n * render() (which seeds the rng from RenderOptions.seed) and the corpus harness\n * (which injects a fixture's `rng` strategy). Keeping the rng a parameter is what\n * lets the deterministic parity fixtures assert exact output.\n *\n * Order: strip stray sentinels → collapse-once #set + tree-walk (+ #include) →\n * cosmetic post-process (if on) → mandatory neutralize safety-restore (always).\n */\nimport { renderAst, type PluralIssue, type RenderCtx } from './render';\nimport { postProcess } from './postprocess';\nimport { safetyRestore, stripSentinels } from './neutralize';\nimport { parseTemplate } from './parser';\nimport { isParsedAst, type Ast, type ParsedAst } from './ast';\nimport { AstVersionError } from './errors';\nimport type { Rng } from './rng';\n\n/** Default for {@link PipelineOptions.maxDepth} (#include + parse-nesting guard). */\nexport const DEFAULT_MAX_DEPTH = 20;\n\nexport interface PipelineOptions {\n context?: Record<string, string>;\n locale?: string;\n includeResolver?: (ref: string) => string | null;\n postProcess?: boolean;\n maxDepth?: number;\n onPluralError?: (issue: PluralIssue) => void;\n}\n\nexport function renderWith(input: string | Ast, rng: Rng, opts: PipelineOptions = {}): string {\n const ctx: RenderCtx = {\n runtimeContext: opts.context ?? {},\n rng,\n locale: opts.locale ?? '',\n resolver: opts.includeResolver,\n maxDepth: opts.maxDepth ?? DEFAULT_MAX_DEPTH,\n includeStack: [],\n onPluralError: opts.onPluralError,\n };\n // Strip stray engine sentinels from author markup so only neutralize() introduces them.\n const ast = resolveAst(typeof input === 'string' ? stripSentinels(input) : input);\n let out = renderAst(ast, ctx);\n // Cosmetic post-process defaults ON (§0.1); false skips it. It runs on the still-\n // shielded form (neutralize sentinels are inert here).\n if (opts.postProcess !== false) out = postProcess(out);\n // Mandatory neutralize safety-restore (§6) — ALWAYS runs, even with postProcess:false.\n return safetyRestore(out);\n}\n\n/** Resolve a `string | Ast` input to a parsed AST (parses a string fresh). */\nfunction resolveAst(input: string | Ast): ParsedAst {\n if (typeof input === 'string') return parseTemplate(input);\n if (isParsedAst(input)) return input;\n throw new AstVersionError('Ast was not produced by this engine version.');\n}\n","/**\n * RNG seam. Signature `(min, max) => int` inclusive — mirrors the plugin's\n * injectable `$random_fn`. The engine short-circuits `min === max` (see\n * `randomInt` in render.ts), so this is only invoked when a real choice exists.\n */\nexport type Rng = (min: number, max: number) => number;\n\n/**\n * Build an RNG from a `seed` (deterministic PRNG — reproducible within THIS\n * engine; cross-engine sequence parity is a non-goal §3.2) or, when omitted,\n * from `Math.random` (universal on Workers / Node / browser).\n */\nexport function makeRng(seed: number | string | undefined): Rng {\n const next =\n seed === undefined\n ? Math.random\n : mulberry32(typeof seed === 'number' ? seed >>> 0 : hashString(seed));\n return (min, max) => min + Math.floor(next() * (max - min + 1));\n}\n\n/** mulberry32 — tiny, fast, well-distributed 32-bit PRNG. */\nfunction mulberry32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) | 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/** FNV-1a hash of a string seed → 32-bit uint. */\nfunction hashString(s: string): number {\n let h = 2166136261;\n for (let i = 0; i < s.length; i += 1) {\n h ^= s.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n return h >>> 0;\n}\n","/**\n * @spintax/core — framework-agnostic Spintax engine (parse / render / validate /\n * extract / analyze / neutralize). Public API contract per spec §9.2 / §9.3.\n *\n * STATUS: M3. The full §9.2 surface — parse / render / validate / extract /\n * analyze / neutralize — is implemented.\n */\n\nimport { parseTemplate } from './internal/parser';\nimport { validateTemplate } from './internal/validator';\nimport { extractFromSource } from './internal/extract';\nimport { renderWith } from './internal/pipeline';\nimport { neutralize as neutralizeValue } from './internal/neutralize';\nimport { makeRng } from './internal/rng';\nimport { AstVersionError } from './internal/errors';\nimport { isParsedAst, walk, type Ast, type ParsedAst } from './internal/ast';\nimport type { PluralIssue } from './internal/render';\nimport {\n normalizeBaseLang as normalizeBaseLangInternal,\n pluralArity as pluralArityForBase,\n} from './internal/plurals';\n\n// ─── Public types (§9.2) ─────────────────────────────────────────────────────\n\n/**\n * Opaque, versioned parse result. NOT a public data contract in v1 — consumers\n * pass it back to render/validate/extract/analyze, they do not introspect it.\n * An in-memory perf handle, not a serialization format (do not persist across\n * engine versions).\n */\nexport type { Ast };\n\n/** Reported through {@link RenderOptions.onPluralError}; never thrown. */\nexport type { PluralIssue };\n\nexport interface RenderOptions {\n /** Variable map (T1, author-controlled by default — §6). */\n context?: Record<string, string>;\n /** Deterministic RNG seed; omit ⇒ nondeterministic. */\n seed?: number | string;\n /** Plural-bucket locale (§3.1); omit ⇒ default EN-style 2-form. */\n locale?: string;\n /** Host-injected, SYNCHRONOUS #include resolver (§4.1); omit ⇒ #include disabled. */\n includeResolver?: (ref: string) => string | null;\n /** Default TRUE (§0.1). false skips cosmetic post-process only; the mandatory neutralize safety-restore still runs (§6). */\n postProcess?: boolean;\n /** #include + parse-nesting guard; defaults to {@link DEFAULT_MAX_DEPTH}. */\n maxDepth?: number;\n /**\n * Observer for `{plural …}` blocks the renderer could not resolve — the port of\n * the plugin's `on_error` callable. Observation ONLY: output degrades exactly as\n * it does without it (§0.1 lenient contract — `render()` never throws on template\n * content), and the host decides whether a report is fatal.\n *\n * Worth wiring when a render is PERSISTED rather than shown: an unresolved count\n * erases its block, which is indistinguishable in the output from copy that was\n * meant to be empty.\n */\n onPluralError?: (issue: PluralIssue) => void;\n}\n\nexport interface ValidateOptions {\n /** Plural-bucket locale for arity verdicts (§3.1); omit ⇒ default 2-form. */\n locale?: string;\n /** Slug/id allow-list; enables \"unknown #include target\" verdicts. */\n knownIncludes?: readonly string[];\n /**\n * Variable names the host will supply at render (globals / context keys).\n * Suppresses the `variable.undefined` WARNING for them — verdict is unaffected\n * (an undefined var is never an error). Case-insensitive.\n */\n knownVariables?: readonly string[];\n}\n\nexport interface Diagnostic {\n severity: 'error' | 'warning';\n /** Stable machine code — parity-gated (wording/position are not). */\n code: string;\n message: string;\n /** 1-based. */\n line: number;\n /** 1-based. */\n column: number;\n endLine?: number;\n endColumn?: number;\n /** Structured specifics keyed off `code`, e.g. { expected: 3, got: 2 }. */\n data?: Record<string, unknown>;\n}\n\nexport interface ExtractResult {\n refs: string[];\n sets: string[];\n includes: string[];\n}\n\nexport interface Analysis extends ExtractResult {\n diagnostics: Diagnostic[];\n /** Best-effort construct counts — NOT a variant-cardinality promise (§9.3). */\n constructs: Record<string, number>;\n}\n\n/** Default value for {@link RenderOptions.maxDepth}. */\nexport { DEFAULT_MAX_DEPTH } from './internal/pipeline';\n\n// ─── Locale helpers ──────────────────────────────────────────────────────────\n//\n// Exported so a consumer that must AGREE with the engine about plurals can ask\n// it, instead of keeping a copy of the table. A copy is not hypothetical: this\n// repo's own authoring prompt kept one, and it drifted twice — once on content\n// (a new locale added in one place) and once on shape (`locale.slice(0, 2)`\n// instead of this normalization, which disagrees on any 3-letter tag).\n//\n// `findPluralBlocks` is deliberately NOT exported alongside these: it returns\n// byte offsets into the source, i.e. parser internals, and publishing it would\n// freeze that shape and invite consumers to build on the parse layer — the same\n// reason `Ast` is opaque (see its doc above).\n\n/**\n * A locale's base language tag: `pt-BR`→`pt`, `uk_UA`→`uk`, `RU`→`ru`. Absent or\n * empty gives `''`.\n *\n * Knows nothing of ISO-639-3, so a 3-letter tag is returned whole (`srp`→`srp`)\n * and is NOT recognized as its 2-letter language.\n */\nexport function normalizeBaseLang(locale?: string | null): string {\n return normalizeBaseLangInternal(locale ?? '');\n}\n\n/**\n * How many `{plural …}` forms this locale takes — 3 for the Slavic one/few/other\n * family (ru/uk/be + sr/hr/bs), 2 for everything else.\n *\n * Takes a RAW locale and normalizes internally, unlike the internal helper of the\n * same name: a public function that silently answered 2 for `sr-Latn` would be a\n * trap. Accepts an absent locale, and unknown tags fall back to 2 rather than\n * throwing (§3.1), so the same optional value `RenderOptions.locale` carries can be\n * passed straight through.\n *\n * NOTE the asymmetry with {@link validate}: an absent or empty locale makes the\n * validator skip the arity check ENTIRELY (structural verdicts only), whereas this\n * answers the 2-form default that {@link render} would then apply. Ask this what\n * render will do; do not read it as \"what validate will enforce\".\n */\nexport function pluralArity(locale?: string | null): number {\n return pluralArityForBase(normalizeBaseLang(locale));\n}\n\n// ─── Errors (§9.3 — minimal, not a taxonomy) ─────────────────────────────────\n\nexport { SpintaxError, IncludeResolverError, AstVersionError, NotImplementedError } from './internal/errors';\n\n// ─── Public API surface (§9.2) ───────────────────────────────────────────────\n\nexport function parse(src: string): Ast {\n return parseTemplate(src);\n}\n\nexport function render(input: string | Ast, opts: RenderOptions = {}): string {\n // Public entry: seed the rng, then run the shared pipeline (internal/pipeline).\n return renderWith(input, makeRng(opts.seed), opts);\n}\n\nexport function validate(input: string | Ast, opts: ValidateOptions = {}): Diagnostic[] {\n return validateTemplate(resolveSource(input), opts);\n}\n\n/** Resolve a `string | Ast` input to its source text (for the raw-text checks). */\nfunction resolveSource(input: string | Ast): string {\n if (typeof input === 'string') return input;\n if (isParsedAst(input)) return input.source;\n throw new AstVersionError('Ast was not produced by this engine version.');\n}\n\nexport function extract(input: string | Ast): ExtractResult {\n return extractFromSource(resolveSource(input));\n}\n\nexport function analyze(input: string | Ast, opts: ValidateOptions = {}): Analysis {\n const ast = resolveAst(input);\n const extracted = extractFromSource(ast.source);\n return {\n ...extracted,\n diagnostics: validateTemplate(ast.source, opts),\n constructs: countConstructs(ast, extracted.includes.length),\n };\n}\n\n/** Resolve a `string | Ast` input to a parsed AST (parses a string fresh). */\nfunction resolveAst(input: string | Ast): ParsedAst {\n if (typeof input === 'string') return parseTemplate(input);\n if (isParsedAst(input)) return input;\n throw new AstVersionError('Ast was not produced by this engine version.');\n}\n\n/**\n * Best-effort construct census (§9.3) — counts author-visible constructs, NOT a\n * variant-cardinality promise. `set`/`include` are directive counts; the rest are\n * AST node types (nested nodes included; literals excluded).\n */\nfunction countConstructs(ast: ParsedAst, includeCount: number): Record<string, number> {\n const counts: Record<string, number> = {\n enumeration: 0,\n permutation: 0,\n variable: 0,\n conditional: 0,\n plural: 0,\n };\n walk(ast.nodes, (n) => {\n if (n.type in counts) counts[n.type] = (counts[n.type] ?? 0) + 1;\n });\n counts.set = Object.keys(ast.setDefs).length;\n counts.include = includeCount;\n return counts;\n}\n\nexport function neutralize(value: string): string {\n return neutralizeValue(value);\n}\n"]}
|