@cbortech/cbor 0.27.1 → 0.27.2
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/README.ja.md +27 -0
- package/README.md +28 -0
- package/dist/ast/CborItem.d.ts +17 -2
- package/dist/ast/CborTag.d.ts +22 -0
- package/dist/ast/CborUnresolvedAppExt.d.ts +9 -0
- package/dist/ast/index.cjs +1 -1
- package/dist/ast/index.js +2 -2
- package/dist/cbor/tagLabels.d.ts +26 -0
- package/dist/cddl/eRefScope.d.ts +241 -0
- package/dist/cddl/eref.d.ts +64 -0
- package/dist/cddl/implicitTags.d.ts +28 -0
- package/dist/cddl/index.cjs +2 -2
- package/dist/cddl/index.cjs.map +1 -1
- package/dist/cddl/index.d.ts +2 -0
- package/dist/cddl/index.js +26 -25
- package/dist/cddl/index.js.map +1 -1
- package/dist/cddl/validator.d.ts +98 -2
- package/dist/cdn/index.cjs +1 -1
- package/dist/cdn/index.js +1 -1
- package/dist/cdn/serialize-utils.d.ts +20 -13
- package/dist/extensions/eref.d.ts +135 -0
- package/dist/index.cjs +7 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +190 -81
- package/dist/index.js.map +1 -1
- package/dist/js/fromJS.d.ts +23 -1
- package/dist/mapEntries-8zshEr-t.js +7085 -0
- package/dist/mapEntries-8zshEr-t.js.map +1 -0
- package/dist/mapEntries-DwHPAzCN.cjs +68 -0
- package/dist/mapEntries-DwHPAzCN.cjs.map +1 -0
- package/dist/schema-7r2xjpMK.js +345 -0
- package/dist/schema-7r2xjpMK.js.map +1 -0
- package/dist/schema-YiigSWjR.cjs +8 -0
- package/dist/schema-YiigSWjR.cjs.map +1 -0
- package/dist/{serialize-utils-h-CVB9rg.js → serialize-utils-BQtutOo6.js} +14 -6
- package/dist/serialize-utils-BQtutOo6.js.map +1 -0
- package/dist/{serialize-utils-DhlW61ZX.cjs → serialize-utils-DQ8T3Mzw.cjs} +5 -5
- package/dist/serialize-utils-DQ8T3Mzw.cjs.map +1 -0
- package/dist/types.d.ts +153 -4
- package/package.json +8 -8
- package/dist/mapEntries-CCLaJSaJ.js +0 -4127
- package/dist/mapEntries-CCLaJSaJ.js.map +0 -1
- package/dist/mapEntries-CZZJScaj.cjs +0 -13
- package/dist/mapEntries-CZZJScaj.cjs.map +0 -1
- package/dist/schema-DN9inJny.js +0 -1977
- package/dist/schema-DN9inJny.js.map +0 -1
- package/dist/schema-zsg5yCPK.cjs +0 -63
- package/dist/schema-zsg5yCPK.cjs.map +0 -1
- package/dist/serialize-utils-DhlW61ZX.cjs.map +0 -1
- package/dist/serialize-utils-h-CVB9rg.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapEntries-DwHPAzCN.cjs","names":[],"sources":["../src/cddl/errors.ts","../src/tag.ts","../src/types.ts","../src/simple.ts","../src/utils/float16.ts","../src/cbor/encode.ts","../src/ast/CborItem.ts","../src/ast/CborUint.ts","../src/ast/CborNint.ts","../src/utils/hexfloat.ts","../src/ast/CborFloat.ts","../src/cbor/tagLabels.ts","../src/ast/CborTag.ts","../src/ast/CborByteString.ts","../src/ast/CborIndefiniteByteString.ts","../src/ast/CborIndefiniteTextString.ts","../src/ast/CborArray.ts","../src/ast/CborMap.ts","../src/ast/CborSimple.ts","../src/ast/CborEmbeddedCBOR.ts","../src/utils/strip-comments.ts","../src/extensions/b32.ts","../src/ast/CborUnresolvedAppExt.ts","../src/ast/CborAppSeqResult.ts","../src/ast/CborEllipsis.ts","../src/ast/CborBignum.ts","../src/cdn/parser.ts","../src/ast/CborTextString.ts","../src/extensions/dt.ts","../src/utils/ip.ts","../src/extensions/ip.ts","../src/extensions/cri.ts","../src/extensions/bignum.ts","../src/cbor/decoder.ts","../src/extensions/cbordata.ts","../src/extensions/ellipsis.ts","../src/extensions/concat.ts","../src/extensions/ilstrings.ts","../src/extensions/float.ts","../src/extensions/builtins.ts","../src/cddl/eref.ts","../src/cddl/tokenizer.ts","../src/cddl/parser.ts","../src/cddl/prelude.ts","../src/cddl/equal.ts","../src/cddl/controls.ts","../src/cddl/validator.ts","../src/cddl/eRefScope.ts","../src/extensions/eref.ts","../src/js/fromJS.ts","../src/mapEntries.ts"],"sourcesContent":["/**\n * Structured errors thrown by the CDDL tokenizer, parser, and compiler.\n *\n * Both carry source positions so tooling (editors, linters, playgrounds) can\n * point at the offending range without parsing the message.\n */\n\n/** A semantic problem found while compiling a syntactically valid CDDL file. */\nexport interface CddlWarning {\n /** Stable machine-readable identifier, e.g. 'undefined-name'. */\n code:\n | 'no-rules'\n | 'duplicate-rule'\n | 'undefined-name'\n | 'generic-arity'\n | 'invalid-major'\n | 'invalid-root';\n message: string;\n /** Character offset of the start of the offending range in the source input. */\n start?: number;\n /** Character offset just past the end of the offending range. */\n end?: number;\n}\n\n/**\n * A single validation failure. When a data item does not match the schema,\n * the reported error is the one recorded at the deepest point the matcher\n * reached (failures discarded by backtracking are noise and are not kept).\n */\nexport interface CddlValidationError {\n message: string;\n /** Location inside the instance, e.g. '/claims/2/name' ('' = root). */\n path: string;\n /** Instance-side source offsets (byte offsets for CBOR input, character\n * offsets for CDN input), when the input carried them. */\n start?: number;\n end?: number;\n /** The CDDL rule being matched when the failure was recorded. */\n ruleName?: string;\n /** Schema-side source offsets of the CDDL construct that failed to match. */\n schemaStart?: number;\n schemaEnd?: number;\n}\n\n/** A non-fatal observation made while validating (e.g. unsupported control\n * operators, whose targets are then matched without the constraint). */\nexport interface CddlValidationWarning {\n message: string;\n schemaStart?: number;\n schemaEnd?: number;\n}\n\n/** Result of {@link CddlSchema.validate}. */\nexport interface ValidationResult {\n valid: boolean;\n /** Empty when valid; otherwise the deepest-reach failure(s). */\n errors: CddlValidationError[];\n /** Present when the validator had to approximate or skip constraints. */\n warnings?: CddlValidationWarning[];\n}\n\n/** Syntax error thrown by the CDDL tokenizer and parser. */\nexport class CddlSyntaxError extends SyntaxError {\n /** Character offset of the start of the offending range in the source input. */\n readonly offset?: number;\n /** 1-based line number of the offending range. */\n readonly line?: number;\n /** 1-based column number of the offending range. */\n readonly column?: number;\n /** Character offset just past the end of the offending range. */\n readonly endOffset?: number;\n\n constructor(\n message: string,\n position?: {\n offset?: number;\n line?: number;\n column?: number;\n endOffset?: number;\n }\n ) {\n const loc =\n position?.line !== undefined\n ? ` at line ${position.line}, column ${position.column}`\n : '';\n super(`CDDL parse error${loc}: ${message}`);\n this.name = 'CddlSyntaxError';\n this.offset = position?.offset;\n this.line = position?.line;\n this.column = position?.column;\n this.endOffset = position?.endOffset;\n }\n}\n\n/**\n * Error thrown when a data item does not match a CDDL schema supplied via\n * the `cddl` option of a throwing entry point (`CBOR.parse`, `CBOR.decode`,\n * `CBOR.fromCDN`, `CBOR.encode`, …). Non-throwing checks (`CBOR.validate`,\n * `CddlSchema.validate`) report the same failures in their result instead.\n */\nexport class CddlMismatchError extends Error {\n /** The deepest-reach validation failure(s). */\n readonly errors: CddlValidationError[];\n /** Non-fatal validator observations (approximated/skipped constraints). */\n readonly warnings: CddlValidationWarning[];\n\n constructor(\n errors: CddlValidationError[],\n warnings: CddlValidationWarning[] = []\n ) {\n const head = errors[0];\n const loc = head?.path ? ` at ${head.path}` : '';\n const rest = errors.length > 1 ? ` (and ${errors.length - 1} more)` : '';\n super(`CDDL validation failed${loc}: ${head?.message ?? 'unknown'}${rest}`);\n this.name = 'CddlMismatchError';\n this.errors = errors;\n this.warnings = warnings;\n }\n}\n\n/**\n * Semantic error thrown by `CDDL.compile` in strict mode (the default) when\n * a syntactically valid file has semantic problems: undefined names,\n * duplicate rule definitions, generic arity mismatches, and the like.\n * With `strict: false` the same problems are collected into\n * `CddlSchema.warnings` instead.\n */\nexport class CddlSemanticError extends Error {\n readonly warnings: CddlWarning[];\n\n constructor(warnings: CddlWarning[]) {\n const head = warnings[0];\n const rest =\n warnings.length > 1 ? ` (and ${warnings.length - 1} more)` : '';\n super(`CDDL semantic error: ${head?.message ?? 'unknown'}${rest}`);\n this.name = 'CddlSemanticError';\n this.warnings = warnings;\n }\n}\n","export const CBOR_TAG: unique symbol = Symbol.for('cbor.tag');\n\n// ─── Internal wrappers ────────────────────────────────────────────────────────\n\nexport class Null {\n valueOf(): null {\n return null;\n }\n toJSON(): null {\n return null;\n }\n}\n\nexport class Undefined {\n valueOf(): undefined {\n return undefined;\n }\n toJSON(): undefined {\n return undefined;\n }\n}\n\n// ─── Public helpers ───────────────────────────────────────────────────────────\n\n/** @internal */\nexport function getCborTag(value: unknown): bigint | undefined {\n if (!_canHaveTag(value)) return undefined;\n const sym = (value as Record<symbol, unknown>)[CBOR_TAG];\n return typeof sym === 'bigint' ? sym : undefined;\n}\n\n/** @internal */\nexport function setCborTag(value: unknown, tag: bigint): object {\n let obj: object;\n switch (typeof value) {\n case 'number':\n obj = new Number(value);\n break;\n case 'string':\n obj = new String(value);\n break;\n case 'boolean':\n obj = new Boolean(value);\n break;\n case 'bigint':\n obj = Object(value);\n break;\n case 'undefined':\n obj = new Undefined();\n break;\n case 'object':\n if (value === null) {\n obj = new Null();\n break;\n }\n obj = value as object;\n break;\n default:\n throw new TypeError(\n `setCborTag: cannot tag value of type ${typeof value}`\n );\n }\n (obj as Record<symbol, bigint>)[CBOR_TAG] = tag;\n return obj;\n}\n\n/** @internal */\nexport function removeCborTag(value: unknown): unknown {\n if (value instanceof Number) return value.valueOf();\n if (value instanceof String) return value.valueOf();\n if (value instanceof Boolean) return value.valueOf();\n if (Object.prototype.toString.call(value) === '[object BigInt]')\n return (value as { valueOf(): bigint }).valueOf();\n if (value instanceof Null) return null;\n if (value instanceof Undefined) return undefined;\n if (typeof value === 'object' && value !== null) {\n delete (value as Record<symbol, unknown>)[CBOR_TAG];\n return value;\n }\n return value;\n}\n\n/** @internal */\nexport function getCborTaggedValue(value: unknown): unknown {\n if (value instanceof Number) return value.valueOf();\n if (value instanceof String) return value.valueOf();\n if (value instanceof Boolean) return value.valueOf();\n if (Object.prototype.toString.call(value) === '[object BigInt]')\n return (value as { valueOf(): bigint }).valueOf();\n if (value instanceof Null) return null;\n if (value instanceof Undefined) return undefined;\n return value;\n}\n\n// ─── Internal helper ──────────────────────────────────────────────────────────\n\n/** Return true if value can carry the [CBOR_TAG] symbol (i.e. is a non-null object). */\nfunction _canHaveTag(value: unknown): value is object {\n // All boxed primitives (Number, String, Boolean, BigInt objects) also have\n // typeof === 'object', so a single check covers all cases.\n return typeof value === 'object' && value !== null;\n}\n\n// ─── Tag namespace ────────────────────────────────────────────────────────────\n\n/**\n * Namespace for CBOR tag annotation utilities.\n *\n * @example\n * const v = CBOR.fromCDN('42(\"hello\")').toJS();\n * Tag.get(v); // 42n\n * Tag.getValue(v); // \"hello\"\n *\n * const tagged = Tag.set([1, 2, 3], 100n);\n * Tag.remove(tagged); // [1, 2, 3]\n */\nexport class Tag {\n private constructor() {}\n\n /** Unique symbol used to attach a CBOR tag number to a JS value. */\n static readonly symbol: typeof CBOR_TAG = CBOR_TAG;\n\n /** Wrapper class for tagged `null` values. */\n static readonly Null = Null;\n\n /** Wrapper class for tagged `undefined` values. */\n static readonly Undefined = Undefined;\n\n /** Return the CBOR tag number attached to `value`, or `undefined` if none. */\n static get(value: unknown): bigint | undefined {\n return getCborTag(value);\n }\n\n /** Attach a CBOR tag number to `value` and return the annotated value. */\n static set(value: unknown, tag: bigint): object {\n return setCborTag(value, tag);\n }\n\n /** Remove the `[Tag.symbol]` annotation from `value` and return the plain value. */\n static remove(value: unknown): unknown {\n return removeCborTag(value);\n }\n\n /** Return the underlying plain JS value held inside a tagged wrapper. */\n static getValue(value: unknown): unknown {\n return getCborTaggedValue(value);\n }\n}\n","/**\n * Shared option types and plugin interfaces.\n */\n\n// ─── Omit sentinel ───────────────────────────────────────────────────────────\n\n/**\n * Sentinel returned from a replacer or reviver to omit the key/element from\n * the output. Use this instead of returning `undefined` when `undefinedOmits`\n * is `false` (the default) and you need to drop a specific entry.\n *\n * Accessible as `CBOR.OMIT` on the main class.\n */\nexport const CBOR_OMIT: unique symbol = Symbol('cbor.omit');\n\n// ─── Extension plugin ─────────────────────────────────────────────────────────\n// Defined in extensions/types.ts and re-exported here for convenience.\nexport type { CborExtension } from './extensions/types';\nimport type { CborExtension } from './extensions/types';\n\n// Type-only; used only by ItemContext/itemOptions below. Safe despite the\n// reverse direction (ast/CborItem.ts imports types from here) because type\n// imports are erased at compile time — there is no runtime circular require.\nimport type { CborItem } from './ast/CborItem';\n\n// ─── CDDL ─────────────────────────────────────────────────────────────────────\n// Type-only imports; note however that supporting CDDL source text as the\n// `cddl` option makes the facade (cbor.ts) import the compiler at runtime,\n// so the main entry loads the CDDL chunks as well. Accepting only compiled\n// schemas would keep the compiler exclusive to the `/cddl` subpath.\nimport type { CddlSchema } from './cddl/schema';\nimport type { ValidateOptions as CddlValidateOptions } from './cddl/validator';\nimport type { CddlValidationError, CddlValidationWarning } from './cddl/errors';\n\n// ─── Per-item option overrides ─────────────────────────────────────────────────\n\n/**\n * Context passed to an `itemOptions` callback (see `ToJSOptions.itemOptions`)\n * describing where the node being visited sits in the tree.\n */\nexport interface ItemContext {\n /**\n * The direct parent AST node. `undefined` for the root value being\n * converted. A tag or app-sequence wrapper is its content's `parent` —\n * see `path` for how wrappers affect addressing.\n */\n parent?: CborItem;\n\n /**\n * The path segment identifying this node: an array index (`number`), or a\n * map key's JS value (any type — CBOR keys are not limited to strings).\n * Always equal to the last element of `path`, except `undefined` for the\n * root value and while converting a map key itself (`isMapKey: true`),\n * since a key has no path of its own — it names its sibling value's\n * segment instead. A tag or app-sequence wrapper's content inherits the\n * wrapper's own `key` (and `path`) unchanged, since the wrapper adds no\n * segment of its own — see `path`.\n */\n key?: unknown;\n\n /**\n * The map key's own AST node, present when this node is a map entry's key\n * or value — but *not* inherited into a tag/app-sequence wrapper's\n * content the way `key`/`path` are, so it is only reliable at the map\n * entry itself. Lets a callback inspect a non-scalar key structurally\n * (e.g. via `keyNode._toCDN()`) instead of relying only on `key`'s\n * computed JS value.\n */\n keyNode?: CborItem;\n\n /**\n * `true` when this invocation is for converting a map key itself, rather\n * than one of that key's sibling value's descendants.\n */\n isMapKey?: boolean;\n\n /**\n * Path from the root to this node, as a sequence of array indices and map\n * key JS values. Empty for the root value. A tag or app-sequence wrapper\n * does not add a segment of its own — its content shares the wrapper's own\n * path.\n */\n readonly path: readonly unknown[];\n\n /**\n * The options in effect for this node going into this call — i.e. the\n * root options merged with whatever overrides its ancestors already\n * returned, *before* this callback's own return value is merged on top.\n * Read from this to build on the current value of an option (e.g. add an\n * extension to whatever list is already in effect) instead of overriding\n * it outright, or to make a decision based on an option's current value.\n *\n * A mutable-looking field here (currently just `extensions`) is a fresh\n * copy, not the live array in effect elsewhere — mutating it in place\n * (e.g. `ctx.options.extensions.push(ext)`) has no effect on this node,\n * its siblings, or the caller's own options; return an override instead.\n *\n * Has no `reviver` — its type is `ReadonlyToJSNodeOptions`, not\n * `ToJSOptions` — for the same reason this callback's own return value\n * can't set one:\n * since this callback may run more than once for the same node (see\n * `ToJSOptions.itemOptions`), always reflecting only the reviver-\n * independent options keeps what it reads consistent with what it can\n * write, and keeps a callback that only inspects `options` pure across\n * every one of those calls.\n *\n * @example\n * // Add `dt_as_Date` to whatever extensions are already configured,\n * // rather than replacing them.\n * itemOptions: (_node, ctx) => ({\n * extensions: [...(ctx.options.extensions ?? []), dt_as_Date],\n * })\n */\n readonly options: ReadonlyToJSNodeOptions;\n}\n\n/**\n * `ToJSOptions` with `reviver` removed. Used wherever an API only ever\n * needs to see the reviver-*independent* part of the options in effect for\n * a node — an `itemOptions` callback's return value, and the `options`\n * parameter of `CborExtension.toJS()` — because reviving the value a node\n * converts to always happens afterwards, exactly once per visit, in the\n * container holding it (see `CborArray`/`CborMap`); it is never something\n * the conversion of the node itself should (or, for `CborExtension.toJS()`,\n * even can) branch on. Keeping `reviver` out of both signatures — rather\n * than merely documenting that it should be ignored — means neither can\n * observe whether one is present, which is what makes it safe for a\n * `reviver`-driven `CborArray`/`CborMap` to convert a child more than once\n * (see `ToJSOptions.itemOptions`) without either one's result depending on\n * *which* of those conversions it was called for.\n */\nexport type ToJSNodeOptions = Omit<ToJSOptions, 'reviver'>;\n\n/**\n * `ToJSNodeOptions`, as handed to code that must not mutate it in place:\n * `ItemContext.options` and the `options` parameter of\n * `CborExtension.toJS()`. Both describe options actually in effect\n * elsewhere in the tree, so mutating what's handed out here must not be\n * able to reach that: reassigning a top-level property is a type error\n * (`Readonly<...>`), and `extensions`, the one field on `ToJSOptions`\n * that's an ordinary mutable array, is narrowed to a readonly array so an\n * in-place mutation like `.push()` is one too. This only guards against\n * *accidental* mutation via the type system — the implementation\n * additionally hands out a fresh snapshot, with its own copy of\n * `extensions`, on every call, so even a deliberate cast past this type\n * can't corrupt what another node, sibling, hook, or pass sees (see\n * `_toJSChild`'s `toReadonlyNodeOptions`).\n */\nexport type ReadonlyToJSNodeOptions = Readonly<\n Omit<ToJSNodeOptions, 'extensions'>\n> & {\n readonly extensions?: readonly CborExtension[];\n};\n\n// ─── Options ──────────────────────────────────────────────────────────────────\n\nexport interface ToHexDumpOptions {\n /**\n * Indentation per nesting level.\n * - `number`: number of spaces (e.g. `3` → `\" \"`)\n * - `string`: literal indent string (e.g. `'\\t'`)\n * @default 3\n */\n indent?: number | string;\n /** Comment marker used in the hex dump. Default: `'--'` */\n commentStyle?: '--' | '#';\n}\n\nexport interface ToJSOptions {\n /**\n * How to represent CBOR integer values (major type 0 / 1) in JavaScript.\n * - `'auto'`: `number` when the value is within the safe integer range\n * (±`Number.MAX_SAFE_INTEGER`), `bigint` otherwise.\n * - `'number'`: always `number` (precision may be lost for large values).\n * - `'bigint'`: always `bigint`.\n * @default 'auto'\n */\n integerAs?: 'auto' | 'number' | 'bigint';\n\n /**\n * How to represent CBOR map values when converting to JavaScript.\n * - `'auto'`: `Record<string, unknown>` when every key is a text string,\n * or (with a CDDL `cddl` schema and `eRefKeys` not `false`) an e-ref\n * annotated integer key that resolves to its name string — `Map<unknown,\n * unknown>` for any other key type. Duplicate *text-string* keys are\n * silently overwritten (last value wins), same as `'object'` below —\n * but if a text-string key and an e-ref name key resolve to the same\n * property string (e.g. `&(title: -1)` alongside a literal `\"title\"`\n * key in the same map), `'auto'` falls back to `MapEntries` instead of\n * silently dropping one of them.\n * - `'object'`: always `Record<string, unknown>` — non-string keys are\n * converted via `String()`. Duplicate keys (including a text/e-ref\n * collision as above) are overwritten (last wins) — unlike `'auto'`,\n * `'object'` never falls back, since it was explicitly requested.\n * - `'entries'`: always `MapEntries` (a typed `Array` subclass) — preserves all\n * entries including duplicate keys (§2.4.2 of draft-ietf-cbor-edn-literals-27).\n * `fromJS()` recognises `MapEntries` instances and converts them back to `CborMap`.\n * @default 'auto'\n */\n mapAs?: 'auto' | 'object' | 'entries';\n\n /**\n * When `true`, CBOR tag annotations are omitted from the JavaScript value.\n *\n * By default, generic tags are preserved using `CBOR.Tag` so that\n * `toJS()` → `fromJS()` can round-trip CBOR tags. Enable this option when\n * you only need the tagged content as a plain JavaScript value.\n *\n * @default false\n */\n stripTags?: boolean;\n\n /**\n * Whether a tag the CDDL schema itself implies is left off the JavaScript\n * value — e.g. with `{ t: time }` (prelude `time = #6.1(number)`), the\n * CBOR `{\"t\": 1(-14159024)}` (CDN `{\"t\": DT'1969-07-21T02:56:16Z'}`)\n * converts to `{ t: -14159024 }` (a plain `number`) rather than a\n * `Number` object carrying `Tag.symbol`.\n *\n * A tag counts as implied only where `FromJSOptions.implicitTags` would\n * add it back when converting the result with the same schema, so\n * `toJS()` → `fromJS()` still round-trips: it must be matched by a\n * `#6.N(type)` with a literal tag number, and the untagged content must\n * not be acceptable at that position on its own — under `time / number`\n * a tagged `1(5)` keeps its tag, since plain `5` would stay untagged.\n * Tags the schema doesn't require (`any`, `#6.<uint>(…)`, …) are always\n * kept.\n *\n * Only takes effect for an item validated via `FromCBOROptions.cddl` /\n * `FromCDNOptions.cddl` / `FromJSOptions.cddl`; without a schema, every\n * tag is kept as before. Pass `false` to keep every tag even with one.\n * `stripTags: true` removes all tags regardless.\n *\n * @default true\n */\n implicitTags?: boolean;\n\n /**\n * Post-conversion reviver function, applied bottom-up after the CBOR value\n * has been converted to JavaScript.\n *\n * Called for every key/value pair — including map entries with non-string\n * keys — and finally for the root value with key `''`.\n * Return `CBOR.OMIT` to remove the entry from its parent container.\n * When `undefinedOmits` is `true`, returning `undefined` also removes the\n * entry (matching `JSON.parse` behavior).\n *\n * Note: this option is honoured by `CborItem.toJS()` and the `CBOR.*`\n * shortcut methods. Calling `_toJS()` directly bypasses it.\n */\n reviver?: (this: unknown, key: unknown, value: unknown) => unknown;\n\n /**\n * When `true`, a reviver returning `undefined` removes the entry from its\n * parent container, matching `JSON.parse` behavior.\n * When `false` (default), only `CBOR.OMIT` removes an entry; returning\n * `undefined` keeps the entry as CBOR `undefined` (simple 23).\n * @default false\n */\n undefinedOmits?: boolean;\n\n /**\n * Extension plugins consulted during `toJS()`, tried in order for every\n * node before its own default conversion. An extension takes part by\n * implementing `CborExtension.toJS()`; the first one to return a result\n * for a given node wins and that node's own `_toJS()` is not called.\n *\n * Unlike the `extensions` option on `FromCDNOptions`/`FromCBOROptions`,\n * this does not affect parsing — it only lets `toJS()` reinterpret nodes\n * that a *different* extension configuration already produced. For\n * example, a tree parsed with the plain `dt` extension (`DT'...'` →\n * `number`) can still be converted with `dt_as_Date` selected here\n * (`DT'...'` → `Date`), and vice versa — see `itemOptions` below to apply\n * this to only part of a tree.\n *\n * There is no `builtinExtensions` equivalent for `toJS()`: leaving this\n * unset (the default) keeps every node's own built-in conversion\n * behavior, so no bundled extension needs to be \"re-added\" here just to\n * get default output.\n */\n extensions?: CborExtension[];\n\n /**\n * Called for every node during `toJS()`, before that node is converted,\n * to override the options used for its subtree. Return a partial options\n * object to merge over the options in effect for this node (they apply to\n * this node and are inherited by its descendants, who may override them\n * again); return `undefined` to make no change.\n *\n * This is the mechanism for applying an option — including `extensions`,\n * to select a different conversion for one node without affecting its\n * siblings — to only part of a document, keyed off `ctx.path` or the\n * node's own shape (`item instanceof ...`).\n *\n * **May be called more than once for the same AST node.** With a\n * `reviver` present, `CborArray`/`CborMap` convert each child at least\n * twice: once (with `reviver` itself withheld from the options this\n * callback sees, though its own return value is honoured as normal) to\n * build a holder a `reviver` call can inspect via `this[j]` for a\n * not-yet-processed sibling `j`, and once more, for real, to compute the\n * value the container actually keeps — and a node several levels down\n * can in principle be offered to this callback more than twice, if a\n * container at some intermediate level runs a pre-population pass of its\n * own while itself sitting inside an *outer* container's. Each call is\n * independent and reflects only the state relevant to *that* particular\n * conversion (e.g. `ctx.path` for a value under a composite map key\n * shows whatever that key currently converts to, which can differ\n * between an earlier, not-yet-revived call and a later one after the\n * key's own `reviver` has run). Write this callback as a pure function of\n * `item`/`ctx` — it must not assume, or count, how many times it runs.\n *\n * @example\n * // Convert only `date1` with `dt_as_Date`, leaving other DT values as\n * // the epoch numbers the tree was originally parsed with.\n * item.toJS({\n * itemOptions: (node, ctx) =>\n * ctx.path.length === 1 && ctx.path[0] === 'date1'\n * ? { extensions: [dt_as_Date] }\n * : undefined,\n * });\n */\n itemOptions?: (\n item: CborItem,\n ctx: ItemContext\n ) => Partial<ToJSNodeOptions> | undefined;\n\n /**\n * Whether a map key annotated by CDDL `e'...'` external-reference\n * resolution (draft-ietf-cbor-edn-e-ref) — an integer key the `cddl`\n * schema names via a `&(name: value)` group entry at a map-member-key\n * position, e.g. `? &(title: -1) => oltext` — converts to a plain-object\n * key spelled as that name (`\"title\"`) instead of the integer itself. A\n * general CDDL constant rule (`title = -1`) is not enough on its own to\n * annotate a key this way — see `cddl/eref.ts`'s module doc — only\n * `e'title'` written explicitly in CDN source resolves via a plain\n * constant rule.\n *\n * Defaults to `true`: such a key exists at all only because some earlier\n * `cddl`-validated decode/parse (or an `eRefKeys`-driven `fromJS()`, see\n * `FromJSOptions.eRefKeys`) already named it, so leaving this option unset\n * uses that name — pass `false` explicitly to fall back to the plain\n * integer key instead (e.g. for code that reads `obj[-1]` and doesn't\n * want it silently renamed to `obj.title`). A map with no CDDL-named keys\n * at all is entirely unaffected either way — `mapAs: 'auto'`'s own choice\n * between a plain object and `MapEntries` only ever treats a key as\n * object-eligible via this option when the key is actually annotated;\n * this is not a general \"coerce integer keys to strings\" switch.\n *\n * Only takes effect for a key CDDL validation has already annotated (see\n * `FromCBOROptions.cddl` / `FromCDNOptions.cddl`); without a schema, or for\n * a key the schema does not name this way, the key converts as usual.\n * Annotation is unambiguous by construction (a name mapped to more than\n * one value, or a value named more than once, in the same schema is\n * excluded from annotation entirely — and a name ambiguous in either\n * direction is excluded from *both*), so this never introduces a name\n * collision on its own — though a name can still collide with an\n * unrelated map's own genuine text-string key of the same spelling\n * (e.g. `&(title: -1)` alongside a literal `\"title\"` key in the same\n * map). `mapAs: 'auto'` treats that case differently from a plain\n * duplicate text-string key: it detects the collision and falls back to\n * `MapEntries` rather than silently dropping one side — see\n * `ToJSOptions.mapAs`. An explicit `mapAs: 'object'` still overwrites\n * (last value wins), the same as it does for any other non-injective key\n * conversion. Only integer-valued names are annotated (see\n * `cddl/eref.ts`'s Scope note) — a float, text, or byte-string map key is\n * never affected.\n *\n * @default true\n */\n eRefKeys?: boolean;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface ToCBOROptions {}\n\n/**\n * A CBOR validity violation detected during decoding.\n */\nexport interface DecodeWarning {\n /** Human-readable description of the violation. */\n message: string;\n /** Byte offset within the decoded input where the violation was detected. */\n offset: number;\n}\n\n/**\n * A CDN/EDN validity violation detected during parsing.\n */\nexport interface ParseWarning {\n /** Human-readable description of the violation. */\n message: string;\n /** Character offset within the input text where the violation was detected. */\n offset?: number;\n /** Line number (1-based) where the violation was detected. */\n line?: number;\n /** Column number (1-based) where the violation was detected. */\n column?: number;\n /**\n * Character offset just past the end of the offending range, when the\n * violation is attributable to a specific token. Lets tooling underline\n * the exact range instead of a single position.\n */\n endOffset?: number;\n /**\n * `true` when the violation is a hard syntax error that stopped parsing\n * (emitted by non-strict sequence parsing, which reports the failure as a\n * warning and abandons the rest of the input). Tooling should present\n * fatal warnings as errors.\n */\n fatal?: boolean;\n\n /**\n * `true` when this entry is an informational hint (e.g. an app-string\n * prefix matches a known optional extension that isn't registered) rather\n * than a validity violation. Parsing is unaffected either way, but tooling\n * that treats `onWarning` calls as failures (see `CBOR.validate()`) should\n * not count these against validity.\n */\n hint?: boolean;\n\n /**\n * For a `fatal` warning built from a caught syntax error (see\n * `CdnSyntaxError`), the original error object with its position fields\n * intact. `CBOR.validate()` promotes this into `ValidateResult.error`.\n */\n cause?: Error;\n}\n\nexport interface FromCBOROptions {\n /**\n * Byte offset within the supplied input at which CBOR decoding starts.\n * Useful for reading one item from a CBOR Sequence.\n *\n * @default 0\n */\n offset?: number;\n\n /**\n * Allow bytes after the decoded item.\n *\n * When `false`, decoding still requires the item to consume the remaining\n * input, preserving the historical single-item behaviour. With `strict: false`\n * a trailing byte becomes a recoverable warning rather than an error, but\n * truly malformed trailing data (e.g. truncated items) still throws. Set this\n * to `true` when using `CborItem.end` to continue decoding a CBOR Sequence.\n *\n * @example\n * // Read two items from a CBOR Sequence, validating that the second is last.\n * const first = CBOR.fromCBOR(bytes, { allowTrailing: true });\n * const second = CBOR.fromCBOR(bytes, { offset: first.end });\n *\n * @default false\n */\n allowTrailing?: boolean;\n\n /**\n * Extension plugins applied during CBOR decoding.\n * Extensions with `parseTag()` are invoked when a tagged item is\n * encountered; returning a non-`undefined` value replaces the default\n * `CborTag` node.\n */\n extensions?: CborExtension[];\n\n /**\n * Override the default set of bundled app-extensions\n * (`dt`, `ip`, `cri`, `t1`, `b1`, `ilbs`, `ilts`, `float`).\n *\n * - omitted (default): use the standard bundled set.\n * - array: replace the bundled set with exactly these extensions.\n * - `false`: disable all of them.\n *\n * `bignum` (tags 2/3) and embedded-CBOR (tag 24) support are core RFC 8949\n * representation features, not app-extensions, and are always active\n * regardless of this option.\n *\n * `dt`, `ip`, `t1`, and `b1` are mandatory-to-implement per §3 of\n * draft-ietf-cbor-edn-literals-27; disabling them produces a decoder that\n * no longer conforms to that recommendation. This is intended for\n * allowlisting scenarios (see §8 Security considerations of the same\n * draft) where an application wants explicit control over which\n * extensions it accepts.\n */\n builtinExtensions?: CborExtension[] | false;\n\n /**\n * Controls how CBOR validity violations are handled.\n *\n * - `true` (default): violations call `onWarning` and then throw, stopping\n * decoding immediately.\n * - `false`: recoverable violations call `onWarning` and decoding continues\n * with a best-effort interpretation of the data.\n *\n * Truly malformed data (e.g. truncated input, reserved AI values) always\n * throws regardless of this setting. Trailing bytes after a successfully\n * decoded item are a recoverable violation and are therefore controlled by\n * this flag.\n *\n * @default true\n */\n strict?: boolean;\n\n /**\n * Callback invoked when a CBOR validity violation is detected.\n *\n * In strict mode (the default), this is called before the error is thrown.\n * In non-strict mode (`strict: false`), this is called and decoding\n * continues.\n *\n * If not supplied and `silent` is not `true`, violations are reported via\n * `console.warn`.\n */\n onWarning?: (warning: DecodeWarning) => void;\n\n /**\n * When `true`, suppresses the default `console.warn` output for validity\n * violations. An explicit `onWarning` callback is still invoked even when\n * `silent` is `true`.\n *\n * @default false\n */\n silent?: boolean;\n\n /**\n * CDDL schema to validate decoded items against: either a compiled schema\n * (`CDDL.compile()` from `@cbortech/cbor/cddl`) or CDDL source text.\n * Source text is compiled on first use with default compile options and\n * cached, so passing the same string repeatedly does not recompile; pass a\n * compiled schema to control `CompileOptions` yourself. Invalid CDDL text\n * throws `CddlSyntaxError` / `CddlSemanticError` at the call site.\n *\n * Each decoded item is validated after decoding, against the schema's\n * root rule by default (or `cddlValidationOptions.rule`, if set); a\n * mismatch throws {@link CddlMismatchError}. Sequence entry points\n * (`fromCBORSeq`, `decodeSeq`, …) validate each item of the sequence\n * individually against that same rule. `CBOR.validate()` collects\n * mismatches into `ValidateResult.cddlErrors` instead of throwing.\n */\n cddl?: CddlSchema | string;\n\n /**\n * Options forwarded to the CDDL validator when `cddl` is supplied\n * (`features` for the `.feature` control operator, `maxDepth`,\n * `maxSteps`, and `rule` to validate against a rule other than the\n * schema's root). Ignored without `cddl`.\n */\n cddlValidationOptions?: CddlValidateOptions;\n}\n\n/**\n * Options for parsing an annotated hex dump.\n */\nexport interface FromHexDumpOptions {\n /**\n * Extension plugins applied during CBOR decoding.\n * Extensions with `parseTag()` are invoked when a tagged item is encountered;\n * returning a non-`undefined` value replaces the default `CborTag` node.\n */\n extensions?: CborExtension[];\n\n /**\n * Override the default set of bundled app-extensions.\n * Mirrors `FromCBOROptions.builtinExtensions`.\n */\n builtinExtensions?: CborExtension[] | false;\n\n /**\n * Controls how CBOR validity violations are handled during hex-dump decoding.\n * Mirrors `FromCBOROptions.strict`. With `strict: false`, trailing bytes after\n * the first decoded item (i.e. a CBOR Sequence) emit a warning instead of\n * throwing, allowing the first item to be returned.\n *\n * @default true\n */\n strict?: boolean;\n\n /**\n * Callback invoked when a CBOR validity violation is detected.\n * Mirrors `FromCBOROptions.onWarning`.\n */\n onWarning?: (warning: DecodeWarning) => void;\n\n /**\n * When `true`, suppresses the default `console.warn` output for violations.\n * Mirrors `FromCBOROptions.silent`.\n *\n * @default false\n */\n silent?: boolean;\n\n /**\n * Compiled CDDL schema to validate decoded items against.\n * Mirrors `FromCBOROptions.cddl`.\n */\n cddl?: CddlSchema | string;\n\n /**\n * Options forwarded to the CDDL validator.\n * Mirrors `FromCBOROptions.cddlValidationOptions`.\n */\n cddlValidationOptions?: CddlValidateOptions;\n}\n\nexport interface FromCDNOptions {\n /**\n * Character offset within the supplied text at which CDN parsing starts.\n * Leading whitespace/comments at or after this offset are skipped as usual.\n *\n * @default 0\n */\n offset?: number;\n\n /**\n * Allow tokens after the parsed item.\n *\n * When `false`, parsing still requires the item to consume the remaining\n * input, preserving the historical single-item behaviour. With `strict: false`\n * a trailing token becomes a recoverable warning rather than an error, but\n * hard lexer errors in the trailing content (e.g. unterminated strings) still\n * throw. Set this to `true` when using `CborItem.end` to continue parsing a\n * CDN sequence.\n * Top-level comma separators are not skipped by `fromCDN()` itself; handle\n * them in sequence-level code before passing the next `offset`. For example,\n * after parsing `1, 2`, the first item's `end` points just before the comma;\n * advance past that comma before parsing the next item.\n *\n * @example\n * // Read two whitespace-separated items, validating that the second is last.\n * const first = CBOR.fromCDN(text, { allowTrailing: true });\n * const second = CBOR.fromCDN(text, { offset: first.end });\n *\n * @default false\n */\n allowTrailing?: boolean;\n\n /**\n * Extension plugins for CDN parsing.\n * Each extension declares which app-string prefixes (and, in future, tag\n * numbers) it handles via `appStringPrefixes` / `tagNumbers`, and provides\n * callback methods that return `CborItem`-subclassed objects controlling\n * subsequent serialisation.\n *\n * User-supplied extensions take priority over the built-in `dt`/`DT`\n * extension for the same prefix.\n */\n extensions?: CborExtension[];\n\n /**\n * Override the default set of bundled app-extensions\n * (`dt`, `ip`, `cri`, `t1`, `b1`, `ilbs`, `ilts`, `float`).\n *\n * - omitted (default): use the standard bundled set.\n * - array: replace the bundled set with exactly these extensions.\n * - `false`: disable all of them; app-string literals using their\n * prefixes then fall through to `unresolvedExtension` handling.\n *\n * `dt`, `ip`, `t1`, and `b1` are mandatory-to-implement per §3 of\n * draft-ietf-cbor-edn-literals-27; disabling them produces a parser that\n * no longer conforms to that recommendation. This is intended for\n * allowlisting scenarios (see §8 Security considerations of the same\n * draft) where an application wants explicit control over which\n * extensions it accepts from untrusted CDN input.\n *\n * @example\n * // Only accept dt/DT — everything else becomes an Unresolved (tag 999) node.\n * import { CBOR, dt } from '@cbortech/cbor';\n * CBOR.fromCDN(text, { builtinExtensions: [dt] });\n */\n builtinExtensions?: CborExtension[] | false;\n\n /**\n * How to handle unrecognised app-extension identifiers\n * (§5.1 of draft-ietf-cbor-edn-literals-27).\n *\n * - `'cpa999'`: wrap the literal in a `CPA999` tag\n * (`CborUnresolvedAppExt`) instead of failing. The resulting node\n * round-trips through `toCDN()` back to the original notation.\n * - `'error'`: throw `SyntaxError` for unknown prefixes.\n * @default 'cpa999'\n */\n unresolvedExtension?: 'cpa999' | 'error';\n\n /**\n * When `true`, byte-string chunks in text string concatenation\n * (`\"a\" + h'...'`) that are not valid UTF-8 are decoded with the Unicode\n * replacement character (U+FFFD) instead of throwing a `SyntaxError`.\n *\n * The CBOR text string type (RFC 8949 §3.1) requires valid UTF-8;\n * enabling this option produces non-conformant output and should only be\n * used when interoperating with lenient producers.\n *\n * @default false\n */\n allowInvalidUtf8?: boolean;\n\n /**\n * Preserve comments found between CDN values and attach them to the AST.\n *\n * Comments are metadata only: they are ignored by CBOR binary encoding and\n * JavaScript conversion. Use together with `ToCDNOptions.preserveComments`\n * (or `comments`) to include them when formatting back to CDN.\n *\n * Passing `'c-style'`/`'cdn-style'` directly is a deprecated shorthand for\n * `true` plus the equivalent `comments` — still accepted, but prefer\n * `comments` for the output style going forward.\n *\n * @default false\n */\n preserveComments?: boolean | 'c-style' | 'cdn-style';\n\n /**\n * Companion to `preserveComments` for a single options object shared with\n * `toCDN()` (as `CBOR.format()` does internally) — see\n * `ToCDNOptions.comments` for what each value means there. On the\n * parse side, only *whether* a style other than `'strip'` was requested\n * matters: comments are captured when `preserveComments` is `true`, or\n * when `comments` is set to anything other than `'strip'`. Left\n * unset alongside an unset/`false` `preserveComments`, nothing is\n * captured.\n *\n * @default undefined\n */\n comments?: 'strip' | 'c-style' | 'cdn-style';\n\n /**\n * Shorthand for `ToCDNOptions.preserveAll`, so a single option enables\n * round-tripping through both `fromCDN()` and `toCDN()` (as\n * `CBOR.format()` does internally). On the parse side, this only implies\n * `preserveComments: true` (comments must be captured while parsing to be\n * re-emittable); the other `preserve*` behaviors are always captured by\n * the parser and only need to be turned on for `toCDN()`.\n *\n * @default false\n */\n preserveAll?: boolean;\n\n /**\n * Controls how CDN/EDN validity violations are handled.\n *\n * - `true` (default): recoverable violations call `onWarning` and then throw.\n * - `false`: recoverable violations call `onWarning` and parsing continues\n * with a best-effort interpretation of the input.\n *\n * Hard syntax errors (e.g. unterminated strings, unexpected tokens that\n * prevent parsing a value) always throw regardless of this setting.\n * A trailing token after a successfully-parsed value is a recoverable\n * violation and is therefore controlled by this flag.\n *\n * @default true\n */\n strict?: boolean;\n\n /**\n * Callback invoked when a CDN/EDN validity violation is detected.\n *\n * In strict mode (the default), this is called before the error is thrown.\n * In non-strict mode (`strict: false`), this is called and parsing continues.\n *\n * If not supplied and `silent` is not `true`, violations are reported via\n * `console.warn`.\n */\n onWarning?: (warning: ParseWarning) => void;\n\n /**\n * When `true`, suppresses the default `console.warn` output for validity\n * violations. An explicit `onWarning` callback is still invoked even when\n * `silent` is `true`.\n *\n * @default false\n */\n silent?: boolean;\n\n /**\n * Compiled CDDL schema to validate parsed items against.\n * Mirrors `FromCBOROptions.cddl`.\n */\n cddl?: CddlSchema | string;\n\n /**\n * Options forwarded to the CDDL validator.\n * Mirrors `FromCBOROptions.cddlValidationOptions`.\n */\n cddlValidationOptions?: CddlValidateOptions;\n}\n\n/**\n * Options for parsing Concise Diagnostic Notation (CDN).\n *\n * @deprecated Use `FromCDNOptions` instead.\n */\nexport type FromEDNOptions = FromCDNOptions;\n\nexport interface FromJSOptions {\n /**\n * Extension plugins applied during `fromJS()`.\n * Extensions with `fromJS()` are given first chance to convert each value.\n */\n extensions?: CborExtension[];\n\n /**\n * Override the default set of bundled app-extensions.\n * Mirrors `FromCDNOptions.builtinExtensions`. Only affects builtins that\n * implement `fromJS()` / `parseTag()` (none of the bundled app-extensions\n * implement `fromJS()` by default — use `dt_as_Date` via\n * `extensions` for `Date` round-tripping).\n */\n builtinExtensions?: CborExtension[] | false;\n\n /**\n * How to encode integer-valued JS `number`s.\n * - `'int'`: encode as CborUint / CborNint\n * - `'float'`: always encode as CborFloat\n * @default 'int'\n */\n encodeIntegerAs?: 'int' | 'float';\n\n /**\n * How to encode `Uint8Array` values.\n * - `'bytes'`: encode as CborByteString\n * - `'array'`: encode as CborArray of CborUint\n * @default 'bytes'\n */\n uint8ArrayAs?: 'bytes' | 'array';\n\n /**\n * Pre-encoding replacer function or key allowlist, applied before the\n * JavaScript value is converted to a CBOR AST node.\n *\n * - Function: called for every key/value pair (including `MapEntries`\n * entries with non-string keys). Return `CBOR.OMIT` to remove the entry.\n * When `undefinedOmits` is `true`, returning `undefined` also removes it.\n * - Array of strings/numbers: allowlist of object keys to include.\n * `MapEntries` entries retain all entries; their values are recursively\n * filtered.\n *\n * Note: this option is honoured by `fromJS()` and the `CBOR.*` shortcut\n * methods.\n */\n replacer?:\n | ((this: unknown, key: unknown, value: unknown) => unknown)\n | (string | number)[];\n\n /**\n * When `true`, a replacer returning `undefined` removes the entry from the\n * output, matching `JSON.stringify` behavior.\n * When `false` (default), only `CBOR.OMIT` removes an entry; returning\n * `undefined` keeps the entry as CBOR `undefined` (simple 23).\n * @default false\n */\n undefinedOmits?: boolean;\n\n /**\n * Compiled CDDL schema to validate the constructed item against, before\n * encoding/serialization. Mirrors `FromCBOROptions.cddl`.\n */\n cddl?: CddlSchema | string;\n\n /**\n * Options forwarded to the CDDL validator.\n * Mirrors `FromCBOROptions.cddlValidationOptions`.\n */\n cddlValidationOptions?: CddlValidateOptions;\n\n /**\n * When not `false`, a plain object's property name that the `cddl` schema\n * names — via a `&(name: value)` group entry at a map-member-key\n * position (e.g. `? &(title: -1) => oltext`), or a bare reference to a\n * constant rule at that same position — converts to that integer key\n * instead of a text-string key, so `fromJS({ title: \"oops\" }, { cddl })`\n * produces the same map `toJS()` on that map would read back as\n * `{ title: \"oops\" }` (both options default to on, so neither needs\n * spelling out explicitly to get a round-trip). The resulting key\n * round-trips through `toCDN()` as `e'title'` the same way a\n * schema-annotated key produced by `fromCBOR()`/`fromCDN()` does — only\n * an unambiguous, integer-valued name is ever used this way (see\n * `cddl/eref.ts`'s module doc).\n *\n * `ToJSOptions.eRefKeys` only ever renames an integer key some earlier\n * step already labeled (`annotateERefKeys()`, run automatically after a\n * successful `cddl`-validated decode/parse — or `e'name'` written\n * explicitly in CDN source); this direction is different, since it\n * *constructs* the key before any validation happens — so which names are\n * even eligible is resolved **positionally**: only a name bound at a member-key position\n * within the CDDL type actually governing *this* property's own position\n * (starting from the schema's root rule, or `cddlValidationOptions.rule`\n * when set, and descending through nested map types the same way this\n * object's own nesting does) is used, never a name that merely exists\n * *somewhere* in the schema. A property named `title` is therefore left\n * as an ordinary text-string key unless the schema specifically names\n * `title` at the exact position this object is being converted for —\n * even if some unrelated, structurally unreachable rule elsewhere in the\n * same schema happens to name `title` too (see `cddl/eRefScope.ts`'s own\n * module doc, including its Scope note on what \"governing type\" this can\n * and can't resolve).\n *\n * Only applies to a plain object's own properties (`Object.entries()`), not\n * to a `MapEntries` key, which is preserved exactly as given (a native\n * `Map` is not currently recognized by `fromJS()` at all — see its own\n * doc — independent of `eRefKeys`) — a `MapEntries` entry's *value* still\n * gets a nested scope when its own key is a string naming a known map\n * property, the same way an ordinary property's value does, so a nested\n * object reached this way still converts correctly; an array element\n * never does, regardless. Without a schema, or for a property name the\n * schema does not name this way at this exact position, the key converts as usual (a\n * text-string key). Pass `false` explicitly to keep every property as a\n * plain text-string key even when the schema would otherwise name one —\n * e.g. for code that writes `{ title: \"oops\" }` and wants that spelled\n * literally rather than resolved to `-1`. Requires `cddl` — has no effect\n * on its own.\n *\n * @default true\n */\n eRefKeys?: boolean;\n\n /**\n * Whether a tag the CDDL schema requires is added to a value that lacks\n * it — e.g. with `{ t: time }` (prelude `time = #6.1(number)`),\n * `{ t: -14159024 }` (a plain `number`, no `Tag.symbol`) converts to\n * `{\"t\": 1(-14159024)}` (CDN `{\"t\": DT'1969-07-21T02:56:16Z'}`). The\n * mirror image of `ToJSOptions.implicitTags`.\n *\n * Inference is a fallback, never a rewrite of valid data: nothing is\n * added when the converted value already matches the schema, and at\n * every choice an alternative the value matches as-is wins — with\n * `time / number`, a plain `5` stays `5`. Only a `#6.N(type)` with a\n * literal tag number is inferred (the tag is created the same way a\n * `Tag.symbol`-annotated value would be, so tag 1 becomes a `DT'…'`\n * node); a value already carrying `Tag.symbol` is used as given. When\n * even inference cannot make the value match, it is left unchanged and\n * the usual `CddlMismatchError` is thrown.\n *\n * Requires `cddl` — has no effect on its own. Pass `false` to require\n * every tag to be spelled out via `Tag.symbol`, as without a schema.\n *\n * @default true\n */\n implicitTags?: boolean;\n}\n\n// ─── Per-item option overrides (toCDN) ─────────────────────────────────────────\n\n/**\n * Context passed to a `toCDN()` `itemOptions` callback (see\n * `ToCDNOptions.itemOptions`) describing where the node being visited sits\n * in the tree. Structurally the same shape as `ItemContext` (`toJS()`'s\n * own per-item context — see there for the full rationale behind each\n * field), but `path`'s map-key segments are derived the CDN way: a\n * text-string key contributes its string value, any other key contributes\n * its own `toCDN()` rendering — there is no \"JS value\" for a CDN key to\n * contribute instead, since converting to JS is not what this call is\n * doing.\n *\n * Unlike `ItemContext`, a node's `toCDN()` `itemOptions` callback can run\n * more than once for reasons `toJS()`'s never does: `inlineLeafContainers`\n * (and a tag/app-sequence value's own multi-word check) render an entry a\n * second time, at the *same* depth and options, purely to answer a layout\n * question (does it fit on one line? is it multi-word?) before the real\n * render — an existing, deliberate characteristic of `toCDN()` itself (see\n * `serializeContainer` in `cdn/serialize-utils.ts`), not something\n * `itemOptions` introduces. Write this callback as a pure function of\n * `item`/`ctx`, the same guidance as `ItemContext`'s own, for the same\n * reason: it must not assume, or count, how many times it runs.\n */\nexport interface CdnItemContext {\n /** The direct parent AST node. `undefined` for the root value being converted. */\n parent?: CborItem;\n\n /**\n * The path segment identifying this node: an array index (`number`), or\n * a map key's string value/`toCDN()` rendering (see `CdnItemContext`'s\n * own note). Always equal to the last element of `path`, except\n * `undefined` for the root value and while converting a map key itself\n * (`isMapKey: true`). A tag or app-sequence wrapper's content inherits\n * the wrapper's own `key` (and `path`) unchanged, since the wrapper adds\n * no segment of its own.\n */\n key?: unknown;\n\n /** The map key's own AST node, present when this node is a map entry's key or value. */\n keyNode?: CborItem;\n\n /**\n * `true` when this invocation is for converting a map key itself, rather\n * than one of that key's sibling value's descendants.\n */\n isMapKey?: boolean;\n\n /**\n * Path from the root to this node, as a sequence of array indices and\n * map key identifiers (see `CdnItemContext`'s own note). Empty for the\n * root value. A tag or app-sequence wrapper does not add a segment of\n * its own — its content shares the wrapper's own path.\n */\n readonly path: readonly unknown[];\n\n /**\n * The options in effect for this node going into this call — the root\n * options merged with whatever overrides its ancestors already\n * returned, *before* this callback's own return value is merged on top.\n * A mutable-looking field here (currently just the deprecated\n * `textStringFormat`) is a fresh copy, not the live array in effect\n * elsewhere — mutating it in place has no effect on this node, its\n * siblings, or the caller's own options; return an override instead.\n */\n readonly options: ReadonlyToCDNOptions;\n}\n\n/**\n * `ToCDNOptions`, as handed to code that must not mutate it in place —\n * `CdnItemContext.options` — the `toCDN()` counterpart of\n * `ReadonlyToJSNodeOptions`. `textStringFormat` (the one field on\n * `ToCDNOptions` that's an ordinary mutable array, and already deprecated)\n * is narrowed to a readonly array for the same reason `extensions` is\n * there; see `ReadonlyToJSNodeOptions`'s own doc for the full rationale.\n */\nexport type ReadonlyToCDNOptions = Readonly<\n Omit<ToCDNOptions, 'textStringFormat'>\n> & {\n readonly textStringFormat?: readonly TextStringFormat[];\n};\n\nexport interface ToCDNOptions {\n /**\n * Indentation for pretty-printing.\n * - `number`: number of spaces\n * - `string`: literal indent string (e.g. `'\\t'`)\n * - omit for single-line output\n *\n * Like `JSON.stringify`, `0` and `''` are equivalent to omitting the\n * option: the output is a single line. Single-line output is guaranteed\n * to contain no newlines; layout-dependent options (`preserveComments`,\n * `preserveBlankLines`, `splitCdn`, `splitNewline`, `preserveConcatenation`)\n * are ignored.\n */\n indent?: number | string;\n\n /**\n * Master switch that turns on every `preserve*` option below at once,\n * except the deprecated `preserveTextString` — `preserveComments`,\n * `preserveByteString`, `preserveRawString`, `preserveConcatenation`,\n * `preserveNumberFormat`, `preserveAppPrefix`, and\n * `preserveBlankLines` — for reformatting CDN text (e.g. on save in an\n * editor) with minimal changes: only whitespace/indentation, plus\n * anything an explicitly-set individual option overrides.\n *\n * An option explicitly set to a value (including `false`) is left as-is;\n * `preserveAll` only fills in the ones left `undefined`. So\n * `{ preserveAll: true, preserveNumberFormat: false }` preserves\n * everything except number literal spelling. `preserveComments` is filled\n * in with `true` only when `comments` is *also* left unset — an\n * explicit `comments` with no `preserveComments` still normalizes\n * comments to that style under `preserveAll`, instead of being overridden\n * by the verbatim fill-in.\n *\n * When parsing via `CBOR.fromCDN()` separately from `toCDN()` (rather\n * than through `CBOR.format()`, which passes the same options to both),\n * also pass `preserveAll` (or `preserveComments`) to `FromCDNOptions` so\n * comments are captured in the first place — see\n * `FromCDNOptions.preserveAll`. Bignums are unaffected by\n * `preserveNumberFormat` even under `preserveAll`; see that option.\n *\n * @default false\n */\n preserveAll?: boolean;\n\n /**\n * Emit comments previously captured by `FromCDNOptions.preserveComments`,\n * with their original markers kept as-is (no normalization) — takes\n * precedence over `comments` when `true`.\n *\n * - `true`: emit comments verbatim, with whichever marker each one was\n * originally written with.\n * - `false` / omitted: defer to `comments` (see below) — `'strip'` (the\n * default when that's also unset) or unset means no comments are\n * emitted.\n * - `'c-style'` / `'cdn-style'`: deprecated shorthand for `false` plus the\n * equivalent `comments`; still accepted, but prefer setting\n * `comments` directly.\n *\n * Only effective when `indent` enables pretty-printing: single-line\n * output strips all comments regardless, since line comments (`#`, `//`)\n * can only be terminated by a newline.\n *\n * @default false\n */\n preserveComments?: boolean | 'c-style' | 'cdn-style';\n\n /**\n * Style to normalize comment markers to when emitting comments previously\n * captured by `FromCDNOptions.preserveComments` — only consulted when\n * `preserveComments` is not `true` (see there).\n *\n * - `'strip'` / omitted: don't emit comments at all.\n * - `'c-style'`: emit comments, normalising line comments to `//` and block\n * comments to `/* … *\\/`.\n * - `'cdn-style'`: emit comments, normalising line comments to `#` and block\n * comments to `/ … /`. When a `/* … *\\/` comment's content contains `/`\n * (which cannot be represented inside `/ … /`), the `/* … *\\/` form is\n * kept as-is.\n *\n * Only effective when `indent` enables pretty-printing; see\n * `preserveComments`.\n *\n * @default 'strip'\n */\n comments?: 'strip' | 'c-style' | 'cdn-style';\n\n /**\n * Re-emit a blank line above an array/map entry (or indefinite-length\n * string chunk) that had one before it anywhere in the parsed CDN source,\n * so paragraph-like groupings of entries survive a reformat. At most one\n * blank line is ever emitted per gap, regardless of how many blank lines\n * were originally there.\n *\n * Detection is based purely on entry source positions — it does not\n * require `preserveComments` and is unaffected by whether comments are\n * emitted.\n *\n * Only effective when `indent` enables pretty-printing. A container with\n * a preserved blank line is always emitted one-entry-per-line, the same\n * as a container with preserved comments (see `inlineLeafContainers`).\n *\n * @default false\n */\n preserveBlankLines?: boolean;\n\n /**\n * Re-emit byte string literals parsed from CDN using their original source\n * text when available.\n *\n * This preserves the spelling and interior layout of non-concatenated\n * `h'...'`, `b64'...'`, `b32'...'`, `h32'...'`, raw-backtick byte strings,\n * and single-quoted byte strings — including a `h'xx...yy'`-family elided\n * literal (§5.2), whose spelling is kept independently of\n * `preserveConcatenation` when it has no `+` of its own (see that\n * option). Byte strings produced by `+` concatenation are normalised as\n * usual; combine with `preserveConcatenation` to keep both the part\n * boundaries and each part's spelling.\n *\n * A comment inside the literal is stripped unless `preserveComments` is\n * also set — `preserveByteString` alone preserves everything about the\n * literal's spelling *except* its comments, the same as an unpreserved\n * literal (re-derived from the decoded value) never has comments either.\n *\n * When enabled, this takes precedence over `bstrEncoding` and `sqstr` for\n * byte strings that carry original EDN source text.\n *\n * In single-line output (no `indent`), an original spelling that spans\n * multiple lines — after any comment is stripped — falls back to normal\n * serialization; single-line spellings are kept.\n *\n * @default false\n */\n preserveByteString?: boolean;\n\n /**\n * Re-emit text strings written as raw backtick literals (`` `...` ``,\n * ``` ``...`` ```, …) using their original source text instead of\n * converting them to double-quoted form.\n *\n * Applies to non-concatenated raw string literals; combine with\n * `preserveConcatenation` to also keep the spelling of raw string parts\n * inside a `+` chain. Preserved raw strings are emitted verbatim: they are\n * never re-escaped, re-indented, or split by `splitCdn` / `splitNewline`.\n *\n * Raw byte string forms (e.g. `` h`...` ``) are covered by\n * `preserveByteString`, not this option.\n *\n * In single-line output (no `indent`), a spelling that spans multiple\n * lines falls back to normal escaping; single-line spellings are kept.\n *\n * @default false\n */\n preserveRawString?: boolean;\n\n /**\n * Re-emit double-quoted text strings (`\"...\"`) using their original CDN\n * source spelling — escape sequences (`é` vs. the literal character),\n * quoting choices, etc. — instead of re-escaping them from the decoded\n * string value.\n *\n * Applies to non-concatenated double-quoted literals only; a string\n * reached via `+` concatenation is normalised as usual regardless of this\n * option. Preserved strings are emitted verbatim: they are never\n * re-indented or split by `splitCdn` / `splitNewline`.\n *\n * Raw backtick literals (`` `...` ``) are covered by `preserveRawString`,\n * not this option.\n *\n * In single-line output (no `indent`), a spelling that spans multiple\n * lines falls back to normal escaping; single-line spellings are kept.\n *\n * @deprecated Verbatim spelling and `splitCdn` / `splitNewline` reflow\n * are mutually exclusive for a given literal — enabling this option\n * silently defeats both for any non-concatenated double-quoted string.\n * It still works when set explicitly, but no longer participates in\n * `preserveAll` and has been removed from the playground's preserve\n * options.\n *\n * @default false\n */\n preserveTextString?: boolean;\n\n /**\n * Re-emit integer and floating-point literals using their original CDN\n * source spelling — base (`0xff` / `0o377` / `0b101` / decimal), digit\n * spelling, decimal point / exponent form, and encoding-indicator suffix\n * (e.g. `1.5_1`) — instead of normalising them via `intFormat` /\n * `floatFormat` and recomputed encoding indicators.\n *\n * Takes precedence over `intFormat` and `floatFormat` for literals parsed\n * from CDN text. Values that did not originate from CDN text (e.g. built\n * via `CBOR.from()` or decoded from CBOR bytes) always fall back to normal\n * formatting, since there is no original spelling to preserve. Bignums\n * (integers outside the uint64/int64 range) are unaffected and always\n * render as plain decimal.\n *\n * Combine with `preserveByteString`, `preserveRawString`,\n * `preserveConcatenation`, and `preserveComments` to reformat CDN text\n * (e.g. whitespace/indentation only) with minimal changes to the rest of\n * the source.\n *\n * @default false\n */\n preserveNumberFormat?: boolean;\n\n /**\n * Whether to emit commas between array/map elements.\n * - `'comma'`: emit commas (`[1, 2, 3]`)\n * - `'none'`: omit commas, use spaces only (`[1 2 3]`)\n * - `'trailing'`: emit commas including a trailing comma after the last element\n * @default 'comma'\n */\n commas?: 'comma' | 'none' | 'trailing';\n\n /**\n * Fallback binary encoding for byte string literals when sqstr is not applicable.\n * - `'hex'`: `h'...'`\n * - `'base64'`: `b64'...'`\n * - `'base64url'`: `b64'...'` (base64url alphabet)\n * @default 'hex'\n */\n bstrEncoding?: 'hex' | 'base64' | 'base64url';\n\n /**\n * Whether to prefer single-quoted string form (`sqstr`) for byte strings.\n * - `'printable-string'`: emit `'...'` when the bytes are valid UTF-8 and\n * contain no control characters; fall back to `bstrEncoding` otherwise.\n * - `'string'`: emit `'...'` when the bytes are valid UTF-8;\n * fall back to `bstrEncoding` otherwise.\n * - `'none'`: never emit sqstr; always use `bstrEncoding`.\n * @default 'printable-string'\n */\n sqstr?: 'printable-string' | 'string' | 'none';\n\n /**\n * Whether to use app-prefix notation — app-string (`dt'...'`, `` dt`...` ``)\n * or app-sequence (`dt<<...>>`) — for built-in extensions.\n * - `true`: emit extension notation (`DT'2023-01-01T12:00:00Z'`)\n * - `false`: emit raw CBOR notation (`1(-14159024)`, `52(h'c000022a')`)\n *\n * Named after `app-prefix` (§6.1 of draft-ietf-cbor-edn-literals-27), the\n * identifier both notations are built from — not just the app-string form,\n * despite the old `appStrings` name (`false` also falls back to raw tag\n * notation for a preserved app-sequence spelling; see `preserveAppPrefix`).\n *\n * @default true\n */\n appPrefix?: boolean;\n\n /**\n * @deprecated Renamed to `appPrefix` — the old name only described the\n * app-string form even though this option also gates app-sequence\n * (`<<...>>`) notation. Still honoured when `appPrefix` is left unset,\n * but `appPrefix` wins if both are set.\n */\n appStrings?: boolean;\n\n /**\n * For built-in extensions that support app-string notation\n * (`prefix'...'` or `` prefix`...` ``), app-sequence notation\n * (`prefix<<...>>`), and/or a raw tag literal (`N(...)`), re-emit a value\n * using its exact original spelling instead of normalizing it to the\n * regenerated `prefix'...'` form.\n *\n * By default, an extension like `dt`/`DT` or `ip`/`IP` regenerates its\n * notation from the resolved value on every call — so\n * `` DT`1969-07-21T02:56:16Z` ``, `DT<<'1969-07-21T02:56:16Z'>>`, and even\n * the raw tag form `1(1749772800)` all become\n * `DT'2025-06-13T00:00:00Z'`-style `prefix'...'` notation, even though all\n * of these denote the same value. `preserveAppPrefix` keeps the\n * original spelling instead — whichever quoting (`'...'` vs `` `...` ``),\n * bracketing (`<<...>>`), or raw tag form was used. Has no effect when\n * `appPrefix` is `false` (raw tag notation is used either way regardless\n * of the original spelling), or on values not parsed from one of these\n * forms.\n *\n * In single-line output (no `indent`), a spelling that spans multiple\n * lines falls back to normal (regenerated) notation; single-line\n * spellings are kept.\n *\n * An explicit `preserveComments`/`comments` setting is still applied\n * to comments inside a preserved app-sequence spelling: marker styles are\n * normalised without changing the notation family, and stripping comments\n * (`preserveComments: false` with `comments` unset or `'strip'`)\n * removes them while retaining the surrounding source spelling. Leaving\n * *both* unset keeps the spelling's comments exactly as originally\n * written, since nothing was explicitly requested.\n *\n * Named after `app-prefix` (§6.1 of draft-ietf-cbor-edn-literals-27; e.g.\n * `dt`, `DT`, `ip`, `IP`), the identifier that `app-string`/`app-sequence`\n * notation is built from. The raw tag literal case is still covered: it's\n * the source spelling that used *no* app-prefix at all, and this option\n * preserves that choice too, not just spellings that did use one.\n * `preserveAppSequence` was the old, narrower name for this same option,\n * since it also preserves app-string and raw-tag spellings, not just\n * `<<...>>` sequences.\n *\n * @default false\n */\n preserveAppPrefix?: boolean;\n\n /**\n * @deprecated Renamed to `preserveAppPrefix` — the old name only\n * described the `<<...>>` form even though this option also preserves\n * `prefix'...'` / `` prefix`...` `` and raw tag (`N(...)`) spellings.\n * Still honoured when `preserveAppPrefix` is left unset, but\n * `preserveAppPrefix` wins if both are set, and it no longer\n * participates in `preserveAll` (use `preserveAppPrefix` for that).\n */\n preserveAppSequence?: boolean;\n\n /**\n * Numeric format for integer values in CDN output.\n * - `'decimal'`: standard decimal notation (e.g. `42`, `-14159024`)\n * - `'hex'`: hexadecimal notation (e.g. `0x2a`, `-0xd83130`)\n * - `'octal'`: octal notation (e.g. `0o52`, `-0o67061560`)\n * - `'binary'`: binary notation (e.g. `0b101010`, `-0b110110000011000100110000`)\n * @default 'decimal'\n */\n intFormat?: 'decimal' | 'hex' | 'octal' | 'binary';\n\n /**\n * Numeric format for floating-point values in CDN output.\n * - `'decimal'`: standard decimal notation (e.g. `1.5`, `145544.0_3`)\n * - `'hex'`: C99-style hex float notation (e.g. `0x1.8p+0`, `0x1.1c54p+17_3`)\n * - `'app-extension'`: `float'...'` app-string notation carrying the\n * value's exact IEEE 754 bit pattern (e.g. `float'3fc00000'`), per §3.8\n * of draft-ietf-cbor-edn-literals-27. Unlike `'decimal'`/`'hex'`, this\n * is derived from the value's actual encoded bytes rather than its\n * numeric text, so it losslessly represents NaN payloads and\n * ±Infinity too (not just finite values). Falls back to `'decimal'`\n * when `appPrefix` is `false`, matching how other built-in extensions\n * fall back to raw notation.\n *\n * A value originally parsed from a `float'...'`/`float<<...>>` literal\n * normally re-emits that exact source spelling regardless of this option\n * (so its own encoding-width choice, or a non-canonical bit pattern, isn't\n * silently normalized away) — leaving `floatFormat` unset, or setting it\n * to `'app-extension'`, keeps that round-trip. Explicitly requesting\n * `'decimal'` or `'hex'` opts out of it and reformats the value like any\n * other float, since that's the point of asking for a different format.\n * @default 'decimal'\n */\n floatFormat?: 'decimal' | 'hex' | 'app-extension';\n\n /**\n * Split long text strings using CDN string concatenation syntax (`\"a\" + \"b\"`).\n * Only effective when `indent` enables pretty-printing.\n *\n * - `'newline'`: split at newline characters\n * - `'cdn'`: split according to CDN structure when the string content\n * is parseable as CDN (JSON superset)\n * - `'cboredn'`: deprecated alias for `'cdn'`\n *\n * When both are specified, CDN structure split points are combined with\n * newline split points.\n *\n * @deprecated Use `splitCdn` / `splitNewline` instead. When one of those\n * is specified, it takes precedence over the corresponding array entry.\n */\n textStringFormat?: TextStringFormat[];\n\n /**\n * Format text strings whose content is parseable as CDN (a JSON superset)\n * by splitting them with CDN string concatenation (`\"{\" + \"1:2\" + \"}\"`)\n * and structure-aware indentation, the same way the surrounding CDN is\n * formatted. Only effective when `indent` is specified.\n *\n * When the string content parses as CDN, this takes precedence over\n * `preserveConcatenation`; when it does not, the original concatenation\n * is preserved as usual.\n *\n * `inlineLeafContainers` applies to the embedded CDN structure too: an\n * array/map/`<<...>>` in the string content that would stay on one line\n * as a real value keeps its split points collapsed here as well (e.g.\n * `\"[1, 2, 3]\"` stays a single literal instead of splitting per element).\n *\n * Replaces the deprecated `textStringFormat: ['cdn']`.\n *\n * @default false\n */\n splitCdn?: boolean;\n\n /**\n * Split text strings at newline characters using CDN string concatenation\n * (`\"line1\\n\" + \"line2\"`). Only effective when `indent` is specified.\n *\n * Combines with `preserveConcatenation`: preserved concatenation parts\n * are further split at the newline characters they contain.\n *\n * Replaces the deprecated `textStringFormat: ['newline']`.\n *\n * @default false\n */\n splitNewline?: boolean;\n\n /**\n * Preserve `+` string concatenation from the parsed CDN source.\n *\n * When a text string or byte string was parsed from a CDN concatenation\n * chain (e.g. `\"a\" + \"b\"` or `h'01' + h'02'`), re-emit it as a\n * concatenation with the original part boundaries instead of joining the\n * parts into a single literal. Each part is re-serialized with the normal\n * rules (`bstrEncoding` / `sqstr` for byte strings); combine with\n * `preserveByteString` to also keep the original spelling of byte string\n * parts.\n *\n * Interaction with the split options: `splitCdn` takes precedence for\n * text strings whose content parses as CDN, while `splitNewline` combines\n * with this option by further splitting the preserved parts at newline\n * characters. Has no effect on values that did not originate from a CDN\n * concatenation, and only takes effect when `indent` enables\n * pretty-printing (single-line output joins the parts into one literal).\n *\n * Also applies within an elision (`...`, §5.2 of\n * draft-ietf-cbor-edn-literals-27): a `+`-joined fragment on either side of\n * an ellipsis keeps its own part boundaries too (e.g. `'test' +\n * h'1234...abcd' + ...` stays exactly as written instead of merging\n * `'test'` into the byte fragment before it), and byte-string elision\n * keeps the `h'xx' + ... + h'yy'` spelling instead of the default compact\n * `h'xx...yy'` literal. Unlike the text/byte-string case above, this\n * applies regardless of `indent`, and the parts stay on one line even\n * under `indent` (elision is always single-line): a `+` boundary inside an\n * ellipsis is never a lossless merge — the elided middle can't be \"joined\n * in\" — so there's no indent-dependent fallback to prefer, and no reason\n * to reflow it.\n *\n * @default false\n */\n preserveConcatenation?: boolean;\n\n /**\n * Render preserved `+` string concatenation (see `preserveConcatenation`)\n * or an elision chain (`...`, §5.2) using `t1<<...>>` / `b1<<...>>`\n * app-sequence notation (draft-ietf-cbor-edn-literals-27 §3.5)\n * instead of the legacy `+` operator.\n *\n * - `false` (default): `\"a\" + \"b\"` / `'test' + h'1234...abcd' + ...`.\n * - `true`: `t1<<\"a\", \"b\">>` / `b1<<h'1234', h'..abcd'>>`. Falls back to\n * `false`'s rendering when `appPrefix` is `false`, since this notation\n * is itself an app-string form.\n *\n * For a plain (non-elision) concatenation, only changes the spelling used\n * where `preserveConcatenation` already causes multi-part rendering; has\n * no effect when concatenation collapses into a single merged literal\n * (e.g. `preserveConcatenation` unset, or a text string whose content is\n * reflowed by `splitCdn` instead). An elision chain is different: `...`\n * denotes genuinely unknown content, so it always renders as multiple\n * parts regardless of `preserveConcatenation` — `modernConcat` therefore\n * also applies to it unconditionally (`preserveConcatenation` there only\n * controls how much of a fragment's *own* internal boundary is shown, not\n * whether the chain itself is shown as multiple parts).\n *\n * Has no effect on a value that was itself parsed from `t1<<...>>` /\n * `b1<<...>>` source: when `appPrefix` is not `false`, `encodingIndicators`\n * is `'auto'` (both defaults), and the source is either single-line or\n * being rendered with `indent` enabled, that spelling is kept verbatim\n * regardless of `modernConcat` (see `t1`/`b1` in\n * [String Concatenation and Indefinite-Length Strings](../README.md#string-concatenation-and-indefinite-length-strings)).\n * A multi-line source falls back to normalized (collapsed) output in\n * single-line mode, since that layout can't be reproduced without\n * `indent`. `modernConcat` only affects values reconstructed from a `+`\n * chain.\n *\n * @default false\n */\n modernConcat?: boolean;\n\n /**\n * Render an indefinite-length string using `ilts<<...>>` / `ilbs<<...>>`\n * app-sequence notation (draft-ietf-cbor-edn-literals-27 §3.6)\n * instead of the legacy `(_ \"a\", \"b\")` streamstring form.\n *\n * - `false` (default): `(_ \"a\", \"b\")`.\n * - `true`: `ilts<<\"a\", \"b\">>` / `ilbs<<h'..', h'..'>>`. Falls back to\n * `false`'s rendering when `appPrefix` is `false`, since this notation\n * is itself an app-string form.\n *\n * Applies whenever an indefinite-length string is rendered as chunks;\n * unaffected by `encodingIndicators: 'never'`, which merges the chunks\n * into a single definite-length literal regardless of this option.\n *\n * Has no effect on a value that was itself parsed from `ilts<<...>>` /\n * `ilbs<<...>>` source: when `appPrefix` is not `false`, `encodingIndicators`\n * is `'auto'` (both defaults), and the source is either single-line or\n * being rendered with `indent` enabled, that spelling is kept verbatim\n * regardless of `modernStreamSyntax`. A multi-line source falls back to\n * normalized (collapsed) output in single-line mode, since that layout\n * can't be reproduced without `indent`. `modernStreamSyntax` only affects\n * values reconstructed from a legacy `(_ ...)` chunk list.\n *\n * @default false\n */\n modernStreamSyntax?: boolean;\n\n /**\n * When pretty-printing with `indent`, keep an array, map, or\n * indefinite-length string group (`(_ \"a\", \"b\")`) on a single line when\n * none of its entries contains an array or map (even wrapped in a tag),\n * none of its entries is a text string with two or more words (also even\n * wrapped in a tag), and every entry serializes without a line break\n * (e.g. `[1, 2, 3]`, `{\"a\": 1}`, `(_ \"a\", \"b\")`). Word boundaries follow\n * `Intl.Segmenter`'s word-break rules, so `[\"hello\", \"world\"]` still\n * collapses to one line (each entry is a single word) while `[\"Hello,\n * World!\", \"This is the CBOR library.\"]` renders one entry per line (each\n * has two or more) — space-less scripts (Japanese, Chinese, ...) are still\n * split on their own dictionary-based word boundaries. Nested leaf\n * containers still collapse individually: `[[1, 2], [3, 4]]` renders with\n * one inner array per line.\n *\n * `<<...>>` (CBOR Sequence Literal / embedded CBOR) is not governed by\n * this option at all: its own parens never require an additional line\n * break by themselves, regardless of `inlineLeafContainers`'s value,\n * since (unlike an array, map, or indefinite-length string group) it has\n * no nested-structure display of its own to spread out — it's a flat\n * sequence of encoded items. Instead it stays on one line exactly when\n * every entry's own actual rendering already does — an entry that is\n * itself an array/map is not disqualified just for being one, unlike in\n * an outer array/map. Concretely: `<<{1: -7}>>` renders as `<<{1: -7}>>`\n * when `inlineLeafContainers` lets the inner map collapse to one line,\n * but as `<<\\n {\\n 1: -7\\n }\\n>>` when it doesn't (the map itself\n * still spreads one entry per line without the option, same as it would\n * anywhere else — `<<...>>` just doesn't add a break of its own on top\n * of that). `[{1: -7}]`, by contrast, always spreads its `{1: -7}` entry\n * onto its own line regardless of whether the map itself collapses,\n * since a nested array/map always disqualifies an outer array/map's\n * entry. A two-or-more-word text entry still forces a break inside\n * `<<...>>` either way, irrespective of `inlineLeafContainers`.\n *\n * Containers with preserved comments are always emitted in multi-line\n * form. Has no effect when `indent` is omitted.\n *\n * @default false\n */\n inlineLeafContainers?: boolean;\n\n /**\n * Control whether CBOR encoding-width indicators (`_N`) are appended to CDN output.\n *\n * - `'always'`: always emit the encoding indicator, even for canonical encodings\n * (e.g. `1_i`, `\"hello\"_i`, `[_i 1, 2]`)\n * - `'auto'`: emit indicators only when the CBOR encoding is non-canonical —\n * i.e. more bytes were used than necessary (e.g. `1_3` for a uint encoded with 8 bytes)\n * - `'never'`: never emit encoding indicators\n *\n * @default 'auto'\n */\n encodingIndicators?: 'always' | 'auto' | 'never';\n\n /**\n * Called for every node during `toCDN()`, before that node is rendered,\n * to override the options used for its subtree. Return a partial options\n * object to merge over the options in effect for this node (they apply to\n * this node and are inherited by its descendants, who may override them\n * again); return `undefined` to make no change.\n *\n * This is the mechanism for applying an option to only part of a\n * document — e.g. rendering one array element in hex while the rest stay\n * decimal — keyed off `ctx.path` or the node's own shape\n * (`item instanceof ...`).\n *\n * **May be called more than once for the same AST node** — see\n * `CdnItemContext`'s own note on why, and why this callback should be a\n * pure function of `item`/`ctx` rather than relying on how many times it\n * runs.\n *\n * Not called for keys of an indefinite-length string's chunks or a\n * `<<...>>` sequence's items, which have no key of their own to convert\n * (only array elements and map entries/keys have a `path` segment).\n *\n * @example\n * // Render only the value at key \"raw\" using hex integers, leaving the\n * // rest of the document in the default decimal format.\n * item.toCDN({\n * indent: 2,\n * itemOptions: (_node, ctx) =>\n * ctx.path.length === 1 && ctx.path[0] === 'raw'\n * ? { intFormat: 'hex' }\n * : undefined,\n * });\n */\n itemOptions?: (\n item: CborItem,\n ctx: CdnItemContext\n ) => Partial<ToCDNOptions> | undefined;\n}\n\nexport type TextStringFormat = 'newline' | 'cdn' | DeprecatedTextStringFormat;\n\n/** @deprecated Use `'cdn'` instead. */\nexport type DeprecatedTextStringFormat = 'cboredn';\n\n/**\n * Options for serializing Concise Diagnostic Notation (CDN).\n *\n * @deprecated Use `ToCDNOptions` instead.\n */\nexport type ToEDNOptions = ToCDNOptions;\n\nexport interface CborComment {\n kind: 'line' | 'block';\n marker: '#' | '//' | '/*' | '/';\n text: string;\n start: number;\n end: number;\n line: number;\n col: number;\n /**\n * `true` when this is a `leading` comment that ends on the same source\n * line as the node it's attached to — e.g. `/ protected / << ... >>` in an\n * RFC 9052-style annotated array, as opposed to a comment on its own line\n * above the value. `toCDN()` renders these as an inline prefix on the\n * value's own line instead of a separate line above it. `undefined` for\n * `trailing`/`dangling` comments, where it doesn't apply.\n */\n sameLine?: boolean;\n}\n\nexport interface CborComments {\n leading?: CborComment[];\n trailing?: CborComment[];\n dangling?: CborComment[];\n}\n\n/**\n * Options for `CBOR.validate()`.\n */\nexport interface ValidateOptions {\n /**\n * Input format.\n * - `'cbor'`: binary CBOR, decoded as a CBOR Sequence (RFC 8742).\n * - `'cdn'`: CDN text, parsed as a CDN Sequence.\n * - `'hex'`: annotated hex dump text, decoded as a CBOR Sequence.\n * @default 'cbor'\n */\n type?: 'cbor' | 'cdn' | 'hex';\n\n /**\n * Extension plugins used while decoding/parsing.\n * Mirrors `FromCBOROptions.extensions` / `FromCDNOptions.extensions`.\n */\n extensions?: CborExtension[];\n\n /**\n * Override the default set of bundled app-extensions.\n * Mirrors `FromCBOROptions.builtinExtensions`.\n */\n builtinExtensions?: CborExtension[] | false;\n\n /**\n * How to handle unrecognised app-extension identifiers.\n * Only applies when `type` is `'cdn'`; mirrors `FromCDNOptions.unresolvedExtension`.\n * @default 'cpa999'\n */\n unresolvedExtension?: 'cpa999' | 'error';\n\n /**\n * CDDL schema to validate each decoded/parsed item against: either a\n * compiled schema (`CDDL.compile()` from `@cbortech/cbor/cddl`) or CDDL\n * source text (compiled on first use and cached; mirrors\n * `FromCBOROptions.cddl`).\n *\n * Unlike the throwing entry points, `CBOR.validate()` does not throw on a\n * mismatch: failures are collected into `ValidateResult.cddlErrors` (and\n * validator observations into `ValidateResult.cddlWarnings`), and any\n * mismatch makes `valid` `false`. Each item of a sequence is validated\n * individually against the schema's root rule by default (or\n * `cddlValidationOptions.rule`, if set). Note that invalid CDDL source\n * text itself still throws (`CddlSyntaxError` / `CddlSemanticError`): the\n * schema is part of the call, not the data being validated.\n */\n cddl?: CddlSchema | string;\n\n /**\n * Options forwarded to the CDDL validator.\n * Mirrors `FromCBOROptions.cddlValidationOptions`.\n */\n cddlValidationOptions?: CddlValidateOptions;\n}\n\n/**\n * Result of `CBOR.validate()`.\n */\nexport interface ValidateResult {\n /**\n * `true` when every item decoded/parsed without error and without any\n * warnings. `false` when the input was malformed (see `error`) or\n * well-formed but in violation of a validity constraint (see `warnings`).\n */\n valid: boolean;\n\n /** Number of items successfully decoded/parsed before any error. */\n count: number;\n\n /**\n * Validity violations encountered while decoding/parsing in non-strict\n * mode (recoverable — decoding continued after each one). Excludes\n * informational hints (see `hints`) and the fatal CDN warning that\n * `error` is built from, if any.\n */\n warnings: (DecodeWarning | ParseWarning)[];\n\n /**\n * Informational hints (`ParseWarning.hint`) encountered while parsing,\n * e.g. an app-string prefix that matches a known optional extension which\n * isn't registered. Hints never affect `valid`; they are collected here so\n * tooling can still surface them.\n */\n hints: ParseWarning[];\n\n /**\n * Set when decoding/parsing failed outright: either it threw (e.g.\n * truncated CBOR data), or — for CDN input — `fromCDNSeq()` abandoned the\n * rest of the sequence after a hard syntax error (reported internally as a\n * `fatal` warning, which `validate()` promotes to `error` rather than\n * including in `warnings`). For a CDN syntax error this is the original\n * `CdnSyntaxError`, position fields intact.\n */\n error?: Error;\n\n /**\n * CDDL validation failures, collected per decoded item. Only present when\n * `ValidateOptions.cddl` was supplied (empty array when every item\n * matched). Any entry makes `valid` `false`.\n */\n cddlErrors?: CddlValidationError[];\n\n /**\n * Non-fatal CDDL validator observations (e.g. unsupported control\n * operators whose constraints were skipped). Only present when\n * `ValidateOptions.cddl` was supplied. Never affects `valid`.\n */\n cddlWarnings?: CddlValidationWarning[];\n}\n\n/** Options for `fromCBORSeq()` (`offset`/`allowTrailing` are excluded — the generator manages them). */\nexport type FromCBORSeqOptions = Omit<\n FromCBOROptions,\n 'offset' | 'allowTrailing'\n>;\n\n/** Options for `fromCDNSeq()` (`offset`/`allowTrailing` are excluded — the generator manages them). */\nexport type FromCDNSeqOptions = Omit<\n FromCDNOptions,\n 'offset' | 'allowTrailing'\n>;\n\n/**\n * Combined options for the `CBOR` constructor.\n *\n * These defaults are applied to every subsequent method call on the instance.\n * Per-call options always take precedence over these defaults.\n *\n * Note: `encodeIntegerAs` (from {@link FromJSOptions}) and `integerAs` (from\n * {@link ToJSOptions}) are distinct fields and do not conflict.\n */\nexport type CBOROptions = FromCDNOptions &\n FromJSOptions &\n ToCBOROptions &\n ToCDNOptions &\n ToJSOptions &\n ToHexDumpOptions;\n","/**\n * Wrapper for unrecognised CBOR simple values (0–255, excluding false/true/\n * null/undefined). Returned by CborSimple.toJS() so that fromJS() can\n * reconstruct the original CborSimple node and preserve the round-trip.\n *\n * Also serves as a namespace for simple-value utilities.\n *\n * @example\n * const v = CBOR.fromCDN('simple(19)').toJS();\n * Simple.is(v); // true\n * Simple.get(v); // 19\n *\n * const node = CBOR.fromJS(new Simple(19));\n * node.toCDN(); // \"simple(19)\"\n */\nexport class Simple {\n readonly value: number;\n\n constructor(value: number) {\n if (!Number.isInteger(value) || value < 0 || value > 255)\n throw new RangeError('Simple value must be an integer in 0–255');\n this.value = value;\n }\n\n valueOf(): number {\n return this.value;\n }\n\n toJSON(): never {\n throw new TypeError(`simple(${this.value}) cannot be serialized to JSON`);\n }\n\n /** Return true if value is a Simple instance. */\n static is(value: unknown): value is Simple {\n return value instanceof Simple;\n }\n\n /** Return the simple number if value is a Simple instance, otherwise undefined. */\n static get(value: unknown): number | undefined {\n return value instanceof Simple ? value.value : undefined;\n }\n}\n","/**\n * Float16 (IEEE 754 binary16) encode/decode utilities.\n *\n * Uses native DataView.getFloat16 / setFloat16 when both are available,\n * and falls back to a manual bit-manipulation implementation otherwise.\n *\n * binary16 format:\n * bit 15 : sign\n * bits 14-10: exponent (5 bits, bias = 15)\n * bits 9- 0: mantissa (10 bits)\n */\n\nexport const hasNativeFloat16 =\n 'getFloat16' in DataView.prototype && 'setFloat16' in DataView.prototype;\n\n// Reusable 8-byte buffer for float64 bit extraction (avoids per-call allocation)\nconst _buf8 = new ArrayBuffer(8);\nconst _dv8 = new DataView(_buf8);\n\n/**\n * float64 → float16 bit pattern (16-bit unsigned integer).\n *\n * Operates directly on float64 bits to avoid double-rounding artifacts that\n * arise from a float64 → float32 → float16 two-step conversion.\n * Implements IEEE 754 round-to-nearest-ties-to-even (RN-TE).\n *\n * Exported for testing (manual vs native consistency checks).\n */\nexport function float64ToFloat16Bits(value: number): number {\n // Store the float64 in big-endian order so the bit layout is predictable\n _dv8.setFloat64(0, value, false);\n const hi = _dv8.getUint32(0, false); // bits 63-32 of IEEE 754 binary64\n const lo = _dv8.getUint32(4, false); // bits 31-0\n\n const sign = (hi >>> 31) & 1;\n const exp64 = (hi >>> 20) & 0x7ff; // 11-bit exponent, bias 1023\n const mantHi = hi & 0x000f_ffff; // top 20 bits of the 52-bit mantissa\n // lo = lower 32 bits of the mantissa\n\n // ── Infinity / NaN ──────────────────────────────────────────────────────────\n if (exp64 === 0x7ff) {\n if (mantHi === 0 && lo === 0) return (sign << 15) | 0x7c00; // ±Infinity\n // NaN: carry top 10 mantissa bits; guarantee at least one bit is set\n const f16mant = (mantHi >> 10) | (lo !== 0 ? 1 : 0) || 1;\n return (sign << 15) | 0x7c00 | (f16mant & 0x3ff);\n }\n\n // Rebias: float64 exponent bias 1023 → float16 bias 15\n const f16Exp = exp64 - 1023 + 15;\n\n // ── Overflow → ±Infinity ────────────────────────────────────────────────────\n if (f16Exp >= 31) return (sign << 15) | 0x7c00;\n\n let f16mant: number;\n let roundBit: number;\n let sticky: boolean;\n\n if (f16Exp <= 0) {\n // ── Underflow ──────────────────────────────────────────────────────────────\n if (f16Exp < -10) return sign << 15; // → ±0\n\n // ── Denormal ───────────────────────────────────────────────────────────────\n // Reconstruct the 53-bit significand's top 21 bits: [implicit 1][mantHi 20-bit]\n const top21 = (1 << 20) | mantHi;\n\n // Right-shift amount to align the significand for a float16 denormal:\n // f16mant = round(top53 / 2^(43 - f16Exp))\n // We approximate top53 ≈ top21 × 2^32 (low bits from `lo` affect only rounding).\n const s = 11 - f16Exp; // s ∈ [11, 21]\n\n if (s <= 20) {\n f16mant = (top21 >> s) & 0x3ff;\n roundBit = (top21 >> (s - 1)) & 1;\n sticky = (top21 & ((1 << (s - 1)) - 1)) !== 0 || lo !== 0;\n } else {\n // s = 21: the implicit-1 bit becomes the round bit; truncated result is 0\n f16mant = 0;\n roundBit = 1; // implicit 1 is always present\n sticky = mantHi !== 0 || lo !== 0;\n }\n } else {\n // ── Normal ─────────────────────────────────────────────────────────────────\n // Take the top 10 bits of the 52-bit mantissa; round using the next bits.\n f16mant = mantHi >> 10;\n roundBit = (mantHi >> 9) & 1;\n sticky = (mantHi & 0x1ff) !== 0 || lo !== 0;\n }\n\n // ── Round-to-nearest-ties-to-even (RN-TE) ───────────────────────────────────\n if (roundBit !== 0 && (sticky || (f16mant & 1) !== 0)) {\n f16mant++;\n }\n\n // ── Mantissa overflow: carry into exponent ───────────────────────────────────\n if (f16mant >= 1024) {\n // Denormal rounds up to the smallest normal (exp = 1), or normal exponent increments\n const newExp = f16Exp <= 0 ? 1 : f16Exp + 1;\n if (newExp >= 31) return (sign << 15) | 0x7c00; // overflow to Infinity\n return (sign << 15) | (newExp << 10); // mant = 0\n }\n\n const outExp = f16Exp <= 0 ? 0 : f16Exp;\n return (sign << 15) | (outExp << 10) | f16mant;\n}\n\n/**\n * float16 bit pattern → float64.\n * Exported for testing purposes.\n */\nexport function float16BitsToFloat64(bits: number): number {\n const sign = (bits >>> 15) & 1;\n const exp = (bits >>> 10) & 0x1f;\n const mant = bits & 0x3ff;\n\n if (exp === 0x1f) {\n return mant === 0 ? (sign ? -Infinity : Infinity) : NaN;\n }\n if (exp === 0) {\n if (mant === 0) return sign ? -0 : 0;\n // Denormal: (-1)^sign × 2^(-14) × (mant / 1024)\n return (sign ? -1 : 1) * 2 ** -14 * (mant / 1024);\n }\n // Normal: (-1)^sign × 2^(exp-15) × (1 + mant/1024)\n return (sign ? -1 : 1) * 2 ** (exp - 15) * (1 + mant / 1024);\n}\n\n/**\n * Write a float16 value at the given offset in a DataView.\n */\ntype WriteFloat16 = (\n view: DataView,\n offset: number,\n value: number,\n littleEndian: boolean\n) => void;\n\n/**\n * Read a float16 value from the given offset in a DataView, returned as float64.\n */\ntype ReadFloat16 = (\n view: DataView,\n offset: number,\n littleEndian: boolean\n) => number;\n\nconst writeFloat16Native: WriteFloat16 = (\n view,\n offset,\n value,\n littleEndian\n) => {\n view.setFloat16(offset, value, littleEndian);\n};\n\nconst writeFloat16Fallback: WriteFloat16 = (\n view,\n offset,\n value,\n littleEndian\n) => {\n view.setUint16(offset, float64ToFloat16Bits(value), littleEndian);\n};\n\nconst readFloat16Native: ReadFloat16 = (view, offset, littleEndian) => {\n return view.getFloat16(offset, littleEndian);\n};\n\nconst readFloat16Fallback: ReadFloat16 = (view, offset, littleEndian) => {\n return float16BitsToFloat64(view.getUint16(offset, littleEndian));\n};\n\n// Dispatch between native and fallback once at module initialization time.\nexport const writeFloat16: WriteFloat16 = hasNativeFloat16\n ? writeFloat16Native\n : writeFloat16Fallback;\n\nexport const readFloat16: ReadFloat16 = hasNativeFloat16\n ? readFloat16Native\n : readFloat16Fallback;\n","import {\n float64ToFloat16Bits,\n float16BitsToFloat64,\n writeFloat16 as writeFloat16ToView,\n} from '../utils/float16';\nimport type { FloatPrecision } from '../ast/CborFloat';\nimport { AI_1BYTE, AI_2BYTE, AI_4BYTE, AI_8BYTE } from './constants';\n\n// ─── Encoding width ───────────────────────────────────────────────────────────\n\n/**\n * EDN encoding indicator, mapping to a specific CBOR AI encoding:\n * 'i' → ai 0–23 (argument in initial byte, value must be 0–23)\n * 0 → AI 24 (1-byte argument, value must be 0–0xFF)\n * 1 → AI 25 (2-byte argument, value must be 0–0xFFFF)\n * 2 → AI 26 (4-byte argument, value must be 0–0xFFFFFFFF)\n * 3 → AI 27 (8-byte argument, value must be 0–0xFFFFFFFFFFFFFFFF)\n */\nexport type EncodingWidth = 'i' | 0 | 1 | 2 | 3;\n\n// ─── Output writer ────────────────────────────────────────────────────────────\n\n/** Scratch space for float conversions (single-threaded use only). */\nconst SCRATCH = new DataView(new ArrayBuffer(8));\nconst SCRATCH_BYTES = new Uint8Array(SCRATCH.buffer);\n\n/** Shared encoder — constructing TextEncoder per string is needlessly slow. */\nconst textEncoder = new TextEncoder();\nconst hasEncodeInto = typeof textEncoder.encodeInto === 'function';\n\n/** CBOR head size in bytes for an auto-width argument `n`. */\nfunction headSizeFor(n: number): number {\n if (n <= 23) return 1;\n if (n <= 0xff) return 2;\n if (n <= 0xffff) return 3;\n if (n <= 0xffff_ffff) return 5;\n return 9;\n}\n\n/** CBOR head size in bytes for an explicit encoding width. */\nfunction headSizeForWidth(ew: EncodingWidth): number {\n return ew === 'i' ? 1 : [2, 3, 5, 9][ew];\n}\n\n/**\n * Growable byte buffer used by the CBOR encoder.\n *\n * AST nodes write themselves into a single shared writer via `_encodeTo`,\n * so an encode pass performs one buffer copy at the end instead of\n * re-copying every child's bytes at each nesting level.\n *\n * @internal\n */\nexport class CborWriter {\n private buf: Uint8Array;\n private len = 0;\n\n constructor(initialCapacity = 256) {\n this.buf = new Uint8Array(initialCapacity);\n }\n\n private _ensure(extra: number): void {\n const needed = this.len + extra;\n if (needed <= this.buf.length) return;\n let capacity = this.buf.length * 2;\n while (capacity < needed) capacity *= 2;\n const grown = new Uint8Array(capacity);\n grown.set(this.buf);\n this.buf = grown;\n }\n\n writeByte(b: number): void {\n this._ensure(1);\n this.buf[this.len++] = b;\n }\n\n writeBytes(bytes: Uint8Array): void {\n this._ensure(bytes.length);\n this.buf.set(bytes, this.len);\n this.len += bytes.length;\n }\n\n writeUint16(value: number): void {\n this._ensure(2);\n const b = this.buf;\n b[this.len++] = (value >>> 8) & 0xff;\n b[this.len++] = value & 0xff;\n }\n\n writeUint32(value: number): void {\n this._ensure(4);\n const b = this.buf;\n b[this.len++] = (value >>> 24) & 0xff;\n b[this.len++] = (value >>> 16) & 0xff;\n b[this.len++] = (value >>> 8) & 0xff;\n b[this.len++] = value & 0xff;\n }\n\n writeBigUint64(value: bigint): void {\n SCRATCH.setBigUint64(0, value, false);\n this._ensure(8);\n this.buf.set(SCRATCH_BYTES, this.len);\n this.len += 8;\n }\n\n writeFloat16(value: number): void {\n writeFloat16ToView(SCRATCH, 0, value, false);\n this._ensure(2);\n const b = this.buf;\n b[this.len++] = SCRATCH_BYTES[0];\n b[this.len++] = SCRATCH_BYTES[1];\n }\n\n writeFloat32(value: number): void {\n SCRATCH.setFloat32(0, value, false);\n this._ensure(4);\n const b = this.buf;\n b[this.len++] = SCRATCH_BYTES[0];\n b[this.len++] = SCRATCH_BYTES[1];\n b[this.len++] = SCRATCH_BYTES[2];\n b[this.len++] = SCRATCH_BYTES[3];\n }\n\n writeFloat64(value: number): void {\n SCRATCH.setFloat64(0, value, false);\n this._ensure(8);\n this.buf.set(SCRATCH_BYTES, this.len);\n this.len += 8;\n }\n\n /**\n * Write a definite-length string head + UTF-8 body in one pass.\n *\n * The body is encoded directly into this writer's buffer with\n * TextEncoder.encodeInto(), avoiding the temporary Uint8Array that\n * TextEncoder.encode() allocates for every string. The head position is\n * predicted from the UTF-16 length (a lower bound on the UTF-8 length);\n * when multi-byte characters push the byte count across a head-width\n * boundary the body is shifted up with copyWithin (rare in practice).\n */\n writeTextString(\n mt: number,\n value: string,\n encodingWidth?: EncodingWidth\n ): void {\n if (!hasEncodeInto) {\n // Environments without encodeInto: one temporary array, as before.\n const encoded = textEncoder.encode(value);\n writeHeadTo(this, mt, encoded.length, encodingWidth);\n this.writeBytes(encoded);\n return;\n }\n const predictedHead =\n encodingWidth === undefined\n ? headSizeFor(value.length)\n : headSizeForWidth(encodingWidth);\n // Worst case: 3 UTF-8 bytes per UTF-16 code unit, plus the largest head.\n this._ensure(9 + 3 * value.length);\n const { written } = textEncoder.encodeInto(\n value,\n this.buf.subarray(this.len + predictedHead)\n );\n // The UTF-8 length is never smaller than the UTF-16 length, so the head\n // can only grow; the _ensure above already covers the largest head.\n const head =\n encodingWidth === undefined ? headSizeFor(written) : predictedHead;\n if (head !== predictedHead) {\n this.buf.copyWithin(\n this.len + head,\n this.len + predictedHead,\n this.len + predictedHead + written\n );\n }\n // For an explicit encodingWidth too small for `written` this throws\n // RangeError before writing anything; this.len is untouched in that case.\n writeHeadTo(this, mt, written, encodingWidth);\n this.len += written;\n }\n\n /** Copy of the bytes written so far. */\n finish(): Uint8Array {\n return this.buf.slice(0, this.len);\n }\n}\n\n// ─── Header encoding ──────────────────────────────────────────────────────────\n\nconst MAX_FOR_WIDTH = [\n 0xffn,\n 0xffffn,\n 0xffff_ffffn,\n 0xffff_ffff_ffff_ffffn,\n] as const;\n\n/** Maximum CBOR argument value representable with the given encoding width. */\nexport function maxForEncodingWidth(ew: EncodingWidth): bigint {\n return ew === 'i' ? 23n : MAX_FOR_WIDTH[ew];\n}\n\n/**\n * Write a CBOR initial byte + argument into `w`.\n *\n * When `encodingWidth` is provided the argument is always written using that\n * many additional bytes (AI = 24 + encodingWidth), even if the value would fit\n * in fewer bytes. Without it the smallest valid encoding is chosen.\n *\n * `value` may be a number (common for lengths and counts — avoids a BigInt\n * allocation per head) or a bigint (required for full uint64 range).\n */\nexport function writeHeadTo(\n w: CborWriter,\n mt: number,\n value: number | bigint,\n encodingWidth?: EncodingWidth\n): void {\n // Fast path: auto-width number argument below 2^32\n if (\n encodingWidth === undefined &&\n typeof value === 'number' &&\n value < 0x1_0000_0000\n ) {\n if (value <= 23) {\n w.writeByte((mt << 5) | value);\n } else if (value <= 0xff) {\n w.writeByte((mt << 5) | AI_1BYTE);\n w.writeByte(value);\n } else if (value <= 0xffff) {\n w.writeByte((mt << 5) | AI_2BYTE);\n w.writeUint16(value);\n } else {\n w.writeByte((mt << 5) | AI_4BYTE);\n w.writeUint32(value);\n }\n return;\n }\n\n const v = typeof value === 'number' ? BigInt(value) : value;\n if (encodingWidth !== undefined) {\n // Immediate encoding: value must fit in the lower 5 bits of the initial byte\n if (encodingWidth === 'i') {\n if (v > 23n)\n throw new RangeError(\n `value ${v} does not fit in immediate encoding _i (max 23)`\n );\n w.writeByte((mt << 5) | Number(v));\n return;\n }\n if (v > MAX_FOR_WIDTH[encodingWidth]) {\n throw new RangeError(\n `value ${v} does not fit in encodingWidth _${encodingWidth} (max ${MAX_FOR_WIDTH[encodingWidth]})`\n );\n }\n const ai = AI_1BYTE + encodingWidth; // 24, 25, 26, or 27\n w.writeByte((mt << 5) | ai);\n if (ai === AI_1BYTE) w.writeByte(Number(v));\n else if (ai === AI_2BYTE) w.writeUint16(Number(v));\n else if (ai === AI_4BYTE) w.writeUint32(Number(v));\n else w.writeBigUint64(v);\n return;\n }\n if (v <= 23n) {\n w.writeByte((mt << 5) | Number(v));\n } else if (v <= 0xffn) {\n w.writeByte((mt << 5) | AI_1BYTE);\n w.writeByte(Number(v));\n } else if (v <= 0xffffn) {\n w.writeByte((mt << 5) | AI_2BYTE);\n w.writeUint16(Number(v));\n } else if (v <= 0xffff_ffffn) {\n w.writeByte((mt << 5) | AI_4BYTE);\n w.writeUint32(Number(v));\n } else {\n w.writeByte((mt << 5) | AI_8BYTE);\n w.writeBigUint64(v);\n }\n}\n\n/**\n * Encode a CBOR initial byte + argument into a Uint8Array.\n * Convenience wrapper around {@link writeHeadTo} for callers that need the\n * bytes directly (e.g. hex dumps).\n */\nexport function writeHead(\n mt: number,\n value: number | bigint,\n encodingWidth?: EncodingWidth\n): Uint8Array {\n const w = new CborWriter(9);\n writeHeadTo(w, mt, value, encodingWidth);\n return w.finish();\n}\n\n// ─── Float precision helpers ──────────────────────────────────────────────────\n\nconst _f32buf = new DataView(new ArrayBuffer(4));\n\n/**\n * Returns true if `value` can be exactly represented as a float16 without\n * precision loss (including -0, Infinity, -Infinity, NaN identity).\n */\nexport function canEncodeAsFloat16(value: number): boolean {\n return Object.is(float16BitsToFloat64(float64ToFloat16Bits(value)), value);\n}\n\n/**\n * Returns true if `value` can be exactly represented as a float32 without\n * precision loss.\n */\nexport function canEncodeAsFloat32(value: number): boolean {\n _f32buf.setFloat32(0, value, false);\n return Object.is(_f32buf.getFloat32(0, false), value);\n}\n\n/**\n * Choose the smallest float precision that represents `value` exactly.\n * Used by CborFloat.toCBOR() when `precision` is undefined.\n */\nexport function autoSelectFloatPrecision(value: number): FloatPrecision {\n if (canEncodeAsFloat16(value)) return 'half';\n if (canEncodeAsFloat32(value)) return 'single';\n return 'double';\n}\n","import type {\n CBOROptions,\n ToCDNOptions,\n ToJSOptions,\n ToHexDumpOptions,\n ToCBOROptions,\n CborComment,\n CborComments,\n DecodeWarning,\n ParseWarning,\n ItemContext,\n ReadonlyToJSNodeOptions,\n CdnItemContext,\n ReadonlyToCDNOptions,\n} from '../types';\nimport { CBOR_OMIT } from '../types';\nimport {\n convertCommentText,\n resolveIndent,\n splitLeadingComments,\n shouldEmitComments,\n resolveCommentStyle,\n} from '../cdn/serialize-utils';\nimport { CborWriter } from '../cbor/encode';\nimport { bytesToSpacedHexUpper } from '../utils/hex';\n\n/** @internal One line of an annotated hex dump. */\nexport interface AnnotatedLine {\n depth: number;\n hex: string;\n comment: string;\n}\n\nexport interface AppSeqEncodingEdit {\n /** Start/end offsets within appSeqSource of an existing indicator. */\n start: number;\n end: number;\n /** Replacement used by encodingIndicators: 'always'. */\n always: string;\n /** Replacement used by encodingIndicators: 'never'. */\n never: string;\n}\n\n/**\n * Original literal features used by the sole item inside a preserved\n * `prefix<<item>>` source. They let serialization honour an explicitly\n * disabled sibling `preserve*` option instead of replaying that literal\n * verbatim through `preserveAppPrefix`.\n */\nexport interface AppSeqSourceFeatures {\n byteString?: boolean;\n textString?: boolean;\n rawString?: boolean;\n concatenation?: boolean;\n}\n\n/**\n * Fill in every `preserve*` option left `undefined` with `true`, for\n * `ToCDNOptions.preserveAll` — except the deprecated `preserveTextString`,\n * which no longer participates in `preserveAll`. An option the caller\n * explicitly set (including to `false`) is left untouched.\n *\n * `preserveComments` is only filled in with `true` (verbatim) when\n * `comments` is *also* left unset — an explicit `comments` with no\n * `preserveComments` should still normalize comments to that style under\n * `preserveAll`, not be overridden by the verbatim fill-in (see\n * `ToCDNOptions.preserveComments`).\n *\n * Assumes `preserveAppPrefix` has already been resolved from the\n * deprecated `preserveAppSequence` alias by the caller (see `toCDN()`); like\n * `preserveTextString`, the deprecated name itself no longer participates\n * directly. (`appStrings`/`appPrefix` aren't part of the `preserve*` family\n * and don't participate in `preserveAll` at all.)\n */\nfunction expandPreserveAll(options: ToCDNOptions): ToCDNOptions {\n return {\n ...options,\n preserveComments:\n options.comments !== undefined\n ? options.preserveComments\n : (options.preserveComments ?? true),\n preserveByteString: options.preserveByteString ?? true,\n preserveRawString: options.preserveRawString ?? true,\n preserveConcatenation: options.preserveConcatenation ?? true,\n preserveNumberFormat: options.preserveNumberFormat ?? true,\n preserveAppPrefix: options.preserveAppPrefix ?? true,\n preserveBlankLines: options.preserveBlankLines ?? true,\n };\n}\n\n/**\n * Resolve deprecated `ToCDNOptions` aliases — `preserveAppSequence` into\n * `preserveAppPrefix`, and `appStrings` into `appPrefix` — for whichever\n * canonical name was left unset by the caller. Each canonical name always\n * wins over its deprecated alias when both are explicitly set.\n */\nfunction resolveDeprecatedAppPrefixAliases(\n options: ToCDNOptions\n): ToCDNOptions {\n if (\n options.preserveAppSequence === undefined &&\n options.appStrings === undefined\n )\n return options;\n return {\n ...options,\n preserveAppPrefix: options.preserveAppPrefix ?? options.preserveAppSequence,\n appPrefix: options.appPrefix ?? options.appStrings,\n };\n}\n\n/**\n * Resolve deprecated `ToCDNOptions` aliases within an `itemOptions` override\n * *in isolation*, before it is merged onto the ambient effective options.\n *\n * `resolveDeprecatedAppPrefixAliases` only fills in a canonical name when\n * that name is itself left `undefined` on the object it's given. An override\n * like `{ appStrings: false }` must be resolved against *itself* — where\n * `appPrefix` is absent — not against the already-merged effective options,\n * where an ancestor's resolved `appPrefix: true` would already occupy\n * that slot and win, silently discarding the child's own alias-based\n * override (this is `_resolveCdnOptions`'s exact bug this guards against).\n *\n * Because `resolveDeprecatedAppPrefixAliases` unconditionally assigns\n * `preserveAppPrefix`/`appPrefix` (via `??`) whenever either deprecated name\n * is set, resolving against the override alone can introduce a literal\n * `undefined` for a canonical key the override never mentioned (e.g.\n * `preserveAppPrefix: undefined` from an override that only ever touched\n * `appStrings`). Copying that back verbatim would overwrite an inherited\n * value with `undefined` instead of leaving it untouched, so only a\n * genuinely resolved (non-`undefined`) key is copied into the result.\n */\nfunction normalizeCdnOverride(\n override: Partial<ToCDNOptions>\n): Partial<ToCDNOptions> {\n if (\n override.preserveAppSequence === undefined &&\n override.appStrings === undefined\n )\n return override;\n const resolved = resolveDeprecatedAppPrefixAliases(override as ToCDNOptions);\n const result: Partial<ToCDNOptions> = { ...override };\n if (resolved.preserveAppPrefix !== undefined)\n result.preserveAppPrefix = resolved.preserveAppPrefix;\n if (resolved.appPrefix !== undefined) result.appPrefix = resolved.appPrefix;\n return result;\n}\n\n/**\n * @internal\n * Shared, frozen empty path passed as the default `path` argument to\n * `_toJS()`/`_toJSChild()` so that not using `itemOptions` never allocates a\n * path array.\n */\nconst EMPTY_PATH: readonly unknown[] = Object.freeze([]);\n\n/**\n * @internal\n * Cheap upfront check for whether per-node option/extension resolution is\n * needed at all for a given `toJS()` options object. Container nodes use\n * this to choose between the plain `child._toJS(options)` recursion (when\n * `false`, identical cost to before `itemOptions`/`extensions` existed) and\n * `child._toJSChild(options, path, ctx)` (when `true`).\n */\nexport function needsItemDispatch(options: ToJSOptions | undefined): boolean {\n return !!(options?.itemOptions || options?.extensions?.length);\n}\n\n/**\n * @internal\n * Options for a reviver-driven container's \"raw\" structural pre-population\n * pass (see `CborArray`/`CborMap.toObject`) — `reviver` removed, everything\n * else (including `itemOptions`/`extensions`) left as-is.\n *\n * This pass's output is never returned to the caller as the final result —\n * every position it computes is unconditionally overwritten by the *real*\n * (revived) pass's own result before `toJS()` returns — but it is not\n * write-only scaffolding either: a `reviver` reads it directly, as `this[j]`\n * for a not-yet-processed sibling `j`, while deciding how to revive an\n * *earlier* sibling (matching `JSON.parse`'s own reviver contract, which\n * this replicates). That value must reflect `itemOptions`/`extensions`\n * exactly as the real pass would — e.g. an `integerAs: 'bigint'` override\n * for position `j` — or a reviver reading `this[j]` would see the wrong\n * type. So `itemOptions`/`extensions` stay active here, unlike `reviver`\n * itself.\n *\n * Running dispatch during this pass is safe only because callers building\n * a child's occurrence for it — `CborArray`/`CborMap.toObject` — insert\n * `RAW_PASS_MARKER` into that occurrence (see `Occurrence`), so its\n * resolutions are filed under a different `DispatchCache` key than the\n * real pass's and can never be reused *by* the real pass, however many\n * ancestor levels apart the two passes are. That distinction matters for\n * more than consistency — a composite (non-scalar) map key is itself\n * revived differently between the two passes (this pass leaves its own\n * nested content entirely unrevived, matching `this[j]`'s contract above;\n * the real pass revives it normally), so a value node whose\n * `ItemContext.path` is built from that key's converted JS value would\n * otherwise see a stale, pre-revival path if the real pass reused this\n * pass's cached decision.\n */\nexport function withoutReviver(\n options: ToJSOptions | undefined\n): ToJSOptions | undefined {\n if (!options) return options;\n return { ...options, reviver: undefined };\n}\n\n/**\n * @internal\n * Build the `reviver`-free, `extensions`-copied view of `options` handed\n * to code that must not be able to mutate options actually in effect\n * elsewhere in the tree — `ItemContext.options` and the `options`\n * parameter of `CborExtension.toJS()` — see `ReadonlyToJSNodeOptions`.\n *\n * A plain `{ ...options, reviver: undefined }` spread (as `withoutReviver`\n * does) is not enough here: `extensions`, if present, would still be the\n * *same array* `options.extensions` is, so `.push()`/`.splice()`/etc. on\n * the copy would still mutate the original in place — corrupting it for\n * this node's own later use, its siblings, and the caller. `extensions` is\n * the only field on `ToJSOptions` that's an ordinary mutable container, so\n * it's the only one that needs its own copy here.\n */\nexport function toReadonlyNodeOptions(\n options: ToJSOptions\n): ReadonlyToJSNodeOptions {\n const { reviver: _reviver, extensions, ...rest } = options;\n return extensions ? { ...rest, extensions: [...extensions] } : rest;\n}\n\n/**\n * @internal\n * Symbol-keyed slot, stashed on the top-level `toJS()` options object,\n * holding the per-call dispatch cache (see `DispatchCache` below). Reading\n * and writing through this indirection (rather than a typed field on\n * `ToJSOptions`) keeps the cache out of the public option surface while\n * still surviving every `{ ...options, ...override }` copy made while\n * resolving `itemOptions` overrides — object spread carries own-enumerable\n * symbol-keyed properties along with string-keyed ones — so the *same*\n * cache reaches every node touched by one `toJS()` call, however deep.\n */\nconst kDispatchCache = Symbol('cbor.itemOptions.dispatchCache');\n\n/**\n * @internal\n * A node's resolved `itemOptions`/`extensions` outcome at one occurrence,\n * cached across the duplicate visits that occurrence can receive within\n * one `toJS()` call (see `DispatchCache`).\n *\n * - `'value'`: an extension's `toJS()` hook matched and fully resolved this\n * occurrence — reused verbatim on a later visit to the same occurrence,\n * since the hook never even sees `reviver` itself (see `_toJSChild`'s\n * stripped `hookOptions`) and so cannot have produced a result that\n * depends on it; only the container holding the *returned* value still\n * applies reviver to it, once per visit, as usual.\n * - `'override'`: `options.itemOptions()` ran (and no extension matched);\n * `override` is its raw return value, applied at use time as\n * `{ ...options, ...override }` rather than stored pre-merged.\n */\ntype DispatchOutcome =\n | { kind: 'value'; value: unknown }\n | { kind: 'override'; override: Partial<ToJSOptions> | undefined };\n\n/**\n * @internal\n * Stable, allocation-light identifier for \"this occurrence of a node\" —\n * used only to key `DispatchCache` lookups, never exposed via\n * `ItemContext`. Built exactly the way `ItemContext.path` is (accumulated\n * from the root, one element per container level, unchanged through a\n * tag/app-sequence wrapper), but from *structural* container positions —\n * an array index, or a map entry's ordinal paired with a `'k'`/`'v'` role\n * tag (see `CborArray`/`CborMap`) — rather than from the JS values `path`\n * is built from.\n *\n * That distinction matters in two ways `path` alone (or even `path` plus\n * only the *immediate* container's identity) does not cover:\n *\n * - A composite (non-scalar) map key re-converts to a *new* array/object\n * every time its JS value is asked for, so two visits to the very same\n * logical position produce `path`s that are structurally equal but not\n * reference-equal at that segment — unusable for matching.\n * - Two different positions can legitimately produce the very same `path`,\n * when duplicate map entries carry equal keys (e.g. two `\"a\"` entries).\n * - A *container* (not just a leaf) can itself be a shared node instance\n * reused at two positions (e.g. the same `CborArray` placed at two\n * different indices of an outer array). Matching only on `{immediate\n * parent identity, local slot}` — as an earlier version of this type\n * did — correctly distinguishes the *container's own* two occurrences,\n * but not its *descendants'*: each of the shared container's children\n * would resolve `{parent: <the shared container>, slot: <local index>}`\n * identically regardless of which of the container's own two\n * occurrences was being converted, silently conflating them. Chaining\n * the full occurrence from the root — rather than just one level —\n * avoids this: the shared container's own two occurrences differ\n * earlier in the chain, so appending the same local slot to each still\n * yields two different full chains for its children.\n *\n * A local slot only needs to be unique among its own container's direct\n * children — `CborArray` uses the element index (`number`) directly;\n * `CborMap` prefixes a map entry's ordinal with `'k'`/`'v'`\n * (`` `k${i}` ``/`` `v${i}` ``) so a key and its own value, which share an\n * ordinal, don't collide.\n *\n * `RAW_PASS_MARKER` (see below) is the one non-structural element this\n * chain can contain: `CborArray`/`CborMap.toObject` insert it — once,\n * immediately before that level's own local slot — only when building a\n * child's occurrence for their raw structural pre-population pass (see\n * `withoutReviver`), never for the real, revived pass. That's what lets\n * `_toJSChild`'s cache correctly tell apart the *distinct* raw-pass\n * resolutions a single occurrence can otherwise receive when more than one\n * ancestor level forks — e.g. the very same value node visited once\n * through an outer container's own raw pass (before *any* ancestor has\n * revived anything) and once more through a different, inner container's\n * own raw pass nested inside the outer's real pass (after some ancestor,\n * such as a composite map key, *has* already been revived) — two visits\n * that share every structural coordinate yet must not share a cached\n * decision, since what a reviver-sensitive value like that key converts to\n * differs between them (see `DispatchCacheEntry`). A container that isn't\n * itself forking (no `reviver` in its own options, so it takes the plain,\n * unsplit path) never inserts the marker — it simply passes the\n * occurrence chain it was given through unchanged before extending it with\n * its own children's local slots, the same way it always did.\n */\nexport type Occurrence = readonly unknown[];\n\n/**\n * @internal\n * Sentinel inserted into an `Occurrence` chain by `CborArray`/\n * `CborMap.toObject` when building a child's occurrence for their own raw\n * structural pre-population pass — see `Occurrence`'s own note. A\n * dedicated symbol rather than a string/number so it can never collide\n * with an ordinary local slot value (an array index or a `` `k${i}` ``/\n * `` `v${i}` `` map-entry tag).\n */\nexport const RAW_PASS_MARKER: unique symbol = Symbol(\n 'cbor.itemOptions.rawPass'\n);\n\n/**\n * @internal\n * The root value's occurrence, for `toJS()`'s own top-level `_toJSChild()`\n * call — empty, the same way `ItemContext.path` is empty at the root. Also\n * used by `CborTag`/`CborAppSeqResult` as a defensive fallback if `_toJS()`\n * is ever invoked without an `occurrence` (only possible via a direct,\n * non-`toJS()` call to `_toJS()`, which the dispatch cache never sees).\n */\nexport const ROOT_OCCURRENCE: Occurrence = Object.freeze([]);\n\n/**\n * @internal\n * One resolved occurrence of a node, cached under that node in\n * `DispatchCache`. `occurrence` identifies *which* occurrence this is — a\n * single `CborItem` instance can legitimately appear at more than one\n * occurrence in a hand-built tree (e.g. the same shared node reused at two\n * array indices, or as the value of two entries sharing a duplicate map\n * key — or, transitively, as a descendant of such a shared node), and a\n * reviver-driven container's raw structural pre-population pass (see\n * `withoutReviver`) produces yet more distinct occurrences of its own for\n * the very same node, via `RAW_PASS_MARKER` — see `Occurrence`. A later\n * visit only reuses `outcome` once `occurrence` matches elementwise —\n * seeing this node again at a *different* occurrence (a distinct\n * `DispatchCacheEntry` in the same node's list, see `DispatchCache`)\n * resolves fresh instead, exactly as if no caching were happening for that\n * occurrence yet.\n *\n * The raw pass's own resolutions are never reused by the real, revived\n * pass (or vice versa) purely because their occurrences differ by\n * `RAW_PASS_MARKER` — not because of any separate bookkeeping — so\n * `itemOptions`/an extension's `toJS()` hook can run more than once for\n * what looks like \"the same node\" from the outside: once for each\n * distinct raw pass it's reachable through (there can be more than one,\n * nested — see `Occurrence`), plus once more for the real pass. That is\n * the accepted cost of a raw pass's placeholder value being observable\n * (`this[j]` for a not-yet-processed sibling `j`, inside an *earlier*\n * sibling's own reviver call) and therefore needing to reflect\n * `itemOptions`/`extensions` accurately rather than being computed as if\n * neither were configured.\n */\ninterface DispatchCacheEntry {\n occurrence: Occurrence;\n outcome: DispatchOutcome;\n}\n\n/**\n * @internal\n * One `toJS()` call's dispatch cache, keyed by node identity, each node\n * mapped to the list of occurrences resolved for it so far (almost always\n * exactly one — see `DispatchCacheEntry`). Exists because `CborArray`/\n * `CborMap` (with a `reviver`) and any nesting through `CborTag`/\n * `CborAppSeqResult` wrappers each visit the *same* occurrence more than\n * once — see `DispatchOutcome` — and `itemOptions`/an extension's `toJS()`\n * hook must still each run exactly once per occurrence, since either may be\n * stateful or otherwise have observable side effects.\n */\ntype DispatchCache = WeakMap<CborItem, DispatchCacheEntry[]>;\n\nfunction getDispatchCache(\n options: ToJSOptions | undefined\n): DispatchCache | undefined {\n return (options as Record<symbol, unknown> | undefined)?.[kDispatchCache] as\n DispatchCache | undefined;\n}\n\n/**\n * @internal\n * Attach a fresh dispatch cache to a top-level `toJS()` call's merged\n * options. Called once per `toJS()` invocation (never by internal\n * recursion), so unrelated calls never share a cache.\n */\nfunction withDispatchCache(options: ToJSOptions): ToJSOptions {\n const cache: DispatchCache = new WeakMap();\n return Object.assign({}, options, { [kDispatchCache]: cache });\n}\n\nfunction sameOccurrence(a: Occurrence, b: Occurrence): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n\n/**\n * @internal\n * Find the cached entry (if any) for the exact occurrence among a node's\n * previously-resolved occurrences.\n */\nfunction findOccurrence(\n entries: DispatchCacheEntry[] | undefined,\n occurrence: Occurrence\n): DispatchCacheEntry | undefined {\n return entries?.find((e) => sameOccurrence(e.occurrence, occurrence));\n}\n\n/**\n * @internal\n * Record a newly-resolved occurrence, appending to (rather than replacing)\n * whatever occurrences of this node were already recorded — see\n * `DispatchCacheEntry`.\n */\nfunction recordOccurrence(\n cache: DispatchCache,\n node: CborItem,\n entry: DispatchCacheEntry\n): void {\n const existing = cache.get(node);\n if (existing) existing.push(entry);\n else cache.set(node, [entry]);\n}\n\n// ─── toCDN() per-item dispatch ──────────────────────────────────────────────\n//\n// Much simpler than toJS()'s: there is no reviver, so no scenario ever\n// needs a node's itemOptions decision to be tied to *which* of two\n// differently-revived contexts produced it — the one thing DispatchCache's\n// whole occurrence/RAW_PASS_MARKER design exists for. toCDN() already has\n// its own, unrelated reason a node can be rendered more than once per\n// parent render (see `CdnItemContext`'s own doc), and the existing code's\n// own answer to that (see `serializeContainer` in cdn/serialize-utils.ts)\n// is to accept it rather than cache around it — a real, resolved\n// instance-level cache having already turned out unsafe there (see\n// `CborTag._isMultiWordText`). So `itemOptions` here just resolves fresh\n// on every call, with no cache at all.\n\n/**\n * @internal\n * Cheap upfront check for whether per-node option resolution is needed at\n * all for a given `toCDN()` options object — the `toCDN()` analogue of\n * `needsItemDispatch`.\n */\nexport function needsCdnItemDispatch(\n options: ToCDNOptions | undefined\n): boolean {\n return !!options?.itemOptions;\n}\n\n/**\n * @internal\n * Build the copied-`textStringFormat` view of `options` handed to\n * `CdnItemContext.options` — the `toCDN()` analogue of\n * `toReadonlyNodeOptions`; see `ReadonlyToCDNOptions`. Also strips\n * `CDN_OVERRIDE_TRACKER` (see there) — `ctx.options` is documented as\n * reflecting the current *effective options*, so it should never expose an\n * internal, out-of-band bookkeeping key that isn't part of `ToCDNOptions` at\n * all, even though it isn't otherwise observable through any named field.\n */\nexport function toReadonlyCdnOptions(\n options: ToCDNOptions\n): ReadonlyToCDNOptions {\n const { textStringFormat, ...rest } = options as ToCDNOptions & {\n [CDN_OVERRIDE_TRACKER]?: CdnOverrideTrackerBox;\n };\n delete rest[CDN_OVERRIDE_TRACKER];\n return textStringFormat\n ? { ...rest, textStringFormat: [...textStringFormat] }\n : rest;\n}\n\n/**\n * @internal\n * Out-of-band symbol key that lets a caller (currently only\n * `CborAppSeqResult._toCDN`) track, across an entire `_resolveCdnOptions()`\n * subtree, whether `itemOptions` ever actually returned an override —\n * without touching `options.itemOptions` itself.\n *\n * `CborAppSeqResult` needs to know whether its preserved verbatim source is\n * still exactly right after offering `itemOptions` a chance to override one\n * of its descendants (see its own doc). Wrapping `options.itemOptions` in a\n * tracking function was tried first, but that function becomes\n * `ctx.options.itemOptions` for every descendant (`_resolveCdnOptions`\n * builds `ctx.options` from the very `options` it was given) — a pure\n * `itemOptions` callback could tell it apart from the caller's own function\n * by identity, observing a difference between an ordinary subtree and one\n * reached through an app-sequence wrapper that `ctx.options`'s \"current\n * effective options\" contract never promises.\n *\n * A symbol-keyed property on `options` instead survives every\n * `{...options, ...override}` merge `_resolveCdnOptions` performs exactly\n * the same way `itemOptions` itself does (object spread copies symbol keys\n * too, and by reference — the same tracker box is shared, never cloned, by\n * every node in the subtree), while never being part of the public\n * `ToCDNOptions` shape or observable through any named field — see\n * `toReadonlyCdnOptions`, which explicitly strips it before building\n * `ctx.options`.\n */\nexport const CDN_OVERRIDE_TRACKER: unique symbol = Symbol('cdnOverrideTracker');\n\n/** @internal Mutable box referenced (never copied) via `CDN_OVERRIDE_TRACKER`. */\nexport interface CdnOverrideTrackerBox {\n applied: boolean;\n}\n\n/**\n * Abstract base class for all CBOR AST nodes.\n *\n * Every node can serialize itself to CBOR binary, CDN text, and a\n * plain JavaScript value. Concrete implementations are provided in each\n * subclass (added in later phases).\n */\nexport abstract class CborItem {\n /**\n * Character offset of the first character of this item in the parsed source.\n * Set by parsers; undefined when the node was constructed directly.\n * For CBOR input this is a byte offset.\n */\n start?: number;\n\n /**\n * Character offset just past the last character of this item in the parsed source.\n * Set by parsers; undefined when the node was constructed directly.\n * For CBOR input this is a byte offset.\n */\n end?: number;\n\n /**\n * Comments captured from CDN source when `preserveComments` is enabled.\n * They do not affect CBOR bytes or JS conversion.\n */\n comments?: CborComments;\n\n /**\n * `true` when this node is an array/map entry (or indefinite-length\n * string chunk) immediately preceded by a blank line in the parsed CDN\n * source — set unconditionally by the parser, regardless of any\n * `preserve*` option, mirroring `start`/`end`. Only consulted by\n * `toCDN()` when `ToCDNOptions.preserveBlankLines` is set; otherwise\n * ignored. Left `undefined` for nodes not parsed as a container entry, or\n * with no blank line before them.\n */\n blankLineBefore?: boolean;\n\n /**\n * Original app-string/-sequence source text — `prefix'...'`,\n * `` prefix`...` ``, or `prefix<<...>>` — set by the parser when the\n * resolving extension declares `preserveAppSeqSource: 'optional'`. A\n * subclass's own `_toCDN()` override may check this (gated behind\n * `ToCDNOptions.preserveAppPrefix`) to round-trip the exact original\n * spelling instead of always regenerating `prefix'...'` notation from the\n * resolved value. Left `undefined` for nodes not parsed from one of these\n * forms.\n */\n appSeqSource?: string;\n\n /**\n * Comments contained within `appSeqSource`, with `start`/`end` offsets\n * relative to that string. These spans allow comment markers to be\n * converted (or comments to be removed) without regenerating and thereby\n * losing the original app-string/-sequence notation.\n */\n appSeqComments?: CborComment[];\n\n /**\n * Source edits for encoding indicators contained in a raw-tag\n * `appSeqSource`. Includes zero-width edits where an indicator was absent\n * so `encodingIndicators: 'always'` can insert one without regenerating\n * the surrounding source.\n */\n appSeqEncodingEdits?: AppSeqEncodingEdit[];\n\n /**\n * `false` when `appSeqEncodingEdits` does not cover every encoding\n * indicator nested inside a raw-tag `appSeqSource` — i.e. its content\n * contains a node type `collectContentEncodingEdits` doesn't know how to\n * edit (e.g. a `CborMap`, `CborTag`, or indefinite-length string inside an\n * `ip` array). Left `undefined` (treated as complete) when coverage is\n * exhaustive, which holds for every tag content type `dt` accepts and for\n * most content `ip` accepts. When `false`, `decideTaggedAppSeqRendering`\n * must not choose the `'source'` decision under `encodingIndicators !==\n * 'auto'`, since surgical span edits would silently leave the uncovered\n * node's indicator unchanged; it falls back to `'structural'` instead.\n */\n appSeqEncodingEditsComplete?: boolean;\n\n /**\n * For an `appSeqSource` parsed from `prefix<<item>>` notation: the offset\n * within `appSeqSource`, relative to its own start, where the sole inner\n * item's own consumption ends — i.e. right after its own encoding\n * indicator, if it had one. Lets `adjustAppSeqIndicator` locate and strip\n * that inner indicator exactly, regardless of what (whitespace, a\n * trailing comma, a comment) separates it from the closing `>>`, rather\n * than pattern-matching text near `>>`. `undefined` when `appSeqSource`\n * isn't `<<...>>` notation, or wasn't captured with a single inner item.\n */\n appSeqInnerEnd?: number;\n\n /**\n * Literal-preservation features present in the sole item of a captured\n * `prefix<<item>>` source. Used to resolve explicitly disabled\n * `preserve*` options without treating unrelated options as conflicts.\n */\n appSeqSourceFeatures?: AppSeqSourceFeatures;\n\n /**\n * Validity violations detected while decoding or parsing this node.\n * Populated when `strict: false` is set in `FromCBOROptions` or\n * `FromCDNOptions`.\n */\n warnings?: (DecodeWarning | ParseWarning)[];\n\n /**\n * Default options bound by a {@link CBOR} instance factory method.\n * Per-call options always take precedence.\n * @internal\n */\n _defaults?: CBOROptions;\n\n /**\n * @internal\n * True when this node is, or contains through wrapper nodes (tags,\n * app-sequence results), an array or map. `inlineLeafContainers` never\n * inlines a container whose entries contain another container, even one\n * that renders on a single line. `CborEmbeddedCBOR` (`<<...>>`) is the one\n * exception: it inlines its own entries based purely on whether they\n * render without a line break, regardless of this flag — see its\n * `_toCDN()`, which omits `entryIsLeaf` for that reason.\n */\n get _containsCdnContainer(): boolean {\n return false;\n }\n\n /**\n * @internal\n * True when this node's own text content (a text string, or a byte\n * string that would render as bare sqstr text) has two or more words —\n * `inlineLeafContainers` never collapses a container whose entries hold\n * such a string onto the container's own line, even though the entry\n * itself has no nested array/map, since a multi-word string reads better\n * with room of its own. See `isMultiWordText()`/`isMultiWordByteString()`\n * in `cdn/serialize-utils.ts`. Takes `options` because whether a byte\n * string even renders as text (`'...'`) rather than a prefixed literal\n * (`h'...'`, `b64'...'`, ...) depends on the `sqstr` option.\n *\n * This method deliberately does *not* also cover the \"is this (or does\n * it wrap) a prefixed literal\" question — a byte-string literal has no\n * word count to check, and an app-string literal (`dt'...'`) is\n * word-counted from its rendered content, but either disqualifies only\n * under the strict rule (and, per\n * `strict`, is an ordinary leaf under the loose one). That's handled\n * generically elsewhere instead, from the *actual rendered text* rather\n * than predicted from this node's type: `isPrefixedLiteralText` for a\n * bare entry (`serializeContainer` checks it against the already\n * rendered `s`), or `isMultiWordRenderedLiteral` for `CborTag`, which\n * overrides this method entirely to tokenize its own `_toCDN()` output\n * instead of delegating here — necessary because a `CborTag` subclass\n * (`CborTaggedIpExt`, `CborTaggedEpochDtExt`, ...) may override `_toCDN()`\n * to render something that doesn't look like generic `tagNum(content)`\n * notation at all, which a semantic prediction from `this.content` alone\n * could never know about.\n *\n * `strict` (default `true`) is passed down by whichever container's own\n * `_toCDN` directly holds this entry: `true` for the strict rule\n * (`CborArray`/`CborMap`, and `CborIndefiniteTextString`/\n * `CborIndefiniteByteString` too — all four provide `entryIsLeaf`),\n * `false` only for `CborEmbeddedCBOR` (`<<...>>`), the one container\n * whose collapse isn't gated behind `inlineLeafContainers` at all and\n * the only one that omits `entryIsLeaf`. This base implementation and\n * `CborTextString`/`CborByteString`'s overrides ignore `strict` (a text\n * string's, or byte string's own sqstr-text, word count is unaffected by\n * it either way) — only `CborTag` (and, transitively, `CborAppSeqResult`\n * delegating to its inner value) actually consult it.\n *\n * `path` is this entry's own full path (see `CdnItemContext.path`),\n * passed down by the same caller for the same reason `renderEntry`\n * receives it: `CborTag`/`CborAppSeqResult` re-render `this` here (see\n * their own overrides) purely to answer this method's question, and that\n * re-render must resolve any of *its own* descendants' `itemOptions`\n * against the entry's real path — not an empty one — or a descendant\n * several levels inside a tag-wrapped entry could see a different\n * `ctx.path` here than the real render further down gives it. Only\n * `CborTag`/`CborAppSeqResult` consult it; every other override ignores\n * it, the same as `strict`.\n */\n _isMultiWordText(\n _options: ToCDNOptions | undefined,\n _strict = true,\n _path?: readonly unknown[]\n ): boolean {\n return false;\n }\n\n /**\n * @internal\n * Optional override: an alternate plain-string spelling to use as this\n * node's `toJS()` object key, in place of `CborMap.toObject()`'s generic\n * `toCDN()` fallback for a non-text-string key. Returns `undefined` to use\n * that default. The base class implements no such override; a subclass\n * that carries an alternate key spelling for a non-text key (e.g. a CDDL\n * e-ref annotated integer key — see `extensions/eref.ts`) overrides this\n * instead of `CborMap` special-casing that subclass directly. Takes the\n * full `ToJSOptions` (unlike `_toCDN`'s options) since a key-naming choice\n * like e-ref's `eRefKeys` is a `toJS()`-only concept with no CDN analogue.\n */\n _jsObjectKey(_options: ToJSOptions | undefined): string | undefined {\n return undefined;\n }\n\n // ─── Public template methods ────────────────────────────────────────────────\n\n /** Serialize this node to CBOR binary. */\n toCBOR(options?: ToCBOROptions): Uint8Array {\n const merged = this._defaults ? { ...this._defaults, ...options } : options;\n const writer = new CborWriter();\n this._encode(writer, merged);\n return writer.finish();\n }\n\n /** Serialize this node to a CDN text string. */\n toCDN(options?: ToCDNOptions): string {\n let merged = this._defaults ? { ...this._defaults, ...options } : options;\n if (merged) merged = resolveDeprecatedAppPrefixAliases(merged);\n if (merged?.preserveAll) merged = expandPreserveAll(merged);\n const eff = this._resolveCdnOptions(merged, EMPTY_PATH, {});\n const body = this._toCDN(eff, 0, EMPTY_PATH);\n // Single-line output strips comments: `#`/`//` comments need a newline\n // to terminate, so they cannot be emitted without breaking the guarantee\n // that single-line output contains no newlines.\n if (!shouldEmitComments(eff) || resolveIndent(eff) === null) return body;\n const style = resolveCommentStyle(eff);\n const { ownLines, inlinePrefix } = splitLeadingComments(this, '', style);\n const trailing = this.comments?.trailing ?? [];\n const bodyWithTrailing =\n trailing.length === 0\n ? body\n : `${body} ${trailing.map((c) => convertCommentText(c, style).trimEnd()).join(' ')}`;\n return [...ownLines, `${inlinePrefix}${bodyWithTrailing}`].join('\\n');\n }\n\n /**\n * Serialize this node to a CDN text string.\n *\n * @deprecated Use `toCDN()` instead.\n */\n toEDN(options?: ToCDNOptions): string {\n return this.toCDN(options);\n }\n\n /**\n * Convert this CBOR AST node to a plain JavaScript value.\n *\n * If `options.reviver` is supplied it is called with key `''` on the root\n * result after the full tree has been converted (matching the semantics of\n * `JSON.parse`). Container nodes call the reviver on each of their direct\n * children during conversion, so the walk is bottom-up.\n */\n toJS(options?: ToJSOptions): unknown {\n const merged = this._defaults ? { ...this._defaults, ...options } : options;\n const result = needsItemDispatch(merged)\n ? this._toJSChild(\n withDispatchCache(merged!),\n EMPTY_PATH,\n ROOT_OCCURRENCE,\n {}\n )\n : this._toJS(merged);\n if (!merged?.reviver) return result;\n const rv = merged.reviver.call({ '': result }, '', result);\n return rv === CBOR_OMIT ? undefined : rv;\n }\n\n /**\n * Generate an RFC 8949 §3 style annotated hex dump of this value.\n *\n * @example\n * const cbor = CBOR.fromCDN('[_ 1, [2, 3]]');\n * console.log(cbor.toHexDump());\n * // 9F -- Start indefinite-length array\n * // 01 -- 1\n * // 82 -- Array of length 2\n * // 02 -- 2\n * // 03 -- 3\n * // FF -- \"break\"\n * // FF -- \"break\"\n */\n toHexDump(options?: ToHexDumpOptions): string {\n let merged: (ToHexDumpOptions & ToCDNOptions) | undefined = this._defaults\n ? { ...this._defaults, ...options }\n : options;\n if (merged) merged = resolveDeprecatedAppPrefixAliases(merged);\n const raw = merged?.indent ?? 3;\n const indentStr = typeof raw === 'string' ? raw : ' '.repeat(raw);\n const marker = (merged?.commentStyle ?? '--') + ' ';\n const lines = this._toHexDump(0, merged);\n // A plain loop, not Math.max(...spread): spreading one argument per line\n // overflows the call stack for items with hundreds of thousands of lines.\n let maxPrefixLen = 0;\n for (const l of lines) {\n const prefixLen = l.depth * indentStr.length + l.hex.length;\n if (prefixLen > maxPrefixLen) maxPrefixLen = prefixLen;\n }\n const col = maxPrefixLen + 2;\n return lines\n .map((l) => {\n const prefix = indentStr.repeat(l.depth) + l.hex;\n return prefix.padEnd(col) + marker + l.comment;\n })\n .join('\\n');\n }\n\n // ─── Internal abstract methods ───────────────────────────────────────────────\n\n /**\n * @internal\n * Encode this node into `writer`, honoring `_toCBOR()` overrides.\n *\n * This is the entry point used by `toCBOR()` and by container nodes when\n * recursing into children. A subclass that overrides `_toCBOR()` (e.g. to\n * emit a pre-computed bit pattern) is authoritative even when one of its\n * built-in base classes implements `_encodeTo()`.\n */\n _encode(writer: CborWriter, options?: ToCBOROptions): void {\n if (this._toCBOR !== CborItem.prototype._toCBOR) {\n writer.writeBytes(this._toCBOR(options));\n return;\n }\n this._encodeTo(writer, options);\n }\n\n /**\n * @internal\n * Write this node's CBOR encoding into `writer`.\n *\n * Built-in nodes override this so that an entire encode pass shares one\n * growing buffer (no per-node Uint8Array allocations or re-copies).\n * Container implementations must recurse via `child._encode()`, never\n * `child._encodeTo()`, so that `_toCBOR()` overrides are honored.\n */\n _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n if (this._toCBOR === CborItem.prototype._toCBOR)\n throw new TypeError(\n 'CborItem subclass must implement _encodeTo() or _toCBOR()'\n );\n writer.writeBytes(this._toCBOR(options));\n }\n\n /**\n * @internal\n * Subclass CBOR encoding implementation.\n * The default builds the bytes via `_encodeTo()`; subclasses may instead\n * override this method directly when producing a standalone byte array is\n * more natural (e.g. emitting a pre-computed bit pattern).\n */\n _toCBOR(options?: ToCBOROptions): Uint8Array {\n const writer = new CborWriter();\n this._encodeTo(writer, options);\n return writer.finish();\n }\n\n /**\n * @internal\n * Depth-aware CDN serialization.\n * Leaf nodes receive `depth` but may ignore it.\n * Container nodes use `depth` for indentation and, when recursing, must\n * resolve each child's options via `child._resolveCdnOptions()` first\n * (rather than passing `options` straight through) so `itemOptions` is\n * honored for every node, not just the root — see `_resolveCdnOptions`.\n * `path` is this node's own full path from the root (see\n * `CdnItemContext.path`); only meaningful when `needsCdnItemDispatch()`\n * is `true` for the options in effect — leaf implementations that don't\n * recurse can ignore it, as can any implementation when dispatch isn't\n * in play.\n */\n abstract _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string;\n\n /**\n * @internal\n * Resolve `options.itemOptions` for this node (if any), returning the\n * options a caller should use for both this node's own `_toCDN()` call\n * and (via `_isMultiWordText()`) any layout probe of it — see\n * `CdnItemContext`. Unlike `toJS()`'s `_toJSChild()`, this never caches:\n * see the \"toCDN() per-item dispatch\" note above `needsCdnItemDispatch`\n * for why that's both unnecessary and, per this codebase's own prior\n * experience with `CborTag._isMultiWordText`, unsafe here specifically.\n *\n * `ctx` follows the same \"no `key`, derived from `path`'s last element\"\n * convention `_toJSChild()` uses (see there) — a caller passes\n * `parent`/`keyNode`/`isMapKey` only; `key` is filled in here.\n */\n _resolveCdnOptions(\n options: ToCDNOptions | undefined,\n path: readonly unknown[],\n ctx: Omit<CdnItemContext, 'path' | 'key' | 'options'>\n ): ToCDNOptions | undefined {\n if (!needsCdnItemDispatch(options)) return options;\n const key =\n ctx.isMapKey || path.length === 0 ? undefined : path[path.length - 1];\n const override = options!.itemOptions!(this, {\n ...ctx,\n key,\n path,\n options: toReadonlyCdnOptions(options!),\n });\n if (!override) return options;\n const tracker = (\n options as ToCDNOptions & {\n [CDN_OVERRIDE_TRACKER]?: CdnOverrideTrackerBox;\n }\n )[CDN_OVERRIDE_TRACKER];\n if (tracker) tracker.applied = true;\n // Normalize the override's own deprecated aliases *before* merging: see\n // `normalizeCdnOverride` for why resolving them after merging would let\n // an already-resolved, inherited canonical value silently outrank the\n // child's own alias-based override.\n let eff: ToCDNOptions = { ...options, ...normalizeCdnOverride(override) };\n if (eff.preserveAll) eff = expandPreserveAll(eff);\n return eff;\n }\n\n /**\n * @internal\n * Core conversion logic implemented by each subclass.\n * Container nodes apply `options.reviver` to their direct children, and\n * must recurse via `child._toJSChild()` (never `child._toJS()` directly)\n * so that `options.itemOptions`/`options.extensions` are honored for\n * every node, not just the root — see `_toJSChild`.\n * `path` is this node's own full path from the root (see `ItemContext.path`);\n * only meaningful, and only ever non-empty, when `needsItemDispatch()` is\n * `true` for the options in effect — leaf implementations that don't\n * recurse can ignore it. `occurrence` is this node's own cache-matching\n * identity (see `Occurrence`) — `CborArray`/`CborMap` build on it to\n * derive their children's own occurrences, and `CborTag`/`CborAppSeqResult`\n * pass it through unchanged to their content's `_toJSChild()` call; leaf\n * implementations that don't recurse can ignore it.\n * Do not call this directly — use `toJS()` instead.\n */\n abstract _toJS(\n options?: ToJSOptions,\n path?: readonly unknown[],\n occurrence?: Occurrence\n ): unknown;\n\n /**\n * @internal\n * Entry point container nodes must use when recursing into a child during\n * `toJS()`, instead of calling `child._toJS(options)` directly, so that\n * `options.itemOptions` and `options.extensions` (toJS hooks) are honored\n * for every node in the tree, not just the root.\n *\n * Guarded by `needsItemDispatch()` at each call site rather than\n * internally, so that containers can skip straight to the cheap\n * `child._toJS(options)` call — matching pre-`itemOptions` behavior\n * exactly, with no extra allocation — whenever neither option is in play\n * for the whole conversion.\n *\n * `path` is this child's own full path from the root, already computed by\n * the caller: `[...parentPath, key]` for an array element or map\n * entry/key, or the parent's own `path` unchanged for a transparent\n * wrapper's content (`CborTag`, `CborAppSeqResult`) — see\n * `ItemContext.path`. `ctx.key` is *not* supplied by the caller — it's\n * derived here from `path`'s own last element (or left `undefined` for\n * the root and for `isMapKey` visits), which is what keeps a wrapper's\n * content correctly reporting its outer key: since `CborTag`/\n * `CborAppSeqResult` pass their own unmodified `path` straight through,\n * that derivation naturally recovers the tag's own key for its content\n * too, matching `ItemContext.key`'s documented invariant of always\n * equalling `path`'s last element outside those two exceptions.\n *\n * `occurrence` identifies this child's position for cache-matching\n * purposes only (see `Occurrence`) — deliberately separate from `path`,\n * which is built from *converted JS values* and so is unreliable for\n * that: matching on `path` alone either double-resolves the same position\n * (a composite map key converts to a fresh, non-`===` array/object every\n * time) or wrongly conflates two different positions that happen to\n * convert to equal `path`s (duplicate map entries with equal keys).\n * `occurrence` avoids both by construction — see `Occurrence`.\n *\n * A single node can be visited more than once *at the same occurrence* in\n * one `toJS()` call — a `reviver`-driven `CborArray`/`CborMap` converts\n * each child once to pre-populate an unrevived holder and once more to\n * compute the revived value (see their own `_toJS()`), and either pass\n * may itself recurse through a `CborTag`/`CborAppSeqResult` wrapper that\n * adds no occurrence of its own (content shares the wrapper's). The raw\n * pre-population pass's own occurrence for a child is distinguished from\n * the real pass's by `RAW_PASS_MARKER` (see `Occurrence`), so that even\n * distinct, *nested* raw passes reaching the same node — one from an\n * outer container's own split, one from a different, inner container's\n * own split nested inside the outer's real pass — resolve independently\n * rather than colliding with each other. Neither `options.itemOptions`\n * nor an `extensions` `toJS()` hook may run more than once for the same\n * occurrence despite all that, since either may be stateful — so the\n * *decision* (not the reviver-dependent application of an `itemOptions`\n * override — see `DispatchOutcome`) is cached in `options`'s dispatch\n * cache, when one is present, and reused on a later visit to that exact\n * occurrence. A node *reused* at more than one occurrence (the same\n * `CborItem` instance placed at two positions in a hand-built tree)\n * still resolves once per occurrence, never conflating two different\n * ones.\n */\n _toJSChild(\n options: ToJSOptions | undefined,\n path: readonly unknown[],\n occurrence: Occurrence,\n ctx: Omit<ItemContext, 'path' | 'key' | 'options'>\n ): unknown {\n const cache = getDispatchCache(options);\n const cached = findOccurrence(cache?.get(this), occurrence);\n if (cached) {\n if (cached.outcome.kind === 'value') return cached.outcome.value;\n const eff = cached.outcome.override\n ? { ...options, ...cached.outcome.override }\n : options;\n return this._toJS(eff, path, occurrence);\n }\n\n const key =\n ctx.isMapKey || path.length === 0 ? undefined : path[path.length - 1];\n let eff = options;\n let override: Partial<ToJSOptions> | undefined;\n if (options?.itemOptions) {\n // `ctx.options` is `options` itself, read-only and with `extensions`\n // (if any) copied — see `toReadonlyNodeOptions` — so the callback\n // can't corrupt what this node, its siblings, or the caller see by\n // mutating what it read. Computed fresh here (never cached) so it\n // always reflects exactly what's in effect for *this* call, not a\n // stale snapshot from an earlier resolution of the same occurrence.\n override = options.itemOptions(this, {\n ...ctx,\n key,\n path,\n options: toReadonlyNodeOptions(options),\n });\n if (override) eff = { ...options, ...override };\n }\n if (eff?.extensions?.length) {\n // Hooks never see `reviver` (see `ReadonlyToJSNodeOptions`) — not\n // merely by convention, but because its type omits the field — so\n // their result can never itself depend on it, which is what makes\n // caching that result across a reviver-driven container's repeat\n // visits sound. `extensions` is likewise copied — freshly for *each*\n // hook, not once and shared across the loop — so one hook mutating\n // it in place (bypassing the readonly type) can't leak into what a\n // later hook in the same loop sees.\n for (const ext of eff.extensions) {\n const hooked = ext.toJS?.(this, toReadonlyNodeOptions(eff));\n if (hooked) {\n if (cache)\n recordOccurrence(cache, this, {\n occurrence,\n outcome: { kind: 'value', value: hooked.value },\n });\n return hooked.value;\n }\n }\n }\n if (cache)\n recordOccurrence(cache, this, {\n occurrence,\n outcome: { kind: 'override', override },\n });\n return this._toJS(eff, path, occurrence);\n }\n\n /**\n * @internal\n * Collect annotated-hex lines for this node.\n * Leaf nodes emit a single line; container nodes override to emit\n * open/close lines with recursively collected children.\n */\n _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n const hex = bytesToSpacedHexUpper(this._toCBOR());\n return [{ depth, hex, comment: this._toCDN(options, 0) }];\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem } from './CborItem';\nimport { MT_UINT } from '../cbor/constants';\nimport {\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n} from '../cdn/serialize-utils';\n\n/** CBOR Major Type 0 — unsigned integer (0 … 2^64−1). */\nexport class CborUint extends CborItem {\n readonly value: bigint;\n encodingWidth: EncodingWidth | undefined;\n /**\n * Original CDN digit spelling (base + digits, without the encoding-\n * indicator suffix), set by the parser when this value came from CDN\n * text. Used by `_toCDN()` to round-trip the literal's base (`0xff`,\n * `0o377`, `0b101`, decimal) when `preserveNumberFormat` is set.\n */\n readonly ednSource?: string;\n\n constructor(\n value: number | bigint,\n options?: { encodingWidth?: EncodingWidth; ednSource?: string }\n ) {\n super();\n this.value = BigInt(value);\n if (this.value < 0n)\n throw new RangeError('CborUint value must be non-negative');\n if (this.value > 0xffff_ffff_ffff_ffffn)\n throw new RangeError('CborUint value exceeds maximum uint64');\n this.encodingWidth = options?.encodingWidth;\n this.ednSource = options?.ednSource;\n }\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n writeHeadTo(writer, MT_UINT, this.value, this.encodingWidth);\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n _path?: readonly unknown[]\n ): string {\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.value)\n );\n if (options?.preserveNumberFormat && this.ednSource !== undefined) {\n return this.ednSource + suffix;\n }\n const v = this.value;\n switch (options?.intFormat) {\n case 'hex':\n return `0x${v.toString(16)}${suffix}`;\n case 'octal':\n return `0o${v.toString(8)}${suffix}`;\n case 'binary':\n return `0b${v.toString(2)}${suffix}`;\n default:\n return v.toString() + suffix;\n }\n }\n\n _toJS(options?: ToJSOptions): unknown {\n const mode = options?.integerAs ?? 'auto';\n if (mode === 'bigint') return this.value;\n if (mode === 'number') return Number(this.value);\n return this.value <= BigInt(Number.MAX_SAFE_INTEGER)\n ? Number(this.value)\n : this.value;\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem } from './CborItem';\nimport { MT_NINT } from '../cbor/constants';\nimport {\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n} from '../cdn/serialize-utils';\n\n/**\n * CBOR Major Type 1 — negative integer (−2^64 … −1).\n *\n * The constructor accepts the actual negative value (e.g. `-5n`).\n * Internally the CBOR \"argument\" `n` is stored, where the decoded value\n * equals `−1 − n`. This matches the wire encoding directly.\n *\n * Examples:\n * new CborNint(-1n) → argument = 0n\n * new CborNint(-5n) → argument = 4n\n */\nexport class CborNint extends CborItem {\n /** CBOR raw argument n, where actual value = −1 − n. */\n readonly argument: bigint;\n encodingWidth: EncodingWidth | undefined;\n /**\n * Original CDN digit spelling (sign + base + digits, without the\n * encoding-indicator suffix), set by the parser when this value came\n * from CDN text. Used by `_toCDN()` to round-trip the literal's base\n * (`-0xff`, `-0o377`, `-0b101`, decimal) when `preserveNumberFormat` is\n * set.\n */\n readonly ednSource?: string;\n\n constructor(\n value: number | bigint,\n options?: { encodingWidth?: EncodingWidth; ednSource?: string }\n ) {\n super();\n const v = BigInt(value);\n if (v >= 0n) throw new RangeError('CborNint value must be negative');\n if (v < -(0xffff_ffff_ffff_ffffn + 1n))\n throw new RangeError('CborNint value exceeds minimum int64');\n this.argument = -1n - v;\n this.encodingWidth = options?.encodingWidth;\n this.ednSource = options?.ednSource;\n }\n\n /** The actual decoded negative value (−1 − argument). */\n get value(): bigint {\n return -1n - this.argument;\n }\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n writeHeadTo(writer, MT_NINT, this.argument, this.encodingWidth);\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n _path?: readonly unknown[]\n ): string {\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.argument)\n );\n if (options?.preserveNumberFormat && this.ednSource !== undefined) {\n return this.ednSource + suffix;\n }\n const abs = this.argument + 1n; // absolute value of the negative number\n switch (options?.intFormat) {\n case 'hex':\n return `-0x${abs.toString(16)}${suffix}`;\n case 'octal':\n return `-0o${abs.toString(8)}${suffix}`;\n case 'binary':\n return `-0b${abs.toString(2)}${suffix}`;\n default:\n return this.value.toString() + suffix;\n }\n }\n\n _toJS(options?: ToJSOptions): unknown {\n const v = this.value;\n const mode = options?.integerAs ?? 'auto';\n if (mode === 'bigint') return v;\n if (mode === 'number') return Number(v);\n return v >= BigInt(Number.MIN_SAFE_INTEGER) ? Number(v) : v;\n }\n}\n","/**\n * Hex float (C99-style, e.g. `0x1.8p+0`) encode/decode utilities.\n *\n * Hex float format:\n * [-] 0x [hex digits] [. [hex digits]] p [+-] [decimal exponent]\n *\n * This notation appears in CDN (draft-ietf-cbor-edn-literals-27) as an\n * alternative representation for floating-point values (major type 7).\n */\n\n// Reusable 8-byte buffer for float64 bit extraction\nconst _buf8 = new ArrayBuffer(8);\nconst _dv8 = new DataView(_buf8);\n\n/**\n * Parse a hex float literal (e.g. `0x4711p+03`, `0x1.8p+0`, `-0x1.fp-2`)\n * to a JS number.\n *\n * Assumes the string has already been stripped of any encoding-indicator\n * suffix (`_1`, `_2`, `_3`).\n */\nexport function parseHexFloat(s: string): number {\n const neg = s.startsWith('-');\n const body = s.slice(neg ? 3 : 2); // strip optional '-' and '0x'/'0X'\n\n const pIdx = body.search(/[pP]/);\n if (pIdx === -1)\n throw new SyntaxError(\n `EDN parse error: hex float missing 'p' exponent: ${s}`\n );\n\n const mantissaStr = body.slice(0, pIdx);\n const expStr = body.slice(pIdx + 1);\n\n // Exponent must be a non-empty decimal integer (optional sign + digits)\n if (!/^[+-]?\\d+$/.test(expStr))\n throw new SyntaxError(\n `EDN parse error: hex float has invalid or missing exponent: ${s}`\n );\n\n const exp = parseInt(expStr, 10);\n\n const dotIdx = mantissaStr.indexOf('.');\n let mantissa: number;\n if (dotIdx === -1) {\n // No decimal point: must have at least one hex digit\n if (!/^[0-9a-fA-F]+$/.test(mantissaStr))\n throw new SyntaxError(\n `EDN parse error: hex float has no mantissa digits: ${s}`\n );\n mantissa = parseInt(mantissaStr, 16);\n } else {\n const intPart = mantissaStr.slice(0, dotIdx);\n const fracStr = mantissaStr.slice(dotIdx + 1);\n // At least one hex digit required on either side of the decimal point\n if (intPart === '' && fracStr === '')\n throw new SyntaxError(\n `EDN parse error: hex float has no mantissa digits: ${s}`\n );\n if (intPart !== '' && !/^[0-9a-fA-F]+$/.test(intPart))\n throw new SyntaxError(\n `EDN parse error: hex float has invalid mantissa: ${s}`\n );\n if (fracStr !== '' && !/^[0-9a-fA-F]+$/.test(fracStr))\n throw new SyntaxError(\n `EDN parse error: hex float has invalid mantissa: ${s}`\n );\n const intVal = intPart === '' ? 0 : parseInt(intPart, 16);\n const fracVal =\n fracStr === '' ? 0 : parseInt(fracStr, 16) / Math.pow(16, fracStr.length);\n mantissa = intVal + fracVal;\n }\n\n const result = mantissa * Math.pow(2, exp);\n return neg ? -result : result;\n}\n\n/**\n * Convert a JS number to a normalized hex float string compatible with\n * CDN diagnostic notation.\n *\n * - Every nonzero finite value: `0x1.[hex fraction]p[+-][exp]` (e.g.\n * `0x1.8p+0` for 1.5) — including a *subnormal* double, renormalized\n * into this same leading-`1` form rather than spelled out anchored to\n * its own stored field layout (`0x0.[hex fraction]p-1022`, still a\n * correct spelling of the same value, but needlessly longer: e.g.\n * `Number.MIN_VALUE` used to read `0x0.0000000000001p-1022`, equal to\n * but far longer than the normalized `0x1p-1074`. A hex-float literal\n * is just `significand * 2^exponent` — there's no reason its spelling\n * should vary by whether the *double* happened to run out of exponent\n * range, once it's just text.)\n * - Zero: `0x0p+0` / `-0x0p+0`\n * - Non-finite values (NaN, ±Infinity) are returned unchanged as EDN tokens.\n */\nexport function floatToHexFloat(v: number): string {\n if (isNaN(v)) return 'NaN';\n if (!isFinite(v)) return v > 0 ? 'Infinity' : '-Infinity';\n\n const neg = Object.is(v, -0) || v < 0;\n const abs = Math.abs(v);\n\n if (abs === 0) return neg ? '-0x0p+0' : '0x0p+0';\n\n _dv8.setFloat64(0, abs, false); // big-endian\n const hi = _dv8.getUint32(0, false);\n const lo = _dv8.getUint32(4, false);\n\n // bits [30:20] of hi = biased exponent (11 bits)\n const biasedExp = (hi >>> 20) & 0x7ff;\n // bits [19:0] of hi = upper 20 bits of 52-bit mantissa\n const mantHi = hi & 0xfffff;\n // lo = lower 32 bits of mantissa\n const mantLo = lo;\n\n let mantissa52: bigint; // the 52 fraction bits that go after \"1.\"\n let exp: number;\n if (biasedExp === 0) {\n // Subnormal: value = 0.[52-bit mantissa] * 2^-1022, with no implicit\n // leading 1 of its own. Renormalize by finding the mantissa's own\n // leading set bit (`mantHi`/`mantLo` can't both be zero here — that\n // combination, with `biasedExp === 0`, would mean `abs === 0`,\n // already returned above) and shifting it up to become the implicit\n // \"1\", the same renormalization step CPU hardware performs when it\n // promotes a subnormal operand.\n const mantissa = (BigInt(mantHi) << 32n) | BigInt(mantLo);\n const bitLength = mantissa.toString(2).length; // 1..52\n const leadingBit = 1n << BigInt(bitLength - 1);\n mantissa52 = (mantissa - leadingBit) << BigInt(52 - (bitLength - 1));\n // value = (leadingBit + r)/2^52 * 2^-1022, with leadingBit = 2^(bitLength-1)\n // and r = mantissa - leadingBit — factor out leadingBit/2^52 to land on\n // the normalized `1.[mantissa52/2^52] * 2^exp` form: exp is the *true*\n // exponent of that leading bit, `bitLength - 1 - 52 - 1022`, not just\n // `bitLength - 1 - 1022` (that's `2^-1022`'s own exponent, before\n // dividing by the mantissa field's `2^52` scale — still needed here,\n // unlike the normal branch below, whose `biasedExp - 1023` already *is*\n // the final exponent by definition of the bias).\n exp = bitLength - 1075;\n } else {\n // Normal: value = 1.[52-bit mantissa] * 2^(biasedExp-1023)\n mantissa52 = (BigInt(mantHi) << 32n) | BigInt(mantLo);\n exp = biasedExp - 1023;\n }\n\n // Format mantissa as 13 hex digits (52 bits / 4), strip trailing zeros\n const hexMant = mantissa52.toString(16).padStart(13, '0');\n const trimmed = hexMant.replace(/0+$/, '');\n const mantPart = trimmed === '' ? '' : `.${trimmed}`;\n\n const expStr = exp >= 0 ? `+${exp}` : `${exp}`;\n const result = `0x1${mantPart}p${expStr}`;\n return neg ? `-${result}` : result;\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem } from './CborItem';\nimport { MT_SIMPLE, AI_2BYTE, AI_4BYTE, AI_8BYTE } from '../cbor/constants';\nimport { autoSelectFloatPrecision, type CborWriter } from '../cbor/encode';\nimport {\n floatValueToString,\n floatSuffix,\n resolveIndent,\n} from '../cdn/serialize-utils';\nimport { floatToHexFloat } from '../utils/hexfloat';\nimport { bytesToHex } from '../utils/hex';\n\nexport type FloatPrecision = 'half' | 'single' | 'double';\n\n/**\n * CBOR Major Type 7 — IEEE 754 floating-point number.\n *\n * `precision` records the encoding size from the original CBOR stream so\n * that lossless round-trips are preserved. When constructing from a JS\n * `number`, omit `precision` (`undefined`) and the encoder will choose\n * the smallest encoding that preserves the value exactly.\n */\nexport class CborFloat extends CborItem {\n readonly value: number;\n /**\n * Encoding size hint.\n * - `'half'` / `'single'` / `'double'`: use exactly this size (set by the\n * decoder to guarantee lossless round-trips).\n * - `undefined`: encoder auto-selects the smallest lossless size.\n */\n precision: FloatPrecision | undefined;\n /**\n * Original app-string source (e.g. `float'7e00'`), set by the parser when\n * this float is the result of a `float'...'` app-string. Used by toCDN()\n * to round-trip the literal when `appPrefix` is not false.\n */\n ednSource?: string;\n\n /**\n * Original CDN literal source text (e.g. `1.50`, `1.5_1`, `0x1.8p+0_1`),\n * set by the parser when this float came from a plain CDN float literal\n * (as opposed to a `float'...'` app-string, which uses `ednSource`\n * above). Used by `_toCDN()` to round-trip the literal's exact spelling,\n * including its encoding-indicator suffix, when `preserveNumberFormat`\n * is set.\n */\n literalSource?: string;\n\n /**\n * Original encoded payload bytes (big-endian, without the initial byte),\n * set by the decoder when the value is NaN so that NaN payloads survive a\n * decode → encode round-trip (a JS `number` cannot carry them).\n * Used by the encoder only when `value` is NaN and the length matches the\n * byte size of the encoded `precision`; ignored otherwise.\n */\n rawBits?: Uint8Array;\n\n constructor(\n value: number,\n options?: {\n precision?: FloatPrecision;\n rawBits?: Uint8Array;\n literalSource?: string;\n }\n ) {\n super();\n this.value = value;\n this.precision = options?.precision;\n this.rawBits = options?.rawBits;\n this.literalSource = options?.literalSource;\n }\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n const precision = this.precision ?? autoSelectFloatPrecision(this.value);\n const initial = MT_SIMPLE << 5;\n // rawBits carries a NaN payload only; for any other value it would let\n // the encoded bytes contradict `value`, so it is ignored.\n const rawBits = Number.isNaN(this.value) ? this.rawBits : undefined;\n\n if (precision === 'half') {\n writer.writeByte(initial | AI_2BYTE); // 0xf9\n if (rawBits?.length === 2) writer.writeBytes(rawBits);\n else writer.writeFloat16(this.value);\n } else if (precision === 'single') {\n writer.writeByte(initial | AI_4BYTE); // 0xfa\n if (rawBits?.length === 4) writer.writeBytes(rawBits);\n else writer.writeFloat32(this.value);\n } else {\n // double\n writer.writeByte(initial | AI_8BYTE); // 0xfb\n if (rawBits?.length === 8) writer.writeBytes(rawBits);\n else writer.writeFloat64(this.value);\n }\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n _path?: readonly unknown[]\n ): string {\n const mode = options?.encodingIndicators ?? 'auto';\n // In single-line output (no `indent`), a source spelling that spans\n // multiple lines (e.g. a `float<<...>>` app-sequence written across\n // lines) cannot be re-emitted, so it falls back to normal serialization.\n // An explicit `floatFormat` request (anything other than leaving it\n // unset, or asking for the app-extension form it's already in) opts out\n // of this round-trip too — the whole point of asking for `'decimal'`/\n // `'hex'` is to reformat every float, including one that started out as\n // a `float'...'` literal.\n if (\n options?.appPrefix !== false &&\n (options?.floatFormat === undefined ||\n options?.floatFormat === 'app-extension') &&\n this.ednSource !== undefined &&\n (resolveIndent(options) !== null || !/[\\r\\n]/.test(this.ednSource))\n ) {\n const ednSource = this.ednSource;\n if (mode === 'never') return ednSource.replace(/_[0-3i]$/, '');\n if (mode === 'always') {\n if (/_[0-3i]$/.test(ednSource)) return ednSource;\n const actual = this.precision ?? autoSelectFloatPrecision(this.value);\n const suffix =\n actual === 'half' ? '_1' : actual === 'single' ? '_2' : '_3';\n return ednSource + suffix;\n }\n return ednSource;\n }\n if (options?.preserveNumberFormat && this.literalSource !== undefined) {\n const literalSource = this.literalSource;\n // Encoding-indicator suffixes are embedded directly in the literal\n // text; _[0-7i] matches the full grammar (not just _[0-3i]) so that a\n // syntactically-present-but-semantically-invalid suffix (e.g. the \"_7\"\n // in a leniently-parsed \"1.5_7\") is still recognised and stripped.\n if (mode === 'never') return literalSource.replace(/_[0-7i]$/, '');\n if (mode === 'always') {\n if (/_[0-7i]$/.test(literalSource)) return literalSource;\n const autoSelected = autoSelectFloatPrecision(this.value);\n return (\n literalSource +\n floatSuffix(this.value, this.precision, autoSelected, 'always')\n );\n }\n return literalSource;\n }\n const autoSelected = autoSelectFloatPrecision(this.value);\n if (\n options?.floatFormat === 'app-extension' &&\n options?.appPrefix !== false\n ) {\n // Derived from the value's actual encoded bytes (via toCBOR(), which\n // honors a _toCBOR() override for e.g. a NaN-payload-preserving\n // subclass) rather than reimplementing bit-pattern logic here — the\n // first byte is the major-7 initial byte, not part of the payload.\n const bytes = this.toCBOR();\n const hex = bytesToHex(bytes.subarray(1));\n return (\n `float'${hex}'` +\n floatSuffix(this.value, this.precision, autoSelected, mode)\n );\n }\n const numStr =\n options?.floatFormat === 'hex'\n ? floatToHexFloat(this.value)\n : floatValueToString(this.value);\n return numStr + floatSuffix(this.value, this.precision, autoSelected, mode);\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n return this.value;\n }\n}\n","/**\n * Human-readable labels for tag numbers defined by RFC 9277 (On Stable\n * Storage for Items in CBOR), used to annotate `Tag N` hex-dump comments.\n */\n\n/** RFC 9277 Appendix B: CoAP Content-Format tags, `0x63740101`..`0x6374FFFF`. */\nconst COAP_CT_TAG_MIN = 0x63740101n;\nconst COAP_CT_TAG_MAX = 0x6374ffffn;\n\n/** RFC 9277 §2.1: protocol-specific (First Come First Served) 4-byte tags. */\nconst PROTOCOL_TAG_MIN = 0x01000000n;\nconst PROTOCOL_TAG_MAX = 0xffffffffn;\n\nconst NAMED_TAGS: ReadonlyMap<bigint, string> = new Map([\n [55799n, 'self-described CBOR'],\n [55800n, 'self-described CBOR Sequence'],\n [55801n, 'CBOR-labeled non-CBOR data'],\n]);\n\n/**\n * Inverse of RFC 9277 Appendix B's `TN(ct) = 0x63740101 + (ct / 255) *\n * 256 + ct % 255`: returns the CoAP Content-Format number `tag` stands for, or\n * `undefined` when `tag` isn't in that range. The mapping never produces a\n * zero byte, so a tag with a zero in either of its low two bytes isn't one.\n */\nexport function coapContentFormatOfTag(tag: bigint): number | undefined {\n if (tag < COAP_CT_TAG_MIN || tag > COAP_CT_TAG_MAX) return undefined;\n const hi = Number((tag >> 8n) & 0xffn);\n const lo = Number(tag & 0xffn);\n if (hi === 0 || lo === 0) return undefined;\n return (hi - 1) * 255 + (lo - 1);\n}\n\n/**\n * The four ASCII characters spelled by a protocol-specific tag number\n * (RFC 9277 §2.1 encourages a mnemonic of four ASCII codes, e.g.\n * `1330664270` = `0x4F50534E` = `\"OPSN\"`), or `undefined` when `tag` is\n * outside `0x01000000`..`0xFFFFFFFF` or any byte isn't printable ASCII\n * (`0x20`..`0x7E`).\n */\nexport function asciiMnemonicOfTag(tag: bigint): string | undefined {\n if (tag < PROTOCOL_TAG_MIN || tag > PROTOCOL_TAG_MAX) return undefined;\n let s = '';\n for (let shift = 24n; shift >= 0n; shift -= 8n) {\n const b = Number((tag >> shift) & 0xffn);\n if (b < 0x20 || b > 0x7e) return undefined;\n s += String.fromCharCode(b);\n }\n return s;\n}\n\n/**\n * RFC 9277 label for `tag`, for a hex-dump comment — `self-described CBOR`,\n * `CoAP Content-Format 112`, `\"OPSN\"` — or `undefined` when there's none.\n * The CoAP range is checked before the ASCII mnemonic: it is a specific\n * allocation, and its `\"ct\"` prefix would otherwise read as a mnemonic.\n */\nexport function rfc9277TagLabel(tag: bigint): string | undefined {\n const named = NAMED_TAGS.get(tag);\n if (named !== undefined) return named;\n const ct = coapContentFormatOfTag(tag);\n if (ct !== undefined) return `CoAP Content-Format ${ct}`;\n const ascii = asciiMnemonicOfTag(tag);\n if (ascii !== undefined) return JSON.stringify(ascii);\n return undefined;\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem, needsItemDispatch, ROOT_OCCURRENCE } from './CborItem';\nimport { Tag } from '../tag';\nimport type { AnnotatedLine, Occurrence } from './CborItem';\nimport { MT_TAG } from '../cbor/constants';\nimport {\n writeHead,\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n isMultiWordRenderedLiteral,\n pushAll,\n renderSingleChildWithComments,\n} from '../cdn/serialize-utils';\nimport { bytesToSpacedHexUpper } from '../utils/hex';\nimport { rfc9277TagLabel } from '../cbor/tagLabels';\n\n/** CBOR Major Type 6 — tagged data item. */\nexport class CborTag extends CborItem {\n readonly tag: bigint;\n readonly content: CborItem;\n encodingWidth: EncodingWidth | undefined;\n /**\n * Original CDN digit spelling of the tag number (base + digits, without\n * the encoding-indicator suffix), set by the parser when this tag came\n * from CDN text. Used by `_toCDN()` to round-trip the tag number's base\n * (`0x3e7`, decimal, …) when `preserveNumberFormat` is set.\n */\n ednSource?: string;\n /**\n * Set by `cddl`-validated decoding/parsing/conversion when the schema\n * itself implies this tag at its position (see `cddl/implicitTags.ts`),\n * so `toJS()` can leave it off the JS value — see\n * `ToJSOptions.implicitTags`.\n * @internal\n */\n _implicit = false;\n\n constructor(\n tag: number | bigint,\n content: CborItem,\n options?: { encodingWidth?: EncodingWidth; ednSource?: string }\n ) {\n super();\n this.tag = BigInt(tag);\n if (this.tag < 0n)\n throw new RangeError('CborTag tag number must be non-negative');\n this.content = content;\n this.encodingWidth = options?.encodingWidth;\n this.ednSource = options?.ednSource;\n }\n\n override get _containsCdnContainer(): boolean {\n return this.content._containsCdnContainer;\n }\n\n /**\n * Checked by tokenizing `this._toCDN()`'s own actual output — not by\n * delegating to `this.content._isMultiWordText()` (a semantic prediction\n * from the AST) — because a subclass may override `_toCDN()` to render\n * something that doesn't match generic `tagNum(content)` notation at all\n * (`CborTaggedIpExt` renders `IP<<'192.0.2.42'>>`, `CborTaggedEpochDtExt`\n * renders `DT'...'`/`DT<<...>>`, ...); a check based on `this.content`\n * would be looking at the wrong thing entirely for those. Tokenizing the\n * real output instead is exact regardless of which class produced it —\n * see `isMultiWordRenderedLiteral`, which also handles the plain,\n * generic-tag case (peeling `tagNum[_EI](...)` to see what's inside, so\n * `100(dt'...')` and `100(\"two words\")` still work the same as before).\n *\n * Deliberately *not* cached: an earlier version cached this render on\n * the instance keyed by `options` reference alone, which was wrong two\n * ways — (1) `preserveConcatenation`'s continuation-line indentation\n * *does* depend on depth even for leaf content, so a render cached at\n * depth 0 here and reused by `_toCDN`'s real render at a different depth\n * produced under-indented continuation lines; (2) the cache persisted\n * on the node forever and was keyed only by object identity, so\n * mutating the same `options` object between two `toCDN()` calls\n * silently returned the first call's stale result. `this` is re-rendered\n * here and again by the real `_toCDN` call from whatever holds this\n * entry — an accepted, narrow cost (only tag-wrapped entries reach this\n * at all).\n */\n override _isMultiWordText(\n options: ToCDNOptions | undefined,\n strict = true,\n path?: readonly unknown[]\n ): boolean {\n return isMultiWordRenderedLiteral(this._toCDN(options, 0, path), strict);\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n writeHeadTo(writer, MT_TAG, this.tag, this.encodingWidth);\n this.content._encode(writer, options);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.tag)\n );\n const tagStr =\n options?.preserveNumberFormat && this.ednSource !== undefined\n ? this.ednSource\n : this.tag.toString();\n // A tag wrapper adds no path segment of its own — the content shares\n // this tag's own path (see CdnItemContext.path) and gets its own\n // itemOptions resolved against it (`_resolveCdnOptions` is a no-op\n // when itemOptions isn't in play, so this is always safe to call).\n const contentOptions = this.content._resolveCdnOptions(\n options,\n path ?? [],\n { parent: this }\n );\n const wrapped = renderSingleChildWithComments(\n this.content,\n this,\n options,\n contentOptions,\n depth,\n (childDepth) => this.content._toCDN(contentOptions, childDepth, path),\n '(',\n ')'\n );\n return `${tagStr}${suffix}${wrapped}`;\n }\n\n /**\n * The hex-dump comment for this tag's head: `Tag N`, followed by an\n * RFC 9277 label when there is one — `Tag 55799 (self-described CBOR)`,\n * `Tag 1668546929 (CoAP Content-Format 112)`, `Tag 1330664270 (\"OPSN\")`\n * for a protocol-specific tag spelling four printable ASCII characters.\n */\n hexDumpComment(): string {\n const label = rfc9277TagLabel(this.tag);\n return label ? `Tag ${this.tag} (${label})` : `Tag ${this.tag}`;\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: bytesToSpacedHexUpper(\n writeHead(MT_TAG, this.tag, this.encodingWidth)\n ),\n comment: this.hexDumpComment(),\n },\n ];\n pushAll(\n lines,\n this.content._toHexDump(depth + 1, { ...options, appPrefix: false })\n );\n return lines;\n }\n\n _toJS(\n options?: ToJSOptions,\n path?: readonly unknown[],\n occurrence?: Occurrence\n ): unknown {\n // A tag wrapper adds no path segment — or occurrence — of its own: the\n // content shares this tag's own path (see ItemContext.path) and its own\n // cache-matching identity (see Occurrence) unchanged.\n const value = needsItemDispatch(options)\n ? this.content._toJSChild(\n options,\n path ?? [],\n occurrence ?? ROOT_OCCURRENCE,\n { parent: this }\n )\n : this.content._toJS(options);\n return this._tagJS(value, options);\n }\n\n /**\n * Attach this tag to the converted content `value` — unless `stripTags`,\n * or the tag is schema-implied (`_implicit`) and `implicitTags` isn't\n * `false`.\n * @internal\n */\n _tagJS(value: unknown, options?: ToJSOptions): unknown {\n if (\n options?.stripTags ||\n (this._implicit && options?.implicitTags !== false)\n )\n return value;\n return Tag.set(value, this.tag);\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem } from './CborItem';\nimport { MT_BYTES } from '../cbor/constants';\nimport {\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n serializeBytes,\n isMultiWordByteString,\n resolveEiSuffix,\n resolveIndent,\n joinConcatParts,\n joinAppSeqParts,\n canonicalEncodingWidth,\n stripByteLiteralComments,\n danglingCommentsByGap,\n shouldEmitComments,\n resolveCommentStyle,\n type ByteCommentSyntax,\n} from '../cdn/serialize-utils';\n\n/**\n * A preserved literal source, with any embedded comment stripped unless\n * comments are requested (`preserveComments`/`comments`) — the preserved\n * spelling should still drop comments by default, the same as an\n * unpreserved literal re-derived from its decoded value would.\n * `commentSyntax` is `undefined` for a literal\n * family with no comment syntax at all (bare sqstr `'...'`) or one whose\n * comment syntax isn't known (an app-string extension other than the\n * specific built-in `b32`/`h32` objects — see `ednCommentSyntax`); in\n * either case the source is returned verbatim, since there's nothing safe\n * to strip.\n */\nfunction preservedSource(\n source: string | undefined,\n options: ToCDNOptions | undefined,\n commentSyntax: ByteCommentSyntax | undefined\n): string | undefined {\n if (source === undefined) return undefined;\n if (shouldEmitComments(options) || commentSyntax === undefined) return source;\n return stripByteLiteralComments(source, commentSyntax);\n}\n\n/** One part of a byte string parsed from a CDN `+` concatenation chain. */\nexport interface CborByteStringPart {\n bytes: Uint8Array;\n /** Original literal source text, when the part came from a byte string token. */\n source?: string;\n /** Which comment syntax `source` recognizes, if any — see `ednCommentSyntax`. */\n commentSyntax?: ByteCommentSyntax;\n /**\n * Source span of this part's own literal token, when known — used to place\n * a comment sitting between two `+`-joined parts (attached to the whole\n * `CborByteString` as a `dangling` comment, since there is no per-part AST\n * node for it to attach to) at the right gap in `_toCDN`'s\n * `preserveConcatenation` branch. `undefined` for a part merged from a\n * single elided literal's own internal segments, which cannot have a\n * comment between them.\n */\n start?: number;\n end?: number;\n}\n\n/** CBOR Major Type 2 — definite-length byte string. */\nexport class CborByteString extends CborItem {\n readonly indefiniteLength = false as const;\n readonly value: Uint8Array;\n /** Preferred EDN encoding for this byte string. */\n readonly ednEncoding: 'hex' | 'base64' | 'base64url' | 'base32' | 'base32hex';\n encodingWidth: EncodingWidth | undefined;\n readonly ednSource: string | undefined;\n /**\n * Which comment syntax `ednSource` recognizes, if any — set once at parse\n * time by whoever actually knows the literal's real origin (see\n * `ByteCommentSyntax`), never re-derived later from its prefix string:\n * a user extension can register under any prefix, including one a\n * built-in (`b32`/`h32`) also uses, so the prefix string alone can't say\n * which comment rules (if any) actually apply. `undefined` when\n * `ednSource` has no comment syntax, or its extension's isn't known.\n */\n readonly ednCommentSyntax: ByteCommentSyntax | undefined;\n /** Part boundaries of the original `+` concatenation chain, if any. */\n readonly ednParts: readonly CborByteStringPart[] | undefined;\n\n constructor(\n value: Uint8Array,\n options?: {\n ednEncoding?: 'hex' | 'base64' | 'base64url' | 'base32' | 'base32hex';\n encodingWidth?: EncodingWidth;\n ednSource?: string;\n ednCommentSyntax?: ByteCommentSyntax;\n ednParts?: readonly CborByteStringPart[];\n }\n ) {\n super();\n this.value = value;\n this.ednEncoding = options?.ednEncoding ?? 'hex';\n this.encodingWidth = options?.encodingWidth;\n this.ednSource = options?.ednSource;\n this.ednCommentSyntax = options?.ednCommentSyntax;\n this.ednParts = options?.ednParts;\n }\n\n /**\n * Only the \"bare sqstr text with 2+ words\" case — the \"is this a\n * prefixed literal\" question is deliberately *not* predicted here from\n * raw bytes at all (a subclass like `CborIpExt` might override `_toCDN()`\n * to render something else entirely, e.g. a preserved\n * `ip<<'192.0.2.42'>>` app-sequence spelling, that raw-byte prediction\n * knows nothing about — see `isMultiWordByteString`'s doc). That\n * question is instead answered from the *actual rendering*: for a bare\n * entry, `serializeContainer`'s own `isPrefixedLiteralText(s)` check\n * already covers it (this node's render *is* `s`, unobscured); for one\n * wrapped in a `CborTag`, `CborTag._isMultiWordText`'s\n * `isMultiWordRenderedLiteral` check covers it instead. `strict` isn't\n * needed here at all now — it's accepted purely for interface\n * consistency with the base class.\n */\n override _isMultiWordText(\n options: ToCDNOptions | undefined,\n _strict = true,\n _path?: readonly unknown[]\n ): boolean {\n return isMultiWordByteString(this.value, options?.sqstr);\n }\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n writeHeadTo(writer, MT_BYTES, this.value.length, this.encodingWidth);\n writer.writeBytes(this.value);\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n _path?: readonly unknown[]\n ): string {\n const indentStr = resolveIndent(options);\n if (\n options?.preserveConcatenation &&\n // Preserved concatenation is a layout feature; single-line mode joins\n // the parts into one literal instead.\n indentStr !== null &&\n this.ednParts !== undefined &&\n this.ednParts.length > 1\n ) {\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(this.value.length))\n );\n let encoding = options?.bstrEncoding ?? this.ednEncoding;\n if (options?.appPrefix === false && encoding !== 'hex') encoding = 'hex';\n const literals = this.ednParts.map((part) => {\n const source = options?.preserveByteString\n ? preservedSource(part.source, options, part.commentSyntax)\n : undefined;\n return source !== undefined\n ? source\n : serializeBytes(part.bytes, encoding, options?.sqstr);\n });\n const midComments = shouldEmitComments(options)\n ? danglingCommentsByGap(\n this.comments?.dangling,\n this.ednParts,\n resolveCommentStyle(options)\n )\n : undefined;\n if (options?.modernConcat && options?.appPrefix !== false) {\n return joinAppSeqParts(\n 'b1',\n literals,\n suffix,\n indentStr,\n _depth,\n midComments\n );\n }\n literals[literals.length - 1] += suffix;\n return joinConcatParts(literals, indentStr, _depth, midComments);\n }\n const preservedWhole = options?.preserveByteString\n ? preservedSource(this.ednSource, options, this.ednCommentSyntax)\n : undefined;\n if (\n preservedWhole !== undefined &&\n // In single-line mode a spelling that spans multiple lines (e.g. a\n // byte string with an interior line comment that survived stripping,\n // or a genuine interior line break) cannot be re-emitted.\n (indentStr !== null || !/[\\r\\n]/.test(preservedWhole))\n ) {\n // App-string byte strings (e.g. b32'...'_1) embed the EI inside ednSource.\n // Regular byte strings (h'...', b64'...') store EI separately in encodingWidth.\n if (/_[0-3i]$/.test(preservedWhole)) {\n const mode = options?.encodingIndicators ?? 'auto';\n if (mode === 'never') return preservedWhole.replace(/_[0-3i]$/, '');\n return preservedWhole; // 'auto' or 'always': EI already present\n }\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(this.value.length))\n );\n return preservedWhole + suffix;\n }\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(this.value.length))\n );\n let encoding = options?.bstrEncoding ?? this.ednEncoding;\n if (options?.appPrefix === false && encoding !== 'hex') encoding = 'hex';\n return serializeBytes(this.value, encoding, options?.sqstr) + suffix;\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n return this.value;\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem, needsCdnItemDispatch } from './CborItem';\nimport type { AnnotatedLine } from './CborItem';\nimport { CborByteString } from './CborByteString';\nimport { MT_BYTES, AI_INDEFINITE, BREAK_CODE } from '../cbor/constants';\nimport type { CborWriter } from '../cbor/encode';\nimport {\n formatTrailingComments,\n hasPreservedComments,\n pushAll,\n serializeContainer,\n} from '../cdn/serialize-utils';\nimport { byteToHexUpper } from '../utils/hex';\n\n/** CBOR Major Type 2 — indefinite-length byte string (chunked). */\nexport class CborIndefiniteByteString extends CborItem {\n readonly indefiniteLength = true as const;\n readonly chunks: CborByteString[];\n\n constructor(chunks: CborByteString[]) {\n super();\n this.chunks = chunks;\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n writer.writeByte((MT_BYTES << 5) | AI_INDEFINITE);\n for (const chunk of this.chunks) chunk._encode(writer, options);\n writer.writeByte(BREAK_CODE);\n }\n\n /**\n * True when any chunk's own decoded content, if it renders as bare sqstr\n * text, has two or more words. Reachable when this node is a *direct*\n * entry of another container (`[(_ \"two words\")]`) — though even then,\n * its own `_toCDN()` already self-disqualifies internally in that case\n * (a multi-word chunk forces a multi-line self-render), which the\n * ordinary \"entry's own rendering has a line break\" check would catch\n * regardless of what this method answers, so this mostly exists for\n * robustness/consistency with `CborTextString`/`CborByteString` rather\n * than because some case is otherwise unreachable.\n *\n * `CborAppSeqResult`, which wraps this node for results like\n * `ilbs<<...>>`, does *not* delegate to this method — it tokenizes its\n * own rendered output directly instead (`isMultiWordRenderedLiteral`),\n * which is exactly why `ilbs<<h'00'>>` stays an ordinary leaf (checked\n * under the loose rule, matching `<<...>>`) while `[h'00']`/`(_ h'00')`\n * still always disqualify — this method's own `_strict` (always `true`,\n * matching how a chunk renders when this container *is* regenerated\n * directly) plays no part in that distinction anymore, and a byte string\n * chunk's own `_isMultiWordText` doesn't consult `strict` at all\n * regardless (see `CborByteString`'s doc — its \"prefixed literal\" case\n * was removed there too).\n */\n override _isMultiWordText(\n options: ToCDNOptions | undefined,\n _strict = true\n ): boolean {\n return this.chunks.some((c) => c._isMultiWordText(options));\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if ((options?.encodingIndicators ?? 'auto') === 'never') {\n const totalLen = this.chunks.reduce((sum, c) => sum + c.value.length, 0);\n const merged = new Uint8Array(totalLen);\n let offset = 0;\n for (const chunk of this.chunks) {\n merged.set(chunk.value, offset);\n offset += chunk.value.length;\n }\n return new CborByteString(merged)._toCDN(options, depth);\n }\n const basePath = path ?? [];\n const dispatch = needsCdnItemDispatch(options);\n const childOptions = (i: number): ToCDNOptions | undefined =>\n dispatch\n ? this.chunks[i]._resolveCdnOptions(options, [...basePath, i], {\n parent: this,\n })\n : options;\n // `ilbs<<...>>` (draft-27 §3.6) replaces the legacy `(_ ...)` marker\n // notation; falls back to it when `appPrefix` disables app-string\n // notation entirely.\n const useIlbs =\n !!options?.modernStreamSyntax && options?.appPrefix !== false;\n if (!useIlbs && this.chunks.length === 0) return \"''_\";\n return serializeContainer({\n node: this,\n options,\n depth,\n openChar: useIlbs ? 'ilbs<<' : '(',\n closeChar: useIlbs ? '>>' : ')',\n count: this.chunks.length,\n indefiniteLength: true,\n indefiniteMarker: !useIlbs,\n encodingWidth: undefined,\n hasEntryComments: (i) => hasPreservedComments(this.chunks[i]),\n renderEntry: (i) =>\n this.chunks[i]._toCDN(\n childOptions(i),\n depth + 1,\n dispatch ? [...basePath, i] : undefined\n ),\n // Unlike CborEmbeddedCBOR (`<<...>>`), the legacy `(_ ...)` group\n // follows the same strict rule as CborArray/CborMap, gated behind\n // inlineLeafContainers: entryIsLeaf is trivially always true (chunks\n // can never be containers), but its presence is what signals \"strict\"\n // to serializeContainer's probe — so a chunk that renders as a\n // prefixed literal (`h'...'`) always disqualifies inlining here, same\n // as it would in `[h'...']`. `ilbs<<...>>` is itself an\n // app-sequence form, so it always collapses like\n // CborEmbeddedCBOR instead (loose rule, entryIsLeaf omitted).\n entryIsLeaf: useIlbs ? undefined : () => true,\n alwaysInlineLeaf: useIlbs,\n entryIsMultiWordText: (i) =>\n this.chunks[i]._isMultiWordText(\n childOptions(i),\n !useIlbs,\n dispatch ? [...basePath, i] : undefined\n ),\n entryLeadingNode: (i) => this.chunks[i],\n entryTrailing: (i, style) =>\n formatTrailingComments(this.chunks[i], style),\n entryOptions: dispatch ? childOptions : undefined,\n });\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: byteToHexUpper((MT_BYTES << 5) | AI_INDEFINITE),\n comment: 'Start indefinite-length byte string',\n },\n ];\n for (const chunk of this.chunks)\n pushAll(lines, chunk._toHexDump(depth + 1, options));\n lines.push({ depth, hex: byteToHexUpper(BREAK_CODE), comment: '\"break\"' });\n return lines;\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n const totalLen = this.chunks.reduce((sum, c) => sum + c.value.length, 0);\n const result = new Uint8Array(totalLen);\n let offset = 0;\n for (const chunk of this.chunks) {\n result.set(chunk.value, offset);\n offset += chunk.value.length;\n }\n return result;\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem, needsCdnItemDispatch } from './CborItem';\nimport type { AnnotatedLine } from './CborItem';\nimport { CborTextString } from './CborTextString';\nimport { MT_TEXT, AI_INDEFINITE, BREAK_CODE } from '../cbor/constants';\nimport type { CborWriter } from '../cbor/encode';\nimport {\n formatTrailingComments,\n hasPreservedComments,\n pushAll,\n serializeContainer,\n} from '../cdn/serialize-utils';\nimport { byteToHexUpper } from '../utils/hex';\n\n/** CBOR Major Type 3 — indefinite-length UTF-8 text string (chunked). */\nexport class CborIndefiniteTextString extends CborItem {\n readonly indefiniteLength = true as const;\n readonly chunks: CborTextString[];\n\n constructor(chunks: CborTextString[]) {\n super();\n this.chunks = chunks;\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n writer.writeByte((MT_TEXT << 5) | AI_INDEFINITE);\n for (const chunk of this.chunks) chunk._encode(writer, options);\n writer.writeByte(BREAK_CODE);\n }\n\n /**\n * True when any chunk is multi-word. Reachable when this node is a\n * *direct* entry of another container (`[(_ \"two words\")]`) — though even\n * then, its own `_toCDN()` already self-disqualifies internally in that\n * case, producing a multi-line self-render that the ordinary \"entry's own\n * rendering has a line break\" check would catch regardless of what this\n * method answers, so this mostly exists for robustness/consistency with\n * `CborTextString`/`CborByteString` rather than because some case is\n * otherwise unreachable. (`CborAppSeqResult`, which wraps this node for\n * results like `ilts<<...>>`, does *not* delegate to this method — it\n * tokenizes its own rendered output directly instead; see its doc for\n * why that turned out to be necessary.) `_strict` is intentionally\n * unused: a chunk is always CborTextString, whose own word count doesn't\n * depend on it.\n */\n override _isMultiWordText(\n options: ToCDNOptions | undefined,\n _strict = true\n ): boolean {\n return this.chunks.some((c) => c._isMultiWordText(options));\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if ((options?.encodingIndicators ?? 'auto') === 'never') {\n const merged = this.chunks.map((c) => c.value).join('');\n return new CborTextString(merged)._toCDN(options, depth);\n }\n const basePath = path ?? [];\n const dispatch = needsCdnItemDispatch(options);\n const childOptions = (i: number): ToCDNOptions | undefined =>\n dispatch\n ? this.chunks[i]._resolveCdnOptions(options, [...basePath, i], {\n parent: this,\n })\n : options;\n // `ilts<<...>>` (draft-27 §3.6) replaces the legacy `(_ ...)` marker\n // notation; falls back to it when `appPrefix` disables app-string\n // notation entirely.\n const useIlts =\n !!options?.modernStreamSyntax && options?.appPrefix !== false;\n if (!useIlts && this.chunks.length === 0) return '\"\"_';\n return serializeContainer({\n node: this,\n options,\n depth,\n openChar: useIlts ? 'ilts<<' : '(',\n closeChar: useIlts ? '>>' : ')',\n count: this.chunks.length,\n indefiniteLength: true,\n indefiniteMarker: !useIlts,\n encodingWidth: undefined,\n hasEntryComments: (i) => hasPreservedComments(this.chunks[i]),\n renderEntry: (i) =>\n this.chunks[i]._toCDN(\n childOptions(i),\n depth + 1,\n dispatch ? [...basePath, i] : undefined\n ),\n // Unlike CborEmbeddedCBOR (`<<...>>`), the legacy `(_ ...)` group\n // follows the same strict rule as CborArray/CborMap, gated behind\n // inlineLeafContainers: entryIsLeaf is trivially always true (chunks\n // can never be containers), but its presence is what signals \"strict\"\n // to serializeContainer's probe. `ilts<<...>>` is itself an\n // app-sequence form, so it always collapses like\n // CborEmbeddedCBOR instead (loose rule, entryIsLeaf omitted).\n entryIsLeaf: useIlts ? undefined : () => true,\n alwaysInlineLeaf: useIlts,\n entryIsMultiWordText: (i) =>\n this.chunks[i]._isMultiWordText(\n childOptions(i),\n !useIlts,\n dispatch ? [...basePath, i] : undefined\n ),\n entryLeadingNode: (i) => this.chunks[i],\n entryTrailing: (i, style) =>\n formatTrailingComments(this.chunks[i], style),\n entryOptions: dispatch ? childOptions : undefined,\n });\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: byteToHexUpper((MT_TEXT << 5) | AI_INDEFINITE),\n comment: 'Start indefinite-length text string',\n },\n ];\n for (const chunk of this.chunks)\n pushAll(lines, chunk._toHexDump(depth + 1, options));\n lines.push({ depth, hex: byteToHexUpper(BREAK_CODE), comment: '\"break\"' });\n return lines;\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n return this.chunks.map((c) => c.value).join('');\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CBOR_OMIT } from '../types';\nimport {\n CborItem,\n needsItemDispatch,\n needsCdnItemDispatch,\n withoutReviver,\n ROOT_OCCURRENCE,\n RAW_PASS_MARKER,\n} from './CborItem';\nimport type { AnnotatedLine } from './CborItem';\nimport { MT_ARRAY, AI_INDEFINITE, BREAK_CODE } from '../cbor/constants';\nimport {\n writeHead,\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n formatTrailingComments,\n hasPreservedComments,\n pushAll,\n serializeContainer,\n} from '../cdn/serialize-utils';\nimport { byteToHexUpper, bytesToSpacedHexUpper } from '../utils/hex';\n\n/** CBOR Major Type 4 — array (definite- or indefinite-length). */\nexport class CborArray extends CborItem {\n readonly items: CborItem[];\n readonly indefiniteLength: boolean;\n encodingWidth: EncodingWidth | undefined;\n\n constructor(\n items: CborItem[],\n options?: { indefiniteLength?: boolean; encodingWidth?: EncodingWidth }\n ) {\n super();\n this.items = items;\n this.indefiniteLength = options?.indefiniteLength ?? false;\n this.encodingWidth = options?.encodingWidth;\n }\n\n override get _containsCdnContainer(): boolean {\n return true;\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n if (this.indefiniteLength) {\n writer.writeByte((MT_ARRAY << 5) | AI_INDEFINITE);\n for (const item of this.items) item._encode(writer, options);\n writer.writeByte(BREAK_CODE);\n return;\n }\n writeHeadTo(writer, MT_ARRAY, this.items.length, this.encodingWidth);\n for (const item of this.items) item._encode(writer, options);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n const basePath = path ?? [];\n const dispatch = needsCdnItemDispatch(options);\n // Resolves itemOptions for element `i` fresh on each call — including\n // when both `renderEntry` and `entryIsMultiWordText` ask for the same\n // `i` during one parent render — rather than caching, matching this\n // whole mechanism's design (see the \"toCDN() per-item dispatch\" note\n // in CborItem.ts).\n const childOptions = (i: number): ToCDNOptions | undefined =>\n dispatch\n ? this.items[i]._resolveCdnOptions(options, [...basePath, i], {\n parent: this,\n })\n : options;\n return serializeContainer({\n node: this,\n options,\n depth,\n openChar: '[',\n closeChar: ']',\n count: this.items.length,\n indefiniteLength: this.indefiniteLength,\n encodingWidth: this.encodingWidth,\n hasEntryComments: (i) => hasPreservedComments(this.items[i]),\n renderEntry: (i) =>\n this.items[i]._toCDN(\n childOptions(i),\n depth + 1,\n dispatch ? [...basePath, i] : undefined\n ),\n entryIsLeaf: (i) => !this.items[i]._containsCdnContainer,\n entryIsMultiWordText: (i) =>\n this.items[i]._isMultiWordText(\n childOptions(i),\n true,\n dispatch ? [...basePath, i] : undefined\n ),\n entryLeadingNode: (i) => this.items[i],\n entryTrailing: (i, style) => formatTrailingComments(this.items[i], style),\n entryOptions: dispatch ? childOptions : undefined,\n });\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n if (this.indefiniteLength) {\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: byteToHexUpper((MT_ARRAY << 5) | AI_INDEFINITE),\n comment: 'Start indefinite-length array',\n },\n ];\n for (const item of this.items)\n pushAll(lines, item._toHexDump(depth + 1, options));\n lines.push({\n depth,\n hex: byteToHexUpper(BREAK_CODE),\n comment: '\"break\"',\n });\n return lines;\n }\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: bytesToSpacedHexUpper(\n writeHead(MT_ARRAY, BigInt(this.items.length), this.encodingWidth)\n ),\n comment: `Array of length ${this.items.length}`,\n },\n ];\n for (const item of this.items)\n pushAll(lines, item._toHexDump(depth + 1, options));\n return lines;\n }\n\n _toJS(\n options?: ToJSOptions,\n path?: readonly unknown[],\n occurrence?: readonly unknown[]\n ): unknown {\n const reviver = options?.reviver;\n const dispatch = needsItemDispatch(options);\n const occ = occurrence ?? ROOT_OCCURRENCE;\n // `rawPass` marks a call as belonging to the raw pre-population pass\n // below — its occurrence gets `RAW_PASS_MARKER` inserted (see\n // `Occurrence`) so it can never be reused by the real, revived pass,\n // even indirectly through some other, more deeply nested raw pass.\n const convert = (\n item: CborItem,\n i: number,\n opts: ToJSOptions | undefined,\n rawPass: boolean\n ) =>\n dispatch\n ? item._toJSChild(\n opts,\n [...(path ?? []), i],\n // Cache-matching identity: chained from this array's own\n // occurrence plus the element's own index, never from a\n // converted JS value — see `Occurrence`.\n rawPass ? [...occ, RAW_PASS_MARKER, i] : [...occ, i],\n { parent: this }\n )\n : item._toJS(opts);\n if (!reviver)\n return this.items.map((item, i) => convert(item, i, options, false));\n // First pass: pre-populate holder with unrevived values so later siblings\n // are still raw when earlier callbacks run (matches JSON.parse sibling\n // timing). `itemOptions`/`extensions` still apply here — see\n // `withoutReviver` — since this holder is directly observable through\n // `this[j]` inside an earlier sibling's own reviver call, not just\n // internal scaffolding; the `RAW_PASS_MARKER` in each element's\n // occurrence above keeps this pass's resolutions from being reused by\n // the real, revived pass below.\n const optNoReviver = withoutReviver(options);\n const holder: unknown[] = this.items.map((item, i) =>\n convert(item, i, optNoReviver, true)\n );\n // Second pass: revive each element depth-first, splice out undefined entries\n // immediately so `this` reflects the compacted in-progress array.\n // Original indices are used as reviver keys; undefined → omit (compact,\n // differs from JSON.parse which leaves holes).\n let deleted = 0;\n for (let i = 0; i < this.items.length; i++) {\n const hIdx = i - deleted;\n const val = convert(this.items[i], i, options, false);\n const rv = reviver.call(holder, String(i), val);\n const omit =\n rv === CBOR_OMIT || (options?.undefinedOmits && rv === undefined);\n if (omit) {\n holder.splice(hIdx, 1);\n deleted++;\n } else {\n holder[hIdx] = rv;\n }\n }\n return holder;\n }\n}\n","import type {\n CborComment,\n ToCDNOptions,\n ToJSOptions,\n ToCBOROptions,\n} from '../types';\nimport { CBOR_OMIT } from '../types';\nimport { MapEntries } from '../mapEntries';\nimport {\n CborItem,\n needsItemDispatch,\n needsCdnItemDispatch,\n withoutReviver,\n ROOT_OCCURRENCE,\n RAW_PASS_MARKER,\n} from './CborItem';\nimport type { AnnotatedLine } from './CborItem';\nimport { CborTextString } from './CborTextString';\nimport { MT_MAP, AI_INDEFINITE, BREAK_CODE } from '../cbor/constants';\nimport {\n writeHead,\n writeHeadTo,\n type CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n convertCommentText,\n hasPreservedComments,\n isPrefixedLiteralText,\n pushAll,\n serializeContainer,\n} from '../cdn/serialize-utils';\nimport { byteToHexUpper, bytesToSpacedHexUpper } from '../utils/hex';\n\n/** CBOR Major Type 5 — map (definite- or indefinite-length). */\nexport class CborMap extends CborItem {\n readonly entries: [CborItem, CborItem][];\n readonly indefiniteLength: boolean;\n encodingWidth: EncodingWidth | undefined;\n\n constructor(\n entries: [CborItem, CborItem][],\n options?: { indefiniteLength?: boolean; encodingWidth?: EncodingWidth }\n ) {\n super();\n this.entries = entries;\n this.indefiniteLength = options?.indefiniteLength ?? false;\n this.encodingWidth = options?.encodingWidth;\n }\n\n override get _containsCdnContainer(): boolean {\n return true;\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n if (this.indefiniteLength) {\n writer.writeByte((MT_MAP << 5) | AI_INDEFINITE);\n for (const [k, v] of this.entries) {\n k._encode(writer, options);\n v._encode(writer, options);\n }\n writer.writeByte(BREAK_CODE);\n return;\n }\n writeHeadTo(writer, MT_MAP, this.entries.length, this.encodingWidth);\n for (const [k, v] of this.entries) {\n k._encode(writer, options);\n v._encode(writer, options);\n }\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n const basePath = path ?? [];\n const dispatch = needsCdnItemDispatch(options);\n // `entryIsMultiWordText` needs each side's own rendering (not just the\n // combined \"key: value\" string serializeContainer sees — see its\n // comment below), and `renderEntry` needs the exact same strings right\n // after — cached per index so a custom key/value's `_toCDN()` is never\n // called twice for the same render, matching serializeContainer's own\n // \"never serialize more than once per parent render\" invariant. The\n // resolved per-item options (and, for a non-text key, the `toCDN()`\n // rendering used as its path label — see `ItemContext.path`'s CDN\n // counterpart) are cached the same way, for the same reason: an\n // `itemOptions` callback should not be asked twice for one entry\n // within a single parent render just because both `renderEntry` and\n // `entryIsMultiWordText` need its result.\n const optsCache: (\n [unknown, ToCDNOptions | undefined, ToCDNOptions | undefined] | undefined\n )[] = [];\n const resolveKV = (\n i: number\n ): [unknown, ToCDNOptions | undefined, ToCDNOptions | undefined] => {\n let r = optsCache[i];\n if (!r) {\n const [k, v] = this.entries[i];\n if (!dispatch) {\n r = [undefined, options, options];\n } else {\n // Independent of `options`/depth — a stable label identifying\n // this entry's key for path purposes, same derivation `toJS()`'s\n // own object-mode key naming uses, not the entry's real render.\n const key = k instanceof CborTextString ? k.value : k.toCDN();\n r = [\n key,\n k._resolveCdnOptions(options, basePath, {\n parent: this,\n isMapKey: true,\n keyNode: k,\n }),\n v._resolveCdnOptions(options, [...basePath, key], {\n parent: this,\n keyNode: k,\n }),\n ];\n }\n optsCache[i] = r;\n }\n return r;\n };\n const kvCache: ([string, string] | undefined)[] = [];\n const renderKV = (i: number): [string, string] => {\n let kv = kvCache[i];\n if (!kv) {\n const [k, v] = this.entries[i];\n const [key, kOpts, vOpts] = resolveKV(i);\n kv = [\n k._toCDN(kOpts, depth + 1, dispatch ? basePath : undefined),\n v._toCDN(vOpts, depth + 1, dispatch ? [...basePath, key] : undefined),\n ];\n kvCache[i] = kv;\n }\n return kv;\n };\n return serializeContainer({\n node: this,\n options,\n depth,\n openChar: '{',\n closeChar: '}',\n count: this.entries.length,\n indefiniteLength: this.indefiniteLength,\n encodingWidth: this.encodingWidth,\n hasEntryComments: (i) => {\n const [key, value] = this.entries[i];\n return hasPreservedComments(key) || hasPreservedComments(value);\n },\n renderEntry: (i, colSep) => {\n const [kStr, vStr] = renderKV(i);\n return `${kStr}${colSep}${vStr}`;\n },\n entryIsLeaf: (i) => {\n const [k, v] = this.entries[i];\n return !k._containsCdnContainer && !v._containsCdnContainer;\n },\n entryIsMultiWordText: (i) => {\n const [k, v] = this.entries[i];\n const [key, kOpts, vOpts] = resolveKV(i);\n const kPath = dispatch ? basePath : undefined;\n const vPath = dispatch ? [...basePath, key] : undefined;\n if (\n k._isMultiWordText(kOpts, true, kPath) ||\n v._isMultiWordText(vOpts, true, vPath)\n )\n return true;\n // serializeContainer's own isPrefixedLiteralText check only sees a\n // map entry's combined \"key: value\" rendering, which can't tell a\n // prefixed literal in the value (or a non-leading key) apart from\n // one embedded inside the other's own quoted content — so check\n // each side's own rendering here instead, same as the multi-word\n // check above already does for text/byte strings.\n const [kStr, vStr] = renderKV(i);\n return isPrefixedLiteralText(kStr) || isPrefixedLiteralText(vStr);\n },\n // Leading comments come from the key; the value's leading comments\n // render inline after the entry (see entryTrailing).\n entryLeadingNode: (i) => this.entries[i][0],\n entryTrailing: (i, style) => {\n const [k, v] = this.entries[i];\n return formatMapEntryTrailingComments(\n [\n ...(k.comments?.trailing ?? []),\n ...(v.comments?.leading ?? []),\n ...(v.comments?.trailing ?? []),\n ],\n style\n );\n },\n // The entry's own comment handling follows the key's resolved\n // options — same as entryLeadingNode's own choice of the key as the\n // entry's leading-comment anchor.\n entryOptions: dispatch ? (i) => resolveKV(i)[1] : undefined,\n });\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n if (this.indefiniteLength) {\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: byteToHexUpper((MT_MAP << 5) | AI_INDEFINITE),\n comment: 'Start indefinite-length map',\n },\n ];\n for (const [k, v] of this.entries) {\n pushAll(lines, k._toHexDump(depth + 1, options));\n pushAll(lines, v._toHexDump(depth + 1, options));\n }\n lines.push({\n depth,\n hex: byteToHexUpper(BREAK_CODE),\n comment: '\"break\"',\n });\n return lines;\n }\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: bytesToSpacedHexUpper(\n writeHead(MT_MAP, BigInt(this.entries.length), this.encodingWidth)\n ),\n comment: `Map of length ${this.entries.length}`,\n },\n ];\n for (const [k, v] of this.entries) {\n pushAll(lines, k._toHexDump(depth + 1, options));\n pushAll(lines, v._toHexDump(depth + 1, options));\n }\n return lines;\n }\n\n _toJS(\n options?: ToJSOptions,\n path?: readonly unknown[],\n occurrence?: readonly unknown[]\n ): unknown {\n const reviver = options?.reviver;\n const dispatch = needsItemDispatch(options);\n const basePath = path ?? [];\n const occ = occurrence ?? ROOT_OCCURRENCE;\n const toEntries = () => {\n const convertPair = (\n k: CborItem,\n v: CborItem,\n i: number,\n opts: ToJSOptions | undefined\n ): [unknown, unknown] => {\n if (!dispatch) return [k._toJS(opts), v._toJS(opts)];\n // The key has no path segment of its own — it names the value's —\n // so it's converted first, against the parent's own path, and its\n // result becomes the value's path segment. The occurrence chains\n // (unlike path) are derived purely from this map's own occurrence\n // plus this entry's own ordinal `i`, never from the key's converted\n // JS value — see `Occurrence`.\n const kJs = k._toJSChild(opts, basePath, [...occ, `k${i}`], {\n parent: this,\n isMapKey: true,\n keyNode: k,\n });\n const vJs = v._toJSChild(opts, [...basePath, kJs], [...occ, `v${i}`], {\n parent: this,\n keyNode: k,\n });\n return [kJs, vJs];\n };\n const result = MapEntries.from(this.entries, ([k, v], i) =>\n convertPair(k, v, i, options)\n );\n if (!reviver) return result;\n const uOmits = options?.undefinedOmits;\n for (let i = 0; i < result.length; i++) {\n const [k, v] = result[i];\n const rv = reviver.call(result, k, v);\n if (rv === CBOR_OMIT || (uOmits && rv === undefined))\n result.splice(i--, 1);\n else result[i] = [k, rv];\n }\n return result;\n };\n const toObject = () => {\n // `rawPass` marks a call as belonging to the raw pre-population pass\n // below — its occurrence gets `RAW_PASS_MARKER` inserted (see\n // `Occurrence`) so it can never be reused by the real, revived pass,\n // even indirectly through some other, more deeply nested raw pass.\n const convertValue = (\n k: CborItem,\n v: CborItem,\n key: string,\n i: number,\n opts: ToJSOptions | undefined,\n rawPass: boolean\n ) =>\n dispatch\n ? v._toJSChild(\n opts,\n [...basePath, key],\n // Derived from this map's own occurrence plus this entry's\n // own ordinal `i`, not from `key` (a converted JS value) —\n // see `Occurrence`.\n rawPass ? [...occ, RAW_PASS_MARKER, `v${i}`] : [...occ, `v${i}`],\n { parent: this, keyNode: k }\n )\n : v._toJS(opts);\n // First pass: pre-populate holder with unrevived values so all sibling\n // keys are visible in `this` when reviver runs (matches JSON.parse).\n // `itemOptions`/`extensions` still apply here — see `withoutReviver`\n // — since this holder is directly observable through `this[key]`\n // inside an earlier sibling's own reviver call, not just internal\n // scaffolding; the `RAW_PASS_MARKER` in each value's occurrence above\n // keeps this pass's resolutions from being reused by the real,\n // revived pass below. When there's no reviver, this loop's result\n // *is* the final output (see `if (!reviver) return holder` below) —\n // `withoutReviver` is then a no-op (`reviver` was already unset), and\n // `rawPass` is `false` so no marker is inserted, matching that this\n // loop is not throwaway in that case.\n const optNoReviver = withoutReviver(options);\n const holder: Record<string, unknown> = {};\n for (let i = 0; i < this.entries.length; i++) {\n const [k, v] = this.entries[i];\n const key =\n k instanceof CborTextString\n ? k.value\n : (k._jsObjectKey(options) ?? k.toCDN());\n const raw = convertValue(k, v, key, i, optNoReviver, !!reviver);\n if (key === '__proto__') {\n Object.defineProperty(holder, key, {\n value: raw,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n } else {\n holder[key] = raw;\n }\n }\n if (!reviver) return holder;\n // Second pass: process each property sequentially depth-first.\n // Only the last occurrence of each key is revived to avoid duplicate\n // callbacks when CBOR maps contain repeated keys.\n const lastIdx = new Map<string, number>();\n for (let i = 0; i < this.entries.length; i++) {\n const [k] = this.entries[i];\n lastIdx.set(\n k instanceof CborTextString\n ? k.value\n : (k._jsObjectKey(options) ?? k.toCDN()),\n i\n );\n }\n for (let i = 0; i < this.entries.length; i++) {\n const [k, v] = this.entries[i];\n const key =\n k instanceof CborTextString\n ? k.value\n : (k._jsObjectKey(options) ?? k.toCDN());\n if (lastIdx.get(key) !== i) continue;\n const val = convertValue(k, v, key, i, options, false);\n const rv = reviver.call(holder, key, val);\n const omit =\n rv === CBOR_OMIT || (options?.undefinedOmits && rv === undefined);\n if (!omit) {\n if (key === '__proto__') {\n Object.defineProperty(holder, key, {\n value: rv,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n } else {\n holder[key] = rv;\n }\n } else {\n delete holder[key];\n }\n }\n return holder;\n };\n\n if (options?.mapAs === 'entries') return toEntries();\n if (options?.mapAs === 'object') return toObject();\n // A key is object-eligible under 'auto' when it's a text string, or when\n // it offers an alternate key spelling via `_jsObjectKey()` (a CDDL\n // e-ref annotated integer key; see `extensions/eref.ts`) — which, by\n // default, every such key does: `eRefKeys` defaults to `true` for a key\n // that exists only because a schema named it in the first place, so\n // only an *explicit* `eRefKeys: false` turns this off (see\n // `CborERefUint`/`CborERefNint`'s own `_jsObjectKey()`, which under\n // `eRefKeys: false` falls back to the key's own plain numeric string\n // rather than `undefined` — so `eRefKeys !== false` is checked here too;\n // it returns `undefined` for a label `fromJS()` couldn't convert back,\n // making that key ineligible like any plain integer).\n //\n // Eligibility alone isn't enough, though: an e-ref name can collide\n // with an unrelated entry's own genuine text key of the same spelling\n // (e.g. `&(title: -1)` alongside a literal `\"title\"` key in the same\n // map) — 'auto' silently overwriting one with the other, via the same\n // property, would be a much less obvious data loss than the *already*\n // -accepted case of two literal duplicate text keys colliding (which\n // 'auto' already tolerates today, independent of e-ref, so that case is\n // deliberately left alone below). Falls back to entries/Map whenever a\n // collision involves at least one non-text side; an explicit\n // `mapAs: 'object'` still accepts it, same as it already does for a\n // literal duplicate key.\n const objectEligible = (k: CborItem): boolean =>\n k instanceof CborTextString ||\n (options?.eRefKeys !== false && k._jsObjectKey(options) !== undefined);\n const isAutoObjectSafe = (): boolean => {\n // Value: whether every occurrence of this key string seen so far was\n // a genuine CborTextString (not e.g. an e-ref name).\n const allTextSoFar = new Map<string, boolean>();\n for (const [k] of this.entries) {\n if (!objectEligible(k)) return false;\n const isText = k instanceof CborTextString;\n const key = isText\n ? (k as CborTextString).value\n : k._jsObjectKey(options)!;\n const priorAllText = allTextSoFar.get(key);\n if (priorAllText !== undefined && !(priorAllText && isText))\n return false;\n allTextSoFar.set(key, isText);\n }\n return true;\n };\n if (isAutoObjectSafe()) return toObject();\n return toEntries();\n }\n}\n\nfunction formatMapEntryTrailingComments(\n comments: CborComment[],\n style?: 'c-style' | 'cdn-style'\n): string {\n if (comments.length === 0) return '';\n return (\n ' ' +\n comments\n .map((comment) => convertCommentText(comment, style).trimEnd())\n .join(' ')\n );\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem } from './CborItem';\nimport { Simple } from '../simple';\nimport { MT_SIMPLE, AI_1BYTE } from '../cbor/constants';\nimport type { CborWriter } from '../cbor/encode';\n\n/**\n * CBOR Major Type 7 — simple value (0–255).\n *\n * Well-known values:\n * 20 → false\n * 21 → true\n * 22 → null\n * 23 → undefined\n */\nexport class CborSimple extends CborItem {\n readonly value: number;\n /**\n * Original CDN digit spelling of the argument to `simple(...)` (base +\n * digits), set by the parser when this value came from CDN text. Used by\n * `_toCDN()` to round-trip the argument's base (`0x10`, decimal, …) when\n * `preserveNumberFormat` is set.\n */\n readonly ednSource?: string;\n\n constructor(value: number, options?: { ednSource?: string }) {\n super();\n if (!Number.isInteger(value) || value < 0 || value > 255)\n throw new RangeError('CborSimple value must be an integer in 0–255');\n this.value = value;\n this.ednSource = options?.ednSource;\n }\n\n static readonly FALSE = new CborSimple(20);\n static readonly TRUE = new CborSimple(21);\n static readonly NULL = new CborSimple(22);\n static readonly UNDEFINED = new CborSimple(23);\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n // Values 0–23: encoded in the initial byte (MT7 | value)\n if (this.value <= 23) {\n writer.writeByte((MT_SIMPLE << 5) | this.value);\n return;\n }\n // Values 24–255: MT7, AI_1BYTE, then one value byte\n writer.writeByte((MT_SIMPLE << 5) | AI_1BYTE);\n writer.writeByte(this.value);\n }\n\n _toCDN(options: ToCDNOptions | undefined, _depth: number): string {\n // A value written as simple(20) etc. is a different spelling choice from\n // the false/true/null/undefined keywords, even though it denotes the\n // same value — so preserveNumberFormat must keep simple(...) notation\n // (checked before the keyword shortcuts below, which only apply to\n // values that were never parsed via simple(...) in the first place).\n if (options?.preserveNumberFormat && this.ednSource !== undefined)\n return `simple(${this.ednSource})`;\n switch (this.value) {\n case 20:\n return 'false';\n case 21:\n return 'true';\n case 22:\n return 'null';\n case 23:\n return 'undefined';\n default:\n return `simple(${this.value})`;\n }\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n switch (this.value) {\n case 20:\n return false;\n case 21:\n return true;\n case 22:\n return null;\n case 23:\n return undefined;\n default:\n return new Simple(this.value);\n }\n }\n}\n","import type { ToCDNOptions, ToJSOptions, ToCBOROptions } from '../types';\nimport { CborItem, needsCdnItemDispatch } from './CborItem';\nimport type { AnnotatedLine } from './CborItem';\nimport { MT_BYTES } from '../cbor/constants';\nimport {\n writeHead,\n writeHeadTo,\n CborWriter,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n formatTrailingComments,\n hasPreservedComments,\n pushAll,\n serializeContainer,\n} from '../cdn/serialize-utils';\nimport { bytesToSpacedHexUpper } from '../utils/hex';\n\n/**\n * CBOR Sequence Literal (§2.3.4) — `<<item, item, ...>>`.\n *\n * Encodes as a definite-length byte string whose value is the concatenation\n * of the CBOR encodings of the contained items.\n *\n * @example\n * // <<1, 2>> → h'0102'\n * new CborEmbeddedCBOR([new CborUint(1n), new CborUint(2n)])\n */\nexport class CborEmbeddedCBOR extends CborItem {\n readonly items: CborItem[];\n encodingWidth: EncodingWidth | undefined;\n\n constructor(items: CborItem[], options?: { encodingWidth?: EncodingWidth }) {\n super();\n this.items = items;\n this.encodingWidth = options?.encodingWidth;\n }\n\n override get _containsCdnContainer(): boolean {\n return this.items.some((item) => item._containsCdnContainer);\n }\n\n /** The raw concatenated CBOR bytes of all contained items. */\n private _content(options?: ToCBOROptions): Uint8Array {\n const inner = new CborWriter();\n for (const item of this.items) item._encode(inner, options);\n return inner.finish();\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n // The head needs the content's byte length, so the items are encoded\n // into a separate buffer first.\n const content = this._content(options);\n writeHeadTo(writer, MT_BYTES, content.length, this.encodingWidth);\n writer.writeBytes(content);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n const basePath = path ?? [];\n const dispatch = needsCdnItemDispatch(options);\n const childOptions = (i: number): ToCDNOptions | undefined =>\n dispatch\n ? this.items[i]._resolveCdnOptions(options, [...basePath, i], {\n parent: this,\n })\n : options;\n return serializeContainer({\n node: this,\n options,\n depth,\n openChar: '<<',\n closeChar: '>>',\n count: this.items.length,\n indefiniteLength: false,\n encodingWidth: this.encodingWidth,\n eiPosition: 'close',\n canonicalCount: () => BigInt(this._content(options).length),\n hasEntryComments: (i) => hasPreservedComments(this.items[i]),\n renderEntry: (i) =>\n this.items[i]._toCDN(\n childOptions(i),\n depth + 1,\n dispatch ? [...basePath, i] : undefined\n ),\n // entryIsLeaf is intentionally omitted (defaults to \"always a leaf\"):\n // unlike CborArray/CborMap, an item that is itself an array/map still\n // inlines here as long as its own rendering fits on one line — <<...>>\n // is a flat sequence of encoded items, not a nested-structure display.\n // alwaysInlineLeaf: this collapse isn't gated behind\n // inlineLeafContainers at all — there's no structural reason to ever\n // spread a flat encoded-item sequence one item per line if it fits.\n alwaysInlineLeaf: true,\n entryIsMultiWordText: (i) =>\n this.items[i]._isMultiWordText(\n childOptions(i),\n false,\n dispatch ? [...basePath, i] : undefined\n ),\n entryLeadingNode: (i) => this.items[i],\n entryTrailing: (i, style) => formatTrailingComments(this.items[i], style),\n entryOptions: dispatch ? childOptions : undefined,\n });\n }\n\n override _toHexDump(depth: number, options?: ToCDNOptions): AnnotatedLine[] {\n const content = this._content();\n const n = content.length;\n const lines: AnnotatedLine[] = [\n {\n depth,\n hex: bytesToSpacedHexUpper(\n writeHead(MT_BYTES, BigInt(n), this.encodingWidth)\n ),\n comment: `Embedded CBOR sequence, ${n} byte${n !== 1 ? 's' : ''}`,\n },\n ];\n for (const item of this.items) {\n pushAll(lines, item._toHexDump(depth + 1, options));\n }\n return lines;\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n return this._content();\n }\n}\n","/**\n * Strip whitespace and EDN §2.1 comments from app-string content.\n *\n * Used by extensions whose content allows the same comment syntax as byte\n * string literals (b32, h32, float, …):\n * SP / LF / CR — whitespace, skipped\n * # … LF — line comment\n * // … LF — line comment\n * /* … *\\/ — block comment (unterminated → SyntaxError)\n * / … / — block comment (unterminated → SyntaxError)\n */\nexport function stripComments(str: string): string {\n let out = '';\n let i = 0;\n while (i < str.length) {\n const ch = str[i];\n if (ch === ' ' || ch === '\\n' || ch === '\\r') {\n i++;\n continue;\n }\n if (ch === '#') {\n while (i < str.length && str[i] !== '\\n') i++;\n continue;\n }\n if (ch === '/') {\n const next = str[i + 1] ?? '';\n if (next === '/') {\n while (i < str.length && str[i] !== '\\n') i++;\n continue;\n }\n if (next === '*') {\n i += 2;\n while (\n i < str.length &&\n !(str[i] === '*' && (str[i + 1] ?? '') === '/')\n )\n i++;\n if (i >= str.length)\n throw new SyntaxError('unterminated block comment');\n i += 2; // consume */\n continue;\n }\n // / … / block comment\n i++;\n while (i < str.length && str[i] !== '/') i++;\n if (i >= str.length) throw new SyntaxError('unterminated block comment');\n i++; // consume closing /\n continue;\n }\n out += ch;\n i++;\n }\n return out;\n}\n","import type { CborExtension } from './types';\nimport { CborByteString } from '../ast/CborByteString';\nimport { stripComments } from '../utils/strip-comments';\n\nconst B32_ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\nconst H32_ALPHA = '0123456789ABCDEFGHIJKLMNOPQRSTUV';\n\nfunction stripBase32Padding(str: string): string {\n let end = str.length;\n while (end > 0 && str.charCodeAt(end - 1) === 0x3d) end--;\n return str.slice(0, end);\n}\n\nfunction base32Decode(\n str: string,\n alpha: string,\n onError?: (msg: string) => void\n): Uint8Array {\n // Padding is optional; strip it before decoding.\n const s = stripBase32Padding(str).toUpperCase();\n // RFC 4648 §6: valid unpadded lengths mod 8 are 0, 2, 4, 5, 7.\n // Lengths 1, 3, 6 can never result from any valid byte sequence.\n const rem = s.length % 8;\n if (rem === 1 || rem === 3 || rem === 6)\n throw new SyntaxError(`invalid base32 length: ${s.length} characters`);\n const lookup = new Uint8Array(128).fill(0xff);\n for (let i = 0; i < alpha.length; i++) lookup[alpha.charCodeAt(i)] = i;\n const out = new Uint8Array(Math.floor((s.length * 5) / 8));\n let buf = 0,\n bufBits = 0,\n outIdx = 0;\n for (const ch of s) {\n const code = ch.charCodeAt(0);\n const val = code < 128 ? lookup[code] : 0xff;\n if (val === 0xff)\n throw new SyntaxError(\n `invalid character in byte string: ${JSON.stringify(ch)}`\n );\n buf = (buf << 5) | val;\n bufBits += 5;\n if (bufBits >= 8) {\n bufBits -= 8;\n out[outIdx++] = (buf >> bufBits) & 0xff;\n }\n }\n // RFC 4648 §3.5: trailing bits in the final quantum must be zero.\n if (bufBits > 0 && (buf & ((1 << bufBits) - 1)) !== 0) {\n const msg = 'non-zero trailing bits in base32 input';\n if (onError) onError(msg);\n else throw new SyntaxError(msg);\n }\n return out;\n}\n\n/** RFC 4648 §6 Base32 (A–Z 2–7) app-string extension. */\nexport const b32: CborExtension = {\n appStringPrefixes: ['b32'],\n parseAppString(_prefix, content, onError) {\n return new CborByteString(\n base32Decode(stripComments(content), B32_ALPHA, onError),\n {\n ednEncoding: 'base32',\n }\n );\n },\n};\n\n/** RFC 4648 §7 Base32Hex (0–9 A–V) app-string extension. */\nexport const h32: CborExtension = {\n appStringPrefixes: ['h32'],\n parseAppString(_prefix, content, onError) {\n return new CborByteString(\n base32Decode(stripComments(content), H32_ALPHA, onError),\n {\n ednEncoding: 'base32hex',\n }\n );\n },\n};\n","/**\n * §5.1 of draft-ietf-cbor-edn-literals-27 — Stand-in for unknown app-extensions.\n *\n * When the CDN parser encounters an unrecognised app-extension\n * identifier (the default `unresolvedExtension: 'cpa999'` behaviour), it wraps\n * the literal in a CPA999 tag instead of throwing a SyntaxError.\n *\n * Structure:\n * CPA999([<prefix>, [<content-items...>]])\n *\n * Examples:\n * cri'https://example.com' → CPA999([\"cri\", [\"https://example.com\"]])\n * hash<<\"data\", -44>> → CPA999([\"hash\", [\"data\", -44]])\n *\n * toCDN() reconstructs the original app-string / app-sequence notation:\n * CPA999([\"cri\", [\"https://example.com\"]]) → cri'https://example.com'\n * CPA999([\"hash\", [\"data\", -44]]) → hash<<\"data\", -44>>\n *\n * Note: CPA999 is a provisional tag number (CPA = Code Point Allocation).\n * It will be replaced by an IANA-assigned tag number upon RFC publication.\n */\n\nimport type { ToCDNOptions } from '../types';\nimport { CborTag } from './CborTag';\nimport { CborArray } from './CborArray';\nimport { CborTextString } from './CborTextString';\nimport type { CborItem } from './CborItem';\nimport { escapeAppString } from '../cdn/serialize-utils';\n\n/** Provisional tag number for the Unresolved App-Extension stand-in. */\nexport const CPA999_TAG = 999n;\n\n/**\n * Stand-in for an unrecognised EDN app-extension literal.\n *\n * Structure:\n * App-string: CPA999([prefix, text])\n * App-sequence: CPA999([prefix, [items...]])\n */\nexport class CborUnresolvedAppExt extends CborTag {\n constructor(prefix: string, items: CborItem[]) {\n // App-string: single text item → tag(999, [prefix, text])\n // App-sequence: otherwise → tag(999, [prefix, [items...]])\n const content =\n items.length === 1 && items[0] instanceof CborTextString\n ? items[0]\n : new CborArray(items);\n super(CPA999_TAG, new CborArray([new CborTextString(prefix), content]));\n }\n\n /** App-string form (`prefix'text'`), as opposed to an app-sequence. */\n private get _isAppString(): boolean {\n return (this.content as CborArray).items[1] instanceof CborTextString;\n }\n\n /**\n * An app-string (`e'alg'`) renders as a plain literal, not the\n * `[prefix, text]` array it wraps, so it's a leaf for\n * `inlineLeafContainers` — word-counted like a text string instead (via\n * `CborTag._isMultiWordText`'s tokenizing of the rendered output).\n */\n override get _containsCdnContainer(): boolean {\n return this._isAppString ? false : super._containsCdnContainer;\n }\n\n override _toCDN(options: ToCDNOptions | undefined, depth: number): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth);\n\n const arr = this.content as CborArray;\n const prefix = (arr.items[0] as CborTextString).value;\n const contentItem = arr.items[1];\n\n // Text string → reconstruct app-string form: prefix'content'\n if (contentItem instanceof CborTextString) {\n return `${prefix}${escapeAppString(contentItem.value)}`;\n }\n\n // Array → reconstruct app-sequence form: prefix<<item, item, ...>>\n const contentArr = contentItem as CborArray;\n const inner = contentArr.items\n .map((item) => item._toCDN(options, depth))\n .join(', ');\n return `${prefix}<<${inner}>>`;\n }\n}\n","import type { ToCDNOptions, ToCBOROptions, ToJSOptions } from '../types';\nimport {\n CborItem,\n needsItemDispatch,\n needsCdnItemDispatch,\n ROOT_OCCURRENCE,\n CDN_OVERRIDE_TRACKER,\n} from './CborItem';\nimport type { Occurrence, CdnOverrideTrackerBox } from './CborItem';\nimport type { CborWriter } from '../cbor/encode';\nimport {\n isMultiWordRenderedLiteral,\n resolveIndent,\n} from '../cdn/serialize-utils';\n\n/**\n * Wraps a resolved app-sequence result and preserves the original EDN source\n * text for round-trip fidelity.\n *\n * In the default `encodingIndicators: 'auto'` mode, `_toCDN` returns the\n * stored source text verbatim. For `'always'` and `'never'`, it delegates to\n * the resolved item so the option is applied recursively to every data item;\n * preserving the source verbatim would leave nested indicators unchanged.\n * In single-line output (no `indent`), a source spelling that spans multiple\n * lines also delegates to the inner item, since it cannot be re-emitted\n * without breaking the single-line guarantee.\n *\n * When `toCDN()`'s `itemOptions` is configured (see `needsCdnItemDispatch`),\n * the verbatim `ednSource` fast path alone can't be trusted: it was produced\n * without ever visiting `this.inner`'s own descendants, so an override\n * targeting one of them (e.g. one chunk of an `ilbs<<...>>`) would otherwise\n * never even be offered the chance to apply. But merely *having* `itemOptions`\n * configured must not by itself change the output — many callers set it\n * without it ever matching anything in this particular subtree, and\n * `itemOptions` returning `undefined` everywhere is documented to mean \"no\n * change\" (see `CdnItemContext`). So this renders through the normal\n * recursive path while tracking, via `CDN_OVERRIDE_TRACKER` (an out-of-band\n * symbol key, *not* a wrapped `itemOptions` — wrapping it would make\n * `ctx.options.itemOptions` a different function for every descendant here\n * than everywhere else in the tree, observable even to a pure callback),\n * whether any call in the subtree actually returned an override, and only\n * swaps in that freshly rendered text when one did; otherwise the exact\n * preserved `ednSource` is still returned.\n *\n * Each `_toCDN()` call installs its *own fresh* tracker box before\n * recursing, rather than reusing whatever tracker it was handed — reusing\n * one directly would let an override applied by some unrelated part of the\n * tree that merely happens to share the same ambient `options` object (a\n * later sibling reached through the same `itemOptions`, say) falsely mark\n * *this* wrapper's own verbatim source as stale. But a genuinely *nested*\n * app-sequence (e.g. a custom `wrap<<ilbs<<h'61'>>>>` extension wrapping an\n * `ilbs<<...>>` result) must still have its own outer verbatim source\n * abandoned when the inner wrapper's own tracked render found something to\n * apply — an inner override changes what the outer source would need to\n * embed too. So once this call's own local tracker comes back `applied`,\n * that fact is additionally bubbled up to whichever ancestor tracker (if\n * any) this call itself received via `options` — the exact wrapper this\n * call is nested inside, never a sibling reached only through shared\n * top-level `options`.\n *\n * CBOR encoding and JS conversion always delegate to the inner item so the\n * wrapper is fully transparent for those operations.\n */\nexport class CborAppSeqResult extends CborItem {\n constructor(\n readonly inner: CborItem,\n readonly ednSource: string\n ) {\n super();\n }\n\n override get _containsCdnContainer(): boolean {\n return this.inner._containsCdnContainer;\n }\n\n /**\n * Same approach as `CborTag`: tokenize this wrapper's own `_toCDN()`\n * output rather than delegating to `this.inner._isMultiWordText()`.\n * Delegating to `this.inner` was tried and found wrong: for\n * `ilbs<<h'68656c6c6f20776f726c64'>>`, the chunk's raw bytes decode to\n * printable \"hello world\", so `this.inner`'s own semantic check reports\n * it as multi-word — but the *actual* rendering is the preserved\n * `ilbs<<...>>` app-sequence spelling, where that chunk appears as a\n * `h'...'` literal, never as decoded text; the semantic prediction and\n * the real output disagree. Tokenizing `this._toCDN()` directly sees\n * whichever one actually happens: the preserved `ednSource` verbatim\n * (`isMultiWordRenderedLiteral` peels the `prefix<<...>>` wrapper and\n * checks each item under the loose rule, same as `<<...>>` — a\n * multi-word text item like `ilts<<\"two words\">>` still always counts,\n * a prefixed-literal item like `ilbs<<h'00'>>` does not) or, in the\n * 'always'/'never' `encodingIndicators` modes, a pure passthrough to\n * `this.inner._toCDN()` with no extra wrapping (any node needing that to\n * be caught, like a self-disqualifying `CborIndefiniteByteString`, has\n * already produced a `\\n` in that string, which the caller's own\n * `s.includes('\\n')` check picks up independently either way).\n */\n override _isMultiWordText(\n options: ToCDNOptions | undefined,\n strict = true,\n path?: readonly unknown[]\n ): boolean {\n return isMultiWordRenderedLiteral(this._toCDN(options, 0, path), strict);\n }\n\n override _encodeTo(writer: CborWriter, options?: ToCBOROptions): void {\n this.inner._encode(writer, options);\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n const mode = options?.encodingIndicators ?? 'auto';\n const sourceEligible =\n options?.appPrefix !== false &&\n mode === 'auto' &&\n (resolveIndent(options) !== null || !/[\\r\\n]/.test(this.ednSource));\n if (!sourceEligible)\n // Transparent wrapper — the inner item shares this wrapper's own path\n // (see CdnItemContext.path) and gets its own itemOptions resolved\n // against it (`_resolveCdnOptions` is a no-op when itemOptions isn't\n // in play, so this is always safe to call).\n return this.inner._toCDN(\n this.inner._resolveCdnOptions(options, path ?? [], { parent: this }),\n depth,\n path\n );\n if (!needsCdnItemDispatch(options)) return this.ednSource;\n // itemOptions is configured, so some descendant *could* override\n // something the verbatim source doesn't reflect — but \"undefined\n // everywhere = no change\" must still hold. Render through the normal\n // recursive path while tracking, via the `CDN_OVERRIDE_TRACKER`\n // out-of-band box (not a wrapped `itemOptions` — see this class's own\n // doc for why that's observably different from the real thing), whether\n // any call in the subtree actually returned a non-undefined override;\n // only then is it safe to decide between the freshly rendered text (an\n // override applied) and the still-exact preserved source (none did).\n //\n // The ancestor tracker (if this call is itself nested inside another\n // app-sequence wrapper's own tracked render) is captured *before* it's\n // shadowed below, so a genuine override found only once this call\n // recurses into `this.inner` can still be bubbled up to it afterwards —\n // see this class's own doc.\n const ancestorTracker = (\n options as ToCDNOptions & {\n [CDN_OVERRIDE_TRACKER]?: CdnOverrideTrackerBox;\n }\n )[CDN_OVERRIDE_TRACKER];\n const tracker: CdnOverrideTrackerBox = { applied: false };\n const tracked: ToCDNOptions & {\n [CDN_OVERRIDE_TRACKER]?: CdnOverrideTrackerBox;\n } = {\n ...options,\n [CDN_OVERRIDE_TRACKER]: tracker,\n };\n const rendered = this.inner._toCDN(\n this.inner._resolveCdnOptions(tracked, path ?? [], { parent: this }),\n depth,\n path\n );\n if (tracker.applied && ancestorTracker) ancestorTracker.applied = true;\n return tracker.applied ? rendered : this.ednSource;\n }\n\n _toJS(\n options?: ToJSOptions,\n path?: readonly unknown[],\n occurrence?: Occurrence\n ): unknown {\n // Transparent wrapper — the inner item shares this wrapper's own path\n // (see ItemContext.path) and its own cache-matching identity (see\n // Occurrence) unchanged.\n return needsItemDispatch(options)\n ? this.inner._toJSChild(\n options,\n path ?? [],\n occurrence ?? ROOT_OCCURRENCE,\n { parent: this }\n )\n : this.inner._toJS(options);\n }\n}\n","/**\n * §5.2 of draft-ietf-cbor-edn-literals-27 — Ellipsis (Elision) tag.\n *\n * Two forms:\n * 888(null) — subtree elision: a whole data item replaced by ...\n * 888([frag, 888(null), frag, ...])\n * — string/bytes elision: fragments alternating with ellipses\n *\n * Note: CPA888 is a provisional tag number.\n */\n\nimport type { ToCDNOptions } from '../types';\nimport { CborTag } from './CborTag';\nimport { CborArray } from './CborArray';\nimport { CborByteString } from './CborByteString';\nimport { CborTextString } from './CborTextString';\nimport { CborSimple } from './CborSimple';\nimport type { CborItem } from './CborItem';\nimport { bytesToHex } from '../utils/hex';\nimport {\n escapeString,\n resolveIndent,\n serializeBytes,\n stripByteLiteralComments,\n convertCommentText,\n danglingCommentsByGap,\n joinConcatParts,\n joinAppSeqParts,\n shouldEmitComments,\n resolveCommentStyle,\n type ByteCommentSyntax,\n} from '../cdn/serialize-utils';\n\nexport const CPA888_TAG = 888n;\n\n/**\n * Comments between two top-level `items` entries (a real `+` the parser\n * never fused away — see `CborByteString.ednParts`/`CborTextString\n * .ednPartSpans` for the case where two literals *did* fuse into one node\n * with no per-part AST node of their own) land on one of them as ordinary\n * `leading`/`trailing`, exactly like any other array entry: `attachComments`\n * runs generically over the whole tree, and both entries are real\n * `CborItem`s once the parser stamps their `start`/`end`.\n */\nfunction boundaryComments(\n prev: CborItem,\n next: CborItem,\n preserveComments: boolean,\n style: 'c-style' | 'cdn-style' | undefined\n): string[] {\n if (!preserveComments) return [];\n return [\n ...(prev.comments?.trailing ?? []).map((c) => convertCommentText(c, style)),\n ...(next.comments?.leading ?? []).map((c) => convertCommentText(c, style)),\n ];\n}\n\n/**\n * Join elision fragments with `+`. Elision is compact/single-line by\n * default — an abbreviated, inherently short summary of the underlying\n * value, not something meant to be reflowed across lines — but reflows\n * across multiple lines, one fragment per line like a real `+`\n * concatenation, when `indent` is enabled *and* there's a *mid-chain*\n * comment to preserve: a single line has nowhere to put a `#`/`//` line\n * comment sitting between two fragments (it has no way to terminate before\n * the rest of the chain), and a block comment kept inline there would be\n * indistinguishable from one actually written that way. With nothing to\n * preserve, or with `indent` disabled (nothing can safely hold a newline),\n * the whole chain still collapses onto one line and any such comment is\n * dropped — matching every other comment kind in single-line output.\n *\n * A comment trailing the *whole* chain needs none of this: it's promoted\n * onto this `CborEllipsis`'s own `comments.trailing` by the parser (see\n * `promoteEllipsisTailComments`), so the ordinary `entryTrailing`/root-\n * `toCDN()` machinery appends it after the rendered body — on the same\n * line if the body stayed single-line, which is always safe since nothing\n * else follows it there.\n */\nfunction joinElisionParts(\n rendered: readonly string[],\n gapComments: readonly (readonly string[])[],\n indentStr: string | null,\n depth: number\n): string {\n if (indentStr === null || !gapComments.some((g) => g.length > 0)) {\n return rendered.join(' + ');\n }\n return joinConcatParts(rendered, indentStr, depth, gapComments);\n}\n\n/**\n * Resolve a preserved source spelling: strip any embedded comment unless\n * comments are requested (`preserveComments`/`comments`) — a preserved\n * spelling should still drop comments by default, the same as an\n * unpreserved literal re-derived from\n * its decoded value would — then, only when the (possibly stripped) result\n * is safe to re-emit verbatim, return it. It's safe when `indent` enables\n * multi-line output, or it doesn't actually contain a newline itself\n * (interior whitespace, or a surviving `#`/`//` line comment) — otherwise it\n * would break `ToCDNOptions.indent`'s single-line guarantee. Mirrors\n * `CborByteString`/`CborTextString`'s own preserved-source fallback check.\n * Returns `undefined` when `source` is `undefined`, or isn't usable.\n */\nfunction preservedSource(\n source: string | undefined,\n options: ToCDNOptions | undefined,\n indentStr: string | null,\n commentSyntax: ByteCommentSyntax | undefined\n): string | undefined {\n if (source === undefined) return undefined;\n const stripped =\n shouldEmitComments(options) || commentSyntax === undefined\n ? source\n : stripByteLiteralComments(source, commentSyntax);\n return isSafeForCurrentMode(stripped, indentStr) ? stripped : undefined;\n}\n\n/**\n * Like `preservedSource`, but for a text source (`CborTextString`'s\n * `ednPartSources`) — text literals have no embedded-comment notation to\n * strip (a `#`/`//` there is just literal text content), so this only\n * applies the single-line safety check.\n */\nfunction usableTextSource(\n source: string | undefined,\n indentStr: string | null\n): source is string {\n return source !== undefined && isSafeForCurrentMode(source, indentStr);\n}\n\nfunction isSafeForCurrentMode(\n source: string,\n indentStr: string | null\n): boolean {\n return indentStr !== null || !/[\\r\\n]/.test(source);\n}\n\nexport class CborEllipsis extends CborTag {\n /**\n * For the array (string/bytes elision) form: `realBoundary[i]` is `true`\n * when a genuine `+` from the source precedes `items[i]` — as opposed to\n * `items[i]` sitting *inside* a single `h'xx...yy'` literal's own `...`\n * notation (index 0's value is never consulted — there is nothing before\n * the first item). `preserveConcatenation` uses this to show only the\n * real boundaries and fuse everything else, exactly as each source\n * literal was spelled.\n *\n * `undefined` means no boundary information is available at all (e.g.\n * reconstructed from raw CBOR bytes, which carry no notion of \"was there\n * a `+` here\" to begin with) — `preserveConcatenation` then has no effect,\n * the same as for a value that didn't originate from CDN source.\n */\n readonly realBoundary: readonly boolean[] | undefined;\n\n /**\n * For a subtree-elision placeholder (`888(null)`, i.e. `content\n * instanceof CborSimple`) that sits *inside* another `CborEllipsis`'s\n * items: `true` when it came from a `h'xx...yy'`-family literal's own\n * `...` notation — even a fully-elided `h'...'` with no hex digits at all\n * — as opposed to a bare standalone `...` token. Only consulted when this\n * placeholder ends up isolated as its own preserved fragment (nothing to\n * fuse it with on either side), to pick the right spelling: `h'...'` vs\n * plain `...`.\n */\n readonly fromByteLiteral: boolean;\n\n /**\n * When `fromByteLiteral` is `true`: that `h'xx...yy'`-family literal's own\n * raw source text (e.g. `h'AB...CD'` verbatim — case, interior whitespace,\n * and any `/ ... /`/`# ...` comments included), for `preserveByteString`\n * to round-trip instead of re-emitting a freshly lower-cased, comment-free\n * `h'...'` literal. `undefined` when `fromByteLiteral` is `false`.\n */\n readonly literalSource: string | undefined;\n\n /** Subtree elision: 888(null) */\n constructor(fromByteLiteral?: boolean, literalSource?: string);\n /** String/bytes elision: 888([items...]) */\n constructor(items: CborItem[], realBoundary?: readonly boolean[]);\n constructor(\n itemsOrFromByteLiteral?: CborItem[] | boolean,\n realBoundaryOrLiteralSource?: readonly boolean[] | string\n ) {\n if (Array.isArray(itemsOrFromByteLiteral)) {\n super(CPA888_TAG, new CborArray(itemsOrFromByteLiteral));\n this.fromByteLiteral = false;\n this.literalSource = undefined;\n this.realBoundary = realBoundaryOrLiteralSource as\n readonly boolean[] | undefined;\n } else {\n super(CPA888_TAG, CborSimple.NULL);\n this.fromByteLiteral = itemsOrFromByteLiteral ?? false;\n this.literalSource = realBoundaryOrLiteralSource as string | undefined;\n this.realBoundary = undefined;\n }\n }\n\n override _toCDN(options: ToCDNOptions | undefined, depth: number): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth);\n if (this.content instanceof CborSimple) {\n // Subtree elision → \"...\"\n return '...';\n }\n if (this.content instanceof CborArray) {\n const preserveConcat = !!options?.preserveConcatenation;\n if (\n preserveConcat ||\n (options?.preserveByteString && !this._hasRealConcatenation())\n ) {\n // Show only the real `+` boundaries, fusing everything else exactly\n // as each source literal (e.g. a `h'xx...yy'`, however its own\n // `...` is positioned) was spelled — see `realBoundary`. With no\n // real boundary at all, this is just the one literal's own spelling.\n const preserved = this._renderPreservedBytesElision(options, depth);\n if (preserved !== undefined) return preserved;\n }\n if (!preserveConcat || this.realBoundary === undefined) {\n // Bytes elision where every fragment is a plain byte string: re-emit\n // the compact `h'xx...yy'` literal — the actual CDN grammar for this\n // (§5.2) — instead of expanding it into `h'xx' + ... + h'yy'`. Always\n // hex, regardless of `bstrEncoding`/`sqstr`: `h'...'` is the only\n // elidable literal form: there is no elided base64 or sqstr spelling.\n // Also the fallback when `preserveConcatenation` is set but there is\n // no boundary information to preserve in the first place.\n const compactHex = this._compactHexElided();\n if (compactHex !== undefined) return compactHex;\n }\n // Otherwise (text elision, or bytes elision mixed with something\n // else): frag + ... + frag, single-line unless a comment needs the\n // extra room — see `joinElisionParts`. Under `modernConcat`, the same\n // fragments become one flat `t1<<frag, ..., frag>>` / `b1<<...>>`\n // argument list instead (`...` renders as the literal ellipsis\n // argument concat.ts's own grammar accepts) — unlike the plain\n // (non-elision) concatenation case, this isn't gated on\n // `preserveConcatenation`: an elision chain has no \"collapsed single\n // literal\" state to fall back to in the first place (the `...` denotes\n // genuinely unknown content, so it always renders as multiple parts —\n // see `preserveConcat` only ever affecting *how much* of a fragment's\n // own internal boundary is shown, e.g. `_renderFragment` vs a fused\n // fragment's own plain `_toCDN()`, never *whether* the top-level chain\n // itself is shown as multiple parts).\n const items = this.content.items;\n const parts = items.map((item) =>\n preserveConcat\n ? this._renderFragment(item, options, depth)\n : item._toCDN(options, depth)\n );\n const preserveComments = shouldEmitComments(options);\n const style = resolveCommentStyle(options);\n const gapComments = items\n .slice(1)\n .map((item, i) =>\n boundaryComments(items[i]!, item, preserveComments, style)\n );\n if (options?.modernConcat) {\n // A group already collapsed to the compact `h'xx...yy'` form (via\n // `_compactHexElided`) never reaches here — only a byte fragment\n // that survives *uncollapsed* (mixed with a text fragment, or with\n // an ellipsis this function doesn't know is byte-typed) counts\n // toward \"every real fragment is byte-typed\" for prefix selection.\n const isByteOnly = items.every(\n (item) =>\n item instanceof CborByteString ||\n (item instanceof CborEllipsis && item.content instanceof CborSimple)\n );\n return joinAppSeqParts(\n isByteOnly ? 'b1' : 't1',\n parts,\n '',\n resolveIndent(options),\n depth,\n gapComments\n );\n }\n return joinElisionParts(\n parts,\n gapComments,\n resolveIndent(options),\n depth\n );\n }\n return super._toCDN(options, depth);\n }\n\n /**\n * `true` when this bytes elision has at least one real `+` boundary\n * somewhere — as opposed to being a single `h'xx...yy'` literal's own\n * `...` notation, which is not \"produced by + concatenation\" (see\n * `preserveByteString`'s own docs) and so has its spelling preserved by\n * `preserveByteString` alone, the same as a non-elided `h'...'` literal.\n *\n * A real boundary can hide two ways: as `realBoundary[i]` (`i > 0`) on the\n * items array itself, or *inside* a merged `CborByteString` whose\n * `ednParts.length > 1` — two `+`-joined literals that sat next to each\n * other with no ellipsis between them (e.g. `h'AB' + h'CD...EF'`) merge\n * into one item during parsing, so their boundary doesn't show up in\n * `realBoundary` at that item's own index.\n */\n private _hasRealConcatenation(): boolean {\n if (this.realBoundary?.some((real, i) => i > 0 && real)) return true;\n const items = (this.content as CborArray).items;\n return items.some(\n (item) =>\n item instanceof CborByteString &&\n item.ednParts !== undefined &&\n item.ednParts.length > 1\n );\n }\n\n /**\n * Render one elision fragment as it should appear under\n * `preserveConcatenation`: a merged multi-part `CborTextString` (see the\n * parser's `currentParts` consolidation) is expanded back into its\n * original `+`-joined literals, single-line, honoring `preserveRawString`\n * per part. Anything else (a single-part fragment, or a nested\n * `CborEllipsis`) renders normally.\n *\n * Only reached for text elision (or anything not shaped like a pure bytes\n * elision, or a bytes elision with no `realBoundary` information) —\n * `_renderPreservedBytesElision` handles the bytes case that has that\n * information, since it needs to see all the fragments together to know\n * which `...`s are real `+`-joined ellipses and which are internal to one\n * `h'...'` literal.\n */\n private _renderFragment(\n item: CborItem,\n options: ToCDNOptions | undefined,\n depth: number\n ): string {\n const indentStr = resolveIndent(options);\n const preserveComments = shouldEmitComments(options);\n const style = resolveCommentStyle(options);\n // `options?.appPrefix === false` already returned via `super._toCDN`\n // before any caller reaches `_renderFragment` — see this class's own\n // `_toCDN` — so `modernConcat` alone is sufficient here.\n const useT1B1 = !!options?.modernConcat;\n if (\n item instanceof CborByteString &&\n item.ednParts !== undefined &&\n item.ednParts.length > 1\n ) {\n const encoding =\n options?.appPrefix === false\n ? 'hex'\n : (options?.bstrEncoding ?? item.ednEncoding);\n const literals = item.ednParts.map((part) => {\n const source = options?.preserveByteString\n ? preservedSource(part.source, options, indentStr, part.commentSyntax)\n : undefined;\n return source !== undefined\n ? source\n : serializeBytes(part.bytes, encoding, options?.sqstr);\n });\n // These parts merged into one `CborByteString` with no per-part AST\n // node of their own — see `_renderPreservedBytesElision`'s equivalent\n // comment — so a comment between two of them landed as `dangling` on\n // `item` as a whole instead.\n const internalGaps = preserveComments\n ? (danglingCommentsByGap(\n item.comments?.dangling,\n item.ednParts,\n style\n ) ?? [])\n : [];\n // Rendered directly here (rather than delegating to `item._toCDN()`,\n // which already knows how to expand its own `ednParts` under\n // `modernConcat` — see `CborByteString.ts`) because that expansion is\n // gated behind multi-line `indent` there, while an elision fragment's\n // own part boundaries must show regardless of indent, same as the\n // legacy `+` case just below.\n return useT1B1\n ? joinAppSeqParts('b1', literals, '', indentStr, depth, internalGaps)\n : joinElisionParts(literals, internalGaps, indentStr, depth);\n }\n if (\n item instanceof CborTextString &&\n item.ednParts !== undefined &&\n item.ednParts.length > 1\n ) {\n const partSources = options?.preserveRawString\n ? item.ednPartSources\n : undefined;\n const literals = item.ednParts.map((text, i) => {\n const source = partSources?.[i];\n return usableTextSource(source, indentStr)\n ? source\n : escapeString(text);\n });\n const internalGaps = preserveComments\n ? (danglingCommentsByGap(\n item.comments?.dangling,\n item.ednPartSpans,\n style\n ) ?? [])\n : [];\n return useT1B1\n ? joinAppSeqParts('t1', literals, '', indentStr, depth, internalGaps)\n : joinElisionParts(literals, internalGaps, indentStr, depth);\n }\n return item._toCDN(options, depth);\n }\n\n /**\n * Re-emit a `888([...])` bytes elision as a single `h'xx...yy'` literal\n * when every item is either a plain `CborByteString` fragment or a\n * subtree-elision placeholder (`888(null)`) — i.e. exactly what\n * `h'xx...yy'` parses into. Returns `undefined` when the items don't\n * match that shape (e.g. text-string elision, or a fragment that isn't a\n * plain byte string), so the caller falls back to the `frag + ... + frag`\n * form.\n */\n private _compactHexElided(): string | undefined {\n const items = (this.content as CborArray).items;\n let hex = '';\n let hasByteFragment = false;\n for (const item of items) {\n if (item instanceof CborByteString) {\n hex += bytesToHex(item.value);\n hasByteFragment = true;\n } else if (\n item instanceof CborEllipsis &&\n item.content instanceof CborSimple\n ) {\n hex += '...';\n } else {\n return undefined;\n }\n }\n // Without an actual byte fragment (e.g. the single-item `888([888(null)])`\n // form), there's nothing bytes-specific to show; fall back to the plain\n // `frag + ... + frag` path, which collapses a lone item to just `...`.\n if (!hasByteFragment) return undefined;\n return `h'${hex}'`;\n }\n\n /**\n * `preserveConcatenation` rendering for a bytes elision. Groups the\n * fragments at every *real* boundary (`realBoundary[i]`) and renders each\n * group as one unit — fusing together whatever sits between real\n * boundaries, including any `h'xx...yy'` literal's own internal `...`\n * (wherever it's positioned — leading, trailing, or in the middle) and\n * the fragments on either side of it, exactly as that literal was\n * written. Within a group, a `CborByteString` that itself merged several\n * `+`-joined literals (`ednParts.length > 1`, always a real boundary\n * internally — see the parser) is further split at each of those parts.\n *\n * Returns `undefined` when there's no `realBoundary` to work from, or an\n * item isn't a plain `CborByteString` or subtree-elision placeholder\n * (e.g. text elision), so the caller falls back to the compact literal or\n * the simpler per-fragment `frag + ... + frag` rendering.\n */\n private _renderPreservedBytesElision(\n options: ToCDNOptions | undefined,\n depth: number\n ): string | undefined {\n if (this.realBoundary === undefined) return undefined;\n const boundary = this.realBoundary;\n const items = (this.content as CborArray).items;\n\n type Segment =\n | {\n bytes: Uint8Array;\n source?: string;\n commentSyntax?: ByteCommentSyntax;\n }\n | { ellipsis: true; fromByteLiteral: boolean; literalSource?: string };\n const groups: Segment[][] = [];\n // `gapComments[i]` holds already-converted comment text that sat\n // between `groups[i]` and `groups[i + 1]` in the source. Every\n // `flush(comments)` call happens exactly at such a gap — `current`\n // (about to become `groups[gapComments.length]`) is whatever came\n // *before* the gap, and whatever gets pushed to `current` right after\n // this call is what comes *after* it — so each call always records one\n // entry, except the final, argument-less flush at the very end of the\n // method (nothing follows the last group).\n const gapComments: string[][] = [];\n let current: Segment[] = [];\n const flush = (comments?: string[]) => {\n if (current.length > 0) {\n groups.push(current);\n gapComments.push(comments ?? []);\n current = [];\n }\n };\n\n const preserveComments = shouldEmitComments(options);\n const style = resolveCommentStyle(options);\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i]!;\n if (i > 0 && boundary[i])\n flush(boundaryComments(items[i - 1]!, item, preserveComments, style));\n if (item instanceof CborEllipsis && item.content instanceof CborSimple) {\n current.push({\n ellipsis: true,\n fromByteLiteral: item.fromByteLiteral,\n literalSource: item.literalSource,\n });\n } else if (item instanceof CborByteString) {\n if (item.ednParts !== undefined && item.ednParts.length > 1) {\n const [firstPart, ...restParts] = item.ednParts;\n current.push({\n bytes: firstPart.bytes,\n source: firstPart.source,\n commentSyntax: firstPart.commentSyntax,\n });\n // These parts merged into one `CborByteString` with no per-part\n // AST node of their own (no ellipsis sat between them — see\n // `CborEllipsis._hasRealConcatenation`'s doc), so a comment\n // between two of them landed as `dangling` on `item` as a whole\n // instead; re-derive which internal gap each one belongs to.\n const internalGaps = preserveComments\n ? danglingCommentsByGap(\n item.comments?.dangling,\n item.ednParts,\n style\n )\n : undefined;\n restParts.forEach((part, j) => {\n flush(internalGaps?.[j]);\n current.push({\n bytes: part.bytes,\n source: part.source,\n commentSyntax: part.commentSyntax,\n });\n });\n } else {\n current.push({\n bytes: item.value,\n source: item.ednSource,\n commentSyntax: item.ednCommentSyntax,\n });\n }\n } else {\n return undefined;\n }\n }\n // The closing flush has no gap after it, so it bypasses `flush()`'s own\n // comment recording — pushing directly keeps `gapComments.length` at\n // exactly `groups.length - 1`.\n if (current.length > 0) groups.push(current);\n if (groups.length === 0) return undefined;\n\n const encoding =\n options?.appPrefix === false ? 'hex' : (options?.bstrEncoding ?? 'hex');\n // A preserved source spelling can itself contain embedded newlines\n // (interior whitespace, or a surviving `#`/`//` line comment) — those\n // are only safe to re-emit verbatim when `indent` enables multi-line\n // output; see `preservedSource`. Otherwise fall back to freshly\n // re-serializing the bytes.\n const indentStr = resolveIndent(options);\n const rendered = groups.map((group) => {\n // A group with more than one segment, or a single ellipsis-only\n // group, always came from exactly one `h'xx...yy'` literal (see the\n // parser: nothing but that literal's own atoms ever ends up fused\n // together) — so any ellipsis segment's `literalSource` is that\n // whole group's original spelling.\n if (options?.preserveByteString) {\n for (const s of group) {\n if (!('ellipsis' in s)) continue;\n // Always came from a BYTES_HEX_ELIDED token (see `_elidedHexAtoms`),\n // so its comment syntax is unconditionally hex's full syntax.\n const literalSource = preservedSource(\n s.literalSource,\n options,\n indentStr,\n 'full'\n );\n if (literalSource !== undefined) return literalSource;\n }\n }\n const byteSegments = group.filter(\n (\n s\n ): s is {\n bytes: Uint8Array;\n source?: string;\n commentSyntax?: ByteCommentSyntax;\n } => !('ellipsis' in s)\n );\n if (byteSegments.length === 0) {\n // Isolated ellipsis-only group with no preserved source: bare\n // `...` for a genuine standalone ellipsis token, `h'...'` when it\n // came from an elided-hex literal (even an entirely-elided one)\n // to keep its byte-typed spelling.\n const fromByteLiteral = group.some(\n (s) => 'ellipsis' in s && s.fromByteLiteral\n );\n return fromByteLiteral ? \"h'...'\" : '...';\n }\n if (group.length === 1) {\n const segment = byteSegments[0];\n const source = options?.preserveByteString\n ? preservedSource(\n segment.source,\n options,\n indentStr,\n segment.commentSyntax\n )\n : undefined;\n return source !== undefined\n ? source\n : serializeBytes(segment.bytes, encoding, options?.sqstr);\n }\n const hex = group\n .map((s) => ('ellipsis' in s ? '...' : bytesToHex(s.bytes)))\n .join('');\n return `h'${hex}'`;\n });\n // `groups.length === 1` (nothing to concatenate — this method can also\n // be reached via `preserveByteString` alone, with no real `+` boundary\n // at all) has nothing for `modernConcat` to change: both branches\n // collapse to the one rendered literal, so only switch notation when\n // there's an actual boundary to show.\n if (\n options?.preserveConcatenation &&\n options?.modernConcat &&\n rendered.length > 1\n ) {\n return joinAppSeqParts('b1', rendered, '', indentStr, depth, gapComments);\n }\n return joinElisionParts(rendered, gapComments, indentStr, depth);\n }\n}\n","/**\n * CBOR bignum tags (RFC 8949 §3.4.3).\n *\n * Tag 2 — unsigned bignum: tag(2, bstr) where bstr is the big-endian\n * encoding of a non-negative integer.\n * Tag 3 — negative bignum: tag(3, bstr) where the value = -1 - unsigned(bstr).\n *\n * These classes are used for integers that fall outside the uint64 / nint64\n * range of CBOR major types 0 and 1:\n * CborBigUint — value ≥ 2^64\n * CborBigNint — value ≤ -(2^64 + 1)\n *\n * toCDN() emits the plain decimal form (e.g. \"18446744073709551616\") so that\n * round-trips through EDN text are human-readable.\n */\n\nimport type { ToCDNOptions, ToJSOptions } from '../types';\nimport { CborTag } from './CborTag';\nimport { CborByteString } from './CborByteString';\n\nexport const BIGNUM_UINT_TAG = 2n;\nexport const BIGNUM_NINT_TAG = 3n;\n\nconst UINT64_MAX = 0xffff_ffff_ffff_ffffn;\nconst NINT64_MIN = -(UINT64_MAX + 1n); // -18446744073709551616n\n\n// ─── Bigint ↔ bytes helpers ───────────────────────────────────────────────────\n\n/**\n * Encode a non-negative bigint as a minimal big-endian byte string.\n * Zero is encoded as the empty byte string per RFC 8949 §3.4.3.\n */\nexport function bigintToBytes(n: bigint): Uint8Array {\n if (n < 0n)\n throw new RangeError('bigintToBytes requires a non-negative value');\n if (n === 0n) return new Uint8Array(0);\n let hex = n.toString(16);\n if (hex.length % 2 !== 0) hex = '0' + hex;\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++)\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n return bytes;\n}\n\n/**\n * Decode a big-endian byte string to a non-negative bigint.\n * Empty bytes → 0n.\n */\nexport function bytesToBigint(bytes: Uint8Array): bigint {\n let n = 0n;\n for (const b of bytes) n = (n << 8n) | BigInt(b);\n return n;\n}\n\n// ─── AST nodes ────────────────────────────────────────────────────────────────\n\n/**\n * Unsigned bignum — integers ≥ 2^64.\n * Wire format: tag(2, big-endian byte string).\n * toCDN() emits the plain decimal integer.\n */\nexport class CborBigUint extends CborTag {\n readonly bigValue: bigint;\n\n constructor(value: bigint) {\n if (value <= UINT64_MAX)\n throw new RangeError(\n `CborBigUint value ${value} fits in CborUint; use CborUint instead`\n );\n super(BIGNUM_UINT_TAG, new CborByteString(bigintToBytes(value)));\n this.bigValue = value;\n }\n\n override _toCDN(_options: ToCDNOptions | undefined, _depth: number): string {\n return this.bigValue.toString();\n }\n\n override _toJS(_options?: ToJSOptions): bigint {\n return this.bigValue;\n }\n}\n\n/**\n * Negative bignum — integers ≤ -(2^64 + 1).\n * Wire format: tag(3, big-endian byte string of (-1 - value)).\n * toCDN() emits the plain decimal integer.\n */\nexport class CborBigNint extends CborTag {\n readonly bigValue: bigint;\n\n constructor(value: bigint) {\n if (value >= NINT64_MIN)\n throw new RangeError(\n `CborBigNint value ${value} fits in CborNint; use CborNint instead`\n );\n super(BIGNUM_NINT_TAG, new CborByteString(bigintToBytes(-1n - value)));\n this.bigValue = value;\n }\n\n override _toCDN(_options: ToCDNOptions | undefined, _depth: number): string {\n return this.bigValue.toString();\n }\n\n override _toJS(_options?: ToJSOptions): bigint {\n return this.bigValue;\n }\n}\n","import {\n Tokenizer,\n type EdnComment,\n type SqstrToken,\n type Token,\n type TokenType,\n} from './tokenizer';\nimport { CdnSyntaxError } from './errors';\nimport type {\n AppSeqEncodingEdit,\n AppSeqSourceFeatures,\n CborItem,\n} from '../ast/CborItem';\nimport type {\n CborComment,\n FromCDNOptions,\n CborExtension,\n ParseWarning,\n} from '../types';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborIndefiniteByteString } from '../ast/CborIndefiniteByteString';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborIndefiniteTextString } from '../ast/CborIndefiniteTextString';\nimport { CborArray } from '../ast/CborArray';\nimport { CborMap } from '../ast/CborMap';\nimport { CborTag } from '../ast/CborTag';\nimport { CborFloat, type FloatPrecision } from '../ast/CborFloat';\nimport { CborSimple } from '../ast/CborSimple';\nimport { CborEmbeddedCBOR } from '../ast/CborEmbeddedCBOR';\nimport {\n autoSelectFloatPrecision,\n maxForEncodingWidth,\n type EncodingWidth,\n} from '../cbor/encode';\nimport {\n canonicalEncodingWidth,\n pushAll,\n shouldEmitComments,\n type ByteCommentSyntax,\n} from './serialize-utils';\nimport { b32, h32 } from '../extensions/b32';\nimport { parseHexFloat } from '../utils/hexfloat';\nimport { hexToBytes } from '../utils/hex';\nimport { base64ToBytes } from '../utils/base64';\nimport { float64ToFloat16Bits, float16BitsToFloat64 } from '../utils/float16';\nimport { resolveBuiltinExtensions } from '../extensions/builtins';\nimport { CborUnresolvedAppExt } from '../ast/CborUnresolvedAppExt';\nimport { CborAppSeqResult } from '../ast/CborAppSeqResult';\nimport { CborEllipsis } from '../ast/CborEllipsis';\nimport { CborBigUint, CborBigNint } from '../ast/CborBignum';\n\n// Shared codec instances — constructing TextEncoder/TextDecoder per call is\n// measurably expensive in hot parsing paths.\nconst textEncoder = new TextEncoder();\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\nconst utf8Lenient = new TextDecoder('utf-8', { fatal: false });\n\n// ─── Public entry point ───────────────────────────────────────────────────────\n\n/**\n * Parse a CDN text string into a CborItem AST node.\n * Throws SyntaxError on invalid input.\n */\nexport function parseCDN(text: string, options?: FromCDNOptions): CborItem {\n const tokenizer = new Tokenizer(text, {\n offset: options?.offset,\n skipRS: (options as (FromCDNOptions & { _skipRS?: boolean }) | undefined)\n ?._skipRS,\n });\n const parser = new CDNParser(tokenizer, options ?? {});\n const node = parser.parse();\n if (shouldEmitComments(options) || options?.preserveAll) {\n attachComments(node, tokenizer.comments, text);\n promoteEllipsisTailComments(node);\n }\n return node;\n}\n\n// ─── Value helpers ────────────────────────────────────────────────────────────\n\n/** Strip an optional _0/_1/_2/_3/_i encoding-indicator suffix from a raw\n * integer token value and return both the numeric string and the width. */\nfunction parseIntegerRaw(raw: string): {\n numStr: string;\n rawSuffix: string | undefined;\n} {\n let numStr = raw;\n let rawSuffix: string | undefined;\n if (/[_][0-7i]$/.test(raw)) {\n rawSuffix = raw[raw.length - 1]!;\n numStr = raw.slice(0, -2);\n }\n return { numStr, rawSuffix };\n}\n\nfunction parseBigInt(raw: string): bigint {\n if (raw.startsWith('-')) return -BigInt(raw.slice(1));\n return BigInt(raw);\n}\n\n/**\n * `item`'s own literal-preservation features, combined with those of\n * whatever it structurally contains.\n *\n * A node can carry `appSeqSourceFeatures` on itself — set when it is *also*\n * the result of parsing a `prefix<<item>>` / `prefix'...'` source, recording\n * features of *that* inner item (see the `appSeqSourceFeatures` field on\n * `CborItem`) — independently of whatever `structuralAppSeqSourceFeatures`\n * finds by walking its children. Both must be combined: a nested extension\n * result (e.g. a `dt<<b64'...'>>` that resolved to a plain epoch number, so\n * `structuralAppSeqSourceFeatures` finds nothing byte-string-like in it\n * structurally) still carries its own inner byte-string literal's features\n * on itself, and an explicitly disabled sibling `preserve*` option must see\n * that when this node is nested inside an outer `preserveAppPrefix`\n * raw-tag/`<<...>>` source (e.g. `ip`'s array content).\n */\nfunction appSeqSourceFeatures(\n item: CborItem | undefined\n): AppSeqSourceFeatures | undefined {\n if (item === undefined) return undefined;\n return combineAppSeqSourceFeatures([\n item.appSeqSourceFeatures,\n structuralAppSeqSourceFeatures(item),\n ]);\n}\n\nfunction structuralAppSeqSourceFeatures(\n item: CborItem\n): AppSeqSourceFeatures | undefined {\n if (item instanceof CborByteString) {\n return {\n byteString: true,\n concatenation: item.ednParts !== undefined && item.ednParts.length > 1,\n };\n }\n if (item instanceof CborTextString) {\n const hasParts = item.ednParts !== undefined;\n const rawPartCount =\n item.ednPartSources?.filter((source) => source !== undefined).length ?? 0;\n // A part with no preserved raw source is ambiguous by itself — it could\n // be an unpreservable double-quoted literal (textString) or a\n // byte-string literal decoded to text per draft-25 §5.1 (byteString); only\n // ednPartIsByteString distinguishes them.\n const byteStringPartCount = hasParts\n ? item.ednParts!.reduce((count, _text, i) => {\n const hasSource = item.ednPartSources?.[i] !== undefined;\n const isByteString = item.ednPartIsByteString?.[i] ?? false;\n return hasSource || !isByteString ? count : count + 1;\n }, 0)\n : 0;\n const unpreservedTextPartCount =\n (hasParts ? item.ednParts!.length : 0) -\n rawPartCount -\n byteStringPartCount;\n return {\n byteString: byteStringPartCount > 0,\n textString:\n item.quotedEdnSource !== undefined || unpreservedTextPartCount > 0,\n rawString: item.ednSource !== undefined || rawPartCount > 0,\n concatenation: hasParts && item.ednParts!.length > 1,\n };\n }\n if (item instanceof CborArray) {\n return combineAppSeqSourceFeatures(item.items.map(appSeqSourceFeatures));\n }\n if (item instanceof CborMap) {\n // ip accepts an arbitrary CborArray as tag content, so a nested map's\n // own byte-string/text-string/concatenation literals must also be\n // detected — otherwise an explicitly disabled sibling `preserve*`\n // option silently has no effect on them (see collectContentEncodingEdits,\n // which has the analogous \"unsupported nested node\" concern for\n // encoding-indicator edits).\n return combineAppSeqSourceFeatures(\n item.entries.flatMap(([k, v]) => [\n appSeqSourceFeatures(k),\n appSeqSourceFeatures(v),\n ])\n );\n }\n if (item instanceof CborTag) return appSeqSourceFeatures(item.content);\n if (\n item instanceof CborIndefiniteByteString ||\n item instanceof CborIndefiniteTextString ||\n item instanceof CborEmbeddedCBOR\n ) {\n const children: CborItem[] =\n item instanceof CborEmbeddedCBOR ? item.items : item.chunks;\n return combineAppSeqSourceFeatures(children.map(appSeqSourceFeatures));\n }\n return undefined;\n}\n\nfunction combineAppSeqSourceFeatures(\n values: (AppSeqSourceFeatures | undefined)[]\n): AppSeqSourceFeatures | undefined {\n const features = values.filter((value) => value !== undefined);\n if (features.length === 0) return undefined;\n return {\n byteString: features.some((value) => value.byteString),\n textString: features.some((value) => value.textString),\n rawString: features.some((value) => value.rawString),\n concatenation: features.some((value) => value.concatenation),\n };\n}\n\nfunction parseFloatToken(\n raw: string,\n onRecoverableError?: (msg: string) => void\n): {\n value: number;\n precision: FloatPrecision | undefined;\n} {\n // Strip any invalid encoding indicator first, before NaN/Infinity checks,\n // so that e.g. \"NaN_7\" still resolves to NaN after the suffix is removed.\n if (raw.endsWith('_i') || raw.endsWith('_0')) {\n const msg =\n '_0 and _i encoding indicators are not valid for floating-point values';\n if (onRecoverableError) {\n onRecoverableError(msg);\n raw = raw.slice(0, -2);\n } else {\n throw new SyntaxError(`EDN parse error: ${msg}`);\n }\n } else if (/[_][4567]$/.test(raw)) {\n const suffix = raw[raw.length - 1]!;\n const msg =\n suffix === '7'\n ? 'indefinite-length encoding (_7) is not valid for floating-point values'\n : `encoding indicator _${suffix} (AI ${Number(suffix) + 24}) is reserved and not valid`;\n if (onRecoverableError) {\n onRecoverableError(msg);\n raw = raw.slice(0, -2);\n } else {\n throw new SyntaxError(`EDN parse error: ${msg}`);\n }\n }\n\n if (raw === 'NaN') return { value: NaN, precision: undefined };\n if (raw === 'Infinity') return { value: Infinity, precision: undefined };\n if (raw === '-Infinity') return { value: -Infinity, precision: undefined };\n\n let numStr = raw;\n let precision: FloatPrecision | undefined;\n if (raw.endsWith('_1')) {\n precision = 'half';\n numStr = raw.slice(0, -2);\n } else if (raw.endsWith('_2')) {\n precision = 'single';\n numStr = raw.slice(0, -2);\n } else if (raw.endsWith('_3')) {\n precision = 'double';\n numStr = raw.slice(0, -2);\n }\n\n // Hex float literal: 0x[hex]p[exp] or -0x[hex]p[exp]\n if (/^-?0[xX]/.test(numStr))\n return { value: parseHexFloat(numStr), precision };\n\n return { value: parseFloat(numStr), precision };\n}\n\n// ─── Blank-line tracking ─────────────────────────────────────────────────────\n\n/**\n * A blank line is a line containing only whitespace between two other lines\n * — i.e. two newlines with nothing but horizontal whitespace between them.\n * Applied to the raw gap between one container entry and the next\n * (comments and all), so a blank line is detected regardless of whether it\n * sits before, after, or inside a leading comment block.\n */\nconst BLANK_LINE_RE = /\\r?\\n[ \\t]*\\r?\\n/;\n\nfunction hasBlankLineBetween(\n text: string,\n start: number,\n end: number\n): boolean {\n return BLANK_LINE_RE.test(text.slice(start, end));\n}\n\n// ─── Comment attachment ──────────────────────────────────────────────────────\n\ninterface NodeInfo {\n node: CborItem;\n start: number;\n end: number;\n}\n\nfunction relativeComments(\n comments: readonly EdnComment[],\n fromIndex: number,\n start: number,\n end: number\n): CborComment[] {\n const result: CborComment[] = [];\n for (let i = fromIndex; i < comments.length; i++) {\n const comment = comments[i]!;\n if (comment.start >= end) break;\n if (comment.start >= start && comment.end <= end)\n result.push({\n ...comment,\n start: comment.start - start,\n end: comment.end - start,\n });\n }\n return result;\n}\n\nfunction sourceSuffixEdit(\n source: string,\n sourceStart: number,\n node: CborItem,\n always: string\n): AppSeqEncodingEdit | undefined {\n if (node.end === undefined) return undefined;\n const hasIndicator = /_[0-7i]$/.test(\n source.slice(Math.max(0, node.end - 2), node.end)\n );\n const start = (hasIndicator ? node.end - 2 : node.end) - sourceStart;\n return {\n start,\n end: node.end - sourceStart,\n always,\n never: '',\n };\n}\n\n/**\n * Collect source-span edits for every encoding indicator nested inside a\n * raw-tag's content, for `adjustRawAppSeqSource`.\n *\n * Returns `undefined` — instead of a partial edit list — when `node` (or\n * anything nested inside it) is a type this function doesn't know how to\n * produce an edit for (e.g. `CborMap`, `CborTag`, `CborSimple`, an\n * indefinite-length string). A partial list would silently leave that\n * node's own indicator un-edited under `encodingIndicators: 'always'` /\n * `'never'`; the caller must fall back to structural re-serialization\n * instead so every nested indicator is actually applied. `ip` accepts an\n * arbitrary `CborArray` as tag content, so this bails out for any element\n * type beyond the ones explicitly handled below rather than assuming\n * coverage is complete.\n */\nfunction collectContentEncodingEdits(\n source: string,\n sourceStart: number,\n node: CborItem\n): AppSeqEncodingEdit[] | undefined {\n if (node instanceof CborUint) {\n const width = node.encodingWidth ?? canonicalEncodingWidth(node.value);\n const edit = sourceSuffixEdit(source, sourceStart, node, `_${width}`);\n return edit ? [edit] : [];\n }\n if (node instanceof CborNint) {\n const width = node.encodingWidth ?? canonicalEncodingWidth(node.argument);\n const edit = sourceSuffixEdit(source, sourceStart, node, `_${width}`);\n return edit ? [edit] : [];\n }\n if (node instanceof CborFloat) {\n const precision = node.precision ?? autoSelectFloatPrecision(node.value);\n const suffix =\n precision === 'half' ? '_1' : precision === 'single' ? '_2' : '_3';\n const edit = sourceSuffixEdit(source, sourceStart, node, suffix);\n return edit ? [edit] : [];\n }\n if (node instanceof CborByteString) {\n const width =\n node.encodingWidth ?? canonicalEncodingWidth(BigInt(node.value.length));\n const edit = sourceSuffixEdit(source, sourceStart, node, `_${width}`);\n return edit ? [edit] : [];\n }\n if (node instanceof CborTextString) {\n const width =\n node.encodingWidth ??\n canonicalEncodingWidth(BigInt(textEncoder.encode(node.value).length));\n const edit = sourceSuffixEdit(source, sourceStart, node, `_${width}`);\n return edit ? [edit] : [];\n }\n if (node instanceof CborArray) {\n const edits: AppSeqEncodingEdit[] = [];\n if (node.indefiniteLength) return undefined;\n if (node.start !== undefined) {\n const tokenizer = new Tokenizer(source, { offset: node.start });\n const open = tokenizer.consume();\n const next = tokenizer.peek();\n const hasIndicator = next.type === 'ENCODING_INDICATOR';\n const width =\n node.encodingWidth ?? canonicalEncodingWidth(BigInt(node.items.length));\n const suffix = `_${width}`;\n const nextSourceChar = source[open.endOffset] ?? '';\n const separator =\n !hasIndicator && /[+\\-.0-9A-Z_a-z]/.test(nextSourceChar) ? ' ' : '';\n edits.push({\n start: (hasIndicator ? next.offset : open.endOffset) - sourceStart,\n end: (hasIndicator ? next.endOffset : open.endOffset) - sourceStart,\n // An inserted container indicator needs a separator before an\n // immediately-adjacent item (`[_i24]` lexes as one identifier).\n always: suffix + separator,\n never: '',\n });\n }\n for (const item of node.items) {\n const itemEdits = collectContentEncodingEdits(source, sourceStart, item);\n if (itemEdits === undefined) return undefined;\n pushAll(edits, itemEdits);\n }\n return edits;\n }\n return undefined;\n}\n\nfunction attachComments(\n root: CborItem,\n comments: EdnComment[],\n source: string\n): void {\n if (comments.length === 0) return;\n const nodes = collectNodes(root);\n const lineAt = buildLineAt(source);\n\n // Two sorted views over the pre-order node list, so each comment resolves\n // its neighbours in O(log N) instead of re-filtering and re-sorting the\n // whole list per comment. Both sorts are stable, so nodes with equal keys\n // keep their pre-order (parent before child) relative order.\n const byStart = [...nodes].sort((a, b) => a.start - b.start || b.end - a.end);\n const byEnd = [...nodes].sort((a, b) => a.end - b.end || a.start - b.start);\n\n // The tokenizer appends comments in source order; sort defensively so the\n // container sweep below stays correct for out-of-order callers.\n const ordered = [...comments].sort((a, b) => a.start - b.start);\n\n // Container-sweep state shared across comments (comments are processed in\n // ascending start order, so pushes and pops are monotone).\n const enclosing: NodeInfo[] = [];\n let nextToPush = 0;\n\n for (const raw of ordered) {\n const comment: CborComment = { ...raw };\n\n // prev: node with the largest end <= comment start (ties: largest start).\n // byEnd is (end asc, start asc), so this is the last index with\n // end <= raw.start, found by upper-bound binary search.\n let lo = 0;\n let hi = byEnd.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (byEnd[mid].end <= raw.start) lo = mid + 1;\n else hi = mid;\n }\n const prev = lo > 0 ? byEnd[lo - 1] : undefined;\n\n const separatorBeforeComment = prev\n ? source.slice(prev.end, raw.start)\n : '';\n if (\n prev &&\n lineAt(prev.end) === raw.line &&\n !separatorBeforeComment.includes(':')\n ) {\n addComment(prev.node, 'trailing', comment);\n continue;\n }\n\n // container: innermost node with start < comment start and comment end\n // < node end. Node spans nest properly and a comment never straddles a\n // node boundary (it is whitespace between tokens), so an interval-stack\n // sweep over byStart works: push nodes starting before the comment,\n // pop nodes that ended before it — the stack top is the container.\n while (\n nextToPush < byStart.length &&\n byStart[nextToPush].start < raw.start\n ) {\n const n = byStart[nextToPush++];\n while (\n enclosing.length > 0 &&\n enclosing[enclosing.length - 1].end <= n.start\n )\n enclosing.pop();\n enclosing.push(n);\n }\n while (\n enclosing.length > 0 &&\n enclosing[enclosing.length - 1].end <= raw.start\n )\n enclosing.pop();\n const container =\n enclosing.length > 0 ? enclosing[enclosing.length - 1] : undefined;\n\n // next: node with the smallest start >= comment end (ties: largest end).\n // byStart is (start asc, end desc), so this is the first index with\n // start >= raw.end, found by lower-bound binary search.\n lo = 0;\n hi = byStart.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (byStart[mid].start < raw.end) lo = mid + 1;\n else hi = mid;\n }\n const next = lo < byStart.length ? byStart[lo] : undefined;\n\n if (!container || (next && next.end <= container.end)) {\n if (next) {\n comment.sameLine = lineAt(raw.end) === lineAt(next.start);\n addComment(next.node, 'leading', comment);\n continue;\n }\n }\n\n // No enclosing node and no following node: the comment lies entirely\n // after `root.end` (a comment before `root.start` is always caught by\n // the `next`-leading branch above, since `root` is itself a collected\n // node). This happens when this parse is one item of a CDN Sequence\n // (`allowTrailing: true`) — the tokenizer's one-token lookahead reads\n // past this item's closing bracket into a comment that actually\n // belongs to whatever follows. Attaching it here would duplicate the\n // sequence-level leading-comment assignment `fromCDNSeq` already makes\n // for the next item, so it is dropped instead of defaulting to `root`.\n if (!container) continue;\n\n addComment(container.node, 'dangling', comment);\n }\n}\n\nfunction collectNodes(root: CborItem): NodeInfo[] {\n const out: NodeInfo[] = [];\n const visit = (node: CborItem) => {\n if (node.start !== undefined && node.end !== undefined)\n out.push({ node, start: node.start, end: node.end });\n if (node instanceof CborArray || node instanceof CborEmbeddedCBOR) {\n for (const item of node.items) visit(item);\n return;\n }\n if (node instanceof CborMap) {\n for (const [key, value] of node.entries) {\n visit(key);\n visit(value);\n }\n return;\n }\n if (\n node instanceof CborIndefiniteByteString ||\n node instanceof CborIndefiniteTextString\n ) {\n for (const chunk of node.chunks) visit(chunk);\n return;\n }\n if (node instanceof CborTag) visit(node.content);\n };\n visit(root);\n return out;\n}\n\nfunction addComment(\n node: CborItem,\n placement: 'leading' | 'trailing' | 'dangling',\n comment: CborComment\n): void {\n node.comments ??= {};\n node.comments[placement] ??= [];\n node.comments[placement].push(comment);\n}\n\n/**\n * A comment right after the very last fragment of a `+`/`...` chain ties,\n * in source position, with the enclosing `CborEllipsis`'s own end — there\n * is no closing delimiter after the last fragment (unlike an array's `]` or\n * a map's `}`) to give the chain a later end of its own — so\n * `attachComments`'s prev/next tie-break resolves it in favour of the more\n * specific, innermost node: the comment lands as `trailing` on the last\n * fragment itself, not on the `CborEllipsis`.\n *\n * Move it up onto the `CborEllipsis`'s own `comments.trailing` so the\n * ordinary `entryTrailing`/root-`toCDN()` machinery renders it after\n * whatever separator the parent adds (`,`, `:`, a closing bracket) instead\n * of `CborEllipsis._toCDN()` folding it into the chain's own body — which\n * would place a `#`/`//` line comment *before* that separator, swallowing\n * it into the comment on re-parse (e.g. `[h'aa' + ..., # next\\n 1]` would\n * otherwise render the trailing `,` inside the comment text itself).\n */\nfunction promoteEllipsisTailComments(node: CborItem): void {\n if (node instanceof CborEllipsis) {\n if (node.content instanceof CborArray) {\n const items = node.content.items;\n for (const item of items) promoteEllipsisTailComments(item);\n const last = items[items.length - 1];\n const lastTrailing = last?.comments?.trailing;\n if (\n lastTrailing !== undefined &&\n lastTrailing.length > 0 &&\n !node.comments?.trailing?.length\n ) {\n node.comments ??= {};\n node.comments.trailing = lastTrailing;\n last.comments!.trailing = undefined;\n }\n }\n return;\n }\n if (node instanceof CborArray || node instanceof CborEmbeddedCBOR) {\n for (const item of node.items) promoteEllipsisTailComments(item);\n return;\n }\n if (node instanceof CborMap) {\n for (const [key, value] of node.entries) {\n promoteEllipsisTailComments(key);\n promoteEllipsisTailComments(value);\n }\n return;\n }\n if (\n node instanceof CborIndefiniteByteString ||\n node instanceof CborIndefiniteTextString\n ) {\n for (const chunk of node.chunks) promoteEllipsisTailComments(chunk);\n return;\n }\n if (node instanceof CborTag) promoteEllipsisTailComments(node.content);\n}\n\nfunction buildLineAt(source: string): (offset: number) => number {\n const starts = [0];\n for (let i = 0; i < source.length; i++) {\n if (source[i] === '\\n') starts.push(i + 1);\n }\n return (offset: number): number => {\n let target = Math.max(0, Math.min(source.length, offset));\n if (target > 0 && target === source.length) target--;\n let lo = 0;\n let hi = starts.length - 1;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (starts[mid] <= target) lo = mid + 1;\n else hi = mid - 1;\n }\n return hi + 1;\n };\n}\n\n// ─── Missing-extension hints ──────────────────────────────────────────────────\n\nconst bundledExtensionHint = (name: string): string =>\n `import { ${name} } from '@cbortech/cbor' and pass it via the 'extensions' option (extensions: [${name}])`;\nconst externalExtensionHint = (name: string, pkg: string): string =>\n `install ${pkg}, import { ${name} } from '${pkg}', and pass it via the 'extensions' option (extensions: [${name}])`;\nconst builtinDisabledHint = (name: string): string =>\n `'${name}' is a default built-in extension that was excluded via the 'builtinExtensions' option; add it back to that array (or omit 'builtinExtensions' to use the default set)`;\n\n/**\n * App-string prefixes handled by known opt-in extensions or by default\n * built-ins that can be excluded via `builtinExtensions`, mapped to guidance\n * on how to (re-)enable them. Used to emit a non-fatal hint when such a\n * prefix is encountered without the corresponding extension registered.\n */\nconst MISSING_EXTENSION_HINTS: ReadonlyMap<string, string> = new Map([\n ['b32', bundledExtensionHint('b32')],\n ['h32', bundledExtensionHint('h32')],\n ['same', bundledExtensionHint('same')],\n ['hash', externalExtensionHint('hash', '@cbortech/hash-extension')],\n ['uuid', externalExtensionHint('uuid', '@cbortech/uuid-extension')],\n ['UUID', externalExtensionHint('uuid', '@cbortech/uuid-extension')],\n // Only reachable via a non-default `builtinExtensions` override — these\n // are otherwise always present in the default bundled set.\n ['dt', builtinDisabledHint('dt')],\n ['DT', builtinDisabledHint('dt')],\n ['ip', builtinDisabledHint('ip')],\n ['IP', builtinDisabledHint('ip')],\n ['cri', builtinDisabledHint('cri')],\n ['CRI', builtinDisabledHint('cri')],\n ['t1', builtinDisabledHint('t1')],\n ['b1', builtinDisabledHint('b1')],\n ['ilbs', builtinDisabledHint('ilbs')],\n ['ilts', builtinDisabledHint('ilts')],\n ['float', builtinDisabledHint('float')],\n // `e'...'` (draft-ietf-cbor-edn-e-ref) needs a CDDL model to resolve names\n // against; it is registered automatically whenever the `cddl` option is\n // supplied, so this is only reached without one.\n [\n 'e',\n \"pass the 'cddl' option (a compiled CddlSchema or CDDL source text) — e'...' external references are enabled automatically whenever a CDDL schema is supplied\",\n ],\n]);\n\n/**\n * One atom of a byte-string `+`/ellipsis chain: either a byte fragment or an\n * ellipsis marker, tagged with whether a genuine `+` from the source\n * precedes it (`real`) as opposed to sitting inside a single `h'xx...yy'`\n * literal's own `...` notation. An ellipsis atom also tracks whether it came\n * from such a literal at all (`fromByteLiteral`), regardless of its own\n * position within it (leading, trailing, or in the middle) — as opposed to a\n * bare standalone `...` token — and, when it did, that literal's own raw\n * source text (`literalSource`, e.g. `h'AB...CD'` verbatim, case/whitespace/\n * comments and all) for `preserveByteString` to round-trip. See\n * `CDNParser._consumeByteEllipsisChain`.\n */\ntype ByteEllipsisAtom =\n | {\n bytes: Uint8Array;\n source?: string;\n commentSyntax?: ByteCommentSyntax;\n real: boolean;\n /**\n * Source span this atom occupies — its own literal token's span for a\n * direct `+`-joined fragment, or the enclosing `h'xx...yy'` token's\n * whole span for an internal segment split out of it (see\n * `_elidedHexAtoms`: no comment can ever sit between two of that\n * token's own internal segments, so sharing the outer span is safe and\n * still lets an *outer* boundary comment resolve correctly against the\n * group as a whole). Lets `_buildFromByteAtoms` stamp `start`/`end` on\n * the `CborByteString`/`CborEllipsis` nodes it builds, so the generic\n * `attachComments` pass (and `CborByteString._toCDN`'s /\n * `CborEllipsis._renderPreservedBytesElision`'s own dangling-comment\n * lookups) can place a comment between two `+`-joined parts instead of\n * dropping it.\n */\n start?: number;\n end?: number;\n }\n | {\n ellipsis: true;\n real: boolean;\n fromByteLiteral: boolean;\n literalSource?: string;\n /** See the byte-atom variant's `start`/`end` doc above. */\n start?: number;\n end?: number;\n };\n\n// ─── Parser ───────────────────────────────────────────────────────────────────\n\nclass CDNParser {\n /** Lookup from app-prefix → extension (user extensions override built-ins). */\n private readonly extByPrefix: Map<string, CborExtension>;\n /** Lookup from tag number → extension. */\n private readonly extByTag: Map<bigint, CborExtension>;\n\n private readonly unresolvedExtension: 'cpa999' | 'error';\n\n /** Warnings accumulated during the current parseValue() call. */\n private _pendingWarnings: ParseWarning[] = [];\n\n /** Prefixes for which a missing-extension hint has already been emitted. */\n private readonly _hintedPrefixes = new Set<string>();\n\n constructor(\n private readonly t: Tokenizer,\n private readonly _options: FromCDNOptions\n ) {\n this.extByPrefix = new Map();\n this.extByTag = new Map();\n this.unresolvedExtension = _options.unresolvedExtension ?? 'cpa999';\n const builtins = resolveBuiltinExtensions(_options.builtinExtensions);\n for (const ext of [...builtins, ...(_options.extensions ?? [])]) {\n for (const prefix of ext.appStringPrefixes ?? [])\n this.extByPrefix.set(prefix, ext);\n for (const tag of ext.tagNumbers ?? []) this.extByTag.set(tag, ext);\n }\n this.t.onEscapeWarning = (msg, offset, line, col, endOffset) => {\n const w: ParseWarning = {\n message: msg,\n offset,\n line,\n column: col,\n endOffset,\n };\n this._pendingWarnings.push(w);\n if (this._options.onWarning) this._options.onWarning(w);\n else if (!this._options.silent)\n console.warn(\n `CDN strict violation at line ${line}, column ${col}: ${msg}`\n );\n if (this._options.strict !== false)\n throw new CdnSyntaxError(msg, { offset, line, column: col, endOffset });\n };\n }\n\n parse(): CborItem {\n const value = this.parseValue();\n if (this._options.allowTrailing) return value;\n const next = this.t.peek();\n if (next.type !== 'EOF') {\n this._warnOrFail(\n `unexpected token after value: ${JSON.stringify(next.value)}`,\n next\n );\n // Reached only in non-strict mode (_warnOrFail throws in strict mode).\n // Drain the pending warning into the returned value's AST node so it\n // is visible to callers that inspect node.warnings directly.\n if (this._pendingWarnings.length > 0) {\n value.warnings ??= [];\n value.warnings.push(...this._pendingWarnings);\n this._pendingWarnings = [];\n }\n // Scan the rest of the input so that hard lexer errors in the trailing\n // content (e.g. unterminated strings) still throw regardless of the\n // strict setting.\n while (this.t.peek().type !== 'EOF') this.t.consume();\n }\n return value;\n }\n\n parseValue(): CborItem {\n const start = this.t.peek().offset;\n const node = this._parseValueNode();\n if (this.t.peek().type === 'UNDERSCORE') {\n const tok = this.t.consume();\n this._warnOrFail(\n 'bare _ is not a valid encoding indicator; use _0, _1, _2, _3, or _i',\n tok\n );\n }\n if (this._pendingWarnings.length > 0) {\n node.warnings ??= [];\n for (const w of this._pendingWarnings) node.warnings.push(w);\n this._pendingWarnings = [];\n }\n node.start = start;\n node.end = this.t.lastEndOffset;\n return node;\n }\n\n private _parseValueNode(): CborItem {\n const tok = this.t.peek();\n switch (tok.type) {\n case 'INTEGER':\n return this.parseIntegerOrTag();\n case 'FLOAT':\n return this.parseFloat();\n case 'TSTR':\n case 'RAWSTRING':\n return this.parseString();\n case 'BYTES_HEX':\n case 'SQSTR':\n case 'BYTES_B64': {\n this.t.consume();\n return this._parseBytesConcat(\n this._decodeBytesToken(tok),\n tok.type,\n tok.raw,\n tok.offset,\n tok.endOffset\n );\n }\n case 'EMPTY_INDEF_BYTES':\n this.t.consume();\n return new CborIndefiniteByteString([]);\n case 'EMPTY_INDEF_TEXT':\n this.t.consume();\n return new CborIndefiniteTextString([]);\n case 'TRUE':\n this.t.consume();\n return new CborSimple(21);\n case 'FALSE':\n this.t.consume();\n return new CborSimple(20);\n case 'NULL':\n this.t.consume();\n return new CborSimple(22);\n case 'UNDEFINED':\n this.t.consume();\n return new CborSimple(23);\n case 'SIMPLE':\n return this.parseSimple();\n case 'LBRACKET':\n return this.parseArray();\n case 'LBRACE':\n return this.parseMap();\n case 'LPAREN':\n return this.parseIndefGroup();\n case 'LT_LT':\n return this.parseEmbeddedCBOR();\n case 'APP_STRING': {\n this.t.consume();\n // Consume optional encoding indicator (e.g. float'fe00'_2).\n let appStrEw: EncodingWidth | undefined;\n let appStrEiRaw = '';\n if (this.t.peek().type === 'ENCODING_INDICATOR') {\n const eiTok = this.t.consume();\n appStrEw = this._resolveEncodingWidth(eiTok.value, eiTok);\n appStrEiRaw = eiTok.raw;\n }\n const ext = this.extByPrefix.get(tok.appPrefix!);\n if (!ext?.parseAppString) {\n if (!ext) this._hintMissingExtension(tok.appPrefix!, tok);\n if (this.unresolvedExtension === 'cpa999')\n return new CborUnresolvedAppExt(tok.appPrefix!, [\n new CborTextString(tok.value),\n ]);\n this._fail(\n `unknown app-string extension: ${JSON.stringify(tok.appPrefix)}`,\n tok\n );\n }\n {\n const warnsBefore = this._pendingWarnings.length;\n try {\n const result = ext.parseAppString(\n tok.appPrefix!,\n tok.value,\n this._extOnError(tok),\n appStrEw !== undefined ? { encodingWidth: appStrEw } : undefined\n );\n // Generic EI post-processing: apply encoding indicator when the\n // extension didn't handle it itself (e.g. dt'...'_2).\n if (appStrEw !== undefined)\n this._applyEiToResult(result, appStrEw, tok);\n if (ext.preserveAppSeqSource === 'optional') {\n // Same rationale as the APP_SEQUENCE case below: tack the\n // source onto the same result node so preserveAppPrefix can\n // round-trip prefix`...` (and non-canonical prefix'...')\n // spellings without changing the node's class/identity.\n result.appSeqSource = tok.raw + appStrEiRaw;\n return result;\n }\n // Propagate ednSource so preserveByteString / appPrefix round-trips correctly.\n // instanceof narrows the type; getPrototypeOf excludes subclasses like CborIpExt.\n if (\n result instanceof CborByteString &&\n Object.getPrototypeOf(result) === CborByteString.prototype &&\n result.ednSource === undefined\n )\n return new CborByteString(result.value, {\n ednEncoding: result.ednEncoding,\n encodingWidth: result.encodingWidth,\n ednSource: tok.raw + appStrEiRaw,\n // A prefix name alone can't say which comment syntax (if\n // any) this content actually uses: a user extension may be\n // registered under the same prefix as a built-in (`ext`\n // here is whichever one actually resolved — see the\n // registration order in the constructor). Only strip\n // comments from preserveByteString's spelling when `ext` is\n // provably the specific built-in b32/h32 object.\n ednCommentSyntax:\n ext === b32 || ext === h32 ? 'full' : undefined,\n });\n if (result instanceof CborFloat && result.ednSource === undefined)\n result.ednSource = tok.raw + appStrEiRaw;\n return result;\n } catch (e) {\n if (this._options.strict !== false) throw e;\n if (this._pendingWarnings.length === warnsBefore)\n this._warn(e instanceof Error ? e.message : String(e), tok);\n return new CborUnresolvedAppExt(tok.appPrefix!, [\n new CborTextString(tok.value),\n ]);\n }\n }\n }\n case 'APP_SEQUENCE': {\n const commentStartIndex = this.t.comments.length;\n this.t.consume();\n const items: CborItem[] = [];\n while (this.t.peek().type !== 'GT_GT') {\n if (this.t.peek().type === 'EOF')\n this._fail(`unterminated ${tok.appPrefix!}<<...>>`, tok);\n if (items.length > 0) {\n if (this.t.peek().type === 'COMMA') {\n this.t.consume();\n if (this.t.peek().type === 'GT_GT') break; // trailing comma\n } else if (this.t.peek().offset === this.t.lastEndOffset) {\n this._warnOrFail(\n '<<...>> items must be separated by \",\" or whitespace',\n this.t.peek()\n );\n }\n }\n items.push(this.parseValue());\n }\n this.expect('GT_GT');\n let seqEw: EncodingWidth | undefined;\n let seqEiTok: Token | undefined;\n if (this.t.peek().type === 'ENCODING_INDICATOR') {\n seqEiTok = this.t.consume();\n seqEw = this._resolveEncodingWidth(seqEiTok.value, seqEiTok);\n }\n const seqExt = this.extByPrefix.get(tok.appPrefix!);\n if (!seqExt) {\n this._hintMissingExtension(tok.appPrefix!, tok);\n if (this.unresolvedExtension === 'cpa999')\n return new CborUnresolvedAppExt(tok.appPrefix!, items);\n this._fail(\n `unknown app-string extension: ${JSON.stringify(tok.appPrefix)}`,\n tok\n );\n }\n if (!seqExt.parseAppSequence)\n this._fail(\n `app-string extension ${JSON.stringify(tok.appPrefix)} does not support <<...>> form`,\n tok\n );\n {\n const warnsBefore = this._pendingWarnings.length;\n try {\n const result = seqExt.parseAppSequence(\n tok.appPrefix!,\n items,\n this._extOnError(tok)\n );\n if (seqEw !== undefined)\n this._applyEiToResult(result, seqEw, seqEiTok ?? tok);\n const rawSource = this.t.source.slice(\n tok.offset,\n this.t.lastEndOffset\n );\n if (seqExt.preserveAppSeqSource === 'optional') {\n // Tack the source onto the same result node (preserving its\n // class/identity) rather than wrapping it; the node's own\n // _toCDN() decides whether to use it (see preserveAppPrefix).\n result.appSeqSource = rawSource;\n result.appSeqComments = relativeComments(\n this.t.comments,\n commentStartIndex,\n tok.offset,\n this.t.lastEndOffset\n );\n // Exact split point for adjustAppSeqIndicator to strip the\n // sole inner item's own indicator by position rather than by\n // pattern-matching text near '>>' (which whitespace, a\n // trailing comma, or a comment between the item and '>>'\n // would defeat).\n if (items.length === 1) {\n if (items[0].end !== undefined)\n result.appSeqInnerEnd = items[0].end - tok.offset;\n result.appSeqSourceFeatures = appSeqSourceFeatures(items[0]);\n }\n } else if (result instanceof CborFloat) {\n if (result.ednSource === undefined) result.ednSource = rawSource;\n } else if (seqExt.preserveAppSeqSource) {\n return new CborAppSeqResult(result, rawSource);\n }\n return result;\n } catch (e) {\n if (this._options.strict !== false) throw e;\n if (this._pendingWarnings.length === warnsBefore)\n this._warn(e instanceof Error ? e.message : String(e), tok);\n return new CborUnresolvedAppExt(tok.appPrefix!, items);\n }\n }\n }\n case 'ELLIPSIS': {\n this.t.consume();\n if (this.t.peek().type !== 'PLUS') return new CborEllipsis();\n const items: CborItem[] = [new CborEllipsis()];\n while (this.t.peek().type === 'PLUS') {\n this.t.consume();\n items.push(this.parseValue());\n }\n // Every item here came from an explicit `+` (this generic chain has\n // no notion of an elided-hex literal's internal `...`), so every\n // boundary is real.\n return new CborEllipsis(\n items,\n items.map(() => true)\n );\n }\n case 'BYTES_HEX_ELIDED': {\n this.t.consume();\n return this._parseHexElidedConcat(tok);\n }\n default:\n this._fail(`unexpected token: ${JSON.stringify(tok.value)}`, tok);\n }\n }\n\n private parseIntegerOrTag(): CborItem {\n const commentStartIndex = this.t.comments.length;\n const tok = this.t.consume(); // INTEGER\n const { numStr, rawSuffix } = parseIntegerRaw(tok.value);\n let tagIndicatorStart =\n rawSuffix !== undefined ? tok.endOffset - 2 : tok.endOffset;\n let tagIndicatorEnd = tok.endOffset;\n // Hex/octal/binary literals return before the suffix check in the tokenizer,\n // so their encoding indicator arrives as a separate ENCODING_INDICATOR token.\n let encodingWidth =\n rawSuffix !== undefined\n ? this._resolveEncodingWidth(rawSuffix, tok)\n : this.consumeEncodingIndicator(undefined, (eiTok) => {\n tagIndicatorStart = eiTok.offset;\n tagIndicatorEnd = eiTok.endOffset;\n });\n const n = parseBigInt(numStr);\n // tok.raw keeps a leading '+' that tok.value drops (e.g. \"+42\" → value\n // \"42\", raw \"+42\"); mirror the same suffix stripping applied to numStr\n // so the preserved spelling matches what the user actually wrote.\n const ednSource = rawSuffix !== undefined ? tok.raw.slice(0, -2) : tok.raw;\n\n // Out-of-range integers become bignum tags per RFC 8949 §3.4.3.\n // Tag numbers must fit in uint64, so a value > UINT64_MAX before '(' is an error.\n if (n > 0xffff_ffff_ffff_ffffn) {\n if (this.t.peek().type === 'LPAREN')\n this._fail('tag number exceeds maximum uint64', tok);\n return new CborBigUint(n);\n }\n if (n < -(0xffff_ffff_ffff_ffffn + 1n)) {\n return new CborBigNint(n);\n }\n\n // Validate that the value fits in the requested encoding width.\n // For nint, the CBOR argument is abs(n)−1 (e.g. -1 → 0, -24 → 23).\n if (encodingWidth !== undefined) {\n const storedValue = n >= 0n ? n : -(n + 1n);\n encodingWidth = this._validateEncodingFit(\n storedValue,\n encodingWidth,\n tok\n );\n }\n\n const intNode =\n n >= 0n\n ? new CborUint(n, { encodingWidth, ednSource })\n : new CborNint(n, { encodingWidth, ednSource });\n\n // integer followed by '(' → tagged data item\n if (this.t.peek().type === 'LPAREN') {\n if (!(intNode instanceof CborUint))\n this._fail('tag number must be non-negative', tok);\n this.t.consume(); // (\n // Rescue setup warnings before content's parseValue() drains them into the content node.\n const setupWarnings = this._pendingWarnings.splice(0);\n const content = this.parseValue();\n this.expect('RPAREN');\n const tagNum = intNode.value;\n const ext = this.extByTag.get(tagNum);\n if (ext?.parseTag) {\n const result = ext.parseTag(tagNum, content);\n if (result !== undefined) {\n if (result instanceof CborTag) {\n if (\n encodingWidth !== undefined &&\n result.encodingWidth === undefined\n )\n result.encodingWidth = encodingWidth;\n if (result.ednSource === undefined) result.ednSource = ednSource;\n if (\n ext.preserveAppSeqSource === 'optional' &&\n result.appSeqSource === undefined\n ) {\n // Raw tag notation (e.g. 1(1749772800)) is itself a spelling\n // that preserveAppPrefix should be able to keep instead of\n // upgrading it to regenerated DT'...' notation.\n result.appSeqSource = this.t.source.slice(\n tok.offset,\n this.t.lastEndOffset\n );\n result.appSeqComments = relativeComments(\n this.t.comments,\n commentStartIndex,\n tok.offset,\n this.t.lastEndOffset\n );\n const tagWidth =\n result.encodingWidth ?? canonicalEncodingWidth(result.tag);\n const contentEdits = collectContentEncodingEdits(\n this.t.source,\n tok.offset,\n result.content\n );\n result.appSeqEncodingEdits = [\n {\n start: tagIndicatorStart - tok.offset,\n end: tagIndicatorEnd - tok.offset,\n always: `_${tagWidth}`,\n never: '',\n },\n ...(contentEdits ?? []),\n ];\n if (contentEdits === undefined)\n result.appSeqEncodingEditsComplete = false;\n result.appSeqSourceFeatures = appSeqSourceFeatures(content);\n }\n }\n if (setupWarnings.length > 0) {\n result.warnings ??= [];\n result.warnings.push(...setupWarnings);\n }\n return result;\n }\n }\n const tagResult = new CborTag(tagNum, content, {\n encodingWidth,\n ednSource,\n });\n if (setupWarnings.length > 0) {\n tagResult.warnings ??= [];\n tagResult.warnings.push(...setupWarnings);\n }\n return tagResult;\n }\n return intNode;\n }\n\n private parseFloat(): CborItem {\n const tok = this.t.consume(); // FLOAT\n const onRecoverableError = (msg: string) => this._warnOrFail(msg, tok);\n const { value, precision } = parseFloatToken(tok.value, onRecoverableError);\n if (precision === 'half' || precision === 'single') {\n const roundTripped =\n precision === 'half'\n ? float16BitsToFloat64(float64ToFloat16Bits(value))\n : Math.fround(value);\n const lossless =\n Object.is(value, roundTripped) || (isNaN(value) && isNaN(roundTripped));\n if (!lossless)\n onRecoverableError(\n `${value} cannot be exactly represented as ${precision === 'half' ? 'f16 (_1)' : 'f32 (_2)'}; use _3 or remove the indicator`\n );\n }\n // tok.raw keeps a leading '+' that tok.value drops (e.g. \"+1.5\" → value\n // \"1.5\", raw \"+1.5\"; likewise \"+Infinity\" → value \"Infinity\").\n return new CborFloat(value, { precision, literalSource: tok.raw });\n }\n\n private parseString(): CborItem {\n const tok = this.t.consume(); // STRING\n\n // Fast path: no concatenation\n if (this.t.peek().type !== 'PLUS') {\n const ew = this.consumeEncodingIndicator(() =>\n BigInt(textEncoder.encode(tok.value).length)\n );\n if (tok.type === 'RAWSTRING')\n return new CborTextString(tok.value, {\n ednSource: tok.raw,\n ...(ew !== undefined ? { encodingWidth: ew } : {}),\n });\n return new CborTextString(tok.value, {\n quotedEdnSource: tok.raw,\n ...(ew !== undefined ? { encodingWidth: ew } : {}),\n });\n }\n\n // Concatenation chain — may include ellipsis, producing CborEllipsis\n let hasEllipsis = false;\n const parts: Array<\n | {\n text: string;\n source?: string;\n isByteString?: boolean;\n start: number;\n end: number;\n }\n | { ellipsis: true; start: number; end: number }\n > = [\n tok.type === 'RAWSTRING'\n ? {\n text: tok.value,\n source: tok.raw,\n start: tok.offset,\n end: tok.endOffset,\n }\n : { text: tok.value, start: tok.offset, end: tok.endOffset },\n ];\n\n while (this.t.peek().type === 'PLUS') {\n this.t.consume(); // +\n const next = this.t.peek();\n if (next.type === 'ELLIPSIS') {\n this.t.consume();\n parts.push({ ellipsis: true, start: next.offset, end: next.endOffset });\n hasEllipsis = true;\n } else if (next.type === 'TSTR' || next.type === 'RAWSTRING') {\n this.t.consume();\n parts.push(\n next.type === 'RAWSTRING'\n ? {\n text: next.value,\n source: next.raw,\n start: next.offset,\n end: next.endOffset,\n }\n : { text: next.value, start: next.offset, end: next.endOffset }\n );\n } else if (this._isBytesToken(next.type)) {\n this.t.consume();\n parts.push({\n text: this._decodeUtf8(this._decodeBytesToken(next), next),\n // draft-25 §5.1: this part is a byte-string literal decoded to text, not a\n // double-quoted literal — appSeqSourceFeatures must attribute it\n // to `byteString`, not the unpreservable `textString`, since both\n // leave `source` undefined here.\n isByteString: true,\n start: next.offset,\n end: next.endOffset,\n });\n } else {\n this._fail(\n `expected string or byte string after +, got ${JSON.stringify(next.value)}`,\n next\n );\n }\n }\n\n if (!hasEllipsis) {\n // No ellipsis — join all text fragments into a single CborTextString,\n // keeping the part boundaries for `preserveConcatenation`.\n const texts = parts.map((p) => ('text' in p ? p.text : ''));\n const sources = parts.map((p) => ('text' in p ? p.source : undefined));\n const isByteStringFlags = parts.map((p) =>\n 'text' in p ? (p.isByteString ?? false) : false\n );\n const spans = parts.map((p) => ({ start: p.start, end: p.end }));\n const joined = texts.join('');\n const ew = this.consumeEncodingIndicator(() =>\n BigInt(textEncoder.encode(joined).length)\n );\n return new CborTextString(joined, {\n ednParts: texts,\n ednPartSpans: spans,\n ...(sources.some((s) => s !== undefined)\n ? { ednPartSources: sources }\n : {}),\n ...(isByteStringFlags.some((b) => b)\n ? { ednPartIsByteString: isByteStringFlags }\n : {}),\n ...(ew !== undefined ? { encodingWidth: ew } : {}),\n });\n }\n\n // Build 888([...]) with consolidated adjacent text fragments, retaining\n // the original boundaries and raw source spellings within each fragment.\n const items: CborItem[] = [];\n const currentParts: Array<{\n text: string;\n source?: string;\n isByteString?: boolean;\n start: number;\n end: number;\n }> = [];\n const flushCurrentParts = () => {\n const texts = currentParts.map((part) => part.text);\n const currentText = texts.join('');\n if (currentText !== '') {\n const sources = currentParts.map((part) => part.source);\n const isByteStringFlags = currentParts.map(\n (part) => part.isByteString ?? false\n );\n const spans = currentParts.map((part) => ({\n start: part.start,\n end: part.end,\n }));\n const node = new CborTextString(currentText, {\n ednParts: texts,\n ednPartSpans: spans,\n ...(sources.some((source) => source !== undefined)\n ? { ednPartSources: sources }\n : {}),\n ...(isByteStringFlags.some((b) => b)\n ? { ednPartIsByteString: isByteStringFlags }\n : {}),\n });\n // Stamp the generic start/end span so `attachComments` (run once,\n // after the whole tree is built) can attach a comment between this\n // item and its neighbour in `items` as `leading`/`trailing`, exactly\n // like any other array entry — see\n // `CborEllipsis._toCDN`'s text-elision rendering.\n node.start = currentParts[0]!.start;\n node.end = currentParts[currentParts.length - 1]!.end;\n items.push(node);\n }\n currentParts.length = 0;\n };\n for (const part of parts) {\n if ('ellipsis' in part) {\n flushCurrentParts();\n const ellipsisNode = new CborEllipsis();\n ellipsisNode.start = part.start;\n ellipsisNode.end = part.end;\n items.push(ellipsisNode);\n } else {\n currentParts.push(part);\n }\n }\n flushCurrentParts();\n\n return new CborEllipsis(items);\n }\n\n private _isBytesToken(type: string): boolean {\n return type === 'BYTES_HEX' || type === 'SQSTR' || type === 'BYTES_B64';\n }\n\n /**\n * Decode a hex payload, converting the codec's plain SyntaxError (e.g. odd\n * length) into a CdnSyntaxError carrying the token's position.\n */\n private _hexToBytes(hex: string, tok: Token): Uint8Array {\n try {\n return hexToBytes(hex);\n } catch (e) {\n if (e instanceof CdnSyntaxError || !(e instanceof SyntaxError)) throw e;\n this._fail(e.message, tok);\n }\n }\n\n private _decodeBytesToken(tok: Token): Uint8Array {\n const onRecoverableError = (msg: string) => this._warnOrFail(msg, tok);\n switch (tok.type) {\n case 'SQSTR': {\n // The tokenizer attaches the UTF-8 payload it already encoded;\n // decoding the hex `value` again would just rebuild the same bytes.\n const bytes = (tok as SqstrToken)._sqstrBytes;\n if (bytes !== undefined) return bytes;\n return this._hexToBytes(tok.value, tok);\n }\n case 'BYTES_HEX':\n return this._hexToBytes(tok.value, tok);\n case 'BYTES_B64':\n try {\n return base64ToBytes(tok.value, onRecoverableError);\n } catch (e) {\n if (e instanceof CdnSyntaxError || !(e instanceof SyntaxError))\n throw e;\n this._fail(e.message, tok);\n }\n default:\n this._fail(`expected byte string token`, tok);\n }\n }\n\n private _decodeUtf8(bytes: Uint8Array, tok: Token): string {\n if (this._options.allowInvalidUtf8) return utf8Lenient.decode(bytes);\n try {\n return utf8Strict.decode(bytes);\n } catch {\n const msg = 'byte string in text concatenation is not valid UTF-8';\n this._warnOrFail(msg, tok);\n return utf8Lenient.decode(bytes);\n }\n }\n\n private _tokenTypeToCdnEncoding(type: string): 'hex' | 'base64' {\n return type === 'BYTES_B64' ? 'base64' : 'hex';\n }\n\n /**\n * Comment syntax (if any) for a *core* byte-string token type (never an\n * app-string extension's — those are resolved by extension identity, not\n * token type, since `_isBytesToken` excludes `APP_STRING` and extension\n * prefixes can never take part in `+`/ellipsis concatenation). `BYTES_HEX`\n * (and its elided form) uses the full syntax; `BYTES_B64` only `#`; `SQSTR`\n * none at all.\n */\n private _tokenTypeToCommentSyntax(\n type: string\n ): ByteCommentSyntax | undefined {\n if (type === 'BYTES_HEX') return 'full';\n if (type === 'BYTES_B64') return 'hash-only';\n return undefined;\n }\n\n private _parseBytesConcat(\n first: Uint8Array,\n firstType: string,\n firstSource: string,\n firstStart: number,\n firstEnd: number\n ): CborByteString | CborEllipsis {\n if (this.t.peek().type !== 'PLUS') {\n const ew = this.consumeEncodingIndicator(() => BigInt(first.length));\n const ednEncoding = this._tokenTypeToCdnEncoding(firstType);\n return new CborByteString(first, {\n ednEncoding,\n ednSource: firstSource,\n ednCommentSyntax: this._tokenTypeToCommentSyntax(firstType),\n ...(ew !== undefined ? { encodingWidth: ew } : {}),\n });\n }\n const initial: ByteEllipsisAtom[] = [\n {\n bytes: first,\n source: firstSource,\n commentSyntax: this._tokenTypeToCommentSyntax(firstType),\n real: false,\n start: firstStart,\n end: firstEnd,\n },\n ];\n const atoms = this._consumeByteEllipsisChain(initial);\n return this._buildFromByteAtoms(\n atoms,\n this._tokenTypeToCdnEncoding(firstType)\n );\n }\n\n /**\n * Parse a BYTES_HEX_ELIDED token (h'xx...yy') and any trailing + concatenation\n * into a CborEllipsis([h'xx', 888(null), h'yy', ...]).\n */\n private _parseHexElidedConcat(firstTok: Token): CborEllipsis {\n const atoms = this._consumeByteEllipsisChain(\n this._elidedHexAtoms(firstTok.value, firstTok)\n );\n // Always has at least one ellipsis atom — it came from an elided token.\n return this._buildFromByteAtoms(atoms, 'hex') as CborEllipsis;\n }\n\n /**\n * Consume a `+`-chain of byte-string / `...` / `h'xx...yy'` tokens\n * following an already-parsed first fragment, returning the flattened,\n * source-ordered atom list (`initial` plus everything the chain adds).\n *\n * Each atom carries `real`: whether a genuine `+` from the source\n * precedes it — as opposed to an ellipsis or byte segment that sits\n * *inside* a single `h'xx...yy'` literal's own notation. Two literal\n * tokens can only end up adjacent with no ellipsis between them by\n * sitting across a `+` (a single elided-hex token's internal segments are\n * always ellipsis-separated from each other), so every atom appended here\n * — the first one from each new token, and every atom of a plain\n * (non-elided) byte token — is real; only an elided token's *internal*\n * segments (beyond its first) are not.\n */\n private _consumeByteEllipsisChain(\n initial: ByteEllipsisAtom[]\n ): ByteEllipsisAtom[] {\n const atoms = initial;\n while (this.t.peek().type === 'PLUS') {\n this.t.consume(); // +\n const next = this.t.peek();\n if (next.type === 'ELLIPSIS') {\n this.t.consume();\n atoms.push({\n ellipsis: true,\n real: true,\n fromByteLiteral: false,\n start: next.offset,\n end: next.endOffset,\n });\n } else if (next.type === 'BYTES_HEX_ELIDED') {\n this.t.consume();\n const sub = this._elidedHexAtoms(next.value, next);\n if (sub.length > 0) sub[0]!.real = true;\n pushAll(atoms, sub);\n } else if (this._isBytesToken(next.type)) {\n this.t.consume();\n atoms.push({\n bytes: this._decodeBytesToken(next),\n source: next.raw,\n commentSyntax: this._tokenTypeToCommentSyntax(next.type),\n real: true,\n start: next.offset,\n end: next.endOffset,\n });\n } else if (next.type === 'TSTR' || next.type === 'RAWSTRING') {\n // draft-25 §5.1: when a byte string leads, the right-hand side must also be a\n // byte string. Text strings are only allowed on the right of a\n // text-leading concatenation. In non-strict mode we UTF-8 encode\n // the text and continue; in strict mode this is a hard error.\n this.t.consume();\n const mixMsg =\n 'text string in a byte-string concatenation is not allowed; ' +\n \"use a byte string literal (h'...', b64'...', or '...') instead\";\n this._warnOrFail(mixMsg, next);\n atoms.push({\n bytes: textEncoder.encode(next.value),\n real: true,\n start: next.offset,\n end: next.endOffset,\n });\n } else {\n this._fail(\n `expected byte string after +, got ${JSON.stringify(next.value)}`,\n next\n );\n }\n }\n return atoms;\n }\n\n /** Flatten a single BYTES_HEX_ELIDED token's own `h'xx...yy...zz'` content\n * into atoms, all marked non-`real`: none of its internal segments sit\n * across an actual `+`. Every ellipsis atom is `fromByteLiteral: true` —\n * it came from this literal's own notation, regardless of where within\n * it (leading, trailing, or in the middle). The caller fixes up the very\n * first atom's `real` flag if this token itself followed a `+`. */\n private _elidedHexAtoms(\n hexWithEllipsis: string,\n tok: Token\n ): ByteEllipsisAtom[] {\n const segments = hexWithEllipsis.split('...');\n const atoms: ByteEllipsisAtom[] = [];\n for (let i = 0; i < segments.length; i++) {\n if (i > 0)\n atoms.push({\n ellipsis: true,\n real: false,\n fromByteLiteral: true,\n literalSource: tok.raw,\n start: tok.offset,\n end: tok.endOffset,\n });\n if (segments[i].length > 0) {\n atoms.push({\n bytes: this._hexToBytes(segments[i], tok),\n commentSyntax: 'full',\n real: false,\n start: tok.offset,\n end: tok.endOffset,\n });\n }\n }\n return atoms;\n }\n\n /**\n * Build the final `CborByteString` (no ellipsis anywhere) or `CborEllipsis`\n * from a flattened atom list, consolidating adjacent byte atoms with no\n * ellipsis between them into one `CborByteString` — retaining `ednParts`\n * for a fragment that merged multiple `real` (`+`-joined) atoms — and\n * building a `realBoundary` array parallel to the resulting `CborEllipsis`\n * items, so `preserveConcatenation` can tell real `+` boundaries apart\n * from a `h'xx...yy'` literal's own internal notation regardless of where\n * the `...` falls within it.\n */\n private _buildFromByteAtoms(\n atoms: ByteEllipsisAtom[],\n ednEncoding: 'hex' | 'base64'\n ): CborByteString | CborEllipsis {\n const hasEllipsis = atoms.some((a) => 'ellipsis' in a);\n if (!hasEllipsis) {\n const byteParts = atoms as Array<{\n bytes: Uint8Array;\n source?: string;\n commentSyntax?: ByteCommentSyntax;\n start?: number;\n end?: number;\n }>;\n const concat = this._concatBytes(byteParts.map((p) => p.bytes));\n const ew = this.consumeEncodingIndicator(() => BigInt(concat.length));\n return new CborByteString(concat, {\n ednEncoding,\n ednParts: byteParts,\n ...(ew !== undefined ? { encodingWidth: ew } : {}),\n });\n }\n\n const items: CborItem[] = [];\n const realBoundary: boolean[] = [];\n const pending: Array<{\n bytes: Uint8Array;\n source?: string;\n commentSyntax?: ByteCommentSyntax;\n real: boolean;\n start?: number;\n end?: number;\n }> = [];\n const flushPending = () => {\n if (pending.length > 0) {\n const node = new CborByteString(\n this._concatBytes(pending.map((p) => p.bytes)),\n {\n // A single fragment (no merge across a real `+`) still needs its\n // own source spelling preserved — e.g. the sole byte atom\n // adjacent to an ellipsis in `h'41' + ...` — so\n // `preserveByteString` has something to round-trip.\n ...(pending.length > 1\n ? {\n ednParts: pending.map(\n ({ bytes, source, commentSyntax, start, end }) => ({\n bytes,\n source,\n commentSyntax,\n start,\n end,\n })\n ),\n }\n : {\n ednSource: pending[0]!.source,\n ednCommentSyntax: pending[0]!.commentSyntax,\n }),\n }\n );\n // Stamp the generic start/end span so `attachComments` (run once,\n // after the whole tree is built) can attach a comment between this\n // item and its neighbour in `items` as `leading`/`trailing`, exactly\n // like any other array entry — see `CborEllipsis._renderPreservedBytesElision`.\n node.start = pending[0]!.start;\n node.end = pending[pending.length - 1]!.end;\n items.push(node);\n realBoundary.push(pending[0]!.real);\n pending.length = 0;\n }\n };\n for (const atom of atoms) {\n if ('ellipsis' in atom) {\n flushPending();\n const ellipsisNode = new CborEllipsis(\n atom.fromByteLiteral,\n atom.literalSource\n );\n ellipsisNode.start = atom.start;\n ellipsisNode.end = atom.end;\n items.push(ellipsisNode);\n realBoundary.push(atom.real);\n } else {\n pending.push(atom);\n }\n }\n flushPending();\n\n return new CborEllipsis(items, realBoundary);\n }\n\n private _concatBytes(parts: Uint8Array[]): Uint8Array {\n const total = parts.reduce((n, p) => n + p.byteLength, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const p of parts) {\n out.set(p, off);\n off += p.byteLength;\n }\n return out;\n }\n\n private parseSimple(): CborSimple {\n this.t.consume(); // 'simple'\n this.expect('LPAREN');\n const numTok = this.t.peek();\n if (numTok.type !== 'INTEGER')\n this._fail(\n `expected integer inside simple(), got ${JSON.stringify(numTok.value)}`,\n numTok\n );\n this.t.consume();\n const { numStr } = parseIntegerRaw(numTok.value);\n const n = Number(parseBigInt(numStr));\n this.expect('RPAREN');\n return new CborSimple(n, { ednSource: numTok.raw });\n }\n\n private parseEmbeddedCBOR(): CborEmbeddedCBOR {\n this.t.consume(); // <<\n const items: CborItem[] = [];\n while (this.t.peek().type !== 'GT_GT') {\n if (items.length > 0) {\n if (this.t.peek().type === 'COMMA') {\n this.t.consume();\n if (this.t.peek().type === 'GT_GT') break; // trailing comma\n } else if (this.t.peek().offset === this.t.lastEndOffset) {\n this._warnOrFail(\n '<<...>> items must be separated by \",\" or whitespace',\n this.t.peek()\n );\n }\n }\n items.push(this.parseValue());\n }\n this.expect('GT_GT');\n let encodingWidth: EncodingWidth | undefined;\n if (this.t.peek().type === 'ENCODING_INDICATOR') {\n const eiTok = this.t.consume();\n encodingWidth = this._resolveEncodingWidth(eiTok.value, eiTok);\n }\n return new CborEmbeddedCBOR(items, { encodingWidth });\n }\n\n private parseArray(): CborArray {\n this.t.consume(); // [\n let indefiniteLength = false;\n let encodingWidth: EncodingWidth | undefined;\n let eiTok: Token | undefined;\n if (this.t.peek().type === 'UNDERSCORE') {\n this.t.consume();\n indefiniteLength = true;\n } else if (this.t.peek().type === 'ENCODING_INDICATOR') {\n eiTok = this.t.consume();\n if (eiTok.value === '7') {\n indefiniteLength = true;\n const msg =\n 'encoding indicator _7 is non-standard; use _ to indicate indefinite length';\n this._warnOrFail(msg, eiTok);\n eiTok = undefined;\n } else {\n encodingWidth = this._resolveEncodingWidth(eiTok.value, eiTok);\n }\n }\n // Rescue setup warnings before inner parseValue() calls drain them into child nodes.\n const setupWarnings = this._pendingWarnings.splice(0);\n const items: CborItem[] = [];\n let blankLineBoundary = this.t.lastEndOffset;\n while (this.t.peek().type !== 'RBRACKET') {\n if (items.length > 0) {\n if (this.t.peek().type === 'COMMA') {\n this.t.consume();\n if (this.t.peek().type === 'RBRACKET') break; // trailing comma\n } else if (this.t.peek().offset === this.t.lastEndOffset) {\n this._warnOrFail(\n 'array items must be separated by \",\" or whitespace',\n this.t.peek()\n );\n }\n }\n const item = this.parseValue();\n if (hasBlankLineBetween(this.t.source, blankLineBoundary, item.start!))\n item.blankLineBefore = true;\n blankLineBoundary = item.end!;\n items.push(item);\n }\n this.expect('RBRACKET');\n if (encodingWidth !== undefined && eiTok !== undefined) {\n encodingWidth = this._validateEncodingFit(\n BigInt(items.length),\n encodingWidth,\n eiTok\n );\n // _validateEncodingFit may add to _pendingWarnings; outer parseValue() flushes those.\n }\n const arrayResult = new CborArray(items, {\n indefiniteLength,\n encodingWidth,\n });\n if (setupWarnings.length > 0) {\n arrayResult.warnings ??= [];\n arrayResult.warnings.push(...setupWarnings);\n }\n return arrayResult;\n }\n\n private parseMap(): CborMap {\n this.t.consume(); // {\n let indefiniteLength = false;\n let encodingWidth: EncodingWidth | undefined;\n let eiTok: Token | undefined;\n if (this.t.peek().type === 'UNDERSCORE') {\n this.t.consume();\n indefiniteLength = true;\n } else if (this.t.peek().type === 'ENCODING_INDICATOR') {\n eiTok = this.t.consume();\n if (eiTok.value === '7') {\n indefiniteLength = true;\n const msg =\n 'encoding indicator _7 is non-standard; use _ to indicate indefinite length';\n this._warnOrFail(msg, eiTok);\n eiTok = undefined;\n } else {\n encodingWidth = this._resolveEncodingWidth(eiTok.value, eiTok);\n }\n }\n // Rescue setup warnings before inner parseValue() calls drain them into child nodes.\n const setupWarnings = this._pendingWarnings.splice(0);\n const entries: [CborItem, CborItem][] = [];\n let blankLineBoundary = this.t.lastEndOffset;\n while (this.t.peek().type !== 'RBRACE') {\n if (entries.length > 0) {\n if (this.t.peek().type === 'COMMA') {\n this.t.consume();\n if (this.t.peek().type === 'RBRACE') break; // trailing comma\n } else if (this.t.peek().offset === this.t.lastEndOffset) {\n this._warnOrFail(\n 'map entries must be separated by \",\" or whitespace',\n this.t.peek()\n );\n }\n }\n const key = this.parseValue();\n if (hasBlankLineBetween(this.t.source, blankLineBoundary, key.start!))\n key.blankLineBefore = true;\n this.expect('COLON');\n const val = this.parseValue();\n blankLineBoundary = val.end!;\n entries.push([key, val]);\n }\n this.expect('RBRACE');\n if (encodingWidth !== undefined && eiTok !== undefined) {\n encodingWidth = this._validateEncodingFit(\n BigInt(entries.length),\n encodingWidth,\n eiTok\n );\n }\n const mapResult = new CborMap(entries, { indefiniteLength, encodingWidth });\n if (setupWarnings.length > 0) {\n mapResult.warnings ??= [];\n mapResult.warnings.push(...setupWarnings);\n }\n return mapResult;\n }\n\n /** Parses `(_ chunk, chunk, ...)` — indefinite byte or text string. */\n private parseIndefGroup():\n CborIndefiniteByteString | CborIndefiniteTextString {\n this.t.consume(); // (\n const next = this.t.peek();\n if (next.type === 'UNDERSCORE') {\n this.t.consume(); // _\n } else if (next.type === 'ENCODING_INDICATOR' && next.value === '7') {\n this.t.consume(); // _7 — alias for _, but non-standard\n const msg7 =\n 'encoding indicator _7 is non-standard; use _ to indicate indefinite length';\n this._warnOrFail(msg7, next);\n } else if (next.type === 'ENCODING_INDICATOR') {\n // _0–_6: not meaningful here; warn and drop, then parse chunks\n const tok = this.t.consume();\n const msg = `encoding indicator _${tok.value} is not valid in an indefinite string group; use _`;\n this._warnOrFail(msg, tok);\n } else if (next.type !== 'RPAREN') {\n // No indicator at all — warn that _ is expected, then parse chunks\n const msg =\n 'indefinite string group is missing _ after (; interpreting as (_ ...)';\n this._warnOrFail(msg, next);\n // Do not consume — the next token is the first chunk\n }\n\n // Rescue any warnings emitted above from _pendingWarnings before inner\n // parseValue() calls for each chunk drain them into the wrong node.\n const setupWarnings = this._pendingWarnings.splice(0);\n\n const chunks: CborItem[] = [];\n let blankLineBoundary = this.t.lastEndOffset;\n while (this.t.peek().type !== 'RPAREN') {\n if (chunks.length > 0) {\n if (this.t.peek().type === 'COMMA') {\n this.t.consume();\n if (this.t.peek().type === 'RPAREN') break; // trailing comma\n } else if (this.t.peek().offset === this.t.lastEndOffset) {\n this._warnOrFail(\n 'indefinite string chunks must be separated by \",\" or whitespace',\n this.t.peek()\n );\n }\n }\n const chunk = this.parseValue();\n if (hasBlankLineBetween(this.t.source, blankLineBoundary, chunk.start!))\n chunk.blankLineBefore = true;\n blankLineBoundary = chunk.end!;\n chunks.push(chunk);\n }\n this.expect('RPAREN');\n\n if (chunks.length === 0)\n this._fail(\n 'empty indefinite group (_ ) is ambiguous; use \\'\\'_ for bytes or \"\"_ for text'\n );\n\n const first = chunks[0];\n // All chunks must be the same type — mixing byte and text strings is\n // a SyntaxError per draft §4.3.\n if (first instanceof CborByteString) {\n const byteChunks = chunks.map((c, i) => {\n if (c instanceof CborByteString) return c;\n this._fail(\n `indefinite byte string chunk ${i} must be a byte string, not a text string`\n );\n });\n const result = new CborIndefiniteByteString(byteChunks);\n if (setupWarnings.length > 0) result.warnings = setupWarnings;\n return result;\n }\n if (first instanceof CborTextString) {\n const textChunks = chunks.map((c, i) => {\n if (c instanceof CborTextString) return c;\n this._fail(\n `indefinite text string chunk ${i} must be a text string, not a byte string`\n );\n });\n const result = new CborIndefiniteTextString(textChunks);\n if (setupWarnings.length > 0) result.warnings = setupWarnings;\n return result;\n }\n this._fail('indefinite group chunks must be byte strings or text strings');\n }\n\n // ── Helpers ─────────────────────────────────────────────────────────────\n\n /**\n * Consume an ENCODING_INDICATOR token if present.\n * Validates the indicator type (reserved/indefinite), and when\n * `getStoredValue` is supplied also checks that the value fits in the\n * requested encoding width. The stored value is computed lazily — only\n * when an indicator is actually present — so callers can pass e.g. a\n * UTF-8 byte-length computation without paying for it on every string.\n */\n private consumeEncodingIndicator(\n getStoredValue?: () => bigint,\n onToken?: (token: Token) => void\n ): EncodingWidth | undefined {\n if (this.t.peek().type === 'ENCODING_INDICATOR') {\n const tok = this.t.consume();\n onToken?.(tok);\n let ew = this._resolveEncodingWidth(tok.value, tok);\n if (ew !== undefined && getStoredValue !== undefined) {\n ew = this._validateEncodingFit(getStoredValue(), ew, tok);\n }\n return ew;\n }\n return undefined;\n }\n\n private expect(type: TokenType): Token {\n const tok = this.t.consume();\n if (tok.type !== type)\n this._fail(\n `expected ${type}, got ${tok.type} (${JSON.stringify(tok.value)})`,\n tok\n );\n return tok;\n }\n\n /**\n * Validate that `storedValue` fits in the given encoding width.\n * Returns `ew` if valid; warns and returns `undefined` if not (throws in strict mode).\n * `storedValue` is the CBOR argument: the integer itself for uint/tag, `abs(n)−1` for nint,\n * the byte-length for strings, or the item count for arrays/maps.\n */\n /** Apply an encoding indicator to a parsed app-string / app-sequence result. */\n private _applyEiToResult(\n result: CborItem,\n ew: EncodingWidth,\n tok: Token\n ): void {\n if (result instanceof CborFloat) {\n const targetPrec: FloatPrecision | undefined =\n ew === 1\n ? 'half'\n : ew === 2\n ? 'single'\n : ew === 3\n ? 'double'\n : undefined;\n if (targetPrec === undefined) {\n this._warnOrFail(\n `encoding indicator _${ew} is not valid for a float; use _1, _2, or _3`,\n tok\n );\n } else if (result.precision !== targetPrec) {\n if (targetPrec !== 'double') {\n const rt =\n targetPrec === 'half'\n ? float16BitsToFloat64(float64ToFloat16Bits(result.value))\n : Math.fround(result.value);\n if (!Object.is(rt, result.value) && !isNaN(result.value))\n this._warnOrFail(\n `${result.value} cannot be exactly represented as ${targetPrec === 'half' ? 'float16 (_1)' : 'float32 (_2)'}`,\n tok\n );\n }\n result.precision = targetPrec;\n }\n } else if (result instanceof CborUint) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(result.value, ew, tok);\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborNint) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(result.argument, ew, tok);\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborByteString) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(\n BigInt(result.value.length),\n ew,\n tok\n );\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborTextString) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(\n BigInt(textEncoder.encode(result.value).length),\n ew,\n tok\n );\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborArray) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(\n BigInt(result.items.length),\n ew,\n tok\n );\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborMap) {\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(\n BigInt(result.entries.length),\n ew,\n tok\n );\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else if (result instanceof CborTag) {\n // Per draft-ietf-cbor-edn-literals-27 §4.1, the EI applies to\n // the tag number, not to the content (e.g. 1_1(4711) → 2-byte tag).\n if (result.encodingWidth === undefined) {\n const ewv = this._validateEncodingFit(result.tag, ew, tok);\n if (ewv !== undefined) result.encodingWidth = ewv;\n }\n } else {\n this._warnOrFail(\n `encoding indicator _${ew} is not applicable to this app-string result type`,\n tok\n );\n }\n }\n\n private _validateEncodingFit(\n storedValue: bigint,\n ew: EncodingWidth,\n tok: Token\n ): EncodingWidth | undefined {\n const max = maxForEncodingWidth(ew);\n if (storedValue <= max) return ew;\n const label = ew === 'i' ? '_i (max 23)' : `_${ew} (max ${max})`;\n const msg = `value ${storedValue} does not fit in encoding indicator ${label}`;\n this._warnOrFail(msg, tok);\n return undefined;\n }\n\n private _resolveEncodingWidth(\n raw: string,\n tok: Token\n ): EncodingWidth | undefined {\n if (raw === '4' || raw === '5' || raw === '6') {\n const ai = Number(raw) + 24; // 28, 29, or 30 — reserved in RFC 8949\n const msg = `encoding indicator _${raw} (AI ${ai}) is reserved and not valid`;\n this._warnOrFail(msg, tok);\n return undefined;\n }\n if (raw === '7') {\n const msg =\n 'indefinite-length encoding (_7) is not valid here; use [_ ...] or {_ ...} for indefinite collections';\n this._warnOrFail(msg, tok);\n return undefined;\n }\n if (raw === 'i') return 'i';\n return Number(raw) as EncodingWidth; // '0'–'3' → 0–3\n }\n\n /** Builds the onError callback passed to extension parseAppString/parseAppSequence. */\n private _extOnError(tok: Token): (msg: string) => void {\n return (msg: string) => this._warnOrFail(msg, tok);\n }\n\n /**\n * Record a strict violation: always emits a ParseWarning, and in strict\n * mode (the default) also throws a SyntaxError at the token's location.\n */\n private _warnOrFail(msg: string, tok?: Token): void {\n this._warn(msg, tok);\n if (this._options.strict !== false) this._fail(msg, tok);\n }\n\n /**\n * Emit a one-time, non-fatal hint when a known opt-in extension prefix\n * (b32, h32, float, same, hash, uuid) is used without the corresponding\n * extension registered. Never throws and does not attach node warnings;\n * parsing continues with the usual unresolved-extension handling.\n */\n private _hintMissingExtension(prefix: string, tok: Token): void {\n const hint = MISSING_EXTENSION_HINTS.get(prefix);\n if (hint === undefined || this._hintedPrefixes.has(prefix)) return;\n this._hintedPrefixes.add(prefix);\n const message = `app-string prefix '${prefix}' requires an extension that is not enabled; ${hint}`;\n if (this._options.onWarning) {\n this._options.onWarning({ message, ...tokenPosition(tok), hint: true });\n } else if (!this._options.silent) {\n console.warn(`CDN: ${message}`);\n }\n }\n\n private _warn(msg: string, tok?: Token): void {\n const warning: ParseWarning = { message: msg };\n if (tok !== undefined) Object.assign(warning, tokenPosition(tok));\n this._pendingWarnings.push(warning);\n if (this._options.onWarning) {\n this._options.onWarning(warning);\n } else if (!this._options.silent) {\n const loc = tok ? ` at line ${tok.line}, column ${tok.col}` : '';\n console.warn(`CDN strict violation${loc}: ${msg}`);\n }\n }\n\n private _fail(msg: string, tok?: Token): never {\n throw new CdnSyntaxError(msg, tok ? tokenPosition(tok) : undefined);\n }\n}\n\n/** A token's source position in the shape shared by ParseWarning and CdnSyntaxError. */\nfunction tokenPosition(tok: Token): {\n offset: number;\n line: number;\n column: number;\n endOffset: number;\n} {\n return {\n offset: tok.offset,\n line: tok.line,\n column: tok.col,\n endOffset: tok.endOffset,\n };\n}\n","import type {\n ToCDNOptions,\n ToJSOptions,\n ToCBOROptions,\n CborComment,\n} from '../types';\nimport { CborItem } from './CborItem';\nimport { MT_TEXT } from '../cbor/constants';\nimport type { CborWriter, EncodingWidth } from '../cbor/encode';\nimport { parseCDN } from '../cdn/parser';\n// Internal lexer reuse: parseCDN() validates embedded CDN first; this pass\n// only needs token offsets so string formatting can split without changing text.\nimport { Tokenizer, type TokenType, type SqstrToken } from '../cdn/tokenizer';\nimport {\n escapeString,\n indentOf,\n resolveIndent,\n resolveEiSuffix,\n canonicalEncodingWidth,\n danglingCommentsByGap,\n isMultiWordText,\n joinAppSeqParts,\n pushAll,\n shouldEmitComments,\n resolveCommentStyle,\n} from '../cdn/serialize-utils';\nimport { hexToBytes } from '../utils/hex';\nimport { base64ToBytes } from '../utils/base64';\n\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\nlet didWarnCborEdnTextStringFormat = false;\n\n/** CBOR Major Type 3 — definite-length UTF-8 text string. */\nexport class CborTextString extends CborItem {\n readonly indefiniteLength = false as const;\n readonly value: string;\n encodingWidth: EncodingWidth | undefined;\n /** Part boundaries of the original `+` concatenation chain, if any. */\n readonly ednParts: readonly string[] | undefined;\n /** Original raw-string source text, when parsed from a single backtick literal. */\n readonly ednSource: string | undefined;\n /**\n * Original double-quoted source text (including its escape sequences),\n * when parsed from a single non-concatenated `\"...\"` literal. Used by\n * `_toCDN()` to round-trip the literal's exact spelling when\n * `preserveTextString` is set.\n */\n readonly quotedEdnSource: string | undefined;\n /**\n * Original source text per `ednParts` entry, aligned by index; `undefined`\n * for parts that were not raw backtick literals.\n */\n readonly ednPartSources: readonly (string | undefined)[] | undefined;\n /**\n * `true` at index `i`, aligned with `ednParts`, when that part came from a\n * byte-string literal on the right of a text-leading `+` concatenation\n * (decoded as UTF-8 and merged in per draft-25 §5.1) rather than a double-quoted\n * `\"...\"` literal. Both cases leave `ednPartSources[i]` `undefined` (byte\n * strings have no preserved raw source here, same as an unpreserved\n * double-quoted literal), so this is what lets `appSeqSourceFeatures`\n * attribute the part to `byteString` instead of the unpreservable\n * `textString`.\n */\n readonly ednPartIsByteString: readonly boolean[] | undefined;\n /**\n * Source span of each `ednParts` entry's own literal token, aligned by\n * index — used to place a comment sitting between two `+`-joined parts at\n * the right gap instead of dropping it (there is no per-part AST node for\n * such a comment to attach to; it lands as `dangling` on this whole node\n * instead — see `CborByteString.ednParts`'s equivalent doc). `undefined`\n * for a node not parsed from a `+` chain at all.\n */\n readonly ednPartSpans: readonly { start: number; end: number }[] | undefined;\n\n constructor(\n value: string,\n options?: {\n encodingWidth?: EncodingWidth;\n ednParts?: readonly string[];\n ednSource?: string;\n quotedEdnSource?: string;\n ednPartSources?: readonly (string | undefined)[];\n ednPartIsByteString?: readonly boolean[];\n ednPartSpans?: readonly { start: number; end: number }[];\n }\n ) {\n super();\n this.value = value;\n this.encodingWidth = options?.encodingWidth;\n this.ednParts = options?.ednParts;\n this.ednSource = options?.ednSource;\n this.quotedEdnSource = options?.quotedEdnSource;\n this.ednPartSources = options?.ednPartSources;\n this.ednPartIsByteString = options?.ednPartIsByteString;\n this.ednPartSpans = options?.ednPartSpans;\n }\n\n override _isMultiWordText(\n _options: ToCDNOptions | undefined,\n _strict = true,\n _path?: readonly unknown[]\n ): boolean {\n return isMultiWordText(this.value);\n }\n\n override _encodeTo(writer: CborWriter, _options?: ToCBOROptions): void {\n writer.writeTextString(MT_TEXT, this.value, this.encodingWidth);\n }\n\n _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n _path?: readonly unknown[]\n ): string {\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(textEncoder.encode(this.value).length))\n );\n return formatTextString(\n this.value,\n suffix,\n options,\n depth,\n this.ednParts,\n this.ednSource,\n this.quotedEdnSource,\n this.ednPartSources,\n this.ednPartSpans,\n this.comments?.dangling\n );\n }\n\n _toJS(_options?: ToJSOptions): unknown {\n return this.value;\n }\n}\n\nfunction formatTextString(\n value: string,\n suffix: string,\n options: ToCDNOptions | undefined,\n depth: number,\n ednParts: readonly string[] | undefined,\n ednSource: string | undefined,\n quotedEdnSource: string | undefined,\n ednPartSources: readonly (string | undefined)[] | undefined,\n ednPartSpans: readonly { start: number; end: number }[] | undefined,\n dangling: readonly CborComment[] | undefined\n): string {\n const indentStr = resolveIndent(options);\n // A preserved raw backtick literal is emitted verbatim — re-escaping,\n // re-indenting, or splitting it would change its meaning or its\n // deliberately chosen form. In single-line mode a spelling that spans\n // multiple lines (raw strings are often written that way) cannot be\n // re-emitted, so it falls back to normal escaping instead.\n if (\n options?.preserveRawString &&\n ednSource !== undefined &&\n (indentStr !== null || !/[\\r\\n]/.test(ednSource))\n ) {\n return ednSource + suffix;\n }\n // Likewise for a preserved double-quoted literal: keep its original\n // escape-sequence spelling instead of re-escaping the decoded value.\n if (\n options?.preserveTextString &&\n quotedEdnSource !== undefined &&\n (indentStr !== null || !/[\\r\\n]/.test(quotedEdnSource))\n ) {\n return quotedEdnSource + suffix;\n }\n // Splits and preserved concatenation are layout features, disabled in\n // single-line mode: the string collapses to one literal.\n if (indentStr === null) {\n return escapeString(value) + suffix;\n }\n const partSources = options?.preserveRawString ? ednPartSources : undefined;\n const hasPreservedRawPart =\n partSources?.some((source) => source !== undefined) ?? false;\n const { cdn, newline } = resolveTextStringSplits(options);\n const preservedParts =\n options?.preserveConcatenation &&\n ednParts !== undefined &&\n (ednParts.length > 1 || hasPreservedRawPart)\n ? ednParts\n : undefined;\n\n if (!cdn && !newline && preservedParts === undefined) {\n return escapeString(value) + suffix;\n }\n\n const cdnBreakpoints = cdn\n ? collectCdnBreakpoints(value, !!options?.inlineLeafContainers, newline)\n : null;\n\n // Preserved concatenation applies unless CDN reflow is applicable (the\n // string content parses as CDN — then structure-aware indentation wins).\n // A preserved raw part takes precedence over CDN reflow because changing\n // its spelling would violate preserveRawString. `splitNewline` combines\n // with this path by further splitting only the non-raw parts.\n if (\n preservedParts !== undefined &&\n (cdnBreakpoints === null || hasPreservedRawPart)\n ) {\n // A comment between two `+`-joined parts has no per-part AST node of\n // its own to attach to — it lands as `dangling` on this whole node\n // instead (see `ednPartSpans`'s doc) — so re-derive which gap each one\n // belongs to from each part's own source span.\n const gapComments = shouldEmitComments(options)\n ? danglingCommentsByGap(\n dangling,\n ednPartSpans,\n resolveCommentStyle(options)\n )\n : undefined;\n const parts: StringPart[] = [];\n for (const [i, text] of preservedParts.entries()) {\n const source = partSources?.[i];\n if (source !== undefined) {\n parts.push({ text, contentDepth: 0, source });\n } else if (newline) {\n const partBreakpoints = new Map<number, number>();\n for (const { point, contentDepth } of collectNewlineBreakpoints(\n text,\n 0\n )) {\n partBreakpoints.set(point, contentDepth);\n }\n pushAll(parts, splitAtBreakpoints(text, partBreakpoints));\n } else {\n parts.push({ text, contentDepth: 0 });\n }\n // Whichever output part `text` ended up split into, the comment for\n // the gap right after it (if any) belongs on the last one — the true\n // `+` boundary to the next preserved part sits right there.\n const comments = gapComments?.[i];\n if (comments && comments.length > 0) {\n parts[parts.length - 1]!.commentsAfter = comments;\n }\n }\n if (options?.modernConcat && options?.appPrefix !== false) {\n const literals = parts.map(\n ({ text, source }) => source ?? escapeString(text)\n );\n const midComments = parts.map((p) => p.commentsAfter ?? []);\n return joinAppSeqParts(\n 't1',\n literals,\n suffix,\n indentStr,\n depth,\n midComments\n );\n }\n return emitParts(parts, suffix, indentStr, depth);\n }\n\n const breakpoints = new Map<number, number>();\n if (cdnBreakpoints !== null) {\n for (const { point, contentDepth } of cdnBreakpoints) {\n breakpoints.set(point, contentDepth);\n }\n }\n if (newline) {\n const newlineBreakpoints =\n cdnBreakpoints !== null\n ? collectCdnNewlineBreakpoints(value)\n : collectNewlineBreakpoints(value, 0);\n for (const { point, contentDepth } of newlineBreakpoints) {\n if (!breakpoints.has(point)) {\n breakpoints.set(point, contentDepth);\n }\n }\n }\n\n const parts = splitAtBreakpoints(value, breakpoints);\n if (parts.length <= 1) return escapeString(value) + suffix;\n return emitParts(parts, suffix, indentStr, depth);\n}\n\n/**\n * Serialize string parts as a `+` concatenation chain, one part per\n * continuation line indented by `depth + 1 + contentDepth`. The EI suffix\n * is appended to the last part. Only reached in multi-line mode — preserved\n * concatenation is disabled in single-line output.\n */\nfunction emitParts(\n parts: readonly StringPart[],\n suffix: string,\n indentStr: string,\n depth: number\n): string {\n const literals = parts.map(({ text, source }, i) => {\n const literal = source ?? escapeString(text);\n return i === parts.length - 1 ? literal + suffix : literal;\n });\n let result = literals[0]!;\n for (let i = 1; i < literals.length; i++) {\n const continuationIndent = indentOf(\n indentStr,\n depth + 1 + parts[i]!.contentDepth\n );\n result += ' +\\n';\n for (const comment of parts[i - 1]!.commentsAfter ?? []) {\n result += `${continuationIndent}${comment}\\n`;\n }\n result += `${continuationIndent}${literals[i]}`;\n }\n return result;\n}\n\n/**\n * Resolve the effective split strategies from `splitCdn` / `splitNewline`,\n * falling back per-field to the deprecated array-valued `textStringFormat`.\n */\nfunction resolveTextStringSplits(options: ToCDNOptions | undefined): {\n cdn: boolean;\n newline: boolean;\n} {\n const formats =\n options?.splitCdn === undefined || options?.splitNewline === undefined\n ? normalizeTextStringFormats(options?.textStringFormat ?? [])\n : [];\n return {\n cdn: options?.splitCdn ?? formats.includes('cdn'),\n newline: options?.splitNewline ?? formats.includes('newline'),\n };\n}\n\nfunction normalizeTextStringFormats(\n formats: NonNullable<ToCDNOptions['textStringFormat']>\n): ('newline' | 'cdn')[] {\n return formats.map((format) => {\n if (format !== 'cboredn') return format;\n if (!didWarnCborEdnTextStringFormat) {\n didWarnCborEdnTextStringFormat = true;\n console.warn(\n \"`textStringFormat: ['cboredn']` is deprecated; use `textStringFormat: ['cdn']` instead.\"\n );\n }\n return 'cdn';\n });\n}\n\ninterface StringBreakpoint {\n point: number;\n contentDepth: number;\n}\n\ninterface StringPart {\n text: string;\n contentDepth: number;\n /** Preserved literal source; emitted verbatim instead of escaping `text`. */\n source?: string;\n /**\n * Already-converted comment text that sat right after this part in the\n * source — a genuine `+` boundary this part precedes, not a further split\n * of the same original preserved part — emitted by `emitParts` right\n * before the next part.\n */\n commentsAfter?: string[];\n}\n\nfunction collectNewlineBreakpoints(\n value: string,\n contentDepth: number\n): StringBreakpoint[] {\n const points: StringBreakpoint[] = [];\n for (let i = 0; i < value.length; i++) {\n const ch = value[i];\n if (ch === '\\r') {\n if (value[i + 1] === '\\n') {\n points.push({ point: i + 2, contentDepth });\n i++;\n } else {\n points.push({ point: i + 1, contentDepth });\n }\n } else if (ch === '\\n') {\n points.push({ point: i + 1, contentDepth });\n }\n }\n return points;\n}\n\nfunction collectCdnBreakpoints(\n value: string,\n inlineLeafContainers: boolean,\n newline: boolean\n): StringBreakpoint[] | null {\n try {\n parseCDN(value);\n } catch {\n return null;\n }\n\n // The parse above validates structure. This second tokenizer pass only\n // collects original-source offsets and nesting depth for non-mutating splits.\n const points: StringBreakpoint[] = [];\n const tokenizer = new Tokenizer(value);\n let nesting = 0;\n let pending: {\n point: number;\n contentDepth: number;\n kind: 'opener' | 'comma';\n } | null = null;\n let sawToken = false;\n let lastTokenEnd = 0;\n // The token immediately before the current one (ignoring the EOF/first\n // iteration), used only to tell an integer-tag's `(` (`100(2)`) apart\n // from an indefinite-length string group's `(` (`(_ \"a\", \"b\")`) — both\n // tokenize as a bare LPAREN.\n let prevType: TokenType | null = null;\n\n // Mirrors serializeContainer's `inlineLeafContainers` probe on the real\n // AST, but over token spans instead of rendered strings: a bracket's own\n // breakpoints are held in `ownCandidates` until it closes, then either\n // discarded (stays on one line) or merged into the parent frame (or\n // `points`, at depth 0). Breakpoints inherited from a child that itself\n // couldn't be fully suppressed live separately in `childCandidates` —\n // those are never discardable no matter what this frame decides for its\n // own brackets (see the tag-paren case below), so they always forward.\n //\n // - LBRACKET/LBRACE (array/map) use the strict rule — no entry may\n // contain a nested array/map at any depth (`entryHasContainer`, set on\n // every currently-open frame so it reaches ancestors through wrapper\n // brackets), matching `_containsCdnContainer`.\n // - LT_LT (embedded CBOR) and APP_SEQUENCE (`prefix<<...>>`) use the\n // loose rule — the *only* frames whose own suppression is unconditional\n // (`isLooseFrame`, independent of `inlineLeafContainers`): an entry only\n // has to render without a break of its own (`entryForcedBreak`),\n // regardless of what it contains — matching CborEmbeddedCBOR's\n // `entryIsLeaf`-less, `alwaysInlineLeaf` probe. Resolved app-sequence\n // extensions vary in how they render, but this is the closest\n // approximation without invoking the parser's extension resolution.\n // - LPAREN as an indefinite-length string group (`(_ ...)` /\n // `CborIndefiniteTextString`/`ByteString`) uses the *strict* rule\n // instead, same as LBRACKET/LBRACE (and gated behind\n // `inlineLeafContainers` the same way, unlike LT_LT/APP_SEQUENCE) — a\n // chunk can never actually contain a nested array/map, so this only\n // differs from the loose rule in practice for a prefixed-literal byte\n // chunk (`h'...'`), which disqualifies here but not inside `<<...>>`.\n // - LPAREN as tag content (`100(2)`) has its *own* `(`/`)` breakpoints\n // unconditionally suppressed (once `inlineLeafContainers` is on)\n // regardless of `allOk`: real `CborTag` wraps its content with bare\n // parens (`renderSingleChildWithComments`) that never add their own\n // line break, even when the content itself renders multi-line — only\n // a comment forces it. But content that itself required real breaks\n // (e.g. `100([[1, 2], [3, 4]])`) still needs those breaks to show up\n // and to keep propagating outward — that's exactly what\n // `childCandidates` carries regardless of this frame's own decision.\n //\n // `entryForcedBreak` is only ever set on the immediate parent frame (not\n // eagerly on every ancestor like `entryHasContainer`): forwarding a\n // frame's breakpoints (own, child-inherited, or both) always marks the\n // parent's current entry forced, which in turn forwards *its* parent's\n // entry when it closes — so it cascades upward one level at a time.\n // `anyForcedBreak` is the same signal, but never reset between entries —\n // needed because a tag-paren frame ignores `entryForcedBreak`/`allOk`\n // for its *own* suppression (its parens stay tight either way), yet\n // still must tell its parent a break happened somewhere inside, even\n // when that break produced no breakpoint of its own to carry the\n // signal (e.g. a `splitNewline` break inside a nested string — the\n // actual breakpoint for that is added by a separate pass entirely).\n interface CdnFrame {\n kind: TokenType;\n isTagParen: boolean;\n // `true` for the one frame pushed immediately after `pushChainSuspend`\n // — the outermost bracket/tag of an ellipsis-led chain's own\n // continuation value (`... + (_ \"a\")`, `... + 100(\"a\")`, ...). Used\n // only to decide, when *this exact* frame closes and is a tag-paren,\n // whether a purely semantic multi-word signal from its content may\n // propagate outward — see `entryForcedBreakStructural` and the\n // `CLOSE_TOKENS` handling below.\n isChainContinuationRoot: boolean;\n openOffset: number;\n ownCandidates: StringBreakpoint[];\n childCandidates: StringBreakpoint[];\n entryHasContainer: boolean;\n entryForcedBreak: boolean;\n anyForcedBreak: boolean;\n // Mirrors `entryForcedBreak`/`anyForcedBreak`, but only for a\n // *structural* reason (a real embedded newline, or an actual forwarded\n // breakpoint from a nested container that genuinely expanded) — never\n // for the purely semantic \"this content is multi-word\" reason. A tag\n // never collapses/expands based on its content's word count the way a\n // real container does, and `CborEllipsis`'s own rendering never\n // delegates to a fragment's semantic multi-word-ness either (it only\n // ever joins each fragment's *actual* rendered text) — so when an\n // `isChainContinuationRoot` tag-paren closes, only this structural\n // signal (not the ordinary one) may propagate to the chain state it's\n // about to restore.\n entryForcedBreakStructural: boolean;\n anyForcedBreakStructural: boolean;\n allOk: boolean;\n }\n const stack: CdnFrame[] = [];\n\n const emit = (point: number, contentDepth: number): void => {\n const top = stack[stack.length - 1];\n if (top) top.ownCandidates.push({ point, contentDepth });\n else points.push({ point, contentDepth });\n };\n\n // Only <<...>>/app-sequence are \"loose\" in the sense of always collapsing\n // regardless of inlineLeafContainers (mirrors CborEmbeddedCBOR's\n // `alwaysInlineLeaf`). An indefinite-length string group (non-tag-paren\n // LPAREN) follows the same strict rule as CborArray/CborMap instead,\n // gated behind inlineLeafContainers like everything else — see\n // `suppressible` below.\n const isLooseFrame = (frame: CdnFrame): boolean =>\n frame.kind === 'LT_LT' || frame.kind === 'APP_SEQUENCE';\n\n // A tag-paren frame is transparent for the strict/loose decision — like\n // real CborTag, which just forwards whatever `strict` it was given to its\n // content rather than deciding independently — so a prefixed byte-string\n // literal's forced-break check (see the BYTES_HEX branch below) must walk\n // up past any enclosing tag-paren frames to find the frame whose own\n // strict/loose rule actually governs it (e.g. `<<100(h'00')>>` stays\n // inline: the tag is transparent, and the governing frame is the loose\n // `<<...>>`, not the tag's own parens).\n const nearestRuleFrame = (): CdnFrame | undefined => {\n for (let i = stack.length - 1; i >= 0; i--) {\n const frame = stack[i];\n if (frame.kind === 'LPAREN' && frame.isTagParen) continue;\n return frame;\n }\n return undefined;\n };\n\n // Folds the entry that just ended (at a comma, or at the closing\n // bracket) into the frame's running \"can this stay on one line\" verdict,\n // then resets the per-entry flags for the next entry. Tag-paren frames\n // never gate their own suppression on this — see the class comment\n // above — but `anyForcedBreak` still accumulates for them.\n const foldEntry = (frame: CdnFrame): void => {\n const ok = isLooseFrame(frame)\n ? !frame.entryForcedBreak\n : !frame.entryHasContainer && !frame.entryForcedBreak;\n frame.allOk = frame.allOk && ok;\n frame.anyForcedBreak = frame.anyForcedBreak || frame.entryForcedBreak;\n frame.anyForcedBreakStructural =\n frame.anyForcedBreakStructural || frame.entryForcedBreakStructural;\n frame.entryHasContainer = false;\n frame.entryForcedBreak = false;\n frame.entryForcedBreakStructural = false;\n };\n\n // Chain-aware multi-word tracking for `+`-concatenation, mirroring\n // isMultiWordTokenRange's chain handling in serialize-utils.ts:\n // `\"one \" + \"word\"` denotes one 2-word text string, not two 1-word ones,\n // so checking each TSTR individually (as every other token type in this\n // scan is checked, immediately, in isolation) under-counts. `chainKind`\n // tracks *which* chain (if any) is in progress — not just whether one is,\n // since a byte-leading chain (first part a prefixed `h'...'`/`b64'...'`)\n // must stay marked as such through every continuation part, even a bare\n // `SQSTR` one that would look text-leading in isolation: that\n // continuation is still part of the *byte* string the chain denotes\n // (concatenation never re-spells a byte-leading chain as one bare\n // `sqstr`), so it must not start its own independent text-leading\n // sub-chain — a byte-leading chain already forces a break unconditionally\n // via the existing BYTES_HEX/etc branch (on its first token, regardless\n // of continuation), independent of chain length, so `finalizeChain` never\n // needs to check anything for one. Only a text-leading chain (first part\n // TSTR/RAWSTRING/bare SQSTR — the same types the branches below check by\n // decoded word count rather than always-strict) accumulates into\n // `chainTexts`. `chainBroken` marks a part that couldn't be decoded\n // (elided hex, an elision-chain `...` link, or a malformed part that\n // shouldn't occur in this library's own output but isn't assumed) so a\n // text-leading chain is never falsely flagged from incomplete data.\n let chainKind: 'none' | 'text' | 'byte' = 'none';\n let chainTexts: string[] = [];\n let chainBroken = false;\n // Whether the chain currently in progress has seen at least one\n // `ELLIPSIS` link and at least one real `+` — i.e. it's a genuine elision\n // *chain* (`\"a\" + ...`, `... + h'00'`, `... + (_ \"a\")`, ...), not a bare\n // standalone `...` with nothing to concatenate at all. See `finalizeChain`\n // for why that distinction matters.\n let chainHasEllipsis = false;\n let chainSawPlus = false;\n // `true` right after an `INTEGER` was seen as an ellipsis-led chain's\n // continuation start — `parseValue()` accepts a bare integer *or* a tag\n // (`INTEGER [ENCODING_INDICATOR] LPAREN ... RPAREN`) there, and the two\n // aren't distinguishable until the token right after the integer (and its\n // own possible encoding indicator) is seen: `LPAREN` means it's a tag\n // (pushes into bracket tracking, same as any other bracketed\n // continuation, below); anything else means it was just a bare integer,\n // and that token is re-resolved as an ordinary chain-continuation check\n // instead.\n let chainAwaitingTagCheck = false;\n\n interface SavedChainState {\n depth: number;\n kind: 'none' | 'text' | 'byte';\n texts: string[];\n broken: boolean;\n hasEllipsis: boolean;\n sawPlus: boolean;\n awaitingTagCheck: boolean;\n }\n // A stack of *saved* (outer) chain states, one per bracketed value\n // currently being scanned as a continuation of an ellipsis-led chain\n // (`... + (_ \"a\")`, `... + [1, 2]`, ...) — only an ellipsis-led chain's\n // continuations can be arbitrary value shapes at all (the restricted\n // string/byte-literal-led grammar never allows one), matching\n // consumeOneItem's recursive handling in serialize-utils.ts. Pushing\n // saves the outer chain exactly as it was and resets the live\n // `chainKind`/etc. variables to a *fresh*, empty chain — the bracket's own\n // content is scanned completely normally against that fresh chain (its\n // own entries need their own, ordinary multi-word tracking; suspending\n // that entirely, an earlier version of this fix's bug, silently dropped\n // e.g. `[\"two words\"]`'s own multi-word check). Each entry's `depth` is\n // the `nesting` level from *before* that bracket opened, so its own\n // matching close (nesting back down to this value) can be recognized\n // regardless of further brackets nested inside it — popping then restores\n // the outer chain exactly as it was, so a further `+` after the bracket\n // resumes the *same* chain rather than starting a new one.\n const chainSuspendStack: SavedChainState[] = [];\n // One-shot: set by `pushChainSuspend`, consumed by the very next\n // `OPEN_TOKENS` push (which is always the bracket/tag that triggered the\n // suspend, in the same iteration) to mark that frame\n // `isChainContinuationRoot`.\n let nextFrameIsChainContinuationRoot = false;\n\n const pushChainSuspend = (depth: number): void => {\n chainSuspendStack.push({\n depth,\n kind: chainKind,\n texts: chainTexts,\n broken: chainBroken,\n hasEllipsis: chainHasEllipsis,\n sawPlus: chainSawPlus,\n awaitingTagCheck: chainAwaitingTagCheck,\n });\n chainKind = 'none';\n chainTexts = [];\n chainBroken = false;\n chainHasEllipsis = false;\n chainSawPlus = false;\n chainAwaitingTagCheck = false;\n nextFrameIsChainContinuationRoot = true;\n };\n\n const popChainSuspendIfDepthMatches = (): void => {\n const saved = chainSuspendStack[chainSuspendStack.length - 1];\n if (saved !== undefined && nesting === saved.depth) {\n chainSuspendStack.pop();\n chainKind = saved.kind;\n chainTexts = saved.texts;\n chainBroken = saved.broken;\n chainHasEllipsis = saved.hasEllipsis;\n chainSawPlus = saved.sawPlus;\n chainAwaitingTagCheck = saved.awaitingTagCheck;\n }\n };\n\n const finalizeChain = (): void => {\n if (chainHasEllipsis && chainSawPlus) {\n // An elision chain resolves, in the real AST, to a `CborEllipsis`\n // wrapping a `CborArray` of fragments (see `src/cdn/parser.ts`'s\n // `concatenate()`) — a *container*-shaped node per\n // `CborArray._containsCdnContainer` (always `true`) and\n // `CborTag._containsCdnContainer` (delegates to its content) — even\n // though its own written source has no literal `[`/`{` of its own.\n // So it disqualifies a strict array/map's inlining the same way an\n // actual nested `[...]`/`{...}` would (mirrors the `LBRACKET`/\n // `LBRACE` handling below: propagated to *every* open frame, since a\n // nested container disqualifies every ancestor's current entry no\n // matter how deep it sits), regardless of what the word-count check\n // above concludes. A loose frame (`<<...>>`/app-sequence) ignores\n // `entryHasContainer` entirely in its own `foldEntry` check, so\n // setting it unconditionally here is safe — it only has an effect\n // where the strict rule already looks at it. A truly standalone bare\n // `...` (no `+` at all, `chainSawPlus` stays `false`) does *not* get\n // this: it resolves to `CborEllipsis(CborSimple.NULL)` — no array, no\n // container.\n for (const frame of stack) frame.entryHasContainer = true;\n }\n if (chainKind === 'text' && !chainBroken && chainTexts.length > 0) {\n if (isMultiWordText(chainTexts.join(''))) {\n const top = stack[stack.length - 1];\n if (top) top.entryForcedBreak = true;\n }\n }\n chainKind = 'none';\n chainTexts = [];\n chainBroken = false;\n chainHasEllipsis = false;\n chainSawPlus = false;\n chainAwaitingTagCheck = false;\n };\n\n for (;;) {\n const token = tokenizer.consume();\n if (token.type === 'EOF') {\n finalizeChain();\n break;\n }\n let skipClosePoint = false;\n\n // A chain can still be waiting to continue past `PLUS`, an\n // `ENCODING_INDICATOR` trailing an individual part, straight into the\n // next chained literal or elision-chain `...` link, or (for an\n // ellipsis-led chain specifically, whose continuations aren't\n // restricted to string/byte literals at all — `parseValue()` in\n // src/cdn/parser.ts accepts *any* value there) into a bracketed value,\n // a tag, or a bare atom — anything else means it's over, and must be\n // resolved before this token's own handling (e.g. a closing bracket\n // popping the frame the chain's break belongs on). This always\n // operates on whatever the *current* chain is — the outer one, or (see\n // `chainSuspendStack`) a bracketed continuation's own fresh one, once\n // pushed — never anything that needs its own suspension.\n let chainContinuationResolved = false;\n if (chainAwaitingTagCheck) {\n if (token.type === 'ENCODING_INDICATOR') {\n // Still deciding — this is the integer's own encoding indicator;\n // wait for what follows it.\n chainContinuationResolved = true;\n } else if (token.type === 'LPAREN') {\n // It's a tag after all (`100(...)`, `100_1(...)`): push into the\n // same bracket tracking as any other bracketed continuation —\n // `nesting` is incremented for this same `LPAREN` by the ordinary\n // `OPEN_TOKENS` handling below, in this same iteration.\n chainAwaitingTagCheck = false;\n pushChainSuspend(nesting);\n chainContinuationResolved = true;\n } else {\n // Just a bare integer after all — fall through to the ordinary\n // check below for this same token, as if nothing special had\n // intervened (mirrors consumeOneItem's own \"not a tag, return\n // p\" — the integer's own extent already ended).\n chainAwaitingTagCheck = false;\n }\n }\n if (!chainContinuationResolved) {\n const chainCanContinueHere =\n token.type === 'PLUS' ||\n token.type === 'ENCODING_INDICATOR' ||\n (prevType === 'PLUS' &&\n (STRINGISH_CHAIN_TYPES.has(token.type) || token.type === 'ELLIPSIS'));\n if (chainKind !== 'none' && !chainCanContinueHere) {\n if (prevType === 'PLUS' && chainHasEllipsis) {\n if (OPEN_TOKENS.has(token.type)) {\n // An ellipsis-led chain's continuation may itself be an\n // arbitrary bracketed value (`... + (_ \"a\")`, `... + [1, 2]`,\n // ...) — push a fresh chain for this bracket's own content\n // (handled entirely normally below, on its own frame, exactly\n // like a standalone entry — it needs its *own* ordinary\n // multi-word tracking, e.g. `[\"two words\"]`'s own entry, not a\n // suspension that would silently skip it) rather than\n // finalizing the outer one.\n pushChainSuspend(nesting);\n } else if (token.type === 'INTEGER') {\n // Could be a bare integer continuation, or the start of a tag\n // (`100(...)`) — not distinguishable yet; resolved on the next\n // token, above.\n chainAwaitingTagCheck = true;\n }\n // Any other bare atom (a float, a simple value, ...): the\n // continuation is exactly this one token (plus an optional\n // trailing encoding indicator, already deferred by the\n // unconditional `ENCODING_INDICATOR` clause above) — nothing to\n // track, since none of the chain-state-mutating branches below\n // match any of these token types anyway; just don't finalize\n // here, and let the *next* token's own check (this token's type\n // becomes the new `prevType`, not `PLUS`) decide normally\n // whether the chain continues (`+`) or ends.\n } else {\n finalizeChain();\n }\n }\n if (token.type === 'PLUS' && chainKind !== 'none') {\n chainSawPlus = true;\n }\n }\n\n if (!sawToken) {\n sawToken = true;\n if (\n token.offset > 0 &&\n hasCommentBetween(tokenizer.comments, 0, token.offset)\n ) {\n emit(token.offset, nesting);\n }\n }\n\n // After an opener/comma, split before the next token so intervening layout\n // whitespace stays at the end of the previous chunk.\n if (pending !== null) {\n if (pending.kind === 'opener' && OPENER_MODIFIER_TOKENS.has(token.type)) {\n pending.point = token.endOffset;\n prevType = token.type;\n lastTokenEnd = token.endOffset;\n continue;\n } else if (\n pending.kind === 'opener' &&\n CLOSE_TOKENS.has(token.type) &&\n hasOnlyWhitespaceBetween(value, pending.point, token.offset)\n ) {\n skipClosePoint = true;\n } else {\n emit(token.offset, pending.contentDepth);\n }\n pending = null;\n }\n\n if (OPEN_TOKENS.has(token.type)) {\n if (token.type === 'LBRACKET' || token.type === 'LBRACE') {\n // A nested array/map disqualifies every ancestor's current entry\n // from the strict leaf rule, no matter how deep it sits.\n for (const frame of stack) frame.entryHasContainer = true;\n }\n nesting++;\n pending = {\n point: token.endOffset,\n contentDepth: nesting,\n kind: 'opener',\n };\n stack.push({\n kind: token.type,\n isTagParen: token.type === 'LPAREN' && prevType === 'INTEGER',\n isChainContinuationRoot: nextFrameIsChainContinuationRoot,\n openOffset: token.offset,\n ownCandidates: [],\n childCandidates: [],\n entryHasContainer: false,\n entryForcedBreak: false,\n anyForcedBreak: false,\n entryForcedBreakStructural: false,\n anyForcedBreakStructural: false,\n allOk: true,\n });\n nextFrameIsChainContinuationRoot = false;\n } else if (CLOSE_TOKENS.has(token.type)) {\n nesting = Math.max(0, nesting - 1);\n // If this closes the bracket that pushed a fresh chain for an\n // ellipsis-led chain's continuation, restore the outer chain exactly\n // as it was before that (matching brackets nested inside it, if any,\n // already came and went via their own push/pop) — the very next\n // iteration's `chainCanContinueHere` check then decides, from that\n // restored state, whether a further `+` continues it or it's time to\n // finalize. The fresh chain this bracket's own content was using (if\n // any) was already finalized against *this* frame by the top-of-loop\n // check earlier in this same iteration, before it's popped below.\n popChainSuspendIfDepthMatches();\n if (!skipClosePoint) {\n emit(token.offset, nesting);\n }\n const frame = stack.pop();\n if (frame) {\n foldEntry(frame);\n const isTag = frame.kind === 'LPAREN' && frame.isTagParen;\n // A loose frame (LT_LT/APP_SEQUENCE) collapses onto one line\n // whenever it fits regardless of inlineLeafContainers — mirrors\n // serializeContainer's `alwaysInlineLeaf`, since there's no\n // structural reason to ever spread a flat encoded-item sequence one\n // item per line if it fits. Everything else — array/map brackets,\n // tag parens, *and* an indefinite-length string group's parens\n // (LPAREN, tag or not) — stays gated behind inlineLeafContainers.\n const suppressible = isLooseFrame(frame)\n ? true\n : inlineLeafContainers &&\n (frame.kind === 'LBRACKET' ||\n frame.kind === 'LBRACE' ||\n frame.kind === 'LPAREN');\n const suppressOwn =\n suppressible &&\n frame.ownCandidates.length > 0 &&\n (isTag || frame.allOk) &&\n !hasCommentBetween(\n tokenizer.comments,\n frame.openOffset,\n token.endOffset\n );\n // Child-inherited breakpoints always forward, regardless of what\n // this frame decided for its own brackets — they represent breaks\n // some descendant already determined were unavoidable.\n const forwarded = suppressOwn\n ? frame.childCandidates\n : [...frame.ownCandidates, ...frame.childCandidates];\n const parent = stack[stack.length - 1];\n // Looped rather than `push(...forwarded)`: spreading a huge array\n // as call arguments can exceed the engine's argument-count limit\n // (a ~130k-item CDN array reproduces a RangeError here).\n if (parent) {\n for (const candidate of forwarded) {\n parent.childCandidates.push(candidate);\n }\n // Even when nothing here produced a breakpoint of its own to\n // carry forward (a suppressed tag paren whose content still had\n // a forced break somewhere inside it), the break itself still\n // happened and still needs to reach the parent — *unless* this\n // frame is the outermost bracket/tag of an ellipsis-led chain's\n // continuation (`isChainContinuationRoot`) and a tag-paren\n // specifically: closing it is about to restore the chain state\n // it was pushed to protect, and only a *structural* reason (a\n // real newline, or an actual forwarded breakpoint) should reach\n // that restored chain — a purely semantic \"my content is\n // multi-word\" signal has no real analogue there (see\n // `entryForcedBreakStructural`'s doc; `CborEllipsis`'s own\n // rendering never delegates to a fragment's semantic\n // multi-word-ness, only its actual rendered text).\n const hasStructuralBreak =\n forwarded.length > 0 || frame.anyForcedBreakStructural;\n const shouldPropagate =\n frame.isChainContinuationRoot && frame.isTagParen\n ? hasStructuralBreak\n : forwarded.length > 0 || frame.anyForcedBreak;\n if (shouldPropagate) {\n parent.entryForcedBreak = true;\n }\n if (hasStructuralBreak) {\n parent.entryForcedBreakStructural = true;\n }\n } else {\n for (const candidate of forwarded) {\n points.push(candidate);\n }\n }\n }\n } else if (token.type === 'COMMA') {\n const top = stack[stack.length - 1];\n if (top) foldEntry(top);\n pending = {\n point: token.endOffset,\n contentDepth: nesting,\n kind: 'comma',\n };\n } else if (token.type === 'TSTR' || token.type === 'RAWSTRING') {\n // A literal/escaped newline inside this token will itself become a\n // breakpoint once `splitNewline` runs (merged in by the caller,\n // outside this function) — that forces this entry's own rendering\n // to contain a line break, exactly like a child bracket that\n // couldn't be suppressed. Mirrors serializeContainer's `s.includes\n // ('\\n')` check on a rendered entry.\n const tokenText = value.slice(token.offset, token.endOffset);\n const hasNewline =\n newline &&\n (token.type === 'TSTR'\n ? collectTstrNewlineBreakpoints(tokenText).length > 0\n : collectNewlineBreakpoints(tokenText, 0).length > 0);\n // A literal/escaped newline always forces a break immediately,\n // independent of concatenation. Not gated on `inlineLeafContainers`\n // here — setting `entryForcedBreak` is a no-op whenever the\n // enclosing frame isn't suppressible anyway (see `suppressible`\n // above), so this stays correct for a loose frame's unconditional\n // collapse too, without needing to know which case applies at this\n // point in the scan.\n if (hasNewline) {\n const top = stack[stack.length - 1];\n if (top) {\n top.entryForcedBreak = true;\n // A real, literal newline — unlike the multi-word check just\n // below — is a genuinely structural fact that would show up in\n // the actual rendered text regardless of what wraps it; see\n // `entryForcedBreakStructural`'s doc.\n top.entryForcedBreakStructural = true;\n }\n }\n // Multi-word-ness (mirrors serializeContainer's `entryIsMultiWordText`\n // probe) is chain-aware: append to an in-progress text-leading chain\n // continuation, or start a new (possibly single-part) one — resolved\n // by `finalizeChain` once the chain is known to be over (see above).\n // Always operates on whichever chain is *current* (see\n // `chainSuspendStack`) — a bracketed continuation's own fresh chain\n // needs this exact same tracking for its own entries (e.g. a plain\n // `\"two words\"` inside `... + [\"two words\"]`), not a suspension that\n // would silently skip it.\n if (prevType === 'PLUS' && chainKind === 'text') {\n chainTexts.push(token.value);\n } else {\n chainKind = 'text';\n chainTexts = [token.value];\n chainBroken = false;\n }\n } else if (token.type === 'SQSTR') {\n // A bare sqstr byte-string literal (`'...'`) is printable text by\n // construction — mirrors CborByteString._isMultiWordText's sqstr\n // branch. `.value` holds hex bytes for SQSTR (byte-string convention),\n // so the decoded UTF-8 payload comes from `_sqstrBytes` instead. As a\n // *continuation* of an already-byte-leading chain (`h'' + 'two\n // words'`), though, it must NOT start its own independent\n // text-leading chain — see the `chainKind` block comment above; it's\n // still just a further byte span of that same byte string, already\n // exempted from the multi-word check by the byte-leading chain's own\n // start (the BYTES_HEX/etc branch below). Always operates on\n // whichever chain is *current*, same as the TSTR/RAWSTRING branch\n // above.\n if (prevType === 'PLUS' && chainKind === 'byte') {\n // no-op: part of an already-exempt byte-leading chain\n } else {\n const bytes = (token as SqstrToken)._sqstrBytes;\n const decoded = bytes ? textDecoder.decode(bytes) : null;\n if (prevType === 'PLUS' && chainKind === 'text') {\n if (decoded === null) chainBroken = true;\n else chainTexts.push(decoded);\n } else {\n chainKind = 'text';\n chainTexts = decoded !== null ? [decoded] : [];\n chainBroken = decoded === null;\n }\n }\n } else if (\n token.type === 'BYTES_HEX' ||\n token.type === 'BYTES_HEX_ELIDED' ||\n token.type === 'BYTES_B64' ||\n token.type === 'APP_STRING'\n ) {\n if (prevType === 'PLUS' && chainKind === 'text') {\n // A continuation of a *text*-leading chain (`\"a\" + h'62'`) is\n // decoded and merged into the accumulated text instead — the\n // unconditional \"always strict\" rule below only applies when *this*\n // token is what fixes the chain's element type (byte-leading, or\n // standalone); a byte-shaped *continuation* of an already\n // text-leading chain doesn't get its own independent say — the\n // combined word count, computed once the chain ends, is what\n // decides it, exactly like isMultiWordTokenRange's chain decoding\n // in serialize-utils.ts (`\"a\" + h'62'` merges to `\"ab\"`, one word,\n // and must not be disqualified just because one part happened to\n // be spelled as `h'62'`). APP_STRING never participates in\n // concatenation (draft-25 §5.1), so it never continues one; `BYTES_HEX_ELIDED`'s\n // missing data can't be decoded, so it always breaks the chain\n // instead of silently under-counting.\n let decoded: string | null = null;\n try {\n if (token.type === 'BYTES_HEX') {\n decoded = textDecoder.decode(hexToBytes(token.value));\n } else if (token.type === 'BYTES_B64') {\n decoded = textDecoder.decode(base64ToBytes(token.value));\n }\n } catch {\n decoded = null;\n }\n if (decoded === null) chainBroken = true;\n else chainTexts.push(decoded);\n } else {\n // Mirrors CborByteString._isMultiWordText's prefixed-literal branch\n // (and, via APP_STRING, `isPrefixedLiteralText`'s generic catch-all\n // for other app-string extensions like `ip'...'`/`dt'...'`, which\n // count only when their own content is multi-word): byte literals\n // have no natural word boundaries to check, so they always count\n // as multi-word under the strict rule (array/map, and — unlike a\n // multi-word text entry — an indefinite-length string group too) —\n // but the *only* loose frame (`<<...>>`/app-sequence) treats it as\n // an ordinary leaf instead, e.g. `<<h'00'>>`/`<<ip'...'>>` stay\n // inline while `(_ h'00')` still breaks. The governing frame is\n // found by `nearestRuleFrame`, not just `top`, since an enclosing\n // tag paren is transparent to this decision. This unconditional\n // check applies whether this literal starts a byte-leading chain or\n // stands alone — a byte-leading chain is never re-spelled as one\n // bare `sqstr`, so it disqualifies the same way a lone prefixed\n // literal already does, independent of chain length (see\n // serialize-utils.ts's isMultiWordTokenRange for the same\n // reasoning) — but *not* when it's really a continuation of a\n // text-leading chain, handled above instead.\n const top = stack[stack.length - 1];\n const ruleFrame = nearestRuleFrame();\n if (\n top &&\n (!ruleFrame || !isLooseFrame(ruleFrame)) &&\n (token.type !== 'APP_STRING' || isMultiWordText(token.value))\n ) {\n top.entryForcedBreak = true;\n }\n if (prevType !== 'PLUS' || chainKind === 'none') {\n // Not a continuation — this token starts a fresh, byte-leading\n // chain (or stands alone, which is the same thing as a one-part\n // chain). Recorded so a *following* continuation part (including\n // a bare SQSTR, which would otherwise look text-leading in\n // isolation) is correctly recognized as still belonging to this\n // byte-leading chain rather than starting an independent one.\n chainKind = 'byte';\n }\n }\n } else if (token.type === 'ELLIPSIS') {\n // An elision-chain link (`\"a\" + ...`, or leading — `... + \"b\"`, an\n // unknown prefix concatenated with a known suffix — CDN's notation\n // for a value with a part deliberately omitted; see\n // serialize-utils.ts's `CHAIN_ATOM_TYPES` for the same grammar,\n // accepted both as a chain's own first value and as any later\n // continuation). Either way its missing content makes the *combined*\n // word count of the whole chain unknowable, never just this part's —\n // so as a *continuation* of a text-leading chain, it poisons that\n // chain (without ending it — more parts may still follow) rather\n // than silently under-counting from only the visible parts; as a\n // *fresh start* (nothing to continue), it begins one already\n // poisoned, so a *later* continuation part (including a bare SQSTR,\n // which would otherwise look like its own fresh text-leading start)\n // is still recognized as belonging to this now-indeterminate chain\n // instead of starting an independent one. A byte-leading chain\n // doesn't track decoded text at all, so there's nothing to poison\n // there. Set unconditionally, regardless of which case below applies\n // (including a continuation of a *byte*-kind chain, e.g. `h'00' +\n // ...`, which none of those cases otherwise touch) — see\n // `finalizeChain`'s `chainHasEllipsis`/`chainSawPlus` check for why a\n // truly standalone `...` (this flag set, but `chainSawPlus` never\n // becomes true) is harmless. Always operates on whichever chain is\n // *current* — an `ELLIPSIS` inside an ellipsis-led chain's own\n // bracketed continuation, if that's even reachable, correctly poisons\n // *that* (fresh, pushed) chain rather than the outer one.\n chainHasEllipsis = true;\n if (prevType === 'PLUS' && chainKind === 'text') {\n chainBroken = true;\n } else if (prevType !== 'PLUS' || chainKind === 'none') {\n chainKind = 'text';\n chainTexts = [];\n chainBroken = true;\n }\n }\n prevType = token.type;\n lastTokenEnd = token.endOffset;\n }\n\n const trailingComment = tokenizer.comments.find(\n (comment) => comment.start >= lastTokenEnd\n );\n if (trailingComment !== undefined) {\n points.push({ point: trailingComment.start, contentDepth: nesting });\n }\n return points;\n}\n\nfunction collectCdnNewlineBreakpoints(value: string): StringBreakpoint[] {\n const points: StringBreakpoint[] = [];\n const tokenizer = new Tokenizer(value);\n let nesting = 0;\n for (;;) {\n const token = tokenizer.consume();\n if (token.type === 'EOF') break;\n\n if (OPEN_TOKENS.has(token.type)) {\n nesting++;\n } else if (CLOSE_TOKENS.has(token.type)) {\n nesting = Math.max(0, nesting - 1);\n } else if (token.type === 'COMMA') {\n // Commas can create structural split points, but never contain newline\n // split points themselves.\n } else if (token.type === 'TSTR') {\n // TSTR uses escape sequences (\\n, \\r) for newlines in addition to\n // literal newline characters.\n const tokenText = value.slice(token.offset, token.endOffset);\n for (const point of collectTstrNewlineBreakpoints(tokenText)) {\n points.push({ point: token.offset + point, contentDepth: nesting + 1 });\n }\n } else if (token.type === 'RAWSTRING') {\n // RAWSTRING has no escape sequences; only literal newlines apply.\n const tokenText = value.slice(token.offset, token.endOffset);\n for (const { point } of collectNewlineBreakpoints(tokenText, 0)) {\n points.push({ point: token.offset + point, contentDepth: nesting + 1 });\n }\n }\n }\n return points;\n}\n\n// Scans the raw source of a CDN double-quoted string (TSTR) for newline\n// escape sequences (\\n, \\r) and literal newline characters, returning the\n// position within tokenText immediately after each such sequence.\nfunction collectTstrNewlineBreakpoints(tokenText: string): number[] {\n const points: number[] = [];\n let i = 1; // skip opening \"\n const end = tokenText.length - 1; // stop before closing \"\n while (i < end) {\n const ch = tokenText[i];\n if (ch === '\\\\') {\n const next = tokenText[i + 1];\n if (next === 'n' || next === 'r') {\n points.push(i + 2);\n i += 2;\n } else if (next === 'u') {\n if (tokenText[i + 2] === '{') {\n const close = tokenText.indexOf('}', i + 3);\n i = close >= 0 ? close + 1 : i + 2;\n } else {\n i += 6; // \\uXXXX\n }\n } else {\n i += 2; // \\\\, \\\", \\t, etc.\n }\n } else if (ch === '\\r') {\n if (tokenText[i + 1] === '\\n') {\n points.push(i + 2);\n i += 2;\n } else {\n points.push(i + 1);\n i++;\n }\n } else if (ch === '\\n') {\n points.push(i + 1);\n i++;\n } else {\n i++;\n }\n }\n return points;\n}\n\nconst OPENER_MODIFIER_TOKENS = new Set<TokenType>([\n 'ENCODING_INDICATOR',\n 'UNDERSCORE',\n]);\n\nconst OPEN_TOKENS = new Set<TokenType>([\n 'LBRACKET',\n 'LBRACE',\n 'LPAREN',\n 'LT_LT',\n // `prefix<<` (app-sequence) is tokenized as one token, unlike a plain\n // `<<`; its close is still a separate GT_GT (in CLOSE_TOKENS), so it\n // must be tracked as an opener here too or nesting/frame bookkeeping\n // desyncs on the matching close.\n 'APP_SEQUENCE',\n]);\n\nconst CLOSE_TOKENS = new Set<TokenType>([\n 'RBRACKET',\n 'RBRACE',\n 'RPAREN',\n 'GT_GT',\n]);\n\n// Token types that can appear as one part of a `+`-concatenation chain\n// (draft-25 §5.1) — mirrors `STRINGISH_TYPES` in serialize-utils.ts.\nconst STRINGISH_CHAIN_TYPES = new Set<TokenType>([\n 'TSTR',\n 'RAWSTRING',\n 'SQSTR',\n 'BYTES_HEX',\n 'BYTES_HEX_ELIDED',\n 'BYTES_B64',\n]);\n\nfunction hasCommentBetween(\n comments: readonly { start: number; end: number }[],\n start: number,\n end: number\n): boolean {\n // Comments use half-open source ranges; this checks for comments wholly\n // contained in [start, end), including one that ends exactly at `end`.\n return comments.some(\n (comment) => comment.start >= start && comment.end <= end\n );\n}\n\nfunction hasOnlyWhitespaceBetween(\n value: string,\n start: number,\n end: number\n): boolean {\n return /^[\\t\\n\\r ]*$/.test(value.slice(start, end));\n}\n\nfunction splitAtBreakpoints(\n value: string,\n breakpoints: Map<number, number>\n): StringPart[] {\n const points = [...breakpoints]\n .filter(([point]) => point > 0 && point < value.length)\n .sort(([a], [b]) => a - b);\n if (points.length === 0) return [{ text: value, contentDepth: 0 }];\n\n const parts: StringPart[] = [];\n let start = 0;\n let contentDepth = 0;\n for (const [point, nextContentDepth] of points) {\n if (point === start) continue;\n parts.push({ text: value.slice(start, point), contentDepth });\n start = point;\n contentDepth = nextContentDepth;\n }\n if (start < value.length) {\n parts.push({ text: value.slice(start), contentDepth });\n }\n return parts;\n}\n","/**\n * Standard CDN \"dt\" / \"DT\" app-extension (§3.2 of draft-ietf-cbor-edn-literals-27).\n *\n * Parses RFC 3339 date-time app-strings into epoch-based numeric CBOR values.\n * The resulting CborItem subclasses override toCDN() so the value round-trips\n * back to dt'...' / DT'...' notation.\n *\n * For a richer variant that makes toJS() return Date objects, use dt_as_Date\n * from ./date instead.\n */\n\nimport type {\n ToCDNOptions,\n ToJSOptions,\n ReadonlyToJSNodeOptions,\n FromJSOptions,\n} from '../types';\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborFloat } from '../ast/CborFloat';\nimport { CborTag } from '../ast/CborTag';\nimport type { EncodingWidth } from '../cbor/encode';\nimport { autoSelectFloatPrecision } from '../cbor/encode';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborByteString } from '../ast/CborByteString';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n floatSuffix,\n decideTaggedAppSeqRendering,\n adjustRawAppSeqSource,\n adjustAppSeqIndicator,\n} from '../cdn/serialize-utils';\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Convert epoch seconds to an RFC 3339 string with appropriate precision.\n *\n * - Integer epoch → \"…Z\" (no fractional part)\n * - Millisecond-precision → \"….SSSZ\" (3 decimal places, e.g. \".500Z\")\n * - Sub-millisecond → \"….S…Z\" (minimal digits, e.g. \".0001Z\")\n *\n * Millisecond precision is used whenever `Math.round(epochSeconds * 1000)`\n * round-trips back to the same float64 value, which is the common case for\n * timestamps stored as integer milliseconds (the JavaScript Date range).\n * Otherwise the shortest decimal representation of the fractional seconds is\n * used so that the float64 value is faithfully represented.\n */\nexport function epochToRfc3339(epochSeconds: number): string {\n if (Number.isInteger(epochSeconds))\n return new Date(epochSeconds * 1000).toISOString().replace(/\\.000Z$/, 'Z');\n\n // Check if millisecond precision suffices (the common case).\n const roundedMs = Math.round(epochSeconds * 1000);\n if (roundedMs / 1000 === epochSeconds)\n return new Date(roundedMs).toISOString().replace(/\\.000Z$/, 'Z');\n\n // Sub-millisecond precision: decompose into whole seconds + fractional part.\n // Math.floor ensures the fractional part is always in [0, 1), which is\n // correct for negative epochs too (e.g. -0.5 → floor=-1, frac=0.5).\n const wholeSeconds = Math.floor(epochSeconds);\n const frac = epochSeconds - wholeSeconds;\n\n // Base timestamp formatted to the second, without any fractional part.\n const base = new Date(wholeSeconds * 1000)\n .toISOString()\n .replace(/\\.\\d+Z$/, '');\n\n // Minimal decimal representation of the fractional seconds (JavaScript's\n // Number.prototype.toString uses the shortest round-trip string).\n const fracStr = frac.toString(); // e.g. \"0.0001\" or \"0.123456\"\n const dotIdx = fracStr.indexOf('.');\n let decDigits = dotIdx >= 0 ? fracStr.slice(dotIdx + 1) : '0';\n // Ensure at least 3 decimal places for conventional readability.\n while (decDigits.length < 3) decDigits += '0';\n\n return `${base}.${decDigits}Z`;\n}\n\n/**\n * Extract a date-time string from a single-item app-sequence.\n * Accepts CborTextString (dt<<\"...\">> ) and CborByteString (dt<<'...'>> , UTF-8).\n */\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\n\nfunction stringFromAppSequence(items: CborItem[]): string {\n if (items.length !== 1)\n throw new SyntaxError('dt<<...>>: expected exactly one item');\n const item = items[0];\n if (item instanceof CborTextString) return item.value;\n if (item instanceof CborByteString) return utf8Strict.decode(item.value);\n throw new SyntaxError('dt<<...>>: expected a text string or byte string');\n}\n\n/**\n * Parse an RFC 3339 string and produce the appropriate epoch CborItem subclass.\n * Integer seconds → CborEpochDtExtUint or CborEpochDtExtNint.\n * Fractional seconds → CborEpochDtExtFloat.\n *\n * Fractional seconds are extracted from the string directly (via parseFloat)\n * before passing the remainder to Date.parse, so sub-millisecond precision\n * is preserved rather than being rounded to the nearest millisecond.\n */\n// RFC 3339 §5.6: date-time = full-date \"T\" full-time, where full-time requires\n// an offset (Z or ±HH:MM). Anything shorter is rejected before Date.parse().\nconst RFC3339_RE =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$/i;\n\nexport function parseDtAppString(\n str: string,\n onError?: (msg: string) => void\n): CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat {\n if (!RFC3339_RE.test(str)) {\n const msg = `dt: invalid RFC 3339 date-time: ${JSON.stringify(str)}`;\n if (onError) onError(msg);\n else throw new SyntaxError(msg);\n }\n\n // Separate the fractional-seconds part (if any) from the rest of the string.\n // This avoids Date.parse() truncating to millisecond precision.\n // Pattern: ...THH:MM:SS(.frac)(Z|±HH:MM)\n const fracMatch = str.match(\n /^(.+T\\d{2}:\\d{2}:\\d{2})(\\.\\d+)(Z|[+-]\\d{2}:\\d{2})$/i\n );\n\n let wholeStr: string;\n let fracValue: number | undefined;\n\n if (fracMatch) {\n // Parse the integer-seconds part (without the fractional digits).\n wholeStr = fracMatch[1] + fracMatch[3];\n // Parse the fractional seconds string with full float64 precision.\n fracValue = parseFloat('0' + fracMatch[2]); // e.g. parseFloat(\"0.0001\")\n } else {\n wholeStr = str;\n fracValue = undefined;\n }\n\n const ms = Date.parse(wholeStr);\n if (isNaN(ms))\n throw new SyntaxError(\n `dt: invalid RFC 3339 date-time: ${JSON.stringify(str)}`\n );\n\n if (fracValue === undefined) {\n const seconds = ms / 1000;\n if (seconds >= 0) return new CborEpochDtExtUint(BigInt(seconds));\n return new CborEpochDtExtNint(BigInt(seconds));\n }\n\n return new CborEpochDtExtFloat(ms / 1000 + fracValue);\n}\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nexport const PREFIX_DT = 'dt';\nexport const PREFIX_DT_TAGGED = 'DT';\nexport const TAG_EPOCH = 1n;\n\n// ─── CborItem subclasses ─────────────────────────────────────────────────────\n\n/**\n * Unsigned epoch timestamp whose toCDN() emits dt'…' notation.\n * The RFC 3339 string is re-derived from the numeric value on each call.\n */\nexport class CborEpochDtExtUint extends CborUint {\n constructor(\n value: number | bigint,\n options?: { encodingWidth?: EncodingWidth; ednSource?: string }\n ) {\n super(value, options);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false)\n return super._toCDN(options, _depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.value)\n );\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n return `${PREFIX_DT}'${epochToRfc3339(Number(this.value))}'${eiSuffix}`;\n }\n}\n\n/**\n * Negative epoch timestamp whose toCDN() emits dt'…' notation.\n * The RFC 3339 string is re-derived from the numeric value on each call.\n */\nexport class CborEpochDtExtNint extends CborNint {\n constructor(\n value: number | bigint,\n options?: { encodingWidth?: EncodingWidth; ednSource?: string }\n ) {\n super(value, options);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false)\n return super._toCDN(options, _depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.argument)\n );\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n return `${PREFIX_DT}'${epochToRfc3339(Number(this.value))}'${eiSuffix}`;\n }\n}\n\n/**\n * Float epoch timestamp whose toCDN() emits dt'…' notation.\n * The RFC 3339 string is re-derived from the numeric value on each call.\n */\nexport class CborEpochDtExtFloat extends CborFloat {\n constructor(\n value: number,\n options?: {\n precision?: 'half' | 'single' | 'double';\n literalSource?: string;\n }\n ) {\n super(value, options);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false)\n return super._toCDN(options, _depth, path);\n const autoSelected = autoSelectFloatPrecision(this.value);\n const eiSuffix = floatSuffix(\n this.value,\n this.precision,\n autoSelected,\n options?.encodingIndicators ?? 'auto'\n );\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n return `${PREFIX_DT}'${epochToRfc3339(this.value)}'${eiSuffix}`;\n }\n}\n\n/**\n * CBOR tag(1, epoch) whose toCDN() emits DT'…' notation.\n * The RFC 3339 string is re-derived from the numeric content on each call.\n */\nexport class CborTaggedEpochDtExt extends CborTag {\n constructor(\n datetimeOrContent:\n string | CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat,\n options?: { encodingWidth?: EncodingWidth }\n ) {\n super(\n TAG_EPOCH,\n typeof datetimeOrContent === 'string'\n ? parseDtAppString(datetimeOrContent)\n : datetimeOrContent,\n options\n );\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n this.ednSource,\n this.appSeqSourceFeatures,\n this.appSeqEncodingEditsComplete\n );\n if (decision === 'verbatim') return this.appSeqSource!;\n if (decision === 'source')\n return adjustRawAppSeqSource(\n this.appSeqSource!,\n options,\n this.appSeqComments,\n this.appSeqEncodingEdits\n );\n if (decision === 'structural')\n return super._toCDN({ ...options, appPrefix: false }, depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(TAG_EPOCH)\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n // Per §4.1, DT'...'_N encodes only the tag number's width.\n // If the inner content has non-canonical encoding, fall back to generic tag\n // notation so the inner EI (e.g. dt'...'_3) is not silently discarded.\n const c = this.content as\n CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat;\n const innerIsNonCanonical =\n c instanceof CborFloat\n ? c.precision !== undefined &&\n c.precision !== autoSelectFloatPrecision(c.value)\n : (c as CborUint | CborNint).encodingWidth !== undefined;\n if (innerIsNonCanonical)\n return super._toCDN({ ...options, appPrefix: false }, depth, path);\n const epochSec = c instanceof CborFloat ? c.value : Number(c.value);\n return `${PREFIX_DT_TAGGED}'${epochToRfc3339(epochSec)}'${eiSuffix}`;\n }\n}\n\n/**\n * CBOR tag(1, epoch) whose toJS() returns a plain Date object.\n * Use dt_as_Date (or createDtExtension({ jsDate: true })) to produce these nodes.\n */\nexport class CborTaggedEpochDtAsDateExt extends CborTaggedEpochDtExt {\n constructor(\n datetimeOrContent:\n string | CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat,\n options?: { encodingWidth?: EncodingWidth }\n ) {\n super(datetimeOrContent, options);\n }\n\n override _toJS(_options?: ToJSOptions): Date {\n const c = this.content as\n CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat;\n const epochMs =\n c instanceof CborFloat ? c.value * 1000 : Number(c.value) * 1000;\n return new Date(epochMs);\n }\n}\n\n/**\n * `CborExtension.toJS()` hook shared by `dt` and `dt_as_Date`: lets `toJS()`\n * reinterpret *any* `CborTaggedEpochDtExt` node (including the\n * `CborTaggedEpochDtAsDateExt` subclass) as either a `number` or a `Date`,\n * regardless of which variant produced it during parsing — see\n * `ToJSOptions.extensions`/`itemOptions`.\n *\n * The `number` branch replicates `CborTag._toJS()`'s own default behaviour\n * (honouring `stripTags`/`implicitTags`/`integerAs` and round-tripping via\n * `Tag.set`)\n * rather than assuming a tag wrapper is unwanted, so selecting the plain\n * `dt` extension here for a subtree parsed with `dt_as_Date` reproduces\n * exactly what parsing that subtree with `dt` would have produced.\n */\nfunction dtToJSHook(\n useDate: boolean\n): (\n item: CborItem,\n options: ReadonlyToJSNodeOptions\n) => { value: unknown } | undefined {\n return (item, options) => {\n if (!(item instanceof CborTaggedEpochDtExt)) return undefined;\n const c = item.content as\n CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat;\n if (useDate) {\n const epochMs =\n c instanceof CborFloat ? c.value * 1000 : Number(c.value) * 1000;\n return { value: new Date(epochMs) };\n }\n // Read-only view (see ReadonlyToJSNodeOptions) passed straight through\n // to a plain conversion that only ever reads it, same as `_toJS` does\n // for its own `options` parameter elsewhere.\n const value = c._toJS(options as ToJSOptions);\n return { value: item._tagJS(value, options as ToJSOptions) };\n };\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\n/**\n * Create a dt/DT CborExtension.\n *\n * - `createDtExtension()` — tagged DT values produce `CborTaggedEpochDtExt`;\n * toJS() returns a number (epoch seconds).\n * - `createDtExtension({ jsDate: true })` — tagged DT values produce\n * `CborTaggedEpochDtAsDateExt`; toJS() returns a `Date` object, and\n * `fromJS(Date)` converts `Date` instances back to tagged epoch values.\n */\nexport function createDtExtension(options?: {\n jsDate?: boolean;\n}): CborExtension {\n const useDate = options?.jsDate ?? false;\n\n function makeTagged(\n datetime: string\n ): CborTaggedEpochDtExt | CborTaggedEpochDtAsDateExt {\n return useDate\n ? new CborTaggedEpochDtAsDateExt(datetime)\n : new CborTaggedEpochDtExt(datetime);\n }\n\n const ext: CborExtension = {\n appStringPrefixes: [PREFIX_DT, PREFIX_DT_TAGGED],\n tagNumbers: [TAG_EPOCH],\n // dt/DT results always have a dedicated subclass (CborEpochDtExt* /\n // CborTaggedEpochDtExt) that regenerates its notation by default;\n // 'optional' preserves the <<...>> spelling only when\n // ToCDNOptions.preserveAppPrefix is set, without changing the\n // returned node's class/identity (see preservedAppSeqSpelling above).\n preserveAppSeqSource: 'optional',\n\n // Lets ToJSOptions.extensions/itemOptions select number-vs-Date output\n // for a CborTaggedEpochDtExt node regardless of which of `dt`/\n // `dt_as_Date` actually parsed it — see dtToJSHook.\n toJS: dtToJSHook(useDate),\n\n parseAppString(\n prefix: string,\n content: string,\n onError?: (msg: string) => void\n ): CborItem {\n if (prefix === PREFIX_DT_TAGGED) return makeTagged(content);\n return parseDtAppString(content, onError);\n },\n\n parseAppSequence(\n prefix: string,\n items: CborItem[],\n onError?: (msg: string) => void\n ): CborItem {\n const str = stringFromAppSequence(items);\n if (prefix === PREFIX_DT_TAGGED) return makeTagged(str);\n return parseDtAppString(str, onError);\n },\n\n parseTag(tag: bigint, value: CborItem): CborItem | undefined {\n if (tag !== TAG_EPOCH) return undefined;\n let content:\n CborEpochDtExtUint | CborEpochDtExtNint | CborEpochDtExtFloat;\n if (value instanceof CborUint) {\n content = new CborEpochDtExtUint(value.value, {\n encodingWidth: value.encodingWidth,\n ednSource: value.ednSource,\n });\n } else if (value instanceof CborNint) {\n content = new CborEpochDtExtNint(value.value, {\n encodingWidth: value.encodingWidth,\n ednSource: value.ednSource,\n });\n } else if (value instanceof CborFloat) {\n // Always preserve as float to avoid losing the original CBOR encoding\n // type (e.g. float64(1.0) must not silently become uint(1)).\n content = new CborEpochDtExtFloat(value.value, {\n precision: value.precision,\n literalSource: value.literalSource,\n });\n } else {\n return undefined;\n }\n content.start = value.start;\n content.end = value.end;\n const result = useDate\n ? new CborTaggedEpochDtAsDateExt(content)\n : new CborTaggedEpochDtExt(content);\n return result;\n },\n };\n\n if (useDate) {\n ext.fromJS = (\n value: unknown,\n _options: FromJSOptions\n ): CborItem | undefined => {\n if (value instanceof Date)\n return new CborTaggedEpochDtAsDateExt(\n epochToRfc3339(value.getTime() / 1000)\n );\n return undefined;\n };\n ext.isJSType = (value: unknown): value is Date => value instanceof Date;\n }\n\n return ext;\n}\n\n// ─── Extension objects ────────────────────────────────────────────────────────\n\n/**\n * Standard dt/DT CborExtension.\n * Tagged DT values produce CborTaggedEpochDtExt; toJS() returns a number.\n * For Date-based toJS() use dt_as_Date or createDtExtension({ jsDate: true }).\n */\nexport const dt: CborExtension = createDtExtension();\n\n/**\n * Full-featured dt/DT CborExtension with Date support.\n * Tagged DT values produce CborTaggedEpochDtAsDateExt; toJS() returns a Date.\n * fromJS(Date) converts Date instances to tagged epoch values.\n */\nexport const dt_as_Date: CborExtension = createDtExtension({ jsDate: true });\n\nexport default dt;\n","/**\n * Shared IPv4 / IPv6 address parsing and formatting utilities.\n * Used by the \"ip\"/\"IP\" extension (RFC 9164) and the \"cri\"/\"CRI\" extension\n * (draft-ietf-core-href).\n */\n\n// ─── Parsing ──────────────────────────────────────────────────────────────────\n\nexport function parseIPv4(str: string): Uint8Array {\n const parts = str.split('.');\n if (parts.length !== 4)\n throw new SyntaxError(`ip: invalid IPv4 address: ${JSON.stringify(str)}`);\n const bytes = new Uint8Array(4);\n for (let i = 0; i < 4; i++) {\n const s = parts[i];\n if (!/^\\d+$/.test(s) || (s.length > 1 && s[0] === '0'))\n throw new SyntaxError(`ip: invalid IPv4 octet: ${JSON.stringify(s)}`);\n const n = parseInt(s, 10);\n if (n > 255) throw new SyntaxError(`ip: IPv4 octet out of range: ${n}`);\n bytes[i] = n;\n }\n return bytes;\n}\n\nexport function parseIPv6(str: string): Uint8Array {\n const bytes = new Uint8Array(16);\n if (str === '::') return bytes;\n\n // Handle IPv4-mapped suffix, e.g. ::ffff:192.0.2.1\n let head = str;\n let ipv4Tail: Uint8Array | null = null;\n const ipv4Match = str.match(/^(.*):(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})$/);\n if (ipv4Match) {\n head = ipv4Match[1];\n if (head.endsWith(':')) head += ':'; // restore :: split by the regex\n ipv4Tail = parseIPv4(ipv4Match[2]);\n }\n\n const halves = head.split('::');\n if (halves.length > 2)\n throw new SyntaxError(`ip: invalid IPv6 address: ${JSON.stringify(str)}`);\n\n const doubleColon = halves.length === 2;\n const leftParts = halves[0] ? halves[0].split(':') : [];\n const rightParts = doubleColon && halves[1] ? halves[1].split(':') : [];\n const totalGroups = ipv4Tail ? 6 : 8;\n\n if (!doubleColon && leftParts.length !== totalGroups)\n throw new SyntaxError(`ip: invalid IPv6 address: ${JSON.stringify(str)}`);\n if (doubleColon && leftParts.length + rightParts.length >= totalGroups)\n throw new SyntaxError(`ip: invalid IPv6 address: ${JSON.stringify(str)}`);\n\n const zeroCount = totalGroups - leftParts.length - rightParts.length;\n const groups = [...leftParts, ...Array(zeroCount).fill('0'), ...rightParts];\n\n let offset = 0;\n for (const g of groups) {\n if (!/^[0-9a-fA-F]{1,4}$/.test(g))\n throw new SyntaxError(`ip: invalid IPv6 group: ${JSON.stringify(g)}`);\n const n = parseInt(g, 16);\n bytes[offset++] = (n >> 8) & 0xff;\n bytes[offset++] = n & 0xff;\n }\n if (ipv4Tail) bytes.set(ipv4Tail, 12);\n return bytes;\n}\n\n// ─── Formatting ───────────────────────────────────────────────────────────────\n\nexport function formatIPv4(bytes: Uint8Array): string {\n return Array.from(bytes).join('.');\n}\n\nexport function formatIPv6(bytes: Uint8Array): string {\n // RFC 5952 §5: IPv4-mapped (::ffff:a.b.c.d) — bytes 0-9 zero, 10-11 = 0xffff\n const isIpv4Mapped =\n bytes.slice(0, 10).every((b) => b === 0) &&\n bytes[10] === 0xff &&\n bytes[11] === 0xff;\n\n const ipv4Suffix = isIpv4Mapped ? formatIPv4(bytes.slice(12)) : null;\n\n const hexGroups = ipv4Suffix ? 6 : 8;\n const groups: number[] = [];\n for (let i = 0; i < hexGroups * 2; i += 2)\n groups.push((bytes[i] << 8) | bytes[i + 1]);\n\n // RFC 5952 §4.2.3: find longest run of consecutive zero groups (≥ 2) for ::\n let bestStart = -1,\n bestLen = 0;\n let i = 0;\n while (i < hexGroups) {\n if (groups[i] === 0) {\n let j = i + 1;\n while (j < hexGroups && groups[j] === 0) j++;\n if (j - i > bestLen) {\n bestStart = i;\n bestLen = j - i;\n }\n i = j;\n } else {\n i++;\n }\n }\n if (bestLen < 2) bestStart = -1;\n\n const fmt = (g: number) => g.toString(16);\n let hexPart: string;\n if (bestStart === -1) {\n hexPart = groups.map(fmt).join(':');\n } else {\n const left = groups.slice(0, bestStart).map(fmt).join(':');\n const right = groups\n .slice(bestStart + bestLen)\n .map(fmt)\n .join(':');\n hexPart = `${left}::${right}`;\n }\n\n return ipv4Suffix ? `${hexPart}:${ipv4Suffix}` : hexPart;\n}\n","/**\n * CDN \"ip\" / \"IP\" app-extension (§3.3 of draft-ietf-cbor-edn-literals-27).\n *\n * Parses IPv4 / IPv6 address strings (RFC 3986 §3.2.2) into byte strings,\n * and optionally wraps them in CBOR tags per RFC 9164:\n * - tag 52 IPv4 address or prefix\n * - tag 54 IPv6 address or prefix\n *\n * Syntax:\n * ip'192.0.2.42' → CborIpExt bare 4-byte string\n * ip'2001:db8::1' → CborIpExt bare 16-byte string\n * ip'192.0.2.0/24' → CborIpPrefixExt bare [24, h'c00002']\n * ip'2001:db8::/32' → CborIpPrefixExt bare [32, h'20010db8']\n * IP'192.0.2.42' → CborTaggedIpExt tag(52, h'...')\n * IP'2001:db8::1' → CborTaggedIpExt tag(54, h'...')\n * IP'192.0.2.0/24' → CborTaggedIpExt tag(52, [24, h'c00002'])\n * IP'2001:db8::/32' → CborTaggedIpExt tag(54, [32, h'20010db8'])\n *\n * Lowercase ip produces the unwrapped content; uppercase IP additionally\n * wraps it in the IANA address family tag (52 for IPv4, 54 for IPv6).\n */\n\nimport type { ToCDNOptions } from '../types';\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborTag } from '../ast/CborTag';\nimport { CborArray } from '../ast/CborArray';\nimport { CborUint } from '../ast/CborUint';\nimport { CborTextString } from '../ast/CborTextString';\nimport { parseIPv4, parseIPv6, formatIPv4, formatIPv6 } from '../utils/ip';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n decideTaggedAppSeqRendering,\n adjustRawAppSeqSource,\n adjustAppSeqIndicator,\n} from '../cdn/serialize-utils';\n\nconst PREFIX_IP = 'ip';\nconst PREFIX_IP_TAGGED = 'IP';\nconst TAG_IPV4 = 52n;\nconst TAG_IPV6 = 54n;\n\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\n\nfunction stringFromAppSequence(items: CborItem[]): string {\n if (items.length !== 1)\n throw new SyntaxError('ip<<...>>: expected exactly one item');\n const item = items[0];\n if (item instanceof CborTextString) return item.value;\n if (item instanceof CborByteString) return utf8Strict.decode(item.value);\n throw new SyntaxError('ip<<...>>: expected a text string or byte string');\n}\n\n// ─── Address parsing ──────────────────────────────────────────────────────────\n\nfunction parseAddress(str: string): { bytes: Uint8Array; isV4: boolean } {\n if (/^\\d/.test(str) && str.includes('.') && !str.includes(':'))\n return { bytes: parseIPv4(str), isV4: true };\n return { bytes: parseIPv6(str), isV4: false };\n}\n\n// ─── Address formatting ───────────────────────────────────────────────────────\n\nfunction formatAddress(bytes: Uint8Array): string {\n if (bytes.length === 4) return formatIPv4(bytes);\n if (bytes.length === 16) return formatIPv6(bytes);\n throw new SyntaxError(`ip: unexpected byte length: ${bytes.length}`);\n}\n\n// ─── CIDR helpers ─────────────────────────────────────────────────────────────\n\nfunction truncateToPrefix(bytes: Uint8Array, prefixLen: number): Uint8Array {\n // RFC 9164 §2.3: zero host bits, then strip trailing zero bytes.\n const masked = new Uint8Array(bytes.length);\n masked.set(bytes);\n const fullBytes = Math.floor(prefixLen / 8);\n const extraBits = prefixLen % 8;\n if (extraBits > 0 && fullBytes < bytes.length)\n masked[fullBytes] &= (0xff << (8 - extraBits)) & 0xff;\n for (let i = fullBytes + (extraBits > 0 ? 1 : 0); i < bytes.length; i++)\n masked[i] = 0;\n let end = Math.ceil(prefixLen / 8);\n while (end > 0 && masked[end - 1] === 0) end--;\n return masked.slice(0, end);\n}\n\nfunction expandToFull(truncated: Uint8Array, fullLen: number): Uint8Array {\n const full = new Uint8Array(fullLen);\n full.set(truncated);\n return full;\n}\n\n// ─── CborItem subclasses ─────────────────────────────────────────────────────\n\n/**\n * Bare IP address byte string whose toCDN() emits ip'…' notation.\n */\nexport class CborIpExt extends CborByteString {\n override _toCDN(\n options: ToCDNOptions | undefined,\n _depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false)\n return super._toCDN(options, _depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(this.value.length))\n );\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n return `${PREFIX_IP}'${formatAddress(this.value)}'${eiSuffix}`;\n }\n}\n\n/**\n * Bare IP address prefix (CIDR) whose toCDN() emits ip'…/prefix' notation.\n * Encoded as [prefixLen, truncatedBytes] per RFC 9164 §2.3, without a tag.\n */\nexport class CborIpPrefixExt extends CborArray {\n private readonly _isV4: boolean;\n\n constructor(prefixLen: number, truncated: Uint8Array, isV4: boolean) {\n super([new CborUint(BigInt(prefixLen)), new CborByteString(truncated)]);\n this._isV4 = isV4;\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n // This form never emits an encoding indicator of its own (unlike the\n // other ip/dt notations), so 'adjusted' only ever strips one.\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n '',\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n const prefixLen = Number((this.items[0] as CborUint).value);\n const truncated = (this.items[1] as CborByteString).value;\n const full = expandToFull(truncated, this._isV4 ? 4 : 16);\n return `${PREFIX_IP}'${formatAddress(full)}/${prefixLen}'`;\n }\n}\n\n/**\n * CBOR tag(52/54, …) IP address whose toCDN() emits IP'…' notation.\n * Content may be a byte string (plain address) or an array [prefix, bytes]\n * (CIDR prefix per RFC 9164).\n */\nexport class CborTaggedIpExt extends CborTag {\n constructor(tag: bigint, content: CborItem) {\n super(tag, content);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n this.ednSource,\n this.appSeqSourceFeatures,\n this.appSeqEncodingEditsComplete\n );\n if (decision === 'verbatim') return this.appSeqSource!;\n if (decision === 'source')\n return adjustRawAppSeqSource(\n this.appSeqSource!,\n options,\n this.appSeqComments,\n this.appSeqEncodingEdits\n );\n // Unlike dt's content classes, ip's content (CborByteString / CborArray\n // / CborUint) never self-switches on `appPrefix`, so no need to force\n // it false here — doing so would also force hex byte-string encoding\n // (see CborByteString._toCDN), overriding `bstrEncoding`/`sqstr`.\n if (decision === 'structural') return super._toCDN(options, depth, path);\n if (decision === 'adjusted') {\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.tag)\n );\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n }\n const fullLen = this.tag === TAG_IPV4 ? 4 : 16;\n const c = this.content as CborItem;\n if (c instanceof CborByteString) {\n // IP'...'_N only encodes the tag's width. If the inner byte string uses a\n // non-canonical length header, fall back to generic tag notation to preserve it.\n if (c.encodingWidth !== undefined)\n return super._toCDN(options, depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.tag)\n );\n return `${PREFIX_IP_TAGGED}'${formatAddress(c.value)}'${eiSuffix}`;\n }\n if (\n c instanceof CborArray &&\n c.items.length === 2 &&\n c.items[0] instanceof CborUint &&\n c.items[1] instanceof CborByteString\n ) {\n // Fall back if the inner array or either of its items has non-canonical encoding.\n if (\n c.encodingWidth !== undefined ||\n (c.items[0] as CborUint).encodingWidth !== undefined ||\n (c.items[1] as CborByteString).encodingWidth !== undefined\n )\n return super._toCDN(options, depth, path);\n const prefixLen = Number((c.items[0] as CborUint).value);\n const full = expandToFull((c.items[1] as CborByteString).value, fullLen);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.tag)\n );\n return `${PREFIX_IP_TAGGED}'${formatAddress(full)}/${prefixLen}'${eiSuffix}`;\n }\n return super._toCDN(options, depth, path);\n }\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\nfunction buildIpValue(prefix: string, content: string): CborItem {\n const slashIdx = content.indexOf('/');\n\n if (slashIdx === -1) {\n const { bytes, isV4 } = parseAddress(content);\n if (prefix === PREFIX_IP_TAGGED)\n return new CborTaggedIpExt(\n isV4 ? TAG_IPV4 : TAG_IPV6,\n new CborByteString(bytes)\n );\n return new CborIpExt(bytes);\n }\n\n // CIDR notation — supported with both lowercase ip and uppercase IP.\n // lowercase ip → bare [prefixLen, truncatedBytes] (no tag)\n // uppercase IP → tag(52/54, [prefixLen, truncatedBytes])\n const addrStr = content.slice(0, slashIdx);\n const lenStr = content.slice(slashIdx + 1);\n if (!/^\\d+$/.test(lenStr))\n throw new SyntaxError(\n `ip: invalid prefix length: ${JSON.stringify(lenStr)}`\n );\n const prefixLen = parseInt(lenStr, 10);\n\n const { bytes, isV4 } = parseAddress(addrStr);\n const maxLen = isV4 ? 32 : 128;\n if (prefixLen > maxLen)\n throw new SyntaxError(\n `ip: prefix length ${prefixLen} exceeds maximum ${maxLen} for ${isV4 ? 'IPv4' : 'IPv6'}`\n );\n\n const truncated = truncateToPrefix(bytes, prefixLen);\n if (prefix === PREFIX_IP_TAGGED) {\n return new CborTaggedIpExt(\n isV4 ? TAG_IPV4 : TAG_IPV6,\n new CborArray([\n new CborUint(BigInt(prefixLen)),\n new CborByteString(truncated),\n ])\n );\n }\n return new CborIpPrefixExt(prefixLen, truncated, isV4);\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\n/**\n * Create an ip/IP CborExtension (RFC 9164 / §3.3 of draft-ietf-cbor-edn-literals-27).\n *\n * - `ip'addr'` → CborIpExt (bare byte string, 4 or 16 bytes)\n * - `IP'addr'` → CborTaggedIpExt tag(52 or 54, bytes)\n * - `IP'addr/prefix'` → CborTaggedIpExt tag(52 or 54, [prefix_len, bytes])\n * - parseTag(52/54, …) → CborTaggedIpExt (reversible via fromCBOR)\n * - fromJS(tagged obj) → CborTaggedIpExt (reversible via fromJS)\n */\nexport const ip: CborExtension = {\n appStringPrefixes: [PREFIX_IP, PREFIX_IP_TAGGED],\n tagNumbers: [TAG_IPV4, TAG_IPV6],\n // ip/IP results always have a dedicated subclass (CborIpExt /\n // CborIpPrefixExt / CborTaggedIpExt) that regenerates its notation by\n // default; 'optional' preserves the <<...>> spelling only when\n // ToCDNOptions.preserveAppPrefix is set, without changing the\n // returned node's class/identity (see preservedAppSeqSpelling).\n preserveAppSeqSource: 'optional',\n\n parseAppString(prefix: string, content: string): CborItem {\n return buildIpValue(prefix, content);\n },\n\n parseAppSequence(prefix: string, items: CborItem[]): CborItem {\n return buildIpValue(prefix, stringFromAppSequence(items));\n },\n\n parseTag(tag: bigint, value: CborItem): CborItem | undefined {\n if (tag !== TAG_IPV4 && tag !== TAG_IPV6) return undefined;\n if (value instanceof CborByteString || value instanceof CborArray)\n return new CborTaggedIpExt(tag, value);\n return undefined;\n },\n};\n\nexport default ip;\n","/**\n * Standard CDN \"cri\" / \"CRI\" app-extension (§3.7 and §6.2.5 of draft-ietf-cbor-edn-literals-27).\n *\n * Converts URI references (RFC 3986) to CRI (Constrained Resource Identifier,\n * draft-ietf-core-href) CBOR array format and back.\n *\n * Syntax:\n * cri'https://example.com/path' → bare CRI array (no CBOR tag)\n * CRI'https://example.com/path' → tag(99, CRI array)\n *\n * CRI array structures (trailing defaults removed):\n * Absolute: [scheme, authority, path, ?query, ?fragment]\n * Network-path: [false, authority, path, ?query, ?fragment]\n * Absolute-path: [true, path, ?query, ?fragment]\n * Relative-path: [uint(discard), path, ?query, ?fragment]\n * Same-document: [0, ?query, ?fragment]\n *\n * where:\n * scheme = scheme-id (nint, e.g. -4 for https) or scheme-name (text)\n * authority = [?userinfo, host, ?port] — host is text labels or IP bytes\n * path = [\"seg1\", \"seg2\", ...]\n * query = [\"k=v\", ...]\n * fragment = text\n * discard = uint — number of path segments to remove from base before appending\n * (1 = same directory, 2 = one level up \"../\", N = (N-1) levels up)\n *\n * Tag number 99 is used for the tagged \"CRI\" variant (§3.7 of draft-ietf-cbor-edn-literals-27).\n */\n\nimport type { ToCDNOptions } from '../types';\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborArray } from '../ast/CborArray';\nimport { CborTag } from '../ast/CborTag';\nimport { CborNint } from '../ast/CborNint';\nimport { CborUint } from '../ast/CborUint';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborSimple } from '../ast/CborSimple';\nimport { parseIPv4, parseIPv6, formatIPv4, formatIPv6 } from '../utils/ip';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n decideTaggedAppSeqRendering,\n adjustRawAppSeqSource,\n adjustAppSeqIndicator,\n} from '../cdn/serialize-utils';\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst PREFIX_CRI = 'cri';\nconst PREFIX_CRI_TAGGED = 'CRI';\n\n/**\n * CBOR tag number for the tagged CRI variant (§3.7 and §6.2.5 of draft-ietf-cbor-edn-literals-27).\n */\nexport const TAG_CRI = 99n;\n\n// ─── Scheme-ID table ──────────────────────────────────────────────────────────\n\n/**\n * Scheme-id values from the IANA URI Schemes Registry.\n * Formula: scheme-id = -(scheme-number + 1)\n * https://www.iana.org/assignments/uri-schemes/uri-schemes.xhtml\n */\nconst SCHEME_ID_BY_NAME = new Map<string, bigint>([\n ['coap', -1n],\n ['coaps', -2n],\n ['http', -3n],\n ['https', -4n],\n ['urn', -5n],\n ['did', -6n],\n ['coap+tcp', -7n],\n ['coaps+tcp', -8n],\n ['coap+ws', -25n],\n ['coaps+ws', -26n],\n]);\n\nconst SCHEME_NAME_BY_ID = new Map<bigint, string>(\n [...SCHEME_ID_BY_NAME.entries()].map(([name, id]) => [id, name])\n);\n\n// ─── Percent-encoding helpers ─────────────────────────────────────────────────\n\nfunction pctDecode(s: string): string {\n try {\n return decodeURIComponent(s);\n } catch {\n return s;\n }\n}\n\nconst textEncoder = new TextEncoder();\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\n\nfunction pctEncodeChar(c: string): string {\n return Array.from(\n textEncoder.encode(c),\n (b) => `%${b.toString(16).toUpperCase().padStart(2, '0')}`\n ).join('');\n}\n\nfunction encodePct(s: string, isAllowed: (c: string) => boolean): string {\n let out = '';\n for (const c of s) {\n out += isAllowed(c) ? c : pctEncodeChar(c);\n }\n return out;\n}\n\n// unreserved = A-Za-z0-9 \"-\" \".\" \"_\" \"~\"\n// sub-delims = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\" / \"*\" / \"+\" / \",\" / \";\" / \"=\"\nfunction isUnreserved(c: string): boolean {\n return /[A-Za-z0-9\\-._~]/.test(c);\n}\nfunction isSubDelim(c: string): boolean {\n return /[!$&'()*+,;=]/.test(c);\n}\n\n// path segment: unreserved | sub-delims | \":\" | \"@\"\nfunction isPathAllowed(c: string): boolean {\n return isUnreserved(c) || isSubDelim(c) || c === ':' || c === '@';\n}\n\n// query item: path chars | \"/\" | \"?\" — but NOT \"&\" (used as item separator between items)\nfunction isQueryItemAllowed(c: string): boolean {\n return (isPathAllowed(c) || c === '/' || c === '?') && c !== '&';\n}\n\n// fragment: same as query\nfunction isFragmentAllowed(c: string): boolean {\n return isPathAllowed(c) || c === '/' || c === '?';\n}\n\n// userinfo: unreserved | sub-delims | \":\" (RFC 3986 §3.2.1: \":\" is allowed in userinfo)\nfunction isUserinfoAllowed(c: string): boolean {\n return isUnreserved(c) || isSubDelim(c) || c === ':';\n}\n\n// registered name label: unreserved | sub-delims\nfunction isRegNameAllowed(c: string): boolean {\n return isUnreserved(c) || isSubDelim(c);\n}\n\n// ─── Authority conversion ──────────────────────────────────────────────────────\n\n/**\n * Parse URI authority string → CRI authority array.\n *\n * CRI authority = [?userinfo, host, ?port]\n * userinfo = (false, text) — two inline elements\n * host-name = *text — zero-or-more text labels, inline\n * host-ip = bytes (4 or 16 bytes) — single inline element\n * port = uint 0..65535 — trailing optional element\n */\nfunction parseAuthorityStr(authStr: string): CborArray {\n const items: CborItem[] = [];\n let str = authStr;\n\n // Strip userinfo (everything up to the last '@')\n const atIdx = str.indexOf('@');\n if (atIdx >= 0) {\n items.push(CborSimple.FALSE);\n items.push(new CborTextString(pctDecode(str.slice(0, atIdx))));\n str = str.slice(atIdx + 1);\n }\n\n // IPv6 bracket literal: [addr]:port\n let hostStr: string;\n let portStr: string | null = null;\n\n if (str.startsWith('[')) {\n const close = str.indexOf(']');\n if (close < 0)\n throw new SyntaxError('cri: unterminated IPv6 bracket in authority');\n hostStr = str.slice(1, close);\n const after = str.slice(close + 1);\n if (after.startsWith(':')) portStr = after.slice(1);\n else if (after.length > 0)\n throw new SyntaxError(\n `cri: unexpected characters after ']' in authority`\n );\n items.push(new CborByteString(parseIPv6(hostStr)));\n } else {\n // IPv4 address or registered name — find port via last ':'\n const colonIdx = str.lastIndexOf(':');\n if (colonIdx >= 0) {\n hostStr = str.slice(0, colonIdx);\n portStr = str.slice(colonIdx + 1);\n } else {\n hostStr = str;\n }\n\n if (hostStr === '') {\n // Empty host (e.g. file:///path) — zero labels, nothing pushed\n } else if (/^\\d{1,3}(\\.\\d{1,3}){3}$/.test(hostStr)) {\n items.push(new CborByteString(parseIPv4(hostStr)));\n } else {\n // Registered name: split by '.' into lowercase labels\n for (const label of hostStr.toLowerCase().split('.')) {\n items.push(new CborTextString(label));\n }\n }\n }\n\n // Optional port\n if (portStr !== null && portStr !== '') {\n if (!/^\\d+$/.test(portStr))\n throw new SyntaxError(`cri: invalid port: ${JSON.stringify(portStr)}`);\n const port = parseInt(portStr, 10);\n if (port > 65535) throw new SyntaxError(`cri: port ${port} out of range`);\n items.push(new CborUint(BigInt(port)));\n }\n\n return new CborArray(items);\n}\n\n/**\n * Convert CRI authority array → URI authority string.\n */\nfunction criAuthorityToUri(auth: CborArray): string {\n const items = auth.items;\n let idx = 0;\n let result = '';\n\n // Userinfo: (false, text) as two consecutive elements\n if (\n idx < items.length &&\n items[idx] instanceof CborSimple &&\n (items[idx] as CborSimple).value === 20\n ) {\n idx++; // skip false sentinel\n const user = items[idx++] as CborTextString;\n result += encodePct(user.value, isUserinfoAllowed) + '@';\n }\n\n if (idx >= items.length) return result; // empty host\n\n const hostFirst = items[idx];\n if (hostFirst instanceof CborByteString) {\n idx++;\n const { length } = hostFirst.value;\n if (length === 4) {\n result += formatIPv4(hostFirst.value);\n } else if (length === 16) {\n result += '[' + formatIPv6(hostFirst.value) + ']';\n } else {\n throw new Error(`cri: unexpected host-ip byte length: ${length}`);\n }\n // Optional zone-id (text string immediately after the IP bytes)\n if (idx < items.length && items[idx] instanceof CborTextString) {\n result += `%25${encodePct((items[idx++] as CborTextString).value, isRegNameAllowed)}`;\n }\n } else {\n // Registered name: consecutive text strings up to the optional uint port\n const labels: string[] = [];\n while (idx < items.length && items[idx] instanceof CborTextString) {\n labels.push(\n encodePct((items[idx++] as CborTextString).value, isRegNameAllowed)\n );\n }\n result += labels.join('.');\n }\n\n // Optional port\n if (idx < items.length && items[idx] instanceof CborUint) {\n result += ':' + (items[idx] as CborUint).value.toString();\n }\n\n return result;\n}\n\n// ─── CRI array ↔ URI string ───────────────────────────────────────────────────\n\n/**\n * Parse `//authority/path` from a string starting with `//`.\n * Returns the CRI authority array and path segments.\n */\nfunction _parseHierarchicalPart(rest: string): {\n authority: CborArray;\n pathSegments: CborTextString[];\n} {\n const afterSlashes = rest.slice(2);\n const slashIdx = afterSlashes.indexOf('/');\n let authStr: string;\n let pathSegments: CborTextString[];\n if (slashIdx >= 0) {\n authStr = afterSlashes.slice(0, slashIdx);\n const pathStr = afterSlashes.slice(slashIdx + 1);\n pathSegments = pathStr\n .split('/')\n .map((s) => new CborTextString(pctDecode(s)));\n } else {\n authStr = afterSlashes;\n pathSegments = [];\n }\n return { authority: parseAuthorityStr(authStr), pathSegments };\n}\n\n/**\n * Parse a URI or URI-reference string into CRI array items.\n *\n * Supports all RFC 3986 reference forms:\n * Absolute URI: https://example.com/path → [scheme, authority, path, ...]\n * Network-path ref: //other.example.com/path → [false, authority, path, ...]\n * Absolute-path ref: /abs/path → [true, path, ...]\n * Relative-path ref: foo, ../bar → [uint(discard), path, ...]\n * Same-document ref: #frag, ?q=1, (empty) → [0, ...]\n *\n * Produces a compact representation with trailing defaults removed.\n */\nfunction uriToCriItems(str: string): CborItem[] {\n // ── 1. Fragment ────────────────────────────────────────────────────────────\n let rest = str;\n let fragment: string | null = null;\n const hashIdx = rest.indexOf('#');\n if (hashIdx >= 0) {\n fragment = pctDecode(rest.slice(hashIdx + 1));\n rest = rest.slice(0, hashIdx);\n }\n\n // ── 2. Query ───────────────────────────────────────────────────────────────\n let queryItems: CborTextString[] | null = null;\n const qIdx = rest.indexOf('?');\n if (qIdx >= 0) {\n const qs = rest.slice(qIdx + 1);\n rest = rest.slice(0, qIdx);\n // Per draft-ietf-core-href §5.1:\n // [] (empty array) = absent query (no \"?\") — this is the trailing default\n // [\"\"] (one empty string) = present but empty query (\"?\")\n // [\"k=v\", ...] = query with parameters\n queryItems = qs.split('&').map((s) => new CborTextString(pctDecode(s)));\n }\n\n // ── 3. Detect reference form and build leading items ───────────────────────\n const items: CborItem[] = [];\n\n const schemeMatch = /^([a-zA-Z][a-zA-Z0-9+.\\-]*):([\\s\\S]*)$/.exec(rest);\n if (schemeMatch) {\n // Absolute URI: scheme + hier-part\n const schemeName = schemeMatch[1].toLowerCase();\n const hierPart = schemeMatch[2];\n const schemeId = SCHEME_ID_BY_NAME.get(schemeName);\n items.push(\n schemeId !== undefined\n ? new CborNint(schemeId)\n : new CborTextString(schemeName)\n );\n if (hierPart.startsWith('//')) {\n const { authority, pathSegments } = _parseHierarchicalPart(hierPart);\n items.push(authority, new CborArray(pathSegments));\n } else if (hierPart.startsWith('/')) {\n const pathSegments = hierPart\n .slice(1)\n .split('/')\n .map((s) => new CborTextString(pctDecode(s)));\n items.push(CborSimple.NULL, new CborArray(pathSegments));\n } else {\n const pathSegments = hierPart\n .split('/')\n .map((s) => new CborTextString(pctDecode(s)));\n items.push(CborSimple.TRUE, new CborArray(pathSegments));\n }\n } else if (rest.startsWith('//')) {\n // Network-path reference: //authority/path\n const { authority, pathSegments } = _parseHierarchicalPart(rest);\n items.push(CborSimple.FALSE, authority, new CborArray(pathSegments));\n } else if (rest.startsWith('/')) {\n // Absolute-path reference: /path\n const pathSegments = rest\n .slice(1)\n .split('/')\n .map((s) => new CborTextString(pctDecode(s)));\n items.push(CborSimple.TRUE, new CborArray(pathSegments));\n } else if (rest === '') {\n // Same-document reference (only query/fragment differ from base)\n items.push(new CborUint(0n));\n } else {\n // Relative-path reference: count leading ../ sequences\n let discard = 1n;\n let pathRest = rest;\n let hasDotSlash = false;\n if (pathRest.startsWith('./')) {\n hasDotSlash = true;\n pathRest = pathRest.slice(2);\n }\n while (pathRest.startsWith('../')) {\n discard++;\n pathRest = pathRest.slice(3);\n }\n // Handle lone '..' or '.' at end\n if (pathRest === '..') {\n discard++;\n pathRest = '';\n } else if (pathRest === '.') {\n pathRest = '';\n }\n // RFC 3986 §3.3 path-noscheme: the first segment of a relative-path reference\n // must not contain ':' unless the path was explicitly prefixed with \"./\"\n // (which disambiguates it from a scheme). Without \"./\" the colon makes the\n // reference look like an absolute URI to parsers, and is most likely a typo.\n // This check applies only when discard=1 (same-directory) and no \"./\" was given.\n // For discard≥2 (e.g. \"../foo:bar\") the leading \"../\" already disambiguates.\n if (discard === 1n && !hasDotSlash && pathRest !== '') {\n const firstSeg = pathRest.split('/')[0];\n if (firstSeg.includes(':'))\n throw new SyntaxError(\n `cri: invalid relative-path reference — first segment must not contain ':' without a './' prefix (RFC 3986 §3.3): ${JSON.stringify(str)}`\n );\n }\n const pathSegments =\n pathRest === ''\n ? []\n : pathRest.split('/').map((s) => new CborTextString(pctDecode(s)));\n items.push(new CborUint(discard), new CborArray(pathSegments));\n }\n\n // ── 4. Append query and fragment ──────────────────────────────────────────\n if (queryItems !== null) items.push(new CborArray(queryItems));\n if (fragment !== null) {\n // When fragment is present but query is absent, use null as placeholder so that\n // \"no query\" is distinguishable from \"empty query []\" at the query position.\n if (queryItems === null) items.push(CborSimple.NULL);\n items.push(new CborTextString(fragment));\n }\n\n // ── 5. Trim trailing defaults ─────────────────────────────────────────────\n // Remove null placeholder for absent query (always at items.length - 2 when present)\n if (fragment !== null && queryItems === null) {\n items.splice(items.length - 2, 1);\n }\n // Remove trailing empty PATH array — but only when it is truly the last element\n // (i.e., neither a query nor a fragment follows it). An empty QUERY array []\n // means \"query is present but empty\" (?), which must be preserved.\n if (queryItems === null && fragment === null) {\n const last = items[items.length - 1];\n if (last instanceof CborArray && last.items.length === 0) {\n items.pop();\n }\n }\n\n // ── 6. Canonical same-document form ──────────────────────────────────────\n // Per §5.2: [discard=0] with no other items is sent as [] (empty array).\n if (\n items.length === 1 &&\n items[0] instanceof CborUint &&\n (items[0] as CborUint).value === 0n\n ) {\n return [];\n }\n\n return items;\n}\n\n/**\n * Encode query and fragment items from `items[startIdx..]` into a URI suffix string.\n * Handles both the `[] = empty query`, `[items] = query params`, `null = absent query`,\n * and optional trailing text fragment.\n */\nfunction _criSuffix(items: readonly CborItem[], startIdx: number): string {\n let idx = startIdx;\n let result = '';\n\n if (idx < items.length) {\n const qi = items[idx];\n if (qi instanceof CborArray) {\n idx++;\n // Per §5.1 / draft-ietf-core-href:\n // [] (empty array) = absent query — omit \"?\" entirely (trailing default)\n // [\"\"] = present but empty query — emit \"?\"\n // [\"k=v\", ...] = query with parameters — emit \"?k=v&...\"\n if (qi.items.length > 0) {\n const params = qi.items.map((s) => {\n if (!(s instanceof CborTextString))\n throw new Error('cri: query item must be a text string');\n return encodePct(s.value, isQueryItemAllowed);\n });\n result += '?' + params.join('&');\n }\n // [] = absent query → no '?' emitted\n } else if (qi instanceof CborSimple && qi.value === 22) {\n idx++; // explicit null = absent query component\n }\n // else: not a query item (text fragment follows); leave idx unchanged\n }\n\n if (idx < items.length && items[idx] instanceof CborTextString) {\n result +=\n '#' + encodePct((items[idx] as CborTextString).value, isFragmentAllowed);\n }\n\n return result;\n}\n\n/**\n * Encode a CRI path array into URI path segments.\n */\nfunction _criPathSegs(pathArr: CborArray): string[] {\n return pathArr.items.map((s) => {\n if (!(s instanceof CborTextString))\n throw new Error('cri: path segment must be a text string');\n return encodePct(s.value, isPathAllowed);\n });\n}\n\n/**\n * Convert CRI array items → URI string.\n *\n * Handles all CRI reference forms:\n * Absolute: first element is CborNint or CborTextString (scheme)\n * Network-path: first element is false (CborSimple(20))\n * Absolute-path: first element is true (CborSimple(21))\n * Relative-path: first element is CborUint (discard count ≥ 1)\n * Same-document: first element is CborUint(0)\n */\nfunction criItemsToUri(items: readonly CborItem[]): string {\n // Per §5.2: [] (empty array) is the canonical form of the same-document\n // reference [discard=0] with no query or fragment.\n if (items.length === 0) return '';\n\n let idx = 0;\n const first = items[idx++];\n\n // ── Absolute URI ──────────────────────────────────────────────────────────\n if (first instanceof CborNint || first instanceof CborTextString) {\n let schemePart: string;\n if (first instanceof CborNint) {\n const name = SCHEME_NAME_BY_ID.get(first.value);\n if (name === undefined)\n throw new Error(`cri: unrecognised scheme-id ${first.value}`);\n schemePart = name + ':';\n } else {\n schemePart = (first as CborTextString).value + ':';\n }\n\n if (idx >= items.length) return schemePart;\n\n const second = items[idx++];\n let authorityPart = '';\n let rootedPath = false;\n\n if (second instanceof CborArray) {\n authorityPart = '//' + criAuthorityToUri(second);\n rootedPath = true;\n } else if (second instanceof CborSimple) {\n if (second.value === 22)\n rootedPath = true; // null = NOAUTH-ROOTBASED\n else if (second.value === 21)\n rootedPath = false; // true = NOAUTH-ROOTLESS\n else\n throw new Error(\n `cri: unexpected no-authority value: simple(${second.value})`\n );\n } else {\n throw new Error('cri: unexpected type for authority element');\n }\n\n let pathPart = '';\n if (idx < items.length && items[idx] instanceof CborArray) {\n const pathArr = items[idx++] as CborArray;\n if (pathArr.items.length > 0) {\n pathPart = (rootedPath ? '/' : '') + _criPathSegs(pathArr).join('/');\n }\n }\n\n return schemePart + authorityPart + pathPart + _criSuffix(items, idx);\n }\n\n // ── Network-path reference: [false, authority-array, path-array, ...] ─────\n if (first instanceof CborSimple && first.value === 20) {\n if (idx >= items.length || !(items[idx] instanceof CborArray))\n throw new Error(\n 'cri: network-path reference requires an authority array'\n );\n const authority = criAuthorityToUri(items[idx++] as CborArray);\n let pathPart = '';\n if (idx < items.length && items[idx] instanceof CborArray) {\n const pathArr = items[idx++] as CborArray;\n if (pathArr.items.length > 0) {\n pathPart = '/' + _criPathSegs(pathArr).join('/');\n }\n }\n return '//' + authority + pathPart + _criSuffix(items, idx);\n }\n\n // ── Absolute-path reference: [true, path-array, ...] ─────────────────────\n if (first instanceof CborSimple && first.value === 21) {\n let pathPart = '/';\n if (idx < items.length && items[idx] instanceof CborArray) {\n const pathArr = items[idx++] as CborArray;\n pathPart = '/' + _criPathSegs(pathArr).join('/');\n }\n return pathPart + _criSuffix(items, idx);\n }\n\n // ── Relative-path / same-document: [uint(discard), ...] ──────────────────\n if (first instanceof CborUint) {\n const discard = first.value;\n\n if (discard === 0n) {\n // Same-document reference: path unchanged, only query/fragment differ\n return _criSuffix(items, idx);\n }\n\n // discard=1 → same directory (no \"../\" prefix)\n // discard=N → (N-1) \"../\" prefixes\n const dotdots = discard === 1n ? '' : '../'.repeat(Number(discard) - 1);\n\n let pathPart: string;\n if (idx < items.length && items[idx] instanceof CborArray) {\n const pathArr = items[idx++] as CborArray;\n if (pathArr.items.length > 0) {\n const segs = _criPathSegs(pathArr);\n // §6.1: when discard=1, prefix with \"./\" if the first segment contains \":\"\n // to prevent URI parsers from misreading it as a scheme (RFC 3986 §3.3).\n const needsDotSlash = discard === 1n && segs[0].includes(':');\n pathPart = (needsDotSlash ? './' : dotdots) + segs.join('/');\n } else {\n // Empty path array (should be trimmed, but handle defensively)\n pathPart = dotdots === '' ? './' : dotdots;\n }\n } else {\n // No path array (trimmed away)\n pathPart = dotdots === '' ? './' : dotdots;\n }\n\n return pathPart + _criSuffix(items, idx);\n }\n\n throw new Error(`cri: unrecognised first element type in CRI array`);\n}\n\n// ─── CborItem subclasses ──────────────────────────────────────────────────────\n\n/**\n * Bare CRI array whose toCDN() emits cri'…' notation.\n * Falls back to generic array notation if the content cannot be expressed as a URI.\n */\nexport class CborCriExt extends CborArray {\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(BigInt(this.items.length))\n );\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n undefined,\n this.appSeqSourceFeatures\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n try {\n return `${PREFIX_CRI}'${criItemsToUri(this.items)}'${eiSuffix}`;\n } catch {\n return super._toCDN(options, depth, path);\n }\n }\n}\n\n/**\n * tag(99, CRI array) whose toCDN() emits CRI'…' notation.\n * Falls back to generic tag notation if the content cannot be expressed as a URI.\n */\nexport class CborTaggedCriExt extends CborTag {\n constructor(content: CborArray) {\n super(TAG_CRI, content);\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const decision = decideTaggedAppSeqRendering(\n options,\n this.appSeqSource,\n this.ednSource,\n this.appSeqSourceFeatures,\n this.appSeqEncodingEditsComplete\n );\n if (decision === 'verbatim') return this.appSeqSource!;\n if (decision === 'source')\n return adjustRawAppSeqSource(\n this.appSeqSource!,\n options,\n this.appSeqComments,\n this.appSeqEncodingEdits\n );\n // Like dt's content classes, cri's content (CborCriExt) re-switches to\n // its own app-string notation unless `appPrefix` is forced false here.\n if (decision === 'structural')\n return super._toCDN({ ...options, appPrefix: false }, depth, path);\n try {\n const inner = this.content as CborArray;\n // CRI'...'_N only encodes the tag's width. If the inner array uses a\n // non-canonical count header, fall back to generic tag notation to preserve it.\n if (inner.encodingWidth !== undefined)\n return super._toCDN(options, depth, path);\n const eiSuffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(TAG_CRI)\n );\n if (decision === 'adjusted')\n return adjustAppSeqIndicator(\n this.appSeqSource!,\n eiSuffix,\n options,\n this.appSeqInnerEnd,\n this.appSeqComments\n );\n return `${PREFIX_CRI_TAGGED}'${criItemsToUri(inner.items)}'${eiSuffix}`;\n } catch {\n return super._toCDN(options, depth, path);\n }\n }\n}\n\n// ─── Builder ──────────────────────────────────────────────────────────────────\n\nfunction stringFromAppSequence(items: CborItem[]): string {\n if (items.length !== 1)\n throw new SyntaxError('cri<<...>>: expected exactly one item');\n const item = items[0];\n if (item instanceof CborTextString) return item.value;\n if (item instanceof CborByteString) return utf8Strict.decode(item.value);\n throw new SyntaxError('cri<<...>>: expected a text string or byte string');\n}\n\nfunction buildCriValue(prefix: string, uri: string): CborItem {\n const criItems = uriToCriItems(uri);\n const arr = new CborCriExt(criItems);\n if (prefix === PREFIX_CRI_TAGGED) return new CborTaggedCriExt(arr);\n return arr;\n}\n\n// ─── Extension factory ────────────────────────────────────────────────────────\n\n/**\n * Create the cri/CRI CborExtension (§3.7 and §6.2.5 of draft-ietf-cbor-edn-literals-27).\n *\n * - `cri'uri'` → CborCriExt (bare CRI array, no CBOR tag)\n * - `CRI'uri'` → CborTaggedCriExt tag(99, CRI array)\n * - parseTag(99n, …) → CborTaggedCriExt (roundtrip from CBOR binary)\n */\nexport const cri: CborExtension = {\n appStringPrefixes: [PREFIX_CRI, PREFIX_CRI_TAGGED],\n tagNumbers: [TAG_CRI],\n // cri/CRI results always have a dedicated subclass (CborCriExt /\n // CborTaggedCriExt) that regenerates its notation by default; 'optional'\n // preserves the source spelling only when ToCDNOptions.preserveAppPrefix\n // is set, without changing the returned node's class/identity.\n preserveAppSeqSource: 'optional',\n\n parseAppString(prefix: string, content: string): CborItem {\n return buildCriValue(prefix, content);\n },\n\n parseAppSequence(prefix: string, items: CborItem[]): CborItem {\n return buildCriValue(prefix, stringFromAppSequence(items));\n },\n\n parseTag(tag: bigint, value: CborItem): CborItem | undefined {\n if (tag !== TAG_CRI) return undefined;\n if (!(value instanceof CborArray)) return undefined;\n const inner = new CborCriExt(value.items, {\n indefiniteLength: value.indefiniteLength,\n encodingWidth: value.encodingWidth,\n });\n inner.start = value.start;\n inner.end = value.end;\n return new CborTaggedCriExt(inner);\n },\n};\n\nexport default cri;\n","/**\n * Built-in bignum extension (RFC 8949 §3.4.3).\n *\n * Intercepts tag 2 (unsigned bignum) and tag 3 (negative bignum) during\n * fromCBOR() and fromCDN() so that out-of-range values are decoded as\n * CborBigUint / CborBigNint rather than plain CborTag nodes.\n *\n * In-range values (those that fit in uint64 / nint64) are left as plain\n * CborTag so that non-canonical bignum encodings of small integers don't\n * silently change behaviour.\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborByteString } from '../ast/CborByteString';\nimport {\n CborBigUint,\n CborBigNint,\n bytesToBigint,\n BIGNUM_UINT_TAG,\n BIGNUM_NINT_TAG,\n} from '../ast/CborBignum';\n\nconst UINT64_MAX = 0xffff_ffff_ffff_ffffn;\nconst NINT64_MIN = -(UINT64_MAX + 1n);\n\nexport const bignum: CborExtension = {\n tagNumbers: [BIGNUM_UINT_TAG, BIGNUM_NINT_TAG],\n\n parseTag(tag: bigint, value: CborItem): CborItem | undefined {\n if (!(value instanceof CborByteString)) return undefined;\n\n if (tag === BIGNUM_UINT_TAG) {\n const n = bytesToBigint(value.value);\n if (n > UINT64_MAX) return new CborBigUint(n);\n return undefined; // fits in uint64 — leave as plain CborTag\n }\n\n if (tag === BIGNUM_NINT_TAG) {\n const n = -1n - bytesToBigint(value.value);\n if (n < NINT64_MIN) return new CborBigNint(n);\n return undefined; // fits in nint64 — leave as plain CborTag\n }\n\n return undefined;\n },\n};\n\nexport default bignum;\n","import type { FromCBOROptions, DecodeWarning, CborExtension } from '../types';\nimport type { CborItem } from '../ast/CborItem';\nimport { resolveBuiltinExtensions } from '../extensions/builtins';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborIndefiniteByteString } from '../ast/CborIndefiniteByteString';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborIndefiniteTextString } from '../ast/CborIndefiniteTextString';\nimport { CborArray } from '../ast/CborArray';\nimport { CborMap } from '../ast/CborMap';\nimport { CborTag } from '../ast/CborTag';\nimport { CborFloat } from '../ast/CborFloat';\nimport { CborSimple } from '../ast/CborSimple';\nimport { float16BitsToFloat64 } from '../utils/float16';\nimport { bytesToHex } from '../utils/hex';\nimport {\n MT_UINT,\n MT_NINT,\n MT_BYTES,\n MT_TEXT,\n MT_ARRAY,\n MT_MAP,\n MT_TAG,\n MT_SIMPLE,\n AI_1BYTE,\n AI_2BYTE,\n AI_4BYTE,\n AI_8BYTE,\n AI_INDEFINITE,\n BREAK_CODE,\n} from './constants';\nimport type { EncodingWidth } from './encode';\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\n/**\n * Returns a non-canonical EncodingWidth when the CBOR additional-info byte\n * uses more bytes than the minimum needed for `value`. Returns undefined for\n * canonical (minimum-width) encodings so they round-trip without an _N marker.\n *\n * Canonical ranges: immediate 0–23, 1-byte 24–255, 2-byte 256–65535,\n * 4-byte 65536–4294967295, 8-byte ≥ 4294967296.\n */\nfunction aiToNonCanonicalEW(\n ai: number,\n value: bigint\n): EncodingWidth | undefined {\n if (ai === AI_1BYTE && value <= 23n) return 0;\n if (ai === AI_2BYTE && value <= 0xffn) return 1;\n if (ai === AI_4BYTE && value <= 0xffffn) return 2;\n if (ai === AI_8BYTE && value <= 0xffff_ffffn) return 3;\n return undefined;\n}\n\n/**\n * Number twin of {@link aiToNonCanonicalEW}, for the length/count arguments\n * read by {@link readLength}. Values ≥ 2^53 arrive rounded, but they are far\n * above every threshold here, so the result is unaffected.\n */\nfunction aiToNonCanonicalEWLen(\n ai: number,\n value: number\n): EncodingWidth | undefined {\n if (ai === AI_1BYTE && value <= 23) return 0;\n if (ai === AI_2BYTE && value <= 0xff) return 1;\n if (ai === AI_4BYTE && value <= 0xffff) return 2;\n if (ai === AI_8BYTE && value <= 0xffff_ffff) return 3;\n return undefined;\n}\n\nconst textDecoderStrict = new TextDecoder('utf-8', {\n fatal: true,\n ignoreBOM: true,\n});\n\nconst textDecoderLenient = new TextDecoder('utf-8', {\n fatal: false,\n ignoreBOM: true,\n});\n\nfunction decodeError(msg: string): never {\n throw new Error(`CBOR decode error: ${msg}`);\n}\n\n/**\n * Emit a CBOR validity violation warning and, unless `strict: false`, throw.\n * Returns the created `DecodeWarning` (only reachable in non-strict mode).\n * For truly malformed data that cannot be recovered, use `decodeError` instead.\n */\nfunction strictViolation(\n msg: string,\n offset: number,\n options: FromCBOROptions | undefined\n): DecodeWarning {\n const warning: DecodeWarning = { message: msg, offset };\n if (options?.onWarning) {\n options.onWarning(warning);\n } else if (!options?.silent) {\n console.warn(`CBOR strict violation at offset ${offset}: ${msg}`);\n }\n if (options?.strict !== false) {\n throw new Error(`CBOR decode error: ${msg}`);\n }\n return warning;\n}\n\nfunction addWarning(node: CborItem, warning: DecodeWarning): void {\n node.warnings ??= [];\n node.warnings.push(warning);\n}\n\n/**\n * Return a data-model fingerprint for a CBOR map key.\n *\n * The fingerprint is designed so that two keys are equal if and only if they\n * represent the same CBOR data-model value, regardless of the encoding form:\n * - Integers: compared by numeric value (width differences ignored)\n * - Text strings: compared by Unicode string content (definite vs indefinite ignored)\n * - Byte strings: compared by raw byte sequence (definite vs indefinite ignored)\n * - Floats: compared by numeric value (precision ignored; all NaN treated equal)\n * - Simple values: compared by simple value number\n * - Arrays/maps/tags: recursively fingerprinted\n *\n * Implemented as two functions: `fingerprintKeyVal` builds a nested-array\n * structure (no pre-serialised strings), and `fingerprintKey` serialises it\n * with a single JSON.stringify call. Keeping recursion in the array domain\n * avoids the exponential character-escaping blowup that occurs when\n * pre-serialised JSON strings are embedded inside further JSON.stringify calls.\n */\nfunction fingerprintKeyVal(key: CborItem): unknown {\n if (key instanceof CborUint) return ['u', String(key.value)];\n if (key instanceof CborNint) return ['n', String(key.value)];\n if (key instanceof CborTextString) return ['t', key.value];\n if (key instanceof CborIndefiniteTextString)\n return ['t', key.chunks.map((c) => c.value).join('')];\n if (key instanceof CborByteString) return ['b', bytesToHex(key.value)];\n if (key instanceof CborIndefiniteByteString) {\n let h = '';\n for (const chunk of key.chunks) h += bytesToHex(chunk.value);\n return ['b', h];\n }\n if (key instanceof CborFloat) {\n // Use String() for all float cases: avoids JSON.stringify silently converting\n // NaN and ±Infinity to null, and -0 to \"0\".\n if (isNaN(key.value)) return ['f', 'NaN'];\n if (Object.is(key.value, -0)) return ['f', '-0'];\n return ['f', String(key.value)];\n }\n if (key instanceof CborSimple) return ['s', key.value];\n if (key instanceof CborArray) return ['A', key.items.map(fingerprintKeyVal)];\n if (key instanceof CborMap) {\n const pairs = key.entries.map(([k, v]) => [\n fingerprintKeyVal(k),\n fingerprintKeyVal(v),\n ]);\n // 0/1 entries: nothing to sort — and skipping the stringify here keeps\n // deeply-nested single-entry map chains linear instead of quadratic.\n if (pairs.length <= 1) return ['M', pairs];\n // Sort by key fingerprint so that maps with the same entries in different\n // insertion order fingerprint identically (RFC 8949 data model: unordered).\n // Decorate-sort-undecorate: stringify each key once, not per comparison.\n const decorated = pairs.map(\n (pair) => [JSON.stringify(pair[0]), pair] as const\n );\n decorated.sort((a, b) => (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));\n return ['M', decorated.map((d) => d[1])];\n }\n if (key instanceof CborTag)\n return ['G', String(key.tag), fingerprintKeyVal(key.content)];\n // Fallback for any remaining AST node (e.g. CborEmbeddedCBOR): canonical CBOR bytes.\n return ['c', bytesToHex(key.toCBOR())];\n}\n\nfunction fingerprintKey(key: CborItem): string {\n // Fast paths for scalar keys (the overwhelmingly common case) — avoids a\n // throwaway array + JSON.stringify per key. JSON fingerprints always start\n // with '[', so these single-letter prefixes cannot collide with them, and\n // each fast-path prefix is distinct so they cannot collide with each other.\n if (key instanceof CborUint) return 'u' + key.value;\n if (key instanceof CborNint) return 'n' + key.value;\n if (key instanceof CborTextString) return 't' + key.value;\n if (key instanceof CborIndefiniteTextString) {\n let s = 't';\n for (const c of key.chunks) s += c.value;\n return s;\n }\n if (key instanceof CborByteString) return 'b' + bytesToHex(key.value);\n if (key instanceof CborIndefiniteByteString) {\n let s = 'b';\n for (const chunk of key.chunks) s += bytesToHex(chunk.value);\n return s;\n }\n if (key instanceof CborFloat) {\n if (isNaN(key.value)) return 'fNaN';\n if (Object.is(key.value, -0)) return 'f-0';\n return 'f' + key.value;\n }\n if (key instanceof CborSimple) return 's' + key.value;\n return JSON.stringify(fingerprintKeyVal(key));\n}\n\n/**\n * Pre-computed BigInt values for CBOR inline arguments 0–23.\n * readArgument() is called for every data item header; avoiding BigInt()\n * construction for the common small-integer case saves measurable time.\n */\nconst SMALL_BIGINTS: readonly bigint[] = Array.from({ length: 24 }, (_, i) =>\n BigInt(i)\n);\n\n/**\n * Default resolved builtins (no `builtinExtensions` override) filtered to\n * those with a parseTag hook, cached after first use. Lazy (not module-level)\n * because cbordata.ts imports decoder.ts, forming a cycle that leaves the\n * builtins module's exports undefined at module init time.\n */\nlet _defaultTagExts: readonly CborExtension[] | undefined;\nfunction getBuiltinTagExts(\n builtinExtensions: CborExtension[] | false | undefined\n): readonly CborExtension[] {\n if (builtinExtensions === undefined)\n return (_defaultTagExts ??= resolveBuiltinExtensions(undefined).filter(\n (ext) => ext.parseTag !== undefined\n ));\n return resolveBuiltinExtensions(builtinExtensions).filter(\n (ext) => ext.parseTag !== undefined\n );\n}\n\n/**\n * Decode a short (< 64 byte) pure-ASCII UTF-8 sequence without invoking\n * TextDecoder. Returns undefined if any byte is >= 0x80 (non-ASCII).\n * Only called for length < 64; longer strings use TextDecoder directly to\n * avoid the double-scan cost of failing mid-way through a large buffer.\n */\nfunction tryDecodeAscii(bytes: Uint8Array, length: number): string | undefined {\n for (let i = 0; i < length; i++) {\n if (bytes[i] >= 0x80) return undefined;\n }\n // eslint-disable-next-line prefer-spread\n return String.fromCharCode.apply(null, bytes as unknown as number[]);\n}\n\n/**\n * Read the CBOR \"argument\" that follows the initial byte.\n * For ai 0–23 the argument is inline; for 24–27 it occupies 1/2/4/8 bytes.\n */\nfunction readArgument(\n view: DataView,\n offset: number,\n ai: number\n): { value: bigint; nextOffset: number } {\n if (ai <= 23) {\n return { value: SMALL_BIGINTS[ai], nextOffset: offset };\n }\n switch (ai) {\n case AI_1BYTE:\n if (offset + 1 > view.byteLength) decodeError('unexpected end of input');\n return { value: BigInt(view.getUint8(offset)), nextOffset: offset + 1 };\n case AI_2BYTE:\n if (offset + 2 > view.byteLength) decodeError('unexpected end of input');\n return {\n value: BigInt(view.getUint16(offset, false)),\n nextOffset: offset + 2,\n };\n case AI_4BYTE:\n if (offset + 4 > view.byteLength) decodeError('unexpected end of input');\n return {\n value: BigInt(view.getUint32(offset, false)),\n nextOffset: offset + 4,\n };\n case AI_8BYTE:\n if (offset + 8 > view.byteLength) decodeError('unexpected end of input');\n return {\n value: view.getBigUint64(offset, false),\n nextOffset: offset + 8,\n };\n default:\n decodeError(`reserved additional info value: ${ai}`);\n }\n}\n\n/**\n * Read the CBOR argument as a JS number — used for the length/count of major\n * types 2–5, where {@link readArgument}'s bigint would immediately be\n * converted back via Number(). Avoids a BigInt allocation per non-immediate\n * header on the decode hot path.\n *\n * An 8-byte argument ≥ 2^53 loses precision exactly as Number(bigint) would\n * (both round to nearest double); such lengths always exceed any real input,\n * so the subsequent bounds check fails identically either way.\n */\nfunction readLength(\n view: DataView,\n offset: number,\n ai: number\n): { value: number; nextOffset: number } {\n if (ai <= 23) {\n return { value: ai, nextOffset: offset };\n }\n switch (ai) {\n case AI_1BYTE:\n if (offset + 1 > view.byteLength) decodeError('unexpected end of input');\n return { value: view.getUint8(offset), nextOffset: offset + 1 };\n case AI_2BYTE:\n if (offset + 2 > view.byteLength) decodeError('unexpected end of input');\n return { value: view.getUint16(offset, false), nextOffset: offset + 2 };\n case AI_4BYTE:\n if (offset + 4 > view.byteLength) decodeError('unexpected end of input');\n return { value: view.getUint32(offset, false), nextOffset: offset + 4 };\n case AI_8BYTE: {\n if (offset + 8 > view.byteLength) decodeError('unexpected end of input');\n const hi = view.getUint32(offset, false);\n const lo = view.getUint32(offset + 4, false);\n return { value: hi * 0x1_0000_0000 + lo, nextOffset: offset + 8 };\n }\n default:\n decodeError(`reserved additional info value: ${ai}`);\n }\n}\n\n// ─── Core recursive decoder ───────────────────────────────────────────────────\n\ntype DecodeResult = { value: CborItem; nextOffset: number };\n\n/**\n * Decode the chunks of an indefinite-length string (major type 2 or 3) up to\n * and including the \"break\" code. `what` is used in error messages and\n * `isChunk` enforces that every chunk is a definite string of that type.\n */\nfunction decodeIndefiniteChunks<T extends CborItem>(\n view: DataView,\n offset: number,\n options: FromCBOROptions | undefined,\n tagExts: readonly CborExtension[],\n what: 'byte string' | 'text string',\n isChunk: (item: CborItem) => item is T\n): { chunks: T[]; nextOffset: number } {\n const chunks: T[] = [];\n let pos = offset;\n while (true) {\n if (pos >= view.byteLength)\n decodeError(`unexpected end of indefinite ${what}`);\n if (view.getUint8(pos) === BREAK_CODE) {\n pos++;\n break;\n }\n const result = decodeItem(view, pos, options, tagExts);\n if (!isChunk(result.value))\n decodeError(`indefinite-length ${what} chunk must be a definite ${what}`);\n chunks.push(result.value);\n pos = result.nextOffset;\n }\n return { chunks, nextOffset: pos };\n}\n\n/**\n * Record a duplicate-key strict violation if `key` was already seen.\n * Mutates `seenKeys` and appends any non-strict-mode warning to `warnings`.\n */\nfunction checkDuplicateKey(\n key: CborItem,\n seenKeys: Set<string>,\n warnings: DecodeWarning[],\n options: FromCBOROptions | undefined\n): void {\n const fp = fingerprintKey(key);\n if (seenKeys.has(fp)) {\n warnings.push(\n strictViolation(\n `duplicate map key at offset ${key.start}`,\n key.start!,\n options\n )\n );\n }\n seenKeys.add(fp);\n}\n\nfunction decodeItem(\n view: DataView,\n offset: number,\n options: FromCBOROptions | undefined,\n tagExts: readonly CborExtension[]\n): DecodeResult {\n const startOffset = offset;\n const result = decodeItemInner(view, offset, options, tagExts);\n result.value.start = startOffset;\n result.value.end = result.nextOffset;\n return result;\n}\n\n/**\n * Copy a float's encoded payload bytes out of the input, so NaN payloads\n * survive a decode → encode round-trip (see `CborFloat.rawBits`).\n */\nfunction floatPayloadBytes(\n view: DataView,\n offset: number,\n length: number\n): Uint8Array {\n return new Uint8Array(view.buffer, view.byteOffset + offset, length).slice();\n}\n\nfunction decodeItemInner(\n view: DataView,\n offset: number,\n options: FromCBOROptions | undefined,\n tagExts: readonly CborExtension[]\n): DecodeResult {\n if (offset >= view.byteLength) decodeError('unexpected end of input');\n\n const initialByte = view.getUint8(offset++);\n const mt = initialByte >> 5;\n const ai = initialByte & 0x1f;\n\n switch (mt) {\n // ── Major Type 0: unsigned integer ────────────────────────────────────────\n case MT_UINT: {\n const { value, nextOffset } = readArgument(view, offset, ai);\n const encodingWidth = aiToNonCanonicalEW(ai, value);\n return { value: new CborUint(value, { encodingWidth }), nextOffset };\n }\n\n // ── Major Type 1: negative integer ───────────────────────────────────────\n case MT_NINT: {\n const { value, nextOffset } = readArgument(view, offset, ai);\n const encodingWidth = aiToNonCanonicalEW(ai, value);\n // CBOR encodes negative integers as -1 - argument\n return {\n value: new CborNint(-1n - value, { encodingWidth }),\n nextOffset,\n };\n }\n\n // ── Major Type 2: byte string ─────────────────────────────────────────────\n case MT_BYTES: {\n if (ai === AI_INDEFINITE) {\n const { chunks, nextOffset } = decodeIndefiniteChunks(\n view,\n offset,\n options,\n tagExts,\n 'byte string',\n (item): item is CborByteString => item instanceof CborByteString\n );\n return { value: new CborIndefiniteByteString(chunks), nextOffset };\n }\n const { value: length, nextOffset: dataOffset } = readLength(\n view,\n offset,\n ai\n );\n const encodingWidth = aiToNonCanonicalEWLen(ai, length);\n if (dataOffset + length > view.byteLength)\n decodeError('byte string extends beyond input');\n const bytes = new Uint8Array(\n view.buffer,\n view.byteOffset + dataOffset,\n length\n );\n return {\n value: new CborByteString(bytes.slice(), { encodingWidth }),\n nextOffset: dataOffset + length,\n };\n }\n\n // ── Major Type 3: text string ─────────────────────────────────────────────\n case MT_TEXT: {\n if (ai === AI_INDEFINITE) {\n const { chunks, nextOffset } = decodeIndefiniteChunks(\n view,\n offset,\n options,\n tagExts,\n 'text string',\n (item): item is CborTextString => item instanceof CborTextString\n );\n return { value: new CborIndefiniteTextString(chunks), nextOffset };\n }\n const { value: length, nextOffset: dataOffset } = readLength(\n view,\n offset,\n ai\n );\n const encodingWidth = aiToNonCanonicalEWLen(ai, length);\n if (dataOffset + length > view.byteLength)\n decodeError('text string extends beyond input');\n const bytes = new Uint8Array(\n view.buffer,\n view.byteOffset + dataOffset,\n length\n );\n let text: string;\n let utf8Warning: DecodeWarning | undefined;\n // Fast path: short pure-ASCII strings (map keys, identifiers) avoid\n // TextDecoder overhead. Capped at 64 bytes to prevent double-scanning\n // long buffers that turn out to contain non-ASCII bytes.\n const asciiText = length < 64 ? tryDecodeAscii(bytes, length) : undefined;\n if (asciiText !== undefined) {\n text = asciiText;\n } else {\n try {\n text = textDecoderStrict.decode(bytes);\n } catch {\n utf8Warning = strictViolation(\n 'invalid UTF-8 sequence in text string',\n dataOffset,\n options\n );\n // Only reached in non-strict mode — decode with replacement characters\n text = textDecoderLenient.decode(bytes);\n }\n }\n const textNode = new CborTextString(text, { encodingWidth });\n if (utf8Warning) addWarning(textNode, utf8Warning);\n return { value: textNode, nextOffset: dataOffset + length };\n }\n\n // ── Major Type 4: array ───────────────────────────────────────────────────\n case MT_ARRAY: {\n if (ai === AI_INDEFINITE) {\n const items: CborItem[] = [];\n let pos = offset;\n while (true) {\n if (pos >= view.byteLength)\n decodeError('unexpected end of indefinite array');\n if (view.getUint8(pos) === BREAK_CODE) {\n pos++;\n break;\n }\n const result = decodeItem(view, pos, options, tagExts);\n items.push(result.value);\n pos = result.nextOffset;\n }\n return {\n value: new CborArray(items, { indefiniteLength: true }),\n nextOffset: pos,\n };\n }\n const { value: length, nextOffset: itemsStart } = readLength(\n view,\n offset,\n ai\n );\n const encodingWidth = aiToNonCanonicalEWLen(ai, length);\n const items: CborItem[] = [];\n let pos = itemsStart;\n for (let i = 0; i < length; i++) {\n const result = decodeItem(view, pos, options, tagExts);\n items.push(result.value);\n pos = result.nextOffset;\n }\n return {\n value: new CborArray(items, { encodingWidth }),\n nextOffset: pos,\n };\n }\n\n // ── Major Type 5: map ─────────────────────────────────────────────────────\n case MT_MAP: {\n if (ai === AI_INDEFINITE) {\n const entries: [CborItem, CborItem][] = [];\n const seenKeysIndef = new Set<string>();\n const indefMapWarnings: DecodeWarning[] = [];\n let pos = offset;\n while (true) {\n if (pos >= view.byteLength)\n decodeError('unexpected end of indefinite map');\n if (view.getUint8(pos) === BREAK_CODE) {\n pos++;\n break;\n }\n const keyResult = decodeItem(view, pos, options, tagExts);\n checkDuplicateKey(\n keyResult.value,\n seenKeysIndef,\n indefMapWarnings,\n options\n );\n pos = keyResult.nextOffset;\n const valResult = decodeItem(view, pos, options, tagExts);\n pos = valResult.nextOffset;\n entries.push([keyResult.value, valResult.value]);\n }\n const indefMapNode = new CborMap(entries, { indefiniteLength: true });\n for (const w of indefMapWarnings) addWarning(indefMapNode, w);\n return { value: indefMapNode, nextOffset: pos };\n }\n const { value: length, nextOffset: entriesStart } = readLength(\n view,\n offset,\n ai\n );\n const encodingWidth = aiToNonCanonicalEWLen(ai, length);\n const entries: [CborItem, CborItem][] = [];\n const seenKeys = new Set<string>();\n const mapWarnings: DecodeWarning[] = [];\n let pos = entriesStart;\n for (let i = 0; i < length; i++) {\n const keyResult = decodeItem(view, pos, options, tagExts);\n checkDuplicateKey(keyResult.value, seenKeys, mapWarnings, options);\n pos = keyResult.nextOffset;\n const valResult = decodeItem(view, pos, options, tagExts);\n pos = valResult.nextOffset;\n entries.push([keyResult.value, valResult.value]);\n }\n const mapNode = new CborMap(entries, { encodingWidth });\n for (const w of mapWarnings) addWarning(mapNode, w);\n return { value: mapNode, nextOffset: pos };\n }\n\n // ── Major Type 6: tagged item ─────────────────────────────────────────────\n case MT_TAG: {\n if (ai === AI_INDEFINITE)\n decodeError('tags cannot use indefinite-length encoding');\n const { value: tagNum, nextOffset: contentStart } = readArgument(\n view,\n offset,\n ai\n );\n const tagEncodingWidth = aiToNonCanonicalEW(ai, tagNum);\n const contentResult = decodeItem(view, contentStart, options, tagExts);\n for (const ext of tagExts) {\n const result = ext.parseTag!(tagNum, contentResult.value, options);\n if (result !== undefined) {\n if (result instanceof CborTag && tagEncodingWidth !== undefined)\n result.encodingWidth = tagEncodingWidth;\n return { value: result, nextOffset: contentResult.nextOffset };\n }\n }\n return {\n value: new CborTag(tagNum, contentResult.value, {\n encodingWidth: tagEncodingWidth,\n }),\n nextOffset: contentResult.nextOffset,\n };\n }\n\n // ── Major Type 7: float / simple value ────────────────────────────────────\n case MT_SIMPLE: {\n // ai 0–19: simple value encoded inline\n if (ai <= 19) {\n return { value: new CborSimple(ai), nextOffset: offset };\n }\n // ai 20–23: false / true / null / undefined\n // Use new instances (not the static singletons) so that decodeItem() can\n // safely set byte-offset properties without corrupting any concurrently\n // live CDN AST that shares the same singleton.\n if (ai === 20) return { value: new CborSimple(20), nextOffset: offset };\n if (ai === 21) return { value: new CborSimple(21), nextOffset: offset };\n if (ai === 22) return { value: new CborSimple(22), nextOffset: offset };\n if (ai === 23) return { value: new CborSimple(23), nextOffset: offset };\n\n // ai 24: simple value in next byte (value must be >= 32)\n if (ai === AI_1BYTE) {\n if (offset + 1 > view.byteLength)\n decodeError('unexpected end of input');\n const simpleVal = view.getUint8(offset);\n if (simpleVal < 32) {\n const w = strictViolation(\n `simple value ${simpleVal} must be encoded in initial byte (0–31 reserved for extended encoding)`,\n offset - 1,\n options\n );\n // Only reached in non-strict mode — decode the value as-is\n const simpleNode = new CborSimple(simpleVal);\n addWarning(simpleNode, w);\n return { value: simpleNode, nextOffset: offset + 1 };\n }\n return { value: new CborSimple(simpleVal), nextOffset: offset + 1 };\n }\n\n // ai 25: half-precision float\n if (ai === AI_2BYTE) {\n if (offset + 2 > view.byteLength)\n decodeError('unexpected end of input');\n const bits = view.getUint16(offset, false);\n const value = float16BitsToFloat64(bits);\n return {\n value: new CborFloat(value, {\n precision: 'half',\n rawBits: Number.isNaN(value)\n ? floatPayloadBytes(view, offset, 2)\n : undefined,\n }),\n nextOffset: offset + 2,\n };\n }\n\n // ai 26: single-precision float\n if (ai === AI_4BYTE) {\n if (offset + 4 > view.byteLength)\n decodeError('unexpected end of input');\n const value = view.getFloat32(offset, false);\n return {\n value: new CborFloat(value, {\n precision: 'single',\n rawBits: Number.isNaN(value)\n ? floatPayloadBytes(view, offset, 4)\n : undefined,\n }),\n nextOffset: offset + 4,\n };\n }\n\n // ai 27: double-precision float\n if (ai === AI_8BYTE) {\n if (offset + 8 > view.byteLength)\n decodeError('unexpected end of input');\n const value = view.getFloat64(offset, false);\n return {\n value: new CborFloat(value, {\n precision: 'double',\n rawBits: Number.isNaN(value)\n ? floatPayloadBytes(view, offset, 8)\n : undefined,\n }),\n nextOffset: offset + 8,\n };\n }\n\n // ai 28–30: reserved\n if (ai < AI_INDEFINITE) {\n decodeError(`reserved additional info value in major type 7: ${ai}`);\n }\n\n // ai 31: break code — not valid at item level\n return decodeError(\n 'unexpected break code outside indefinite-length item'\n );\n }\n }\n // unreachable: all major types 0–7 are handled above\n return decodeError(`unknown major type: ${mt}`);\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\nfunction toInputBytes(data: ArrayBufferView | ArrayBufferLike): Uint8Array {\n if (\n data instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' &&\n data instanceof SharedArrayBuffer)\n ) {\n return new Uint8Array(data);\n }\n if (ArrayBuffer.isView(data)) {\n return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n }\n throw new TypeError('expected ArrayBufferView or ArrayBufferLike');\n}\n\n/**\n * Decode a CBOR-encoded byte array into a CborItem AST node.\n *\n * Accepts any `ArrayBufferView` (e.g. `Uint8Array`, `DataView`) or\n * `ArrayBufferLike` (e.g. `ArrayBuffer`, `SharedArrayBuffer`).\n *\n * Throws if the input is not well-formed CBOR or contains trailing bytes.\n */\nexport function decodeCBOR(\n input: ArrayBufferView | ArrayBufferLike,\n options?: FromCBOROptions\n): CborItem {\n const bytes = toInputBytes(input);\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const offset = options?.offset ?? 0;\n if (!Number.isInteger(offset) || offset < 0 || offset > view.byteLength) {\n throw new RangeError(\n `CBOR decode offset must be an integer between 0 and ${view.byteLength}`\n );\n }\n // Build the tag-extension list once per decode call.\n // For the common case (no user extensions) reuse the pre-filtered module-level\n // constant to avoid a spread + filter allocation on every decode call.\n const builtinTagExts = getBuiltinTagExts(options?.builtinExtensions);\n const tagExts = options?.extensions?.length\n ? [\n ...options.extensions.filter((e) => e.parseTag !== undefined),\n ...builtinTagExts,\n ]\n : builtinTagExts;\n const { value, nextOffset } = decodeItem(view, offset, options, tagExts);\n if (!options?.allowTrailing && nextOffset !== view.byteLength) {\n const w = strictViolation(\n `${view.byteLength - nextOffset} trailing byte(s) after end of CBOR item`,\n nextOffset,\n options\n );\n // Only reached in non-strict mode (strictViolation throws in strict mode).\n addWarning(value, w);\n // Scan the trailing bytes so that truly malformed trailing items\n // (e.g. truncated input, reserved additional-info values) still throw,\n // even though the leading item decoded successfully.\n const scanOpts: FromCBOROptions = { strict: false, silent: true };\n let pos = nextOffset;\n while (pos < view.byteLength) {\n ({ nextOffset: pos } = decodeItem(view, pos, scanOpts, tagExts));\n }\n }\n return value;\n}\n","/**\n * Built-in embedded CBOR extension (RFC 8949 §3.4.5.1).\n *\n * Intercepts tag 24 during fromCBOR() so that the byte string content is\n * decoded as a CBOR data item and represented as CborEmbeddedCBOR. This\n * allows toCDN() to render the value as 24(<<item>>) instead of 24(h'...').\n *\n * If the byte string is not valid CBOR (or has trailing bytes), the extension\n * returns undefined and falls back to the plain CborTag representation.\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport type { DecodeWarning, FromCBOROptions } from '../types';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborEmbeddedCBOR } from '../ast/CborEmbeddedCBOR';\nimport { CborTag } from '../ast/CborTag';\nimport { decodeCBOR } from '../cbor/decoder';\n\nexport const TAG_CBOR_DATA = 24n;\n\nconst cbordata: CborExtension = {\n tagNumbers: [TAG_CBOR_DATA],\n\n parseTag(\n tag: bigint,\n value: CborItem,\n options?: FromCBOROptions\n ): CborItem | undefined {\n if (tag !== TAG_CBOR_DATA) return undefined;\n if (!(value instanceof CborByteString)) return undefined;\n // The embedded bytes are decoded as a fresh buffer starting at offset 0,\n // so any offset reported by the inner decode (via onWarning, or a thrown\n // error) is relative to that buffer and must be translated back to the\n // payload's actual position in the outer input before it reaches callers.\n const payloadStart = (value.end ?? value.value.length) - value.value.length;\n // Forward strict/silent/builtinExtensions into the inner decode, but\n // reset offset and allowTrailing since the embedded bytes start at 0.\n // Forwarding builtinExtensions matters for the allowlist story: a\n // disabled built-in (e.g. dt via builtinExtensions: false) must not\n // re-enable itself for tags found inside embedded CBOR.\n const innerOptions: FromCBOROptions | undefined = options\n ? {\n extensions: options.extensions,\n builtinExtensions: options.builtinExtensions,\n strict: options.strict,\n onWarning: options.onWarning\n ? (w: DecodeWarning) =>\n options.onWarning!({ ...w, offset: w.offset + payloadStart })\n : undefined,\n silent: options.silent,\n }\n : undefined;\n try {\n const decoded = decodeCBOR(value.value, innerOptions);\n return new CborTag(\n TAG_CBOR_DATA,\n new CborEmbeddedCBOR([decoded], { encodingWidth: value.encodingWidth })\n );\n } catch (e) {\n if (innerOptions?.strict !== false) {\n // In strict mode, propagate inner violations to the outer decode.\n throw e;\n }\n // In non-strict mode, fall back to a plain CborTag, but still surface\n // the violation via onWarning — otherwise callers that rely on it to\n // detect problems (e.g. CBOR.validate()) would see no signal at all\n // for tag 24 content that isn't valid CBOR.\n const message = `tag 24 content is not valid CBOR: ${\n e instanceof Error ? e.message : String(e)\n }`;\n const warning: DecodeWarning = { message, offset: payloadStart };\n if (options?.onWarning) {\n options.onWarning(warning);\n } else if (!options?.silent) {\n console.warn(\n `CBOR strict violation at offset ${warning.offset}: ${message}`\n );\n }\n return undefined;\n }\n },\n};\n\nexport default cbordata;\n","/**\n * Core decode support for the CPA888 ellipsis (elision) tag (§5.2 of\n * draft-ietf-cbor-edn-literals-27).\n *\n * Intercepts tag 888 during fromCBOR() and integer-tagged EDN parsing so\n * that elided items decode back to CborEllipsis and round-trip as `...`\n * notation instead of `888(null)` / `888([...])`.\n *\n * Ellipsis is core EDN syntax (the CDN parser handles `...` directly, not\n * via an app-string extension), so this lives in CORE_EXTENSIONS and is not\n * affected by the `builtinExtensions` option.\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborEllipsis, CPA888_TAG } from '../ast/CborEllipsis';\nimport { CborArray } from '../ast/CborArray';\nimport { CborSimple } from '../ast/CborSimple';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborByteString } from '../ast/CborByteString';\n\n/** Subtree elision marker: 888(null), already reconstructed bottom-up. */\nfunction isSubtreeEllipsis(item: CborItem): boolean {\n return item instanceof CborEllipsis && !(item.content instanceof CborArray);\n}\n\n/**\n * A well-formed string-elision array: string fragments of a single kind\n * (all text or all byte) strictly alternating with at least one subtree\n * ellipsis (`h'...'` yields the single-item form `888([888(null)])`).\n * Any other shape stays a plain CborTag — a lenient reconstruction (e.g. of\n * adjacent fragments or adjacent ellipses) would not re-parse to the same\n * data item.\n */\nfunction isElisionArray(items: readonly CborItem[]): boolean {\n let text = false;\n let byte = false;\n let sawEllipsis = false;\n let prevWasEllipsis: boolean | undefined;\n for (const item of items) {\n let isEllipsis: boolean;\n if (isSubtreeEllipsis(item)) {\n isEllipsis = true;\n sawEllipsis = true;\n } else if (item instanceof CborTextString) {\n isEllipsis = false;\n text = true;\n } else if (item instanceof CborByteString) {\n isEllipsis = false;\n byte = true;\n } else {\n return false;\n }\n if (isEllipsis === prevWasEllipsis) return false; // no strict alternation\n prevWasEllipsis = isEllipsis;\n }\n return sawEllipsis && !(text && byte); // fragments must be homogeneous\n}\n\nexport const ellipsis: CborExtension = {\n tagNumbers: [CPA888_TAG],\n\n parseTag(tag: bigint, value: CborItem): CborItem | undefined {\n if (tag !== CPA888_TAG) return undefined;\n if (value instanceof CborSimple && value.value === 22)\n return new CborEllipsis();\n if (value instanceof CborArray && isElisionArray(value.items))\n return new CborEllipsis(value.items);\n return undefined;\n },\n};\n\nexport default ellipsis;\n","/**\n * `t1'...'` / `t1<<...>>` and `b1'...'` / `b1<<...>>` string-concatenation\n * app-extensions (§3.5 of draft-ietf-cbor-edn-literals-27).\n *\n * Builds a single (text or byte) string by joining the bytes of the (text or\n * byte) string arguments from left to right:\n * - `t1` produces a text string; the joined bytes must be valid UTF-8.\n * - `b1` produces a byte string.\n * Text and byte strings can mix within one concatenation.\n *\n * Arguments may include ellipses (`...`); the result is then an ellipsis\n * data item — tag CPA888 wrapping an array of joined string spans\n * alternating with `888(null)` markers (§5.2). Adjacent ellipses collapse\n * into one, and nested ellipsis arguments are flattened.\n *\n * `t1` and `b1` are mandatory-to-implement in draft-27 and are included in\n * the default extension set.\n *\n * NOTE: the identifiers \"t1\" and \"b1\" are explicitly provisional in\n * draft-27 (§3.5) and may be renamed by the CBOR WG.\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborIndefiniteTextString } from '../ast/CborIndefiniteTextString';\nimport { CborIndefiniteByteString } from '../ast/CborIndefiniteByteString';\nimport { CborEllipsis } from '../ast/CborEllipsis';\nimport { CborAppSeqResult } from '../ast/CborAppSeqResult';\nimport { CborArray } from '../ast/CborArray';\n\nconst textEncoder = new TextEncoder();\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\nconst utf8Lenient = new TextDecoder('utf-8', { fatal: false });\n\n/** Marker for an elision within the flattened argument list. */\nconst ELLIPSIS = Symbol('ellipsis');\ntype Part = Uint8Array | typeof ELLIPSIS;\n\nfunction concatBytes(parts: Uint8Array[]): Uint8Array {\n let total = 0;\n for (const p of parts) total += p.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\n/**\n * Flatten one argument into byte spans and ellipsis markers.\n * Nested ellipsis items (e.g. from `h'aa...bb'` arguments) are expanded so\n * that the equivalences of §3.5 hold.\n */\nfunction flattenArg(prefix: string, item: CborItem, parts: Part[]): void {\n if (item instanceof CborAppSeqResult) {\n flattenArg(prefix, item.inner, parts);\n return;\n }\n if (item instanceof CborEllipsis) {\n if (item.content instanceof CborArray) {\n for (const inner of item.content.items) flattenArg(prefix, inner, parts);\n } else {\n parts.push(ELLIPSIS);\n }\n return;\n }\n if (item instanceof CborTextString) {\n parts.push(textEncoder.encode(item.value));\n return;\n }\n if (item instanceof CborByteString) {\n parts.push(item.value);\n return;\n }\n if (item instanceof CborIndefiniteTextString) {\n parts.push(textEncoder.encode(item.chunks.map((c) => c.value).join('')));\n return;\n }\n if (item instanceof CborIndefiniteByteString) {\n parts.push(concatBytes(item.chunks.map((c) => c.value)));\n return;\n }\n throw new SyntaxError(\n `${prefix}<<...>> arguments must be (text or byte) strings or ellipses`\n );\n}\n\n/** Decode joined bytes as UTF-8; recoverable violation when invalid. */\nfunction decodeText(\n bytes: Uint8Array,\n onError: ((msg: string) => void) | undefined\n): string {\n try {\n return utf8Strict.decode(bytes);\n } catch {\n const msg = `t1 concatenation result is not valid UTF-8`;\n if (onError) onError(msg);\n else throw new SyntaxError(msg);\n return utf8Lenient.decode(bytes);\n }\n}\n\nfunction concatenate(\n prefix: string,\n items: CborItem[],\n onError?: (msg: string) => void\n): CborItem {\n const parts: Part[] = [];\n for (const item of items) flattenArg(prefix, item, parts);\n\n const isText = prefix === 't1';\n\n // Consolidate adjacent byte spans; collapse adjacent ellipses (§3.5).\n const fragments: CborItem[] = [];\n let hasEllipsis = false;\n const pending: Uint8Array[] = [];\n const flushPending = () => {\n if (pending.length === 0) return;\n const bytes = concatBytes(pending);\n pending.length = 0;\n if (bytes.length === 0) return; // empty spans add nothing to the 888 array\n fragments.push(\n isText\n ? new CborTextString(decodeText(bytes, onError))\n : new CborByteString(bytes)\n );\n };\n for (const part of parts) {\n if (part === ELLIPSIS) {\n flushPending();\n if (!(fragments[fragments.length - 1] instanceof CborEllipsis)) {\n fragments.push(new CborEllipsis());\n hasEllipsis = true;\n }\n } else {\n pending.push(part);\n }\n }\n\n if (!hasEllipsis) {\n const bytes = concatBytes(pending);\n return isText\n ? new CborTextString(decodeText(bytes, onError))\n : new CborByteString(bytes);\n }\n flushPending();\n\n // A lone ellipsis argument list is equivalent to a single ellipsis.\n if (fragments.length === 1) return new CborEllipsis();\n return new CborEllipsis(fragments);\n}\n\nfunction makeExtension(prefix: 't1' | 'b1'): CborExtension {\n return {\n appStringPrefixes: [prefix],\n preserveAppSeqSource: true,\n\n // prefix'...' / prefix`...` is shorthand for a sequence with exactly\n // that one text string (§3).\n parseAppString(_prefix, content, onError) {\n return concatenate(prefix, [new CborTextString(content)], onError);\n },\n\n parseAppSequence(_prefix, items, onError) {\n return concatenate(prefix, items, onError);\n },\n };\n}\n\n/** Extension object for `t1'...'` / `t1<<...>>` (text-string concatenation). */\nexport const t1: CborExtension = makeExtension('t1');\n\n/** Extension object for `b1'...'` / `b1<<...>>` (byte-string concatenation). */\nexport const b1: CborExtension = makeExtension('b1');\n","/**\n * `ilbs'...'` / `ilbs<<...>>` and `ilts'...'` / `ilts<<...>>` app-extensions\n * (§3.6 of draft-ietf-cbor-edn-literals-27) — build indefinite-length\n * encoded strings.\n *\n * Semantically identical to `b1` / `t1` at the data model level, but instead\n * of concatenating the arguments into a single string, one chunk is created\n * per argument:\n * - `ilbs` produces an indefinite-length byte string (byte chunks),\n * - `ilts` produces an indefinite-length text string (text chunks).\n *\n * Encoding indicators on individual arguments are honored — the chunk keeps\n * the same encoding (e.g. `ilbs<<'Hello '_0, 'world'>>` → `5f 5806 ... ff`).\n * An indefinite-length string argument (e.g. a legacy `(_ ...)` streamstring)\n * is a string at the data model level and contributes one chunk with its\n * merged value. Ellipses cannot be used: there is no way to include an\n * elision in an indefinite-length string.\n *\n * These extensions replace the now-deprecated `(_ chunk, ...)` streamstring\n * syntax for new CDN documents (§4.3); this library keeps accepting the\n * legacy syntax on input.\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport type { EncodingWidth } from '../cbor/encode';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborIndefiniteTextString } from '../ast/CborIndefiniteTextString';\nimport { CborIndefiniteByteString } from '../ast/CborIndefiniteByteString';\nimport { CborEllipsis } from '../ast/CborEllipsis';\nimport { CborAppSeqResult } from '../ast/CborAppSeqResult';\nimport { escapeAppString } from '../cdn/serialize-utils';\n\nconst textEncoder = new TextEncoder();\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\nconst utf8Lenient = new TextDecoder('utf-8', { fatal: false });\n\nfunction concatBytes(parts: Uint8Array[]): Uint8Array {\n let total = 0;\n for (const p of parts) total += p.length;\n const out = new Uint8Array(total);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\nfunction buildIndefinite(\n prefix: string,\n items: CborItem[],\n onError?: (msg: string) => void\n): CborItem {\n const isText = prefix === 'ilts';\n const byteChunks: CborByteString[] = [];\n const textChunks: CborTextString[] = [];\n\n for (let item of items) {\n if (item instanceof CborAppSeqResult) item = item.inner;\n if (item instanceof CborEllipsis)\n throw new SyntaxError(\n `${prefix}<<...>> cannot contain ellipses; there is no way to include an elision in an indefinite-length string`\n );\n\n // Normalize the argument to its data-model string value. Indefinite-\n // length string arguments (e.g. a legacy `(_ ...)` streamstring) are\n // strings at the data model level; their merged value becomes one chunk.\n let argText: string | undefined;\n let argBytes: Uint8Array | undefined;\n // Encoding indicators are only carried by definite-length arguments.\n let ew: EncodingWidth | undefined;\n if (item instanceof CborTextString) {\n argText = item.value;\n ew = item.encodingWidth;\n } else if (item instanceof CborByteString) {\n argBytes = item.value;\n ew = item.encodingWidth;\n } else if (item instanceof CborIndefiniteTextString) {\n argText = item.chunks.map((c) => c.value).join('');\n } else if (item instanceof CborIndefiniteByteString) {\n argBytes = concatBytes(item.chunks.map((c) => c.value));\n } else {\n throw new SyntaxError(\n `${prefix}<<...>> arguments must be (text or byte) strings`\n );\n }\n\n // One chunk per argument, keeping the argument's encoding indicator.\n if (isText) {\n let text: string;\n if (argText !== undefined) {\n text = argText;\n } else {\n try {\n text = utf8Strict.decode(argBytes!);\n } catch {\n // RFC 8949 §3.2.3: each text-string chunk must itself be valid UTF-8.\n const msg = `ilts chunk is not valid UTF-8`;\n if (onError) onError(msg);\n else throw new SyntaxError(msg);\n text = utf8Lenient.decode(argBytes!);\n }\n }\n textChunks.push(\n new CborTextString(\n text,\n ew !== undefined ? { encodingWidth: ew } : undefined\n )\n );\n } else {\n const bytes = argBytes ?? textEncoder.encode(argText!);\n byteChunks.push(\n new CborByteString(\n bytes,\n ew !== undefined ? { encodingWidth: ew } : undefined\n )\n );\n }\n }\n\n return isText\n ? new CborIndefiniteTextString(textChunks)\n : new CborIndefiniteByteString(byteChunks);\n}\n\nfunction makeExtension(prefix: 'ilbs' | 'ilts'): CborExtension {\n return {\n appStringPrefixes: [prefix],\n preserveAppSeqSource: true,\n\n // prefix'...' / prefix`...` is shorthand for a sequence with exactly\n // that one text string (§3) — the result has a single chunk.\n // The result is wrapped so that toCDN() round-trips an app-string form\n // instead of normalizing to the deprecated `(_ ...)` streamstring\n // syntax. The source is reconstructed from the content, so the raw\n // string form prefix`...` normalizes to the single-quoted form.\n parseAppString(_prefix, content, onError) {\n const result = buildIndefinite(\n prefix,\n [new CborTextString(content)],\n onError\n );\n return new CborAppSeqResult(\n result,\n `${prefix}${escapeAppString(content)}`\n );\n },\n\n parseAppSequence(_prefix, items, onError) {\n return buildIndefinite(prefix, items, onError);\n },\n };\n}\n\n/** Extension object for `ilbs<<...>>` (indefinite-length byte string). */\nexport const ilbs: CborExtension = makeExtension('ilbs');\n\n/** Extension object for `ilts<<...>>` (indefinite-length text string). */\nexport const ilts: CborExtension = makeExtension('ilts');\n","/**\n * `float'...'` / `float<<...>>` app-string extension.\n *\n * Interprets a hex bit-pattern as an IEEE 754 floating-point value:\n * - 4 hex digits (2 bytes) → float16 (CBOR major-7, additional 25 / 0xf9)\n * - 8 hex digits (4 bytes) → float32 (CBOR major-7, additional 26 / 0xfa)\n * - 16 hex digits (8 bytes) → float64 (CBOR major-7, additional 27 / 0xfb)\n *\n * The string form `float'...'` supports the same comment syntax as `h'...'`:\n * slash-delimited block comments, C-style block comments, line comments (`//`\n * and `#`). The extension strips comments from the raw content itself.\n *\n * The sequence form `float<<byteStr>>` accepts a single byte-string expression\n * (e.g. `float<<h'7ef0'>>`) and interprets its bytes as float bits.\n *\n * Defined in draft-ietf-cbor-edn-literals-27 §3.8 and included in the default\n * extension set:\n *\n * @example\n * parseCDN(\"float'7ef0'\"); // NaN as float16\n */\n\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborFloat } from '../ast/CborFloat';\nimport { CborByteString } from '../ast/CborByteString';\nimport { float16BitsToFloat64, float64ToFloat16Bits } from '../utils/float16';\nimport { stripComments } from '../utils/strip-comments';\nimport { hexToBytes } from '../utils/hex';\nimport type { EncodingWidth } from '../cbor/encode';\n\n// ── Bit-preserving CborFloat subclasses ───────────────────────────────────────\n// CborFloat stores a JS `number`, which loses NaN payloads. These subclasses\n// override _toCBOR() to emit the original bit pattern verbatim.\n\nclass CborFloat16Bits extends CborFloat {\n private readonly _bits: number;\n constructor(bits: number) {\n super(float16BitsToFloat64(bits), { precision: 'half' });\n this._bits = bits & 0xffff;\n }\n override _toCBOR(): Uint8Array {\n return new Uint8Array([0xf9, (this._bits >> 8) & 0xff, this._bits & 0xff]);\n }\n}\n\nclass CborFloat32Bits extends CborFloat {\n private readonly _raw: Uint8Array;\n constructor(bytes: Uint8Array) {\n super(new DataView(bytes.buffer, bytes.byteOffset).getFloat32(0, false), {\n precision: 'single',\n });\n this._raw = bytes.slice();\n }\n override _toCBOR(): Uint8Array {\n const out = new Uint8Array(5);\n out[0] = 0xfa;\n out.set(this._raw, 1);\n return out;\n }\n}\n\nclass CborFloat64Bits extends CborFloat {\n private readonly _raw: Uint8Array;\n constructor(bytes: Uint8Array) {\n super(new DataView(bytes.buffer, bytes.byteOffset).getFloat64(0, false), {\n precision: 'double',\n });\n this._raw = bytes.slice();\n }\n override _toCBOR(): Uint8Array {\n const out = new Uint8Array(9);\n out[0] = 0xfb;\n out.set(this._raw, 1);\n return out;\n }\n}\n\nfunction floatFromBytes(bytes: Uint8Array): CborFloat {\n if (bytes.length === 2) {\n const bits = (bytes[0]! << 8) | bytes[1]!;\n return new CborFloat16Bits(bits);\n }\n if (bytes.length === 4) return new CborFloat32Bits(bytes);\n if (bytes.length === 8) return new CborFloat64Bits(bytes);\n throw new SyntaxError(\n `float'...' requires 4, 8, or 16 hex digits (2, 4, or 8 bytes); got ${bytes.length} bytes`\n );\n}\n\n/** Expand float16 bit pattern to 4-byte float32 (bit-exact, preserves NaN payloads). */\nfunction float16BitsToFloat32Bytes(bits16: number): Uint8Array {\n const sign = (bits16 >>> 15) & 1;\n const exp16 = (bits16 >>> 10) & 0x1f;\n const mant16 = bits16 & 0x3ff;\n let bits32: number;\n if (exp16 === 0x1f) {\n bits32 = (sign << 31) | 0x7f800000 | (mant16 << 13);\n } else if (exp16 === 0 && mant16 === 0) {\n bits32 = sign << 31;\n } else if (exp16 === 0) {\n // Denormal float16 → normal float32\n let m = mant16;\n let shifts = 0;\n while ((m & 0x200) === 0) {\n m <<= 1;\n shifts++;\n }\n bits32 = (sign << 31) | ((112 - shifts) << 23) | ((m & 0x1ff) << 14);\n } else {\n bits32 = (sign << 31) | ((exp16 + 112) << 23) | (mant16 << 13);\n }\n const out = new Uint8Array(4);\n new DataView(out.buffer).setUint32(0, bits32 >>> 0, false);\n return out;\n}\n\n/** Expand float16 bit pattern to 8-byte float64 (bit-exact, preserves NaN payloads). */\nfunction float16BitsToFloat64Bytes(bits16: number): Uint8Array {\n const sign = (bits16 >>> 15) & 1;\n const exp16 = (bits16 >>> 10) & 0x1f;\n const mant16 = bits16 & 0x3ff;\n const out = new Uint8Array(8);\n const dv = new DataView(out.buffer);\n if (exp16 === 0x1f) {\n dv.setUint32(0, ((sign << 31) | 0x7ff00000 | (mant16 << 10)) >>> 0, false);\n dv.setUint32(4, 0, false);\n } else if (exp16 === 0 && mant16 === 0) {\n dv.setUint32(0, (sign << 31) >>> 0, false);\n dv.setUint32(4, 0, false);\n } else if (exp16 === 0) {\n // Denormal float16 → normal float64\n let m = mant16;\n let shifts = 0;\n while ((m & 0x200) === 0) {\n m <<= 1;\n shifts++;\n }\n dv.setUint32(\n 0,\n ((sign << 31) | ((1008 - shifts) << 20) | ((m & 0x1ff) << 11)) >>> 0,\n false\n );\n dv.setUint32(4, 0, false);\n } else {\n dv.setUint32(\n 0,\n ((sign << 31) | ((exp16 + 1008) << 20) | (mant16 << 10)) >>> 0,\n false\n );\n dv.setUint32(4, 0, false);\n }\n return out;\n}\n\n/** Expand float32 bit pattern to 8-byte float64 (bit-exact, preserves NaN payloads). */\nfunction float32BitsToFloat64Bytes(bytes4: Uint8Array): Uint8Array {\n const bits32 = new DataView(bytes4.buffer, bytes4.byteOffset).getUint32(\n 0,\n false\n );\n const sign = (bits32 >>> 31) & 1;\n const exp32 = (bits32 >>> 23) & 0xff;\n const mant32 = bits32 & 0x7fffff;\n const out = new Uint8Array(8);\n const dv = new DataView(out.buffer);\n if (exp32 === 0xff) {\n dv.setUint32(0, ((sign << 31) | 0x7ff00000 | (mant32 >>> 3)) >>> 0, false);\n dv.setUint32(4, (mant32 & 7) << 29, false);\n } else if (exp32 === 0 && mant32 === 0) {\n dv.setUint32(0, (sign << 31) >>> 0, false);\n dv.setUint32(4, 0, false);\n } else {\n // Normal or denormal: JS arithmetic is exact (float32 ⊂ float64), NaN handled above.\n const f64 = new DataView(bytes4.buffer, bytes4.byteOffset).getFloat32(\n 0,\n false\n );\n dv.setFloat64(0, f64, false);\n }\n return out;\n}\n\n/**\n * Re-encode float bytes at a target precision (_1=half, _2=single, _3=double).\n * Returns undefined if the conversion is lossy (caller should warn).\n */\nfunction reencodeFloat(\n bytes: Uint8Array,\n targetWidth: 1 | 2 | 3,\n onError: (msg: string) => void\n): CborFloat {\n const naturalWidth = bytes.length === 2 ? 1 : bytes.length === 4 ? 2 : 3;\n\n if (naturalWidth === 1) {\n const bits16 = (bytes[0]! << 8) | bytes[1]!;\n if (targetWidth === 2)\n return new CborFloat32Bits(float16BitsToFloat32Bytes(bits16));\n if (targetWidth === 3)\n return new CborFloat64Bits(float16BitsToFloat64Bytes(bits16));\n }\n\n if (naturalWidth === 2) {\n if (targetWidth === 3)\n return new CborFloat64Bits(float32BitsToFloat64Bytes(bytes));\n if (targetWidth === 1) {\n const f32 = new DataView(bytes.buffer, bytes.byteOffset).getFloat32(\n 0,\n false\n );\n const bits16 = float64ToFloat16Bits(f32);\n if (!Object.is(float16BitsToFloat64(bits16), f32) && !isNaN(f32)) {\n onError(\n `float'...' value cannot be exactly represented as float16 (_1)`\n );\n }\n return new CborFloat16Bits(bits16);\n }\n }\n\n if (naturalWidth === 3) {\n const f64 = new DataView(bytes.buffer, bytes.byteOffset).getFloat64(\n 0,\n false\n );\n if (targetWidth === 1) {\n const bits16 = float64ToFloat16Bits(f64);\n if (!Object.is(float16BitsToFloat64(bits16), f64) && !isNaN(f64)) {\n onError(\n `float'...' value cannot be exactly represented as float16 (_1)`\n );\n }\n return new CborFloat16Bits(bits16);\n }\n if (targetWidth === 2) {\n const f32 = Math.fround(f64);\n if (!Object.is(f32, f64) && !isNaN(f64)) {\n onError(\n `float'...' value cannot be exactly represented as float32 (_2)`\n );\n }\n const out = new Uint8Array(4);\n new DataView(out.buffer).setFloat32(0, f32, false);\n return new CborFloat32Bits(out);\n }\n }\n\n // naturalWidth === targetWidth: identity (already handled by caller)\n return floatFromBytes(bytes);\n}\n\n/**\n * Extension object for `float'...'` / `float<<...>>`.\n * Pass to `parseCDN(..., { extensions: [float] })`.\n */\nexport const float: CborExtension = {\n appStringPrefixes: ['float'],\n\n parseAppString(\n _prefix: string,\n content: string,\n onError?: (msg: string) => void,\n options?: { encodingWidth?: EncodingWidth }\n ): CborItem {\n const hex = stripComments(content);\n if (!/^[0-9a-fA-F]*$/.test(hex))\n throw new SyntaxError(`float'...' contains non-hex characters`);\n if (hex.length % 2 !== 0)\n throw new SyntaxError(\n `float'...' hex content has odd length (${hex.length} digits)`\n );\n const bytes = hexToBytes(hex);\n const ew = options?.encodingWidth;\n if (ew === undefined) return floatFromBytes(bytes);\n if (ew !== 1 && ew !== 2 && ew !== 3) {\n const msg = `float'...' encoding indicator _${ew} is not valid; use _1, _2, or _3`;\n if (onError) {\n onError(msg);\n return floatFromBytes(bytes);\n }\n throw new SyntaxError(msg);\n }\n const naturalWidth = bytes.length === 2 ? 1 : bytes.length === 4 ? 2 : 3;\n if (ew === naturalWidth) return floatFromBytes(bytes);\n const fallbackOnError =\n onError ??\n ((msg: string) => {\n throw new SyntaxError(msg);\n });\n return reencodeFloat(bytes, ew, fallbackOnError);\n },\n\n parseAppSequence(\n _prefix: string,\n items: CborItem[],\n onError?: (msg: string) => void\n ): CborItem {\n if (items.length === 0)\n throw new SyntaxError(\n `float<<...>> requires exactly one byte-string item`\n );\n if (items.length > 1) {\n const msg = `float<<...>> expects 1 item; got ${items.length} — using first`;\n if (onError) onError(msg);\n else throw new SyntaxError(msg);\n }\n if (!(items[0] instanceof CborByteString))\n throw new SyntaxError(`float<<...>> item must be a byte string`);\n return floatFromBytes(items[0].value);\n },\n};\n\nexport default float;\n","import type { CborExtension } from './types';\nimport dt from './dt';\nimport ip from './ip';\nimport cri from './cri';\nimport bignum from './bignum';\nimport cbordata from './cbordata';\nimport ellipsis from './ellipsis';\nimport { t1, b1 } from './concat';\nimport { ilbs, ilts } from './ilstrings';\nimport float from './float';\n\n/**\n * Core data-model extensions (bignum tags 2/3, embedded-CBOR tag 24, and the\n * CPA888 ellipsis tag). These implement base CBOR/EDN representation rather\n * than an app-extension, so they are always active and are not affected by\n * the `builtinExtensions` option.\n */\nexport const CORE_EXTENSIONS: readonly CborExtension[] = [\n bignum,\n cbordata,\n ellipsis,\n];\n\n/**\n * Default app-extensions bundled with the library.\n * Overridable per call via `builtinExtensions` (an array to use instead, or\n * `false` to disable all of them).\n *\n * `dt`, `ip`, `t1`, and `b1` are mandatory-to-implement per §3 of\n * draft-ietf-cbor-edn-literals-27; `cri`, `ilbs`, `ilts`, and `float` are\n * bundled but not mandatory.\n */\nexport const BUILTIN_EXTENSIONS: readonly CborExtension[] = [\n dt,\n ip,\n cri,\n t1,\n b1,\n ilbs,\n ilts,\n float,\n];\n\nlet _defaultResolved: readonly CborExtension[] | undefined;\n\n/**\n * Resolve the `builtinExtensions` option to the full list of built-in\n * extensions that should be active: `CORE_EXTENSIONS` plus either the\n * default `BUILTIN_EXTENSIONS` set (`undefined`), a caller-supplied\n * replacement array, or nothing beyond core (`false`).\n */\nexport function resolveBuiltinExtensions(\n builtinExtensions?: CborExtension[] | false\n): readonly CborExtension[] {\n if (builtinExtensions === undefined)\n return (_defaultResolved ??= [...CORE_EXTENSIONS, ...BUILTIN_EXTENSIONS]);\n if (builtinExtensions === false) return CORE_EXTENSIONS;\n return [...CORE_EXTENSIONS, ...builtinExtensions];\n}\n","/**\n * Name/value tables for the `e'...'` external-reference EDN extension\n * (draft-ietf-cbor-edn-e-ref): resolving a CDDL-model mnemonic (`title`) to\n * the constant value it stands for (`-1`), and back.\n *\n * Three kinds of CDDL construct contribute a name, but not symmetrically:\n *\n * - A constant rule: `title = -1` (a rule whose body reduces to a single\n * integer literal). Contributes to `byName` only — `e'title'` should\n * still resolve it while parsing CDN text, but a general-purpose constant\n * says nothing about whether `-1` *means* \"title\" wherever it happens to\n * show up as a map key elsewhere, so it must not drive the reverse\n * annotation direction (`byValue` — see `extensions/eref.ts`'s\n * `annotateERefKeys()` and `ToJSOptions.eRefKeys`) *on its own*.\n * - A named group-enumeration entry used to label a map member key, e.g.\n * `? &(title: -1) => oltext`: the `&(name: value)` enum literal sitting at\n * an entry's own member-key position. Contributes to both `byName` and\n * `byValue`. The same `&(name: value)` syntax appearing somewhere *other*\n * than a member-key position (e.g. as an entry's value type) contributes\n * to `byName` only, for the same reason a constant rule does — it is not\n * itself labeling a map key.\n * - A bare reference to a constant rule, itself sitting at a member-key\n * position, e.g. `? group_mode => bool` where `group_mode = 3` elsewhere\n * in the schema: this pins the entry's key to `group_mode`'s value just\n * as narrowly as `&(name: value)` does (the schema itself requires that\n * exact key, not merely a type the value happens to satisfy), so it\n * contributes to `byValue` too — the *same* constant rule referenced\n * anywhere else (as a value's type, or not referenced by any entry at\n * all) still only contributes to `byName`, same as the first bullet.\n *\n * Only integer-valued constants are covered — a name bound to a float, text,\n * or byte-string literal is not collected. This is a deliberate, narrower\n * scope than the draft's own \"any CDDL constant value\" framing: the `e'...'`\n * use case this library targets first is CDDL models that label map-entry\n * integer keys, per the draft's own `problem-details` example, and\n * `e'name'` for such a non-integer constant currently fails to resolve —\n * see `createERefExtension()`'s parse error.\n *\n * A name bound to more than one different value anywhere in the schema is\n * ambiguous and excluded from `byName` — and, since annotating a value as\n * that name would then make the annotated CDN text itself fail to re-parse\n * (`e'name'` would have nowhere unambiguous to resolve back to), every\n * `byValue` entry for that name is excluded too, regardless of which source\n * produced it. A value bound to more than one different name is\n * independently excluded from `byValue` only (each name individually still\n * resolves via `byName`) — see `ERefTables`.\n */\n\nimport type { CddlSchema } from './schema';\nimport type {\n CddlGroup,\n CddlGroupEntry,\n CddlRule,\n CddlType,\n CddlType1,\n CddlType2,\n} from './ast';\n\nexport interface ERefTables {\n /** Name → value, for resolving `e'name'` while parsing CDN. */\n readonly byName: ReadonlyMap<string, bigint>;\n /**\n * Value → name, for annotating a validated integer map key with a name —\n * populated only from a binding at a genuine map-member-key position\n * (a `&(name: value)` literal, or a bare reference to a constant rule\n * used as the member key itself — never from either construct appearing\n * anywhere else, and never from a general constant rule that isn't\n * referenced at a member-key position at all) and only when neither the\n * name nor the value is ambiguous (see the module doc and\n * `ambiguousNames`).\n */\n readonly byValue: ReadonlyMap<bigint, string>;\n /**\n * Name → value, the exact inverse of `byValue` (safe and unambiguous by\n * construction: every name appearing in `byValue` appears there with\n * exactly one value, since a name bound to more than one value is already\n * excluded — see `ambiguousNames`). Used for the reverse direction:\n * `fromJS()`'s `eRefKeys` option converting a plain-object property name\n * back to the integer key it names, symmetric with `ToJSOptions.eRefKeys`.\n */\n readonly nameToValue: ReadonlyMap<string, bigint>;\n /**\n * Names that were seen bound to more than one different value anywhere in\n * the schema, and so were excluded from `byName` (and, transitively, from\n * every `byValue`/`nameToValue` entry that would have named a value after\n * one of them) — kept separately only to produce a clearer \"ambiguous\"\n * error message than a plain \"not defined\" one would.\n */\n readonly ambiguousNames: ReadonlySet<string>;\n /**\n * Name → value, from `name = <int literal>` rule definitions **only**\n * (including every `/=`/`//=` extension of the same name, when they all\n * agree on a single value) — deliberately excludes a name that's *only*\n * ever used as an `&(name: value)` enum label somewhere in the schema,\n * even though that label also feeds `byName`/`nameToValue` (a\n * general-purpose lookup that doesn't distinguish the two, correctly, for\n * `e'name'`'s own CDN parse direction). A *bare* type reference at a\n * member-key position (`? group_mode => bool`, or a wildcard's own key\n * type, `* group_mode => …`) means \"this rule's own constant value\" —\n * e.g. `group_mode = 3` — never \"this spelling, however it's used\n * anywhere in the schema\"; conflating the two would let an unrelated\n * `&(group_mode: 2) => …` enum label elsewhere make a wildcard whose key\n * type is the *rule* `group_mode` (which might not even be an integer\n * type at all) look like a closed, safe reference when it isn't — see\n * `cddl/eRefScope.ts`'s own use of this.\n */\n readonly ruleConstantValues: ReadonlyMap<string, bigint>;\n}\n\nconst cache = new WeakMap<CddlSchema, ERefTables>();\n\n/**\n * Extract (and cache, per schema instance) the `e'...'` name tables for a\n * compiled CDDL schema.\n */\nexport function getERefTables(schema: CddlSchema): ERefTables {\n let tables = cache.get(schema);\n if (!tables) {\n tables = extractERefTables(schema);\n cache.set(schema, tables);\n }\n return tables;\n}\n\nfunction extractERefTables(schema: CddlSchema): ERefTables {\n // Every name↔value binding, from every source (constant rules, and every\n // `&(name: value)` literal regardless of position) — drives `byName` and\n // `ambiguousNames`: the CDN `e'name'` *parse* direction, and the ambiguity\n // check a name bound to two different values anywhere must fail.\n const nameToValues = new Map<string, Set<bigint>>();\n // Only a binding at a genuine map-member-key position — drives `byValue`\n // (the reverse *annotation* direction).\n const keyPosValueToNames = new Map<bigint, Set<string>>();\n\n const addName = (name: string, value: bigint): void => {\n let values = nameToValues.get(name);\n if (!values) {\n values = new Set();\n nameToValues.set(name, values);\n }\n values.add(value);\n };\n const addKeyPosValue = (value: bigint, name: string): void => {\n let names = keyPosValueToNames.get(value);\n if (!names) {\n names = new Set();\n keyPosValueToNames.set(value, names);\n }\n names.add(name);\n };\n // Names forced out of consideration entirely — merged into\n // `ambiguousNames` at the end, alongside names genuinely bound to more\n // than one distinct integer.\n const forcedAmbiguous = new Set<string>();\n\n // Constant rules: `name = <int literal>`, including every `/=`/`//=`\n // choice extension of the same name — `x = 1` plus `x /= 2` elsewhere in\n // the schema makes `x` denote `1 / 2`, not a single constant, so both\n // literals are collected the same way two *different* rules binding `x`\n // to different values would be, letting the existing ambiguity check\n // below (`nameToValues`) correctly exclude `x` from `byName` rather than\n // resolving it to whichever definition this loop happened to see first.\n // Grouped by name *first* — rather than processed rule by rule — so that\n // an extension whose own body *isn't* a single integer literal (`x /=\n // tstr`, or `x /= 2 / 3`, itself a 2-way choice) forces the whole name\n // out of consideration too: `x` genuinely denotes `1 / tstr` (or\n // `1 / 2 / 3`) then, not reliably an integer at all, so treating *any*\n // reference to it as \"the constant 1\" would be just as wrong as the\n // all-integer ambiguous case below — silently ignoring the non-integer\n // side (as a rule-by-rule loop would, since `literalIntOfEntry` simply\n // returns `undefined` for it) is not the same as it not existing.\n // Always feeds `byName`; also consulted below (`constantValues`) so a\n // member key that's a *bare reference* to one of these rules — `?\n // group_mode => bool`, where `group_mode = 3` — is recognized as a\n // key-position binding too, the same as `&(name: value)` already is (see\n // `walkType2`'s `'ref'` case); a name with more than one possible value\n // there is likewise left for the same post-processing ambiguity check to\n // exclude, not filtered out here.\n const constantValues = new Map<string, Set<bigint>>();\n const rulesByName = new Map<string, CddlRule[]>();\n for (const rule of schema.ast) {\n if (rule.generics?.length) continue;\n let rules = rulesByName.get(rule.name);\n if (!rules) {\n rules = [];\n rulesByName.set(rule.name, rules);\n }\n rules.push(rule);\n }\n for (const [name, rules] of rulesByName) {\n const values: bigint[] = [];\n let hasNonInt = false;\n for (const rule of rules) {\n const value = literalIntOfEntry(rule.body);\n if (value === undefined) hasNonInt = true;\n else values.push(value);\n }\n // A name with *no* integer-literal definition at all was never a\n // constant-rule candidate in the first place — an ordinary map/array/\n // text-typed rule, say — same as the original, simpler rule-by-rule\n // version of this loop, which just skipped it via `continue`.\n if (values.length === 0) continue;\n // A name with *some* integer definitions and *some* non-integer ones\n // (`x = 1` plus `x /= tstr`, or a `/=` extension that's itself a\n // multi-alternative choice like `2 / 3`) is forced out entirely: it\n // genuinely denotes a union that isn't reliably an integer, so\n // treating *any* reference to it as \"the constant\" would be as wrong\n // as the all-integer ambiguous case below.\n if (hasNonInt) {\n forcedAmbiguous.add(name);\n continue;\n }\n for (const value of values) {\n addName(name, value);\n let seen = constantValues.get(name);\n if (!seen) {\n seen = new Set();\n constantValues.set(name, seen);\n }\n seen.add(value);\n }\n }\n\n // `&(name: value)` literal enum groups and bare constant-rule references,\n // wherever they appear.\n for (const rule of schema.ast)\n walkEntry(rule.body, addName, addKeyPosValue, constantValues);\n\n const ambiguousNames = new Set<string>(forcedAmbiguous);\n const byName = new Map<string, bigint>();\n for (const [name, values] of nameToValues) {\n if (values.size > 1 || forcedAmbiguous.has(name)) ambiguousNames.add(name);\n else byName.set(name, values.values().next().value!);\n }\n\n const byValue = new Map<bigint, string>();\n const nameToValue = new Map<string, bigint>();\n for (const [value, names] of keyPosValueToNames) {\n if (names.size !== 1) continue; // value named more than once: ambiguous\n const [name] = names;\n if (ambiguousNames.has(name)) continue; // name itself is ambiguous\n byValue.set(value, name);\n nameToValue.set(name, value);\n }\n\n const ruleConstantValues = new Map<string, bigint>();\n for (const [name, values] of constantValues) {\n if (values.size === 1)\n ruleConstantValues.set(name, values.values().next().value!);\n }\n\n return { byName, byValue, nameToValue, ambiguousNames, ruleConstantValues };\n}\n\n/**\n * The literal integer value of a rule/entry body that reduces to a single\n * `type1` alternative with no range/control operator — e.g. `title = -1`,\n * or (the shortcut form) `title: -1` in a group entry. `undefined` for\n * anything else (a type reference, a group, a range, …).\n */\nfunction literalIntOfEntry(entry: CddlGroupEntry): bigint | undefined {\n if (entry.kind !== 'entry') return undefined;\n return literalIntOfType(entry.value);\n}\n\n/**\n * The literal integer value of a `type`, when it reduces to a single\n * `type1` alternative with no range/control operator. `undefined` for\n * anything else. Exported for `eRefScope.ts`'s own, position-aware name\n * extraction, which needs the exact same check for an entry's own value.\n */\nexport function literalIntOfType(type: CddlType): bigint | undefined {\n if (type.alternatives.length !== 1) return undefined;\n const t1 = type.alternatives[0]!;\n if (t1.op) return undefined;\n return literalIntOfType2(t1.target);\n}\n\nfunction literalIntOfType2(t2: CddlType2): bigint | undefined {\n if (t2.kind !== 'value' || t2.type !== 'int') return undefined;\n return typeof t2.value === 'bigint' ? t2.value : BigInt(t2.value);\n}\n\n// ─── AST walk: find every `&(...)` literal enum group and every bare\n// constant-rule reference at a member-key position, collecting their named,\n// integer-literal-valued entries. Mirrors the structural walk in schema.ts.\n//\n// `atKeyPos` is `true` for the subtree reached from a *specific* entry's own\n// `memberKey.key` (a genuine map-member-key position) and `false` for the\n// subtree reached from that entry's `value` — threaded down through further\n// *type*-level nesting only (parens, tagged content, generic arguments), so\n// a `&(...)` (or a bare reference like `group_mode` in `? group_mode =>\n// bool`, where `group_mode = 3`) several levels inside a member key's own\n// type still counts as key-position. It is deliberately NOT threaded into a\n// nested *group* (`walkGroup`, reached via a map/array type, an\n// `entry-group`, or an enum literal's own group): every group entry\n// re-derives key-vs-value fresh, independent of how the group containing it\n// was itself reached — a `&(inner: 1)` genuinely at *its own* map's\n// member-key position counts as key-position even if that whole nested map\n// sits inside some outer entry's *value* (e.g. `? title: { &(inner: 1) =>\n// tstr }`), and conversely a `&(...)` sitting somewhere in a value\n// contributes to `byName` but never implies its enclosing group's own\n// entries are key-positioned by association. `walkEntry`/`walkGroup` are\n// the only functions that decide this split; every other function just\n// propagates what it was given.\n//\n// `constantValues` (name → its single literal-int value, from every `=`\n// constant rule in the schema — see `extractERefTables`) is threaded\n// through unchanged, purely so `walkType2`'s `'ref'` case can recognize a\n// bare reference to one of those rules.\n\ntype AddNameFn = (name: string, value: bigint) => void;\ntype AddKeyPosValueFn = (value: bigint, name: string) => void;\n/**\n * Name → every literal value some `=`/`/=`/`//=` rule binds it to (see\n * `extractERefTables`'s own comment on why this is a set, not a single\n * value: a `/=`/`//=` extension of an already-defined name can add more).\n */\ntype ConstantValues = ReadonlyMap<string, ReadonlySet<bigint>>;\n\nfunction walkEntry(\n entry: CddlGroupEntry,\n addName: AddNameFn,\n addKeyPosValue: AddKeyPosValueFn,\n constantValues: ConstantValues\n): void {\n if (entry.kind === 'entry-group') {\n walkGroup(entry.group, addName, addKeyPosValue, constantValues);\n return;\n }\n if (entry.memberKey?.kind === 'type1')\n walkType1(\n entry.memberKey.key,\n addName,\n addKeyPosValue,\n true,\n constantValues\n );\n walkType(entry.value, addName, addKeyPosValue, false, constantValues);\n}\n\nfunction walkGroup(\n group: CddlGroup,\n addName: AddNameFn,\n addKeyPosValue: AddKeyPosValueFn,\n constantValues: ConstantValues\n): void {\n for (const choice of group.choices)\n for (const entry of choice)\n walkEntry(entry, addName, addKeyPosValue, constantValues);\n}\n\nfunction walkType(\n type: CddlType,\n addName: AddNameFn,\n addKeyPosValue: AddKeyPosValueFn,\n atKeyPos: boolean,\n constantValues: ConstantValues\n): void {\n for (const alt of type.alternatives)\n walkType1(alt, addName, addKeyPosValue, atKeyPos, constantValues);\n}\n\nfunction walkType1(\n t1: CddlType1,\n addName: AddNameFn,\n addKeyPosValue: AddKeyPosValueFn,\n atKeyPos: boolean,\n constantValues: ConstantValues\n): void {\n walkType2(t1.target, addName, addKeyPosValue, atKeyPos, constantValues);\n if (t1.controller)\n walkType2(t1.controller, addName, addKeyPosValue, atKeyPos, constantValues);\n}\n\nfunction walkType2(\n t2: CddlType2,\n addName: AddNameFn,\n addKeyPosValue: AddKeyPosValueFn,\n atKeyPos: boolean,\n constantValues: ConstantValues\n): void {\n switch (t2.kind) {\n case 'value':\n case 'any':\n return;\n case 'ref': {\n // A bare reference to a constant rule, sitting at a member-key\n // position — e.g. `? group_mode => bool` where `group_mode = 3` —\n // pins that entry's key to `group_mode`'s value exactly as narrowly\n // as `&(name: value)` does; see the module doc. No generic args means\n // this reference *is* the whole key type, not a parameterized type\n // merely mentioning the name, so only that shape qualifies. A name\n // extended with `/=`/`//=` elsewhere has more than one possible\n // value here (see `extractERefTables`'s own comment) — every one of\n // them is added, and the post-processing ambiguity check below\n // (`keyPosValueToNames`/`ambiguousNames`) is what actually excludes\n // an extended name from `byValue`, the same as it already does for\n // two unrelated rules binding one name to different values.\n const values = constantValues.get(t2.name);\n if (atKeyPos && values && !t2.genericArgs?.length) {\n for (const value of values) addKeyPosValue(value, t2.name);\n }\n for (const arg of t2.genericArgs ?? [])\n walkType1(arg, addName, addKeyPosValue, atKeyPos, constantValues);\n return;\n }\n case 'paren':\n walkType(t2.type, addName, addKeyPosValue, atKeyPos, constantValues);\n return;\n case 'map':\n case 'array':\n walkGroup(t2.group, addName, addKeyPosValue, constantValues);\n return;\n case 'unwrap':\n for (const arg of t2.ref.genericArgs ?? [])\n walkType1(arg, addName, addKeyPosValue, atKeyPos, constantValues);\n return;\n case 'enum':\n if (t2.group.kind === 'group') {\n collectEnumGroup(t2.group, addName, addKeyPosValue, atKeyPos);\n walkGroup(t2.group, addName, addKeyPosValue, constantValues);\n } else {\n for (const arg of t2.group.genericArgs ?? [])\n walkType1(arg, addName, addKeyPosValue, atKeyPos, constantValues);\n }\n return;\n case 'tagged':\n if (typeof t2.tag === 'object')\n walkType(t2.tag, addName, addKeyPosValue, atKeyPos, constantValues);\n walkType(t2.item, addName, addKeyPosValue, atKeyPos, constantValues);\n return;\n case 'major':\n if (typeof t2.ai === 'object')\n walkType(t2.ai, addName, addKeyPosValue, atKeyPos, constantValues);\n return;\n }\n}\n\n/**\n * Collect named entries directly in one `&(...)` literal group — e.g. both\n * of `&(title: -1, detail: -2)`'s entries. Only entries whose member key is\n * a bareword or a quoted-text literal, and whose value is a single integer\n * literal, contribute a name (`&(foo: 1..2)`, `&(foo: bar)`, and unnamed\n * entries are silently skipped — not every enum literal is used for naming).\n * `addKeyPosValue` is only called when `atKeyPos` — see `walkEntry`'s doc.\n */\nfunction collectEnumGroup(\n group: CddlGroup,\n addName: AddNameFn,\n addKeyPosValue: AddKeyPosValueFn,\n atKeyPos: boolean\n): void {\n for (const choice of group.choices) {\n for (const entry of choice) {\n if (entry.kind !== 'entry' || !entry.memberKey) continue;\n const mk = entry.memberKey;\n const name =\n mk.kind === 'bareword'\n ? mk.key\n : mk.kind === 'value' && mk.key.type === 'text'\n ? mk.key.value\n : undefined;\n if (name === undefined) continue;\n const value = literalIntOfType(entry.value);\n if (value === undefined) continue;\n addName(name, value);\n if (atKeyPos) addKeyPosValue(value, name);\n }\n }\n}\n","/**\n * CDDL lexer (internal).\n *\n * Implements the token-level grammar of RFC 8610 as updated by RFC 9682\n * (Appendix A collected ABNF). Used by parser.ts and exposed through the\n * `tokenize()` / `tokenizeLenient()` helpers in index.ts so tooling such as\n * syntax highlighters stays in exact agreement with parsing behavior.\n */\n\nimport { CddlSyntaxError } from './errors';\nimport { hexToBytes } from '../utils/hex';\nimport { base64ToBytes } from '../utils/base64';\n\nexport type CddlTokenType =\n | 'ID'\n | 'INT' // raw text in `value`, incl. optional '-' and 0x/0b forms\n | 'FLOAT' // raw text in `value`, decimal or hexfloat\n | 'TSTR' // decoded content in `value`\n | 'BYTES' // raw content in `value`, decoded bytes in `bytes`\n | 'HASH' // '#' with optional major/head-number (see hashMajor/hashAI)\n | 'ASSIGN' // =\n | 'SLASH_EQ' // /=\n | 'DSLASH_EQ' // //=\n | 'SLASH' // /\n | 'DSLASH' // //\n | 'COMMA'\n | 'LPAREN'\n | 'RPAREN'\n | 'LBRACE'\n | 'RBRACE'\n | 'LBRACKET'\n | 'RBRACKET'\n | 'LT'\n | 'GT'\n | 'TILDE'\n | 'AMP'\n | 'RANGE_INCL' // ..\n | 'RANGE_EXCL' // ...\n | 'CTLOP' // .id — operator name (without the dot) in `value`\n | 'STAR'\n | 'PLUS'\n | 'QUEST'\n | 'ARROW' // =>\n | 'COLON'\n | 'CARET'\n | 'EOF'\n /** Synthetic token emitted by tokenizeLenient() for the unscannable tail. */\n | 'ERROR';\n\nexport interface CddlToken {\n type: CddlTokenType;\n /** Processed value: decoded string content, raw numeric text, id text, etc. */\n value: string;\n /** Original source text for this token. */\n raw: string;\n line: number;\n col: number;\n /** Character offset of the first character of this token in the source input. */\n offset: number;\n /** Character offset just past the last character of this token in the source input. */\n endOffset: number;\n /** Only set when type === 'BYTES': the qualifier ('' | 'h' | 'b64'). */\n qualifier?: '' | 'h' | 'b64';\n /** Only set when type === 'BYTES': the decoded byte content. */\n bytes?: Uint8Array;\n /** Only set when type === 'HASH': the major digit (0–9), absent for bare '#'. */\n hashMajor?: number;\n /** Only set when type === 'HASH': the literal head-number after the dot. */\n hashAI?: bigint;\n /**\n * Only set when type === 'HASH': the head-number is a `<type>` expression\n * (RFC 9682 §3.2); the tokens for `<` type `>` follow this token.\n */\n hashAIExpr?: boolean;\n}\n\n/** A `;` line comment collected while scanning. */\nexport interface CddlComment {\n /** Comment text after the ';' marker, without the trailing newline. */\n text: string;\n start: number;\n end: number;\n line: number;\n col: number;\n}\n\n// Shared codec instance — constructing TextEncoder per token is measurably\n// expensive in hot parsing paths (same pattern as cdn/parser.ts).\nconst textEncoder = new TextEncoder();\n\nconst isDigit = (c: string): boolean => c >= '0' && c <= '9';\nconst isHexDigit = (c: string): boolean =>\n isDigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');\nconst isEAlpha = (c: string): boolean =>\n (c >= 'a' && c <= 'z') ||\n (c >= 'A' && c <= 'Z') ||\n c === '@' ||\n c === '_' ||\n c === '$';\n\n/** NONASCII = %xA0-D7FF / %xE000-10FFFD (RFC 9682) */\nconst isNonAscii = (cp: number): boolean =>\n (cp >= 0xa0 && cp <= 0xd7ff) || (cp >= 0xe000 && cp <= 0x10fffd);\n\nexport class CddlTokenizer {\n private readonly input: string;\n private pos = 0;\n private line = 1;\n private col = 1;\n\n /** Comments encountered while scanning, in source order. */\n readonly comments: CddlComment[] = [];\n\n /** Character offset just past the last successfully scanned token. */\n lastEndOffset = 0;\n\n constructor(input: string) {\n this.input = input;\n }\n\n // ─── Low-level helpers ──────────────────────────────────────────────────────\n\n private _eof(): boolean {\n return this.pos >= this.input.length;\n }\n\n private _ch(): string {\n return this.input[this.pos] ?? '';\n }\n\n private _advance(): string {\n const ch = this.input[this.pos] ?? '';\n this.pos++;\n if (ch === '\\n') {\n this.line++;\n this.col = 1;\n } else {\n this.col++;\n }\n return ch;\n }\n\n private _fail(message: string, line?: number, col?: number): never {\n throw new CddlSyntaxError(message, {\n offset: this.pos,\n line: line ?? this.line,\n column: col ?? this.col,\n });\n }\n\n // ─── Whitespace and comments ────────────────────────────────────────────────\n\n /**\n * Skip S = *(SP / NL) where NL = COMMENT / CRLF.\n *\n * Per the ABNF only SP (0x20), LF, and CRLF are whitespace; horizontal tab\n * is not valid CDDL whitespace and is rejected with a targeted message.\n * Deliberate leniency: a bare CR (not part of CRLF) is also accepted as\n * whitespace, as source-level line-ending normalization.\n */\n private _skipWs(): void {\n for (;;) {\n const ch = this._ch();\n if (ch === ' ' || ch === '\\n' || ch === '\\r') {\n this._advance();\n continue;\n }\n if (ch === '\\t')\n this._fail(\n 'horizontal tab is not valid whitespace in CDDL (RFC 8610 ABNF allows only space and newline)'\n );\n if (ch === ';') {\n this._scanComment();\n continue;\n }\n return;\n }\n }\n\n /**\n * COMMENT = \";\" *PCHAR CRLF — collected into `this.comments`.\n *\n * Deliberate leniency: content characters are not PCHAR-validated, and a\n * comment terminated by end-of-input (no trailing newline) is accepted.\n */\n private _scanComment(): void {\n const start = this.pos;\n const line = this.line;\n const col = this.col;\n this._advance(); // ';'\n let p = this.pos;\n while (p < this.input.length) {\n const c = this.input[p]!;\n if (c === '\\n' || c === '\\r') break;\n p++;\n }\n const text = this.input.slice(this.pos, p);\n this.col += p - this.pos;\n this.pos = p;\n this.comments.push({ text, start, end: p, line, col });\n }\n\n // ─── Token production ───────────────────────────────────────────────────────\n\n private _make(\n type: CddlTokenType,\n value: string,\n startOffset: number,\n line: number,\n col: number,\n extra?: Partial<CddlToken>\n ): CddlToken {\n const token: CddlToken = {\n type,\n value,\n raw: this.input.slice(startOffset, this.pos),\n line,\n col,\n offset: startOffset,\n endOffset: this.pos,\n ...extra,\n };\n this.lastEndOffset = this.pos;\n return token;\n }\n\n /** Scan and return the next token (skipping whitespace and comments). */\n consume(): CddlToken {\n this._skipWs();\n const start = this.pos;\n const line = this.line;\n const col = this.col;\n\n if (this._eof()) return this._make('EOF', '', start, line, col);\n\n const ch = this._ch();\n\n if (isEAlpha(ch)) {\n const id = this._scanIdText();\n // bsqual: h'...' / b64'...'\n if ((id === 'h' || id === 'b64') && this._ch() === \"'\")\n return this._scanBytes(id, start, line, col);\n return this._make('ID', id, start, line, col);\n }\n\n if (isDigit(ch) || ch === '-') return this._scanNumber(start, line, col);\n\n if (ch === '\"') return this._scanText(start, line, col);\n if (ch === \"'\") return this._scanBytes('', start, line, col);\n if (ch === '#') return this._scanHash(start, line, col);\n\n switch (ch) {\n case '=':\n this._advance();\n if (this._ch() === '>') {\n this._advance();\n return this._make('ARROW', '=>', start, line, col);\n }\n return this._make('ASSIGN', '=', start, line, col);\n case '/':\n this._advance();\n if (this._ch() === '/') {\n this._advance();\n if (this._ch() === '=') {\n this._advance();\n return this._make('DSLASH_EQ', '//=', start, line, col);\n }\n return this._make('DSLASH', '//', start, line, col);\n }\n if (this._ch() === '=') {\n this._advance();\n return this._make('SLASH_EQ', '/=', start, line, col);\n }\n return this._make('SLASH', '/', start, line, col);\n case '.': {\n // '...' / '..' / '.id' (control operator)\n this._advance();\n if (this._ch() === '.') {\n this._advance();\n if (this._ch() === '.') {\n this._advance();\n return this._make('RANGE_EXCL', '...', start, line, col);\n }\n return this._make('RANGE_INCL', '..', start, line, col);\n }\n if (!isEAlpha(this._ch()))\n this._fail(\n `expected a control operator name after '.' (e.g. .size), got ${this._eof() ? 'end of input' : JSON.stringify(this._ch())}`,\n line,\n col\n );\n const op = this._scanIdText();\n return this._make('CTLOP', op, start, line, col);\n }\n case ',':\n this._advance();\n return this._make('COMMA', ',', start, line, col);\n case '(':\n this._advance();\n return this._make('LPAREN', '(', start, line, col);\n case ')':\n this._advance();\n return this._make('RPAREN', ')', start, line, col);\n case '{':\n this._advance();\n return this._make('LBRACE', '{', start, line, col);\n case '}':\n this._advance();\n return this._make('RBRACE', '}', start, line, col);\n case '[':\n this._advance();\n return this._make('LBRACKET', '[', start, line, col);\n case ']':\n this._advance();\n return this._make('RBRACKET', ']', start, line, col);\n case '<':\n this._advance();\n return this._make('LT', '<', start, line, col);\n case '>':\n this._advance();\n return this._make('GT', '>', start, line, col);\n case '~':\n this._advance();\n return this._make('TILDE', '~', start, line, col);\n case '&':\n this._advance();\n return this._make('AMP', '&', start, line, col);\n case '*':\n this._advance();\n return this._make('STAR', '*', start, line, col);\n case '+':\n this._advance();\n return this._make('PLUS', '+', start, line, col);\n case '?':\n this._advance();\n return this._make('QUEST', '?', start, line, col);\n case ':':\n this._advance();\n return this._make('COLON', ':', start, line, col);\n case '^':\n this._advance();\n return this._make('CARET', '^', start, line, col);\n default:\n this._fail(`unexpected character ${JSON.stringify(ch)}`);\n }\n }\n\n // ─── Identifiers ────────────────────────────────────────────────────────────\n\n /**\n * id = EALPHA *(*(\"-\" / \".\") (EALPHA / DIGIT))\n *\n * Interior '-' and '.' runs are allowed when followed by an EALPHA/DIGIT,\n * so `a.b`, `a-b`, and even `tstr.size` are single ids (the ABNF note\n * \"space may be needed before the operator if type2 ends in a name\" exists\n * for exactly this reason). This includes `..`: RFC 8610 §2.2.2.1 says\n * `min..max` \"is not a range expression but a single name\" — a range with\n * a name on the left-hand side must be written `min .. max`.\n */\n private _scanIdText(): string {\n const start = this.pos;\n this._advance(); // leading EALPHA, verified by caller\n for (;;) {\n const c = this._ch();\n if (isEAlpha(c) || isDigit(c)) {\n this._advance();\n continue;\n }\n if (c === '-' || c === '.') {\n // Look ahead across the separator run without consuming: the run is\n // part of the id only when an EALPHA/DIGIT follows it.\n let q = this.pos;\n while (this.input[q] === '-' || this.input[q] === '.') q++;\n const after = this.input[q] ?? '';\n if (!(isEAlpha(after) || isDigit(after))) break;\n while (this.pos <= q) this._advance(); // separators + first id char\n continue;\n }\n break;\n }\n return this.input.slice(start, this.pos);\n }\n\n // ─── Numbers ────────────────────────────────────────────────────────────────\n\n /**\n * number = hexfloat / (int [\".\" fraction] [\"e\" exponent])\n * hexfloat = [\"-\"] \"0x\" 1*HEXDIG [\".\" 1*HEXDIG] \"p\" exponent\n * uint = DIGIT1 *DIGIT / \"0x\" 1*HEXDIG / \"0b\" 1*BINDIG / \"0\"\n *\n * The token `value` is the raw numeric text; the parser converts it.\n * A '.' followed by another '.' is never consumed (range operator).\n */\n private _scanNumber(start: number, line: number, col: number): CddlToken {\n if (this._ch() === '-') this._advance();\n if (!isDigit(this._ch()))\n this._fail(`expected a digit after '-'`, line, col);\n\n let isFloat = false;\n\n if (this._ch() === '0' && /[xX]/.test(this.input[this.pos + 1] ?? '')) {\n this._advance(); // 0\n this._advance(); // x\n if (!isHexDigit(this._ch()))\n this._fail('expected hex digits after 0x', line, col);\n while (isHexDigit(this._ch())) this._advance();\n // hexfloat fraction/exponent\n if (\n this._ch() === '.' &&\n isHexDigit(this.input[this.pos + 1] ?? '') &&\n this.input[this.pos + 1] !== undefined\n ) {\n // Only a hexfloat may follow; a plain hex int never has a fraction.\n this._advance(); // .\n while (isHexDigit(this._ch())) this._advance();\n if (!/[pP]/.test(this._ch()))\n this._fail(\n \"hexadecimal fraction requires a 'p' exponent (hexfloat)\",\n line,\n col\n );\n }\n if (/[pP]/.test(this._ch())) {\n this._advance(); // p\n if (this._ch() === '+' || this._ch() === '-') this._advance();\n if (!isDigit(this._ch()))\n this._fail(\"expected exponent digits after 'p'\", line, col);\n while (isDigit(this._ch())) this._advance();\n isFloat = true;\n }\n } else if (\n this._ch() === '0' &&\n /[bB]/.test(this.input[this.pos + 1] ?? '')\n ) {\n this._advance(); // 0\n this._advance(); // b\n if (!/[01]/.test(this._ch()))\n this._fail('expected binary digits after 0b', line, col);\n while (/[01]/.test(this._ch())) this._advance();\n } else {\n if (this._ch() === '0' && isDigit(this.input[this.pos + 1] ?? ''))\n this._fail('leading zeros are not allowed in CDDL numbers', line, col);\n while (isDigit(this._ch())) this._advance();\n // fraction — but never consume '..' (range operator)\n if (this._ch() === '.' && isDigit(this.input[this.pos + 1] ?? '')) {\n this._advance(); // .\n while (isDigit(this._ch())) this._advance();\n isFloat = true;\n }\n if (/[eE]/.test(this._ch())) {\n this._advance(); // e\n if (this._ch() === '+' || this._ch() === '-') this._advance();\n if (!isDigit(this._ch()))\n this._fail(\"expected exponent digits after 'e'\", line, col);\n while (isDigit(this._ch())) this._advance();\n isFloat = true;\n }\n }\n\n const raw = this.input.slice(start, this.pos);\n return this._make(isFloat ? 'FLOAT' : 'INT', raw, start, line, col);\n }\n\n /** Scan a uint (decimal / 0x / 0b) for a '#' head-number; returns raw text. */\n private _scanUintRaw(): string {\n const start = this.pos;\n if (!isDigit(this._ch()))\n this._fail('expected an unsigned integer head-number');\n if (this._ch() === '0' && /[xX]/.test(this.input[this.pos + 1] ?? '')) {\n this._advance();\n this._advance();\n if (!isHexDigit(this._ch())) this._fail('expected hex digits after 0x');\n while (isHexDigit(this._ch())) this._advance();\n } else if (\n this._ch() === '0' &&\n /[bB]/.test(this.input[this.pos + 1] ?? '')\n ) {\n this._advance();\n this._advance();\n if (!/[01]/.test(this._ch()))\n this._fail('expected binary digits after 0b');\n while (/[01]/.test(this._ch())) this._advance();\n } else {\n if (this._ch() === '0' && isDigit(this.input[this.pos + 1] ?? ''))\n this._fail('leading zeros are not allowed in CDDL numbers');\n while (isDigit(this._ch())) this._advance();\n }\n return this.input.slice(start, this.pos);\n }\n\n // ─── '#' types ──────────────────────────────────────────────────────────────\n\n /**\n * \"#\" — any\n * \"#\" DIGIT [\".\" head-number] — major type (and tag/simple shorthands)\n * head-number = uint / \"<\" type \">\" (RFC 9682 §3.2)\n *\n * The '#', major digit, and a literal head-number are fused into a single\n * HASH token (they must be adjacent in the source; `# 6` is a bare '#'\n * followed by the value 6). For the `<type>` form, hashAIExpr is set and\n * the `<` type `>` tokens follow.\n */\n private _scanHash(start: number, line: number, col: number): CddlToken {\n this._advance(); // '#'\n const extra: Partial<CddlToken> = {};\n if (isDigit(this._ch())) {\n extra.hashMajor = this._advance().charCodeAt(0) - 0x30;\n if (this._ch() === '.') {\n if (this.input[this.pos + 1] === '<') {\n this._advance(); // '.' — the '<' type '>' tokens follow\n extra.hashAIExpr = true;\n } else {\n this._advance(); // '.'\n extra.hashAI = BigInt(this._scanUintRaw());\n }\n }\n }\n return this._make(\n 'HASH',\n this.input.slice(start, this.pos),\n start,\n line,\n col,\n extra\n );\n }\n\n // ─── Strings ────────────────────────────────────────────────────────────────\n\n /** text = %x22 *SCHAR %x22 — single-line, strict SCHAR/SESC per RFC 9682. */\n private _scanText(start: number, line: number, col: number): CddlToken {\n const value = this._readStringBody('\"');\n return this._make('TSTR', value, start, line, col);\n }\n\n /**\n * bytes = [bsqual] %x27 *BCHAR %x27\n *\n * Unqualified: content is UTF-8-encoded like a text string ('\\'' must be\n * escaped). Qualified h''/b64'': whitespace and ';' line comments inside\n * the literal are ignored, then the rest is hex / base64 decoded\n * (RFC 8610 §3.1).\n */\n private _scanBytes(\n qualifier: '' | 'h' | 'b64',\n start: number,\n line: number,\n col: number\n ): CddlToken {\n const content = this._readStringBody(\"'\");\n let bytes: Uint8Array;\n if (qualifier === '') {\n bytes = textEncoder.encode(content);\n } else {\n const data = stripWsAndComments(content);\n try {\n bytes = qualifier === 'h' ? hexToBytes(data) : base64ToBytes(data);\n } catch (e) {\n if (!(e instanceof SyntaxError) || e instanceof CddlSyntaxError)\n throw e;\n throw new CddlSyntaxError(e.message, {\n offset: start,\n line,\n column: col,\n endOffset: this.pos,\n });\n }\n }\n return this._make('BYTES', content, start, line, col, {\n qualifier,\n bytes,\n });\n }\n\n /**\n * Read the body of a '\"' text string or \"'\" byte string, decoding escapes.\n *\n * SCHAR = %x20-21 / %x23-5B / %x5D-7E / NONASCII / SESC\n * BCHAR = %x20-26 / %x28-5B / %x5D-7E / NONASCII / SESC / \"\\'\" / CRLF\n * SESC = \"\\\" ( %x22 / \"/\" / \"\\\" / b / f / n / r / t / (%x75 hexchar) )\n */\n private _readStringBody(quote: '\"' | \"'\"): string {\n const isBytes = quote === \"'\";\n this._advance(); // opening quote\n let out = '';\n for (;;) {\n if (this._eof())\n this._fail(`unterminated ${isBytes ? 'byte' : 'text'} string literal`);\n const ch = this._ch();\n if (ch === quote) {\n this._advance();\n return out;\n }\n if (ch === '\\\\') {\n const eLine = this.line;\n const eCol = this.col;\n this._advance();\n const e = this._advance();\n switch (e) {\n case '\"':\n out += '\"';\n break;\n case '/':\n out += '/';\n break;\n case '\\\\':\n out += '\\\\';\n break;\n case 'b':\n out += '\\b';\n break;\n case 'f':\n out += '\\f';\n break;\n case 'n':\n out += '\\n';\n break;\n case 'r':\n out += '\\r';\n break;\n case 't':\n out += '\\t';\n break;\n case 'u':\n out += this._readUnicodeEscape(eLine, eCol);\n break;\n case \"'\":\n if (!isBytes)\n this._fail(\n `\\\\' is only valid in byte string literals; text strings do not need it`,\n eLine,\n eCol\n );\n out += \"'\";\n break;\n default:\n this._fail(`invalid escape sequence \\\\${e}`, eLine, eCol);\n }\n continue;\n }\n // CRLF / LF is content in byte strings only.\n if (ch === '\\n' || ch === '\\r') {\n if (!isBytes)\n this._fail(\n 'text string literals cannot span lines (escape the newline as \\\\n)'\n );\n if (ch === '\\r') {\n this._advance();\n if (this._ch() !== '\\n')\n this._fail('bare CR is not allowed in byte string literals');\n this._advance();\n out += '\\r\\n';\n } else {\n this._advance();\n out += '\\n';\n }\n continue;\n }\n // Read the full code point (an astral char spans two UTF-16 units).\n const cp = this.input.codePointAt(this.pos)!;\n if (cp < 0x20 || (cp >= 0x7f && cp <= 0x9f))\n this._fail(\n `unescaped control character U+${cp.toString(16).padStart(4, '0').toUpperCase()} is not allowed in string literals`\n );\n if (cp > 0x7e && !isNonAscii(cp))\n this._fail(\n `code point U+${cp.toString(16).toUpperCase()} is not allowed in CDDL source`\n );\n this._advance();\n if (cp > 0xffff) this._advance(); // astral: second UTF-16 code unit\n out += String.fromCodePoint(cp);\n }\n }\n\n /**\n * hexchar (RFC 9682): after `\\u`, either `{...}` with a scalar value\n * (leading zeros allowed, surrogates rejected) or 4 hex digits, where a\n * high surrogate must be immediately followed by `\\uXXXX` low surrogate.\n */\n private _readUnicodeEscape(eLine: number, eCol: number): string {\n if (this._ch() === '{') {\n this._advance();\n let hex = '';\n while (isHexDigit(this._ch())) hex += this._advance();\n if (hex.length === 0)\n this._fail('\\\\u{} escape requires at least one hex digit', eLine, eCol);\n if (this._ch() !== '}')\n this._fail(\"expected '}' to close \\\\u{...} escape\", eLine, eCol);\n this._advance();\n const cp = parseInt(hex, 16);\n if (cp > 0x10ffff)\n this._fail(\n `\\\\u{${hex}} is above the Unicode code point maximum U+10FFFF`,\n eLine,\n eCol\n );\n if (cp >= 0xd800 && cp <= 0xdfff)\n this._fail(\n `\\\\u{${hex}} is a surrogate code point, not a Unicode scalar value`,\n eLine,\n eCol\n );\n return String.fromCodePoint(cp);\n }\n const readHex4 = (): number => {\n let hex = '';\n for (let i = 0; i < 4; i++) {\n if (!isHexDigit(this._ch()))\n this._fail('\\\\u escape requires four hex digits', eLine, eCol);\n hex += this._advance();\n }\n return parseInt(hex, 16);\n };\n const cp = readHex4();\n if (cp >= 0xd800 && cp <= 0xdbff) {\n // High surrogate: a low surrogate escape must follow immediately.\n if (this._ch() !== '\\\\' || this.input[this.pos + 1] !== 'u')\n this._fail(\n 'high surrogate \\\\u escape must be followed by a low surrogate \\\\u escape',\n eLine,\n eCol\n );\n this._advance();\n this._advance();\n const lo = readHex4();\n if (lo < 0xdc00 || lo > 0xdfff)\n this._fail(\n 'high surrogate \\\\u escape must be followed by a low surrogate \\\\u escape',\n eLine,\n eCol\n );\n return String.fromCodePoint(\n 0x10000 + ((cp - 0xd800) << 10) + (lo - 0xdc00)\n );\n }\n if (cp >= 0xdc00 && cp <= 0xdfff)\n this._fail('lone low surrogate \\\\u escape', eLine, eCol);\n return String.fromCodePoint(cp);\n }\n}\n\n/**\n * Remove whitespace and ';' line comments from the (escape-processed) content\n * of a prefixed h''/b64'' byte string — RFC 8610 §3.1: \"any whitespace\n * present within the string (including comments) is ignored in the prefixed\n * case\".\n */\nfunction stripWsAndComments(content: string): string {\n let out = '';\n let i = 0;\n while (i < content.length) {\n const c = content[i]!;\n if (c === ' ' || c === '\\n' || c === '\\r') {\n i++;\n continue;\n }\n if (c === ';') {\n while (i < content.length && content[i] !== '\\n') i++;\n continue;\n }\n out += c;\n i++;\n }\n return out;\n}\n","/**\n * CDDL recursive-descent parser (internal).\n *\n * Implements the grammar of RFC 8610 as updated by RFC 9682 Appendix A.\n * Produces the plain AST defined in ast.ts; all semantic processing\n * (prelude merging, name resolution, /= and //= extension) happens in\n * schema.ts.\n */\n\nimport { CddlTokenizer, type CddlComment, type CddlToken } from './tokenizer';\nimport { CddlSyntaxError } from './errors';\nimport { parseHexFloat } from '../utils/hexfloat';\nimport type {\n CddlEntryValue,\n CddlGroup,\n CddlGroupEntry,\n CddlMemberKey,\n CddlOccur,\n CddlRef,\n CddlRule,\n CddlType,\n CddlType1,\n CddlType2,\n CddlValue,\n} from './ast';\n\nexport interface ParseCddlResult {\n /** Rules in source order (unmerged; `/=` and `//=` appear as-is). */\n rules: CddlRule[];\n /** `;` comments encountered while scanning, in source order. */\n comments: CddlComment[];\n}\n\n/**\n * Parse CDDL text into rule ASTs.\n * Throws {@link CddlSyntaxError} on invalid input.\n */\nexport function parseCDDL(text: string): ParseCddlResult {\n const tokenizer = new CddlTokenizer(text);\n const parser = new CddlParser(tokenizer);\n const rules = parser.parse();\n return { rules, comments: tokenizer.comments };\n}\n\n/** Token types that continue a type1/type/memberkey after a closing paren. */\nconst TYPE_CONTINUATION: ReadonlySet<string> = new Set([\n 'SLASH',\n 'RANGE_INCL',\n 'RANGE_EXCL',\n 'CTLOP',\n 'ARROW',\n 'CARET',\n]);\n\nclass CddlParser {\n private readonly t: CddlTokenizer;\n private readonly buf: CddlToken[] = [];\n\n constructor(tokenizer: CddlTokenizer) {\n this.t = tokenizer;\n }\n\n // ─── Token plumbing ─────────────────────────────────────────────────────────\n\n private peek(i = 0): CddlToken {\n while (this.buf.length <= i) this.buf.push(this.t.consume());\n return this.buf[i]!;\n }\n\n private consume(): CddlToken {\n return this.buf.shift() ?? this.t.consume();\n }\n\n private expect(type: CddlToken['type'], what: string): CddlToken {\n const tok = this.peek();\n if (tok.type !== type) this._fail(`expected ${what}`, tok);\n return this.consume();\n }\n\n private _fail(message: string, tok: CddlToken): never {\n const got =\n tok.type === 'EOF' ? 'end of input' : `${JSON.stringify(tok.raw)}`;\n throw new CddlSyntaxError(`${message}, got ${got}`, {\n offset: tok.offset,\n endOffset: tok.endOffset,\n line: tok.line,\n column: tok.col,\n });\n }\n\n // ─── cddl = S *(rule S) ─────────────────────────────────────────────────────\n\n parse(): CddlRule[] {\n const rules: CddlRule[] = [];\n while (this.peek().type !== 'EOF') rules.push(this.parseRule());\n return rules;\n }\n\n /**\n * rule = typename [genericparm] S assignt S type\n * / groupname [genericparm] S assigng S grpent\n *\n * For '=' (shared by assignt and assigng) the body is parsed as a group\n * entry, which subsumes a plain type. '/=' is assignt only, so its\n * right-hand side must be a plain type; '//=' (assigng) takes a grpent.\n */\n private parseRule(): CddlRule {\n const nameTok = this.expect('ID', 'a rule name');\n let generics: string[] | undefined;\n if (this.peek().type === 'LT') {\n this.consume();\n generics = [this.expect('ID', 'a generic parameter name').value];\n while (this.peek().type === 'COMMA') {\n this.consume();\n generics.push(this.expect('ID', 'a generic parameter name').value);\n }\n this.expect('GT', `'>' after generic parameters`);\n }\n const assignTok = this.peek();\n let assign: CddlRule['assign'];\n if (assignTok.type === 'ASSIGN') assign = '=';\n else if (assignTok.type === 'SLASH_EQ') assign = '/=';\n else if (assignTok.type === 'DSLASH_EQ') assign = '//=';\n else this._fail(`expected '=', '/=' or '//=' after rule name`, assignTok);\n this.consume();\n const body =\n assign === '/=' ? this.parseTypeAsEntry() : this.parseGroupEntry();\n return {\n kind: 'rule',\n name: nameTok.value,\n ...(generics ? { generics } : {}),\n assign,\n body,\n start: nameTok.offset,\n end: body.end,\n };\n }\n\n /** A plain type in rule-body position, wrapped as an entry AST node. */\n private parseTypeAsEntry(): CddlEntryValue {\n const value = this.parseType();\n return {\n kind: 'entry',\n value,\n start: value.start,\n end: value.end,\n };\n }\n\n // ─── Groups ─────────────────────────────────────────────────────────────────\n\n /** group = grpchoice *(S \"//\" S grpchoice), up to (not including) `closer`. */\n private parseGroup(closer: CddlToken['type']): CddlGroup {\n const start = this.peek().offset;\n const choices: CddlGroupEntry[][] = [[]];\n let lastWasComma = false;\n for (;;) {\n const tok = this.peek();\n if (tok.type === closer) break;\n if (tok.type === 'EOF')\n this._fail(\n `unterminated group; expected ${JSON.stringify(closer)}`,\n tok\n );\n if (tok.type === 'DSLASH') {\n this.consume();\n choices.push([]);\n lastWasComma = false;\n continue;\n }\n choices[choices.length - 1]!.push(this.parseGroupEntry());\n // optcom = S [\",\" S] — the comma after an entry is optional.\n lastWasComma = this.peek().type === 'COMMA';\n if (lastWasComma) this.consume();\n }\n const endTok = this.peek(); // the closer, consumed by the caller\n return {\n kind: 'group',\n choices,\n ...(lastWasComma ? { trailingComma: true } : {}),\n start,\n end: endTok.offset,\n };\n }\n\n /**\n * grpent = [occur S] [memberkey S] type\n * / [occur S] groupname [genericarg] ; covered by the type branch\n * / [occur S] \"(\" S group S \")\"\n */\n private parseGroupEntry(): CddlGroupEntry {\n const start = this.peek().offset;\n const occur = this.tryParseOccur();\n\n // Inline parenthesized group — unless what follows the ')' pulls the\n // parenthesized expression back into type position (e.g. `(\"a\"/\"b\") .size 1`\n // is a paren *type* with a control operator, not a group entry).\n if (this.peek().type === 'LPAREN') {\n const lparen = this.consume();\n const group = this.parseGroup('RPAREN');\n const rparen = this.consume();\n if (TYPE_CONTINUATION.has(this.peek().type)) {\n const paren = this.groupAsParenType(group, lparen, rparen);\n const type1 = this.continueType1(paren);\n return this.finishEntryFromType1(start, occur, type1);\n }\n return {\n kind: 'entry-group',\n ...(occur ? { occur } : {}),\n group,\n start,\n end: rparen.endOffset,\n };\n }\n\n // memberkey shortcuts: bareword \":\" and value \":\"\n const t0 = this.peek(0);\n const t1 = this.peek(1);\n if (t1.type === 'COLON' && (t0.type === 'ID' || this.isValueToken(t0))) {\n let memberKey: CddlMemberKey;\n if (t0.type === 'ID') {\n this.consume();\n const colon = this.consume();\n memberKey = {\n kind: 'bareword',\n key: t0.value,\n cut: true,\n start: t0.offset,\n end: colon.endOffset,\n };\n } else {\n const key = this.parseValue();\n const colon = this.consume();\n memberKey = {\n kind: 'value',\n key,\n cut: true,\n start: key.start,\n end: colon.endOffset,\n };\n }\n const value = this.parseType();\n return {\n kind: 'entry',\n ...(occur ? { occur } : {}),\n memberKey,\n value,\n start,\n end: value.end,\n };\n }\n\n // General case: parse a type1, then decide whether it was a member key.\n const type1 = this.parseType1();\n return this.finishEntryFromType1(start, occur, type1);\n }\n\n /**\n * After parsing an initial type1 in entry position: `^`/`=>` make it a\n * member key (memberkey = type1 S [\"^\" S] \"=>\"); otherwise it starts the\n * entry's type and further `/` alternatives may follow.\n */\n private finishEntryFromType1(\n start: number,\n occur: CddlOccur | undefined,\n type1: CddlType1\n ): CddlEntryValue {\n let memberKey: CddlMemberKey | undefined;\n if (this.peek().type === 'CARET' || this.peek().type === 'ARROW') {\n let cut = false;\n if (this.peek().type === 'CARET') {\n this.consume();\n cut = true;\n }\n const arrow = this.expect('ARROW', `'=>' after member key`);\n memberKey = {\n kind: 'type1',\n key: type1,\n cut,\n start: type1.start,\n end: arrow.endOffset,\n };\n }\n const value = memberKey\n ? this.parseType()\n : this.continueTypeAlternatives(type1);\n return {\n kind: 'entry',\n ...(occur ? { occur } : {}),\n ...(memberKey ? { memberKey } : {}),\n value,\n start,\n end: value.end,\n };\n }\n\n /** occur = [uint] \"*\" [uint] / \"+\" / \"?\" — components must be adjacent. */\n private tryParseOccur(): CddlOccur | undefined {\n const t0 = this.peek(0);\n if (t0.type === 'QUEST') {\n this.consume();\n return {\n kind: 'occur',\n marker: '?',\n start: t0.offset,\n end: t0.endOffset,\n };\n }\n if (t0.type === 'PLUS') {\n this.consume();\n return {\n kind: 'occur',\n marker: '+',\n start: t0.offset,\n end: t0.endOffset,\n };\n }\n if (t0.type === 'STAR') {\n this.consume();\n let max: number | undefined;\n let end = t0.endOffset;\n const next = this.peek();\n if (next.type === 'INT' && next.offset === t0.endOffset) {\n max = this.occurBound(this.consume());\n end = next.endOffset;\n }\n return {\n kind: 'occur',\n marker: '*',\n ...(max !== undefined ? { max } : {}),\n start: t0.offset,\n end,\n };\n }\n // `n*` / `n*m` — only when INT and '*' are adjacent (per the ABNF, occur\n // has no interior whitespace; adjacency is what distinguishes the\n // occurrence `1*2` from the value 1 followed by the occurrence `*2`).\n if (\n t0.type === 'INT' &&\n !t0.value.startsWith('-') &&\n this.peek(1).type === 'STAR' &&\n this.peek(1).offset === t0.endOffset\n ) {\n const min = this.occurBound(this.consume());\n const star = this.consume();\n let max: number | undefined;\n let end = star.endOffset;\n const next = this.peek();\n if (next.type === 'INT' && next.offset === star.endOffset) {\n max = this.occurBound(this.consume());\n end = next.endOffset;\n }\n return { kind: 'occur', marker: '*', min, max, start: t0.offset, end };\n }\n return undefined;\n }\n\n private occurBound(tok: CddlToken): number {\n if (tok.value.startsWith('-'))\n this._fail('occurrence bounds must be unsigned integers', tok);\n const n = Number(tok.value);\n if (!Number.isSafeInteger(n))\n this._fail('occurrence bound is too large', tok);\n return n;\n }\n\n // ─── Types ──────────────────────────────────────────────────────────────────\n\n /** type = type1 *(S \"/\" S type1) */\n private parseType(): CddlType {\n return this.continueTypeAlternatives(this.parseType1());\n }\n\n private continueTypeAlternatives(first: CddlType1): CddlType {\n const alternatives = [first];\n while (this.peek().type === 'SLASH') {\n this.consume();\n alternatives.push(this.parseType1());\n }\n return {\n kind: 'type',\n alternatives,\n start: first.start,\n end: alternatives[alternatives.length - 1]!.end,\n };\n }\n\n /** type1 = type2 [S (rangeop / ctlop) S type2] */\n private parseType1(): CddlType1 {\n return this.continueType1(this.parseType2());\n }\n\n private continueType1(target: CddlType2): CddlType1 {\n const opTok = this.peek();\n let op: CddlType1['op'];\n if (opTok.type === 'RANGE_INCL' || opTok.type === 'RANGE_EXCL')\n op = { kind: 'range', inclusive: opTok.type === 'RANGE_INCL' };\n else if (opTok.type === 'CTLOP') op = { kind: 'ctl', name: opTok.value };\n if (!op)\n return { kind: 'type1', target, start: target.start, end: target.end };\n this.consume();\n const controller = this.parseType2();\n return {\n kind: 'type1',\n target,\n op,\n controller,\n start: target.start,\n end: controller.end,\n };\n }\n\n private parseType2(): CddlType2 {\n const tok = this.peek();\n switch (tok.type) {\n case 'INT':\n case 'FLOAT':\n case 'TSTR':\n case 'BYTES':\n return this.parseValue();\n\n case 'ID': {\n this.consume();\n return this.parseRefTail(tok);\n }\n\n case 'LPAREN': {\n const lparen = this.consume();\n const type = this.parseType();\n const rparen = this.expect(\n 'RPAREN',\n `')' to close the parenthesized type`\n );\n return {\n kind: 'paren',\n type,\n start: lparen.offset,\n end: rparen.endOffset,\n };\n }\n\n case 'LBRACE': {\n const open = this.consume();\n const group = this.parseGroup('RBRACE');\n const close = this.consume();\n return {\n kind: 'map',\n group,\n start: open.offset,\n end: close.endOffset,\n };\n }\n\n case 'LBRACKET': {\n const open = this.consume();\n const group = this.parseGroup('RBRACKET');\n const close = this.consume();\n return {\n kind: 'array',\n group,\n start: open.offset,\n end: close.endOffset,\n };\n }\n\n case 'TILDE': {\n const tilde = this.consume();\n const nameTok = this.expect('ID', `a type name after '~'`);\n const ref = this.parseRefTail(nameTok);\n return { kind: 'unwrap', ref, start: tilde.offset, end: ref.end };\n }\n\n case 'AMP': {\n const amp = this.consume();\n if (this.peek().type === 'LPAREN') {\n this.consume();\n const group = this.parseGroup('RPAREN');\n const rparen = this.consume();\n return {\n kind: 'enum',\n group,\n start: amp.offset,\n end: rparen.endOffset,\n };\n }\n const nameTok = this.expect('ID', `a group name or '(' after '&'`);\n const ref = this.parseRefTail(nameTok);\n return { kind: 'enum', group: ref, start: amp.offset, end: ref.end };\n }\n\n case 'HASH':\n return this.parseHashType(this.consume());\n\n default:\n this._fail('expected a type', tok);\n }\n }\n\n /** Generic arguments after a just-consumed ID token: [genericarg]. */\n private parseRefTail(nameTok: CddlToken): CddlRef {\n if (this.peek().type !== 'LT')\n return {\n kind: 'ref',\n name: nameTok.value,\n start: nameTok.offset,\n end: nameTok.endOffset,\n };\n this.consume();\n const genericArgs = [this.parseType1()];\n while (this.peek().type === 'COMMA') {\n this.consume();\n genericArgs.push(this.parseType1());\n }\n const gt = this.expect('GT', `'>' after generic arguments`);\n return {\n kind: 'ref',\n name: nameTok.value,\n genericArgs,\n start: nameTok.offset,\n end: gt.endOffset,\n };\n }\n\n /**\n * '#' family, from a HASH token produced by the tokenizer:\n * \"#\" → any\n * \"#\" \"6\" [\".\" head-number] \"(\" type \")\" → tagged\n * \"#\" \"7\" [\".\" head-number] → major 7 (simple/float)\n * \"#\" DIGIT [\".\" uint] → major/ai\n * head-number = uint / \"<\" type \">\" (RFC 9682 §3.2)\n */\n private parseHashType(tok: CddlToken): CddlType2 {\n if (tok.hashMajor === undefined) {\n if (tok.hashAIExpr || tok.hashAI !== undefined)\n this._fail(`'#' without a major type cannot take a head-number`, tok);\n return { kind: 'any', start: tok.offset, end: tok.endOffset };\n }\n const major = tok.hashMajor;\n\n let head: bigint | CddlType | undefined = tok.hashAI;\n let headEnd = tok.endOffset;\n if (tok.hashAIExpr) {\n if (major !== 6 && major !== 7)\n this._fail(\n `a <type> head-number is only allowed for #6 and #7 (RFC 9682 §3.2)`,\n tok\n );\n this.expect('LT', `'<' for the head-number expression`);\n head = this.parseType();\n const gt = this.expect('GT', `'>' after the head-number expression`);\n headEnd = gt.endOffset;\n }\n\n // For a literal (or absent) head-number, keep the '#…' source text so the\n // formatter can preserve the number base (e.g. '#6.0x10').\n const raw = tok.hashAIExpr ? undefined : tok.raw;\n\n if (major === 6 && this.peek().type === 'LPAREN') {\n this.consume();\n const item = this.parseType();\n const rparen = this.expect('RPAREN', `')' to close the tagged type`);\n return {\n kind: 'tagged',\n ...(head !== undefined ? { tag: head } : {}),\n item,\n ...(raw !== undefined ? { raw } : {}),\n start: tok.offset,\n end: rparen.endOffset,\n };\n }\n if (tok.hashAIExpr && major === 6)\n this._fail(`#6.<…> must be followed by '(' type ')'`, this.peek());\n\n return {\n kind: 'major',\n major,\n ...(head !== undefined ? { ai: head } : {}),\n ...(raw !== undefined ? { raw } : {}),\n start: tok.offset,\n end: headEnd,\n };\n }\n\n // ─── Values ─────────────────────────────────────────────────────────────────\n\n private isValueToken(tok: CddlToken): boolean {\n return (\n tok.type === 'INT' ||\n tok.type === 'FLOAT' ||\n tok.type === 'TSTR' ||\n tok.type === 'BYTES'\n );\n }\n\n private parseValue(): CddlValue {\n const tok = this.consume();\n const base = { start: tok.offset, end: tok.endOffset, raw: tok.raw };\n switch (tok.type) {\n case 'INT': {\n // BigInt() rejects a sign on 0x/0b literals — apply it separately.\n const big = tok.value.startsWith('-')\n ? -BigInt(tok.value.slice(1))\n : BigInt(tok.value);\n const value =\n big >= BigInt(Number.MIN_SAFE_INTEGER) &&\n big <= BigInt(Number.MAX_SAFE_INTEGER)\n ? Number(big)\n : big;\n return { kind: 'value', type: 'int', value, ...base };\n }\n case 'FLOAT': {\n const value = /^-?0[xX]/.test(tok.value)\n ? parseHexFloat(tok.value)\n : parseFloat(tok.value);\n return { kind: 'value', type: 'float', value, ...base };\n }\n case 'TSTR':\n return { kind: 'value', type: 'text', value: tok.value, ...base };\n case 'BYTES':\n return {\n kind: 'value',\n type: 'bytes',\n value: tok.bytes!,\n qualifier: tok.qualifier!,\n ...base,\n };\n default:\n this._fail('expected a literal value', tok);\n }\n }\n\n /**\n * Reinterpret a parsed parenthesized group as a parenthesized *type* —\n * needed when a range/control operator, '/', or '=>' follows the ')'.\n * Only a group of exactly one plain entry (no occurrence, no member key,\n * no trailing comma, single choice) is a valid type.\n */\n private groupAsParenType(\n group: CddlGroup,\n lparen: CddlToken,\n rparen: CddlToken\n ): CddlType2 {\n const only =\n group.choices.length === 1 && group.choices[0]!.length === 1\n ? group.choices[0]![0]!\n : undefined;\n if (\n !only ||\n only.kind !== 'entry' ||\n only.occur ||\n only.memberKey ||\n group.trailingComma\n )\n this._fail(\n 'this parenthesized group is used as a type (an operator follows), but it contains group syntax',\n this.peek()\n );\n return {\n kind: 'paren',\n type: only.value,\n start: lparen.offset,\n end: rparen.endOffset,\n };\n }\n}\n","/**\n * The CDDL standard prelude (RFC 8610 Appendix D, normative).\n *\n * The prelude is automatically added to each CDDL file. It is technically a\n * postlude: it never disturbs the selection of the first user rule as the\n * root of the definition, and user rules shadow prelude names.\n */\n\nimport { parseCDDL } from './parser';\nimport type { CddlRule } from './ast';\n\n/** Verbatim text of the RFC 8610 Appendix D standard prelude. */\nexport const PRELUDE_CDDL = `any = #\n\nuint = #0\nnint = #1\nint = uint / nint\n\nbstr = #2\nbytes = bstr\ntstr = #3\ntext = tstr\n\ntdate = #6.0(tstr)\ntime = #6.1(number)\nnumber = int / float\nbiguint = #6.2(bstr)\nbignint = #6.3(bstr)\nbigint = biguint / bignint\ninteger = int / bigint\nunsigned = uint / biguint\ndecfrac = #6.4([e10: int, m: integer])\nbigfloat = #6.5([e2: int, m: integer])\neb64url = #6.21(any)\neb64legacy = #6.22(any)\neb16 = #6.23(any)\nencoded-cbor = #6.24(bstr)\nuri = #6.32(tstr)\nb64url = #6.33(tstr)\nb64legacy = #6.34(tstr)\nregexp = #6.35(tstr)\nmime-message = #6.36(tstr)\ncbor-any = #6.55799(any)\n\nfloat16 = #7.25\nfloat32 = #7.26\nfloat64 = #7.27\nfloat16-32 = float16 / float32\nfloat32-64 = float32 / float64\nfloat = float16-32 / float64\n\nfalse = #7.20\ntrue = #7.21\nbool = false / true\nnil = #7.22\nnull = nil\nundefined = #7.23\n`;\n\nlet cached: Map<string, CddlRule> | undefined;\n\n/** The parsed prelude rules by name, parsed once and cached. */\nexport function getPreludeRules(): Map<string, CddlRule> {\n if (!cached) {\n cached = new Map();\n for (const rule of parseCDDL(PRELUDE_CDDL).rules)\n cached.set(rule.name, rule);\n }\n return cached;\n}\n","/**\n * Structural equality and value-access helpers over CBOR AST nodes,\n * used by the CDDL validator for literal matching, map-key comparison,\n * enumerations, and the .eq/.ne control operators.\n *\n * Equality is CDDL value equality, not byte equality: encoding widths and\n * definite/indefinite length are ignored (an indefinite-length \"a\", \"b\"\n * equals the definite \"ab\"), but CBOR type classes stay distinct — an\n * integer never equals a float, and a bignum (tag 2/3) never equals a\n * plain integer.\n */\n\nimport { CborItem } from '../ast/CborItem';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborFloat } from '../ast/CborFloat';\nimport { CborSimple } from '../ast/CborSimple';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborIndefiniteTextString } from '../ast/CborIndefiniteTextString';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborIndefiniteByteString } from '../ast/CborIndefiniteByteString';\nimport { CborEmbeddedCBOR } from '../ast/CborEmbeddedCBOR';\nimport { CborArray } from '../ast/CborArray';\nimport { CborMap } from '../ast/CborMap';\nimport { CborTag } from '../ast/CborTag';\nimport { CborBigUint, CborBigNint } from '../ast/CborBignum';\n\n/**\n * The integer value of a node, including bignums (tags 2/3): CDDL *values*\n * are abstract numbers, so literals, ranges, and comparison operators must\n * see 2^64 the same way whether it arrived as a basic int or as a bignum.\n * (Type matching stays structural: a bignum is a tagged item, not #0/#1.)\n */\nexport function intValueOf(item: CborItem): bigint | undefined {\n if (item instanceof CborUint || item instanceof CborNint) return item.value;\n if (item instanceof CborBigUint || item instanceof CborBigNint)\n return item.bigValue;\n return undefined;\n}\n\n/** The text value of a (possibly indefinite-length) text string node. */\nexport function textValue(item: CborItem): string | undefined {\n if (item instanceof CborTextString) return item.value;\n if (item instanceof CborIndefiniteTextString)\n return item.chunks.map((c) => c.value).join('');\n return undefined;\n}\n\n/**\n * The byte content of a byte-string-like node: a (possibly\n * indefinite-length) byte string, or an `<<…>>` embedded-CBOR literal\n * (whose value is the encoding of its items).\n */\nexport function byteValue(item: CborItem): Uint8Array | undefined {\n if (item instanceof CborByteString) return item.value;\n if (item instanceof CborIndefiniteByteString) {\n const parts = item.chunks.map((c) => c.value);\n const total = parts.reduce((n, p) => n + p.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const p of parts) {\n out.set(p, off);\n off += p.length;\n }\n return out;\n }\n if (item instanceof CborEmbeddedCBOR) {\n const parts = item.items.map((i) => i.toCBOR());\n const total = parts.reduce((n, p) => n + p.length, 0);\n const out = new Uint8Array(total);\n let off = 0;\n for (const p of parts) {\n out.set(p, off);\n off += p.length;\n }\n return out;\n }\n return undefined;\n}\n\nexport function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;\n return true;\n}\n\n/** CDDL value equality of two CBOR AST nodes (see module doc). */\nexport function equalItems(a: CborItem, b: CborItem): boolean {\n if (a === b) return true;\n\n if (a instanceof CborUint)\n return b instanceof CborUint && a.value === b.value;\n if (a instanceof CborNint)\n return b instanceof CborNint && a.value === b.value;\n if (a instanceof CborFloat)\n return (\n b instanceof CborFloat &&\n (a.value === b.value || (Number.isNaN(a.value) && Number.isNaN(b.value)))\n );\n if (a instanceof CborSimple)\n return b instanceof CborSimple && a.value === b.value;\n\n const aText = textValue(a);\n if (aText !== undefined) {\n const bText = textValue(b);\n return bText !== undefined && aText === bText;\n }\n const aBytes = byteValue(a);\n if (aBytes !== undefined) {\n const bBytes = byteValue(b);\n return bBytes !== undefined && bytesEqual(aBytes, bBytes);\n }\n\n if (a instanceof CborArray)\n return (\n b instanceof CborArray &&\n a.items.length === b.items.length &&\n a.items.every((item, i) => equalItems(item, b.items[i]!))\n );\n\n if (a instanceof CborMap) {\n if (!(b instanceof CborMap) || a.entries.length !== b.entries.length)\n return false;\n // Order-insensitive with one-to-one consumption.\n const used = new Array<boolean>(b.entries.length).fill(false);\n for (const [ak, av] of a.entries) {\n let found = false;\n for (let i = 0; i < b.entries.length; i++) {\n if (used[i]) continue;\n const [bk, bv] = b.entries[i]!;\n if (equalItems(ak, bk) && equalItems(av, bv)) {\n used[i] = true;\n found = true;\n break;\n }\n }\n if (!found) return false;\n }\n return true;\n }\n\n // Tags last: bignums, embedded app extensions, etc. are CborTag subclasses.\n if (a instanceof CborTag)\n return (\n b instanceof CborTag &&\n a.tag === b.tag &&\n equalItems(a.content, b.content)\n );\n\n return false;\n}\n","/**\n * Control operator implementations (RFC 8610 §3.8 plus RFC 9165 .plus /\n * .cat / .feature), table-driven and injected with the validator's matching\n * primitives to avoid an import cycle.\n *\n * Operators that are not in the table (.det, .abnf, .abnfb, the RFC 9741\n * text-conversion set, and anything unknown) are reported as a warning by\n * the validator, which then matches the target without the constraint.\n */\n\nimport type { CborItem } from '../ast/CborItem';\nimport { CborUint } from '../ast/CborUint';\nimport { CborFloat } from '../ast/CborFloat';\nimport { decodeCBOR } from '../cbor/decoder';\nimport { textValue, byteValue, intValueOf } from './equal';\nimport type { CddlNodeBase, CddlType2, CddlValue } from './ast';\n\ntype Path = readonly (string | number)[];\n\n/** Matching primitives provided by the validator (closed over env/ctx). */\nexport interface ControlDeps {\n matchType2(item: CborItem, t2: CddlType2, path: Path): boolean;\n /** Like matchType2, but suppresses instance offsets in recorded errors —\n * the item was decoded out of an embedded byte string, so its offsets\n * are relative to the embedded bytes, not the outer document. */\n matchEmbedded(item: CborItem, t2: CddlType2, path: Path): boolean;\n resolveValue(t2: CddlType2): CddlValue | undefined;\n /** Whether some integer ≥ min matches the type; undefined = unanalyzable. */\n existsIntGE(t2: CddlType2, min: bigint): boolean | undefined;\n matchesLiteral(item: CborItem, v: CddlValue): boolean;\n fail(\n path: Path,\n item: CborItem | undefined,\n node: CddlNodeBase | undefined,\n message: string\n ): false;\n warnOnce(message: string, node?: CddlNodeBase): void;\n features: ReadonlySet<string>;\n uint(n: number | bigint): CborItem;\n}\n\nexport type ControlHandler = (\n deps: ControlDeps,\n item: CborItem,\n target: CddlType2,\n controller: CddlType2,\n path: Path,\n node: CddlNodeBase\n) => boolean;\n\nconst textEncoder = new TextEncoder();\nconst utf8Strict = new TextDecoder('utf-8', { fatal: true });\n\n/** Synthesize a literal value for computed operators (.plus, .cat). */\nconst synthValue = (\n v:\n | { type: 'int'; value: number | bigint }\n | { type: 'float'; value: number }\n | { type: 'text'; value: string }\n | { type: 'bytes'; value: Uint8Array; qualifier: '' | 'h' | 'b64' }\n): CddlValue =>\n ({ kind: 'value', raw: '', start: 0, end: 0, ...v }) as CddlValue;\n\nconst numericOf = (item: CborItem): bigint | number | undefined => {\n // Includes bignums (tags 2/3): CDDL values are abstract numbers.\n const int = intValueOf(item);\n if (int !== undefined) return int;\n if (item instanceof CborFloat) return item.value;\n return undefined;\n};\n\nconst valueNumeric = (v: CddlValue): bigint | number | undefined =>\n v.type === 'int' || v.type === 'float' ? v.value : undefined;\n\n/** Compare possibly-mixed bigint/number numerics: -1, 0, 1 (NaN → NaN). */\nconst cmp = (a: bigint | number, b: bigint | number): number => {\n if (typeof a === 'bigint' && typeof b === 'bigint')\n return a < b ? -1 : a > b ? 1 : 0;\n const an = Number(a);\n const bn = Number(b);\n return an < bn ? -1 : an > bn ? 1 : an === bn ? 0 : NaN;\n};\n\n// ─── RFC 8610 §3.8 ────────────────────────────────────────────────────────────\n\nconst size: ControlHandler = (deps, item, target, controller, path, node) => {\n if (!deps.matchType2(item, target, path)) return false;\n const checkSize = (n: number | bigint): boolean =>\n deps.matchType2(deps.uint(n), controller, path)\n ? true\n : deps.fail(\n path,\n item,\n node,\n `size ${n} does not match the .size constraint`\n );\n const text = textValue(item);\n if (text !== undefined) return checkSize(textEncoder.encode(text).length);\n const bytes = byteValue(item);\n if (bytes !== undefined) return checkSize(bytes.length);\n if (item instanceof CborUint) {\n // uint .size N means 0 ≤ value < 256^N (no upper limit on N): the value\n // fits iff the controller's integer set intersects [minBytes, ∞).\n let minBytes = 0;\n for (let v = item.value; v > 0n; v >>= 8n) minBytes++;\n const exists = deps.existsIntGE(controller, BigInt(minBytes));\n if (exists !== undefined)\n return exists\n ? true\n : deps.fail(\n path,\n item,\n node,\n `${item.value} does not fit the .size constraint`\n );\n // The controller could not be analyzed structurally (e.g. it uses a\n // control operator); fall back to a bounded search and say so.\n deps.warnOnce(\n '.size controller could not be analyzed; searching a bounded window of byte counts',\n node\n );\n for (let n = minBytes; n <= minBytes + 64; n++)\n if (deps.matchType2(deps.uint(n), controller, path)) return true;\n return deps.fail(\n path,\n item,\n node,\n `${item.value} does not fit the .size constraint`\n );\n }\n return deps.fail(\n path,\n item,\n node,\n '.size applies to strings and unsigned integers'\n );\n};\n\nconst bits: ControlHandler = (deps, item, target, controller, path, node) => {\n if (!deps.matchType2(item, target, path)) return false;\n const positions: number[] = [];\n const bytes = byteValue(item);\n if (bytes !== undefined) {\n // Bit n of the string means (str[n >> 3] & (1 << (n & 7))) != 0 (§3.8.2).\n for (let i = 0; i < bytes.length; i++)\n for (let j = 0; j < 8; j++)\n if (bytes[i]! & (1 << j)) positions.push(i * 8 + j);\n } else if (item instanceof CborUint) {\n let v = item.value;\n for (let n = 0; v > 0n; n++, v >>= 1n) if (v & 1n) positions.push(n);\n } else {\n return deps.fail(\n path,\n item,\n node,\n '.bits applies to byte strings and unsigned integers'\n );\n }\n for (const n of positions)\n if (!deps.matchType2(deps.uint(n), controller, path))\n return deps.fail(\n path,\n item,\n node,\n `bit ${n} is set but not allowed by .bits`\n );\n return true;\n};\n\nconst regexpCache = new Map<string, RegExp | null>();\n\nconst regexp: ControlHandler = (deps, item, target, controller, path, node) => {\n if (!deps.matchType2(item, target, path)) return false;\n const text = textValue(item);\n if (text === undefined)\n return deps.fail(path, item, node, '.regexp applies to text strings');\n const c = deps.resolveValue(controller);\n if (!c || c.type !== 'text') {\n deps.warnOnce(\n '.regexp controller does not resolve to a text string; not checked',\n node\n );\n return true;\n }\n // Approximation: the spec prescribes XSD regular expressions; we compile\n // the pattern as an anchored JavaScript RegExp with the 'u' flag, which\n // covers common patterns but differs in some character-class details.\n let re = regexpCache.get(c.value);\n if (re === undefined) {\n try {\n re = new RegExp(`^(?:${c.value})$`, 'u');\n } catch {\n re = null;\n }\n regexpCache.set(c.value, re);\n }\n if (re === null) {\n deps.warnOnce(\n `.regexp pattern is not a valid regular expression here: ${c.value}`,\n node\n );\n return true;\n }\n return re.test(text)\n ? true\n : deps.fail(\n path,\n item,\n node,\n `text does not match .regexp ${JSON.stringify(c.value)}`\n );\n};\n\nconst makeCborControl =\n (seq: boolean): ControlHandler =>\n (deps, item, target, controller, path, node) => {\n if (!deps.matchType2(item, target, path)) return false;\n const bytes = byteValue(item);\n if (bytes === undefined)\n return deps.fail(\n path,\n item,\n node,\n `.cbor${seq ? 'seq' : ''} applies to byte strings`\n );\n let decoded: CborItem;\n try {\n if (seq) {\n // §3.8.4: wrap the sequence between 0x9f/0xff and decode as an\n // indefinite-length array.\n const wrapped = new Uint8Array(bytes.length + 2);\n wrapped[0] = 0x9f;\n wrapped.set(bytes, 1);\n wrapped[wrapped.length - 1] = 0xff;\n decoded = decodeCBOR(wrapped);\n } else {\n decoded = decodeCBOR(bytes);\n }\n } catch (e) {\n return deps.fail(\n path,\n item,\n node,\n `byte string does not contain valid CBOR: ${e instanceof Error ? e.message : String(e)}`\n );\n }\n return deps.matchEmbedded(decoded, controller, path)\n ? true\n : deps.fail(\n path,\n item,\n node,\n `embedded CBOR does not match the .cbor${seq ? 'seq' : ''} type`\n );\n };\n\nconst within: ControlHandler = (deps, item, target, controller, path, node) => {\n if (!deps.matchType2(item, target, path)) return false;\n return deps.matchType2(item, controller, path)\n ? true\n : deps.fail(\n path,\n item,\n node,\n 'value does not match the .within/.and constraint'\n );\n};\n\nconst makeCompare =\n (op: 'lt' | 'le' | 'gt' | 'ge'): ControlHandler =>\n (deps, item, target, controller, path, node) => {\n if (!deps.matchType2(item, target, path)) return false;\n const c = deps.resolveValue(controller);\n const bound = c && valueNumeric(c);\n if (bound === undefined) {\n deps.warnOnce(\n `.${op} controller does not resolve to a number; not checked`,\n node\n );\n return true;\n }\n const v = numericOf(item);\n if (v === undefined)\n return deps.fail(path, item, node, `.${op} applies to numbers`);\n const d = cmp(v, bound);\n const ok =\n op === 'lt' ? d < 0 : op === 'le' ? d <= 0 : op === 'gt' ? d > 0 : d >= 0;\n return ok\n ? true\n : deps.fail(path, item, node, `${v} does not satisfy .${op} ${bound}`);\n };\n\nconst eq: ControlHandler = (deps, item, target, controller, path, node) => {\n if (!deps.matchType2(item, target, path)) return false;\n const c = deps.resolveValue(controller);\n if (!c) {\n deps.warnOnce(\n '.eq controller does not resolve to a literal value; not checked',\n node\n );\n return true;\n }\n return deps.matchesLiteral(item, c)\n ? true\n : deps.fail(\n path,\n item,\n node,\n `value does not equal ${c.raw || '.eq controller'}`\n );\n};\n\nconst ne: ControlHandler = (deps, item, target, controller, path, node) => {\n if (!deps.matchType2(item, target, path)) return false;\n const c = deps.resolveValue(controller);\n if (!c) {\n deps.warnOnce(\n '.ne controller does not resolve to a literal value; not checked',\n node\n );\n return true;\n }\n return deps.matchesLiteral(item, c)\n ? deps.fail(\n path,\n item,\n node,\n `value must not equal ${c.raw || '.ne controller'}`\n )\n : true;\n};\n\nconst dflt: ControlHandler = (deps, item, target, controller, path, node) => {\n // .default is a variant of .ne: \"the implied .ne control is there to\n // prevent this value from being sent over the wire\" (RFC 8610 §3.8.6),\n // so the default value itself does not validate.\n if (!deps.matchType2(item, target, path)) return false;\n const c = deps.resolveValue(controller);\n if (!c) {\n deps.warnOnce(\n '.default controller does not resolve to a literal value; the implied .ne is not checked',\n node\n );\n return true;\n }\n return deps.matchesLiteral(item, c)\n ? deps.fail(\n path,\n item,\n node,\n `value equals the default ${c.raw || 'value'} (implied .ne, RFC 8610 §3.8.6)`\n )\n : true;\n};\n\n// ─── RFC 9165 ─────────────────────────────────────────────────────────────────\n\nconst plus: ControlHandler = (deps, item, target, controller, path, node) => {\n const t = deps.resolveValue(target);\n const c = deps.resolveValue(controller);\n const tv = t && valueNumeric(t);\n const cv = c && valueNumeric(c);\n if (t === undefined || tv === undefined || cv === undefined) {\n deps.warnOnce(\n '.plus operands do not resolve to numbers; not checked',\n node\n );\n return deps.fail(path, item, node, '.plus could not be computed');\n }\n // The sum is converted to the type of the target; float→int rounds\n // towards negative infinity (RFC 9165 §2.1).\n if (t!.type === 'float') {\n const sum = Number(tv) + Number(cv);\n return deps.matchesLiteral(item, synthValue({ type: 'float', value: sum }))\n ? true\n : deps.fail(path, item, node, `expected ${sum} (.plus)`);\n }\n // Integer target: compute in bigint so values beyond 2^53 stay exact.\n // An integer CddlValue is only a `number` when within the safe range, so\n // BigInt(tv) is lossless; for a float controller, floor(int + x) equals\n // int + floor(x), keeping the big integer part untouched.\n if (typeof cv === 'number' && !Number.isFinite(cv))\n return deps.fail(path, item, node, '.plus controller is not finite');\n const sum =\n (typeof tv === 'bigint' ? tv : BigInt(tv)) +\n (typeof cv === 'bigint' ? cv : BigInt(Math.floor(cv)));\n return deps.matchesLiteral(item, synthValue({ type: 'int', value: sum }))\n ? true\n : deps.fail(path, item, node, `expected ${sum} (.plus)`);\n};\n\nconst cat: ControlHandler = (deps, item, target, controller, path, node) => {\n const t = deps.resolveValue(target);\n const c = deps.resolveValue(controller);\n const toBytes = (v: CddlValue): Uint8Array | undefined =>\n v.type === 'text'\n ? textEncoder.encode(v.value)\n : v.type === 'bytes'\n ? v.value\n : undefined;\n const tb = t && toBytes(t);\n const cb = c && toBytes(c);\n if (!t || tb === undefined || cb === undefined) {\n deps.warnOnce('.cat operands do not resolve to strings; not checked', node);\n return deps.fail(path, item, node, '.cat could not be computed');\n }\n const joined = new Uint8Array(tb.length + cb.length);\n joined.set(tb, 0);\n joined.set(cb, tb.length);\n // The result has the type of the target (RFC 9165 §2.2).\n if (t.type === 'text') {\n let text: string;\n try {\n text = utf8Strict.decode(joined);\n } catch {\n return deps.fail(path, item, node, '.cat result is not valid UTF-8');\n }\n return deps.matchesLiteral(item, synthValue({ type: 'text', value: text }))\n ? true\n : deps.fail(path, item, node, `expected ${JSON.stringify(text)} (.cat)`);\n }\n return deps.matchesLiteral(\n item,\n synthValue({ type: 'bytes', value: joined, qualifier: 'h' })\n )\n ? true\n : deps.fail(path, item, node, 'byte string does not equal the .cat result');\n};\n\n/** Peel `( … )` layers off a type2 (single plain alternative only). */\nconst stripParens = (t2: CddlType2): CddlType2 => {\n while (\n t2.kind === 'paren' &&\n t2.type.alternatives.length === 1 &&\n !t2.type.alternatives[0]!.op\n )\n t2 = t2.type.alternatives[0]!.target;\n return t2;\n};\n\n/**\n * The .feature controller is a feature name, or an array whose first\n * element is the feature name and whose rest is detail (RFC 9165 §5) —\n * either form may be parenthesized, e.g. `.feature ([\"x\", \"detail\"])`.\n */\nexport const featureName = (\n deps: ControlDeps,\n controller: CddlType2\n): string | undefined => {\n let t2 = stripParens(controller);\n if (t2.kind === 'array') {\n const first = t2.group.choices[0]?.[0];\n if (\n !first ||\n first.kind !== 'entry' ||\n first.value.alternatives.length !== 1 ||\n first.value.alternatives[0]!.op\n )\n return undefined;\n t2 = first.value.alternatives[0]!.target;\n }\n const c = deps.resolveValue(t2);\n return c?.type === 'text' ? c.value : undefined;\n};\n\nconst feature: ControlHandler = (\n deps,\n item,\n target,\n controller,\n path,\n node\n) => {\n const name = featureName(deps, controller);\n if (name === undefined) {\n deps.warnOnce(\n '.feature controller does not resolve to a feature name',\n node\n );\n return deps.fail(path, item, node, 'unresolvable .feature');\n }\n if (!deps.features.has(name)) {\n deps.warnOnce(\n `feature \"${name}\" is not enabled (pass it in options.features to accept it)`,\n node\n );\n return deps.fail(path, item, node, `feature \"${name}\" is not enabled`);\n }\n return deps.matchType2(item, target, path);\n};\n\n// ─── Table ────────────────────────────────────────────────────────────────────\n\nconst CONTROLS: Record<string, ControlHandler> = {\n size,\n bits,\n regexp,\n cbor: makeCborControl(false),\n cborseq: makeCborControl(true),\n within,\n and: within,\n lt: makeCompare('lt'),\n le: makeCompare('le'),\n gt: makeCompare('gt'),\n ge: makeCompare('ge'),\n eq,\n ne,\n default: dflt,\n plus,\n cat,\n feature,\n};\n\nexport function getControl(name: string): ControlHandler | undefined {\n return Object.prototype.hasOwnProperty.call(CONTROLS, name)\n ? CONTROLS[name]\n : undefined;\n}\n","/**\n * CDDL validation engine: matches a CBOR AST (CborItem) against a compiled\n * CDDL schema (CddlSchema).\n *\n * Design notes:\n * - Arrays are matched by backtracking over the group's occurrence\n * indicators (regex-style over the item sequence), enumerating the\n * possible end positions of each sub-group.\n * - Maps are matched by consuming entries: group entries are processed in\n * definition order and greedily consume matching map entries; member keys\n * with cut semantics (`:` and `^ =>`, RFC 8610 §3.5.4) commit to an entry\n * once its key matches, failing the whole map when the value mismatches.\n * - Failures discarded by backtracking are noise; only the failure that\n * reached furthest into the instance source is reported.\n * - `maxSteps` / `maxDepth` bound pathological backtracking and unbounded\n * recursion; exceeding them aborts validation with an explanatory error.\n * - A CDN elision (`...`, CborEllipsis) matches any single item or map\n * entry; container lengths and required counts still apply.\n */\n\nimport type { CddlSchema } from './schema';\nimport { getPreludeRules } from './prelude';\nimport { CborItem } from '../ast/CborItem';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborFloat } from '../ast/CborFloat';\nimport { CborSimple } from '../ast/CborSimple';\nimport { CborArray } from '../ast/CborArray';\nimport { CborMap } from '../ast/CborMap';\nimport { CborTag } from '../ast/CborTag';\nimport { CborEllipsis } from '../ast/CborEllipsis';\nimport { CborAppSeqResult } from '../ast/CborAppSeqResult';\nimport { autoSelectFloatPrecision } from '../cbor/encode';\nimport { textValue, byteValue, bytesEqual, intValueOf } from './equal';\nimport type {\n CddlValidationError,\n CddlValidationWarning,\n ValidationResult,\n} from './errors';\nimport type {\n CddlGroup,\n CddlGroupEntry,\n CddlMemberKey,\n CddlNodeBase,\n CddlRef,\n CddlRule,\n CddlType,\n CddlType1,\n CddlType2,\n CddlValue,\n} from './ast';\nimport { featureName, getControl, type ControlDeps } from './controls';\n\nexport interface ValidateOptions {\n /** Recursion guard for rule references and nested groups (default 256). */\n maxDepth?: number;\n /** Total backtracking step budget (default 1e6). */\n maxSteps?: number;\n /** Feature names accepted by the `.feature` control operator. */\n features?: string[];\n /**\n * Name of the rule to validate against, in place of the schema's root\n * (the first rule in source order — RFC 8610 §3.1 defines only one root\n * per model). Any non-generic rule usable as a type can be selected,\n * defined in the schema or its prelude — e.g. a variant used only as a\n * component elsewhere.\n *\n * An unknown name fails validation (`errors[0].message` is `'<name>' is\n * not defined`) rather than throwing, matching how an unresolved `$ref`\n * inside the schema is reported. A generic rule (`g<T> = ...`) also fails\n * validation rather than throwing: there is no `genericArgs` site to bind\n * its parameters from here, so it cannot be selected directly. Likewise a\n * group-only rule fails with `group rule '<name>' cannot be used as a\n * type`, exactly as when such a rule is referenced in type position.\n */\n rule?: string;\n}\n\n/**\n * One tag on a successful match path: `item` is a `CborTag` matched by a\n * `#6.N(type)` with literal tag number `tag`, or — `inferred` — an\n * untagged item that matched only as the content of such a type (see\n * `TagTracing.infer`).\n */\nexport interface TagRecord {\n readonly item: CborItem;\n readonly tag: bigint;\n readonly inferred: boolean;\n /**\n * For an inferred record, how many inferred tags enclose this one around\n * the same item (0 = outermost): `#6.101(#6.100(int))` records 101 at\n * layer 0 and 100 at layer 1. Re-checking one layer (`.and`, …) repeats\n * its layer; a genuinely nested tag, even of the same number, doesn't.\n * Always 0 for a matched tag.\n */\n readonly layer: number;\n}\n\n/** Tag bookkeeping for {@link validateItem}'s internal callers. */\nexport interface TagTracing {\n /**\n * Let `#6.N(type)` (literal N) accept an untagged item matching `type`,\n * recording it as inferred. Only a fallback: at every type, rule and\n * map-group choice, alternatives are first tried without inference.\n */\n readonly infer?: boolean;\n /** Tags to match as if absent (their content in their place). */\n readonly stripped?: ReadonlySet<CborTag>;\n /** Receives the successful path's records (left empty on failure). */\n readonly trail: TagRecord[];\n}\n\n// ─── Context ──────────────────────────────────────────────────────────────────\n\ntype PathSeg = string | number;\n\n/** Generic parameter bindings; each binding closes over its defining env. */\ntype Env = Map<string, { type1: CddlType1; env: Env }> | undefined;\n\nclass LimitExceeded extends Error {}\n\nclass Ctx {\n steps = 0;\n ruleName: string | undefined;\n /** >0 while matching content decoded out of a .cbor/.cborseq byte string,\n * whose node offsets are relative to the embedded bytes — meaningless in\n * the outer document, so they are suppressed. */\n embeddedDepth = 0;\n /** >0 while matching inside a prelude rule, whose node offsets point into\n * the prelude text; errors are anchored to the referencing user node. */\n preludeDepth = 0;\n preludeRef: CddlNodeBase | undefined;\n readonly warnings: CddlValidationWarning[] = [];\n private readonly warned = new Set<string>();\n /**\n * Implicit-tag bookkeeping (see `matchTags()`): when `infer` is set, a\n * `#6.N(type)` with a literal tag number also accepts an *untagged* item\n * matching `type` — as a fallback only, see `strictFirst()`.\n */\n infer = false;\n /** Tags matched as if absent (their content stands in their place). */\n stripped: ReadonlySet<CborTag> | undefined;\n /**\n * Tag matches/inferences on the current match path, when recording.\n * Failing branches truncate it back (`ctx.trail.length = mark`), so on\n * overall success it holds the successful path's records only.\n */\n trail: TagRecord[] | undefined;\n /** Inferred tags currently open around each item (see `TagRecord.layer`). */\n readonly inferLayers = new Map<CborItem, number>();\n best: (CddlValidationError & { depth: number; startKey: number }) | undefined;\n\n constructor(\n readonly schema: CddlSchema,\n readonly maxDepth: number,\n readonly maxSteps: number,\n readonly features: Set<string>\n ) {}\n\n /**\n * Run `fn` with inference off first, then (only if that fails) on: at a\n * choice point, an alternative the item matches as-is always wins over\n * one it would match only with an inferred tag (so `time / number`\n * leaves a plain number untagged).\n */\n strictFirst(fn: () => boolean): boolean {\n if (!this.infer) return fn();\n this.infer = false;\n try {\n if (fn()) return true;\n } finally {\n this.infer = true;\n }\n return fn();\n }\n\n step(): void {\n if (++this.steps > this.maxSteps)\n throw new LimitExceeded(\n `validation aborted: step budget of ${this.maxSteps} exceeded (pathological backtracking?)`\n );\n }\n\n checkDepth(depth: number): void {\n if (depth > this.maxDepth)\n throw new LimitExceeded(\n `validation aborted: recursion depth ${this.maxDepth} exceeded (cyclic rules without progress?)`\n );\n }\n\n warnOnce(message: string, node?: CddlNodeBase): void {\n const key = `${message}@${node?.start ?? -1}`;\n if (this.warned.has(key)) return;\n this.warned.add(key);\n this.warnings.push({\n message,\n ...(node ? { schemaStart: node.start, schemaEnd: node.end } : {}),\n });\n }\n\n /**\n * Record a failure candidate. The failure furthest into the instance\n * source wins (the standard furthest-progress heuristic — sub-failures\n * of ultimately-successful alternatives, e.g. the uint branch of `int`\n * rejecting a negative number, are left behind by later progress);\n * offset ties are broken by the deeper instance path, then recency.\n */\n fail(\n path: readonly PathSeg[],\n item: CborItem | undefined,\n node: CddlNodeBase | undefined,\n message: string\n ): false {\n const suppressed = this.embeddedDepth > 0;\n const startKey = suppressed ? -1 : (item?.start ?? -1);\n if (\n !this.best ||\n startKey > this.best.startKey ||\n (startKey === this.best.startKey && path.length >= this.best.depth)\n ) {\n const schemaNode = this.preludeDepth > 0 ? this.preludeRef : node;\n this.best = {\n depth: path.length,\n startKey,\n message,\n path: path.length === 0 ? '/' : '/' + path.join('/'),\n ...(!suppressed && item?.start !== undefined\n ? { start: item.start, end: item.end }\n : {}),\n ...(this.ruleName !== undefined ? { ruleName: this.ruleName } : {}),\n ...(schemaNode\n ? { schemaStart: schemaNode.start, schemaEnd: schemaNode.end }\n : {}),\n };\n }\n return false;\n }\n}\n\n// ─── Entry point ──────────────────────────────────────────────────────────────\n\nexport function validateItem(\n schema: CddlSchema,\n item: CborItem,\n options?: ValidateOptions,\n tags?: TagTracing\n): ValidationResult {\n const ruleName = options?.rule ?? schema.root?.name;\n if (ruleName === undefined)\n return {\n valid: false,\n errors: [\n {\n message: 'schema has no rules (no root to validate against)',\n path: '/',\n },\n ],\n };\n const ctx = new Ctx(\n schema,\n options?.maxDepth ?? 256,\n options?.maxSteps ?? 1_000_000,\n new Set(options?.features ?? [])\n );\n if (tags) {\n ctx.infer = tags.infer ?? false;\n ctx.stripped = tags.stripped;\n ctx.trail = tags.trail;\n }\n // A generic rule's parameters are only ever bound from a referencing\n // site's `genericArgs` (see `bindGenericsForDef`); neither the schema\n // root nor `{ rule }` has one to supply, so selecting a generic rule here\n // would either leave its parameter names unresolved (reported as\n // undefined names, misleadingly) or silently ignore them if unused.\n // Reject it explicitly instead.\n const defs = ruleDefs(ctx, ruleName);\n const genericCount = defs?.[0]?.generics?.length ?? 0;\n if (genericCount > 0)\n return {\n valid: false,\n errors: [\n {\n message: `rule '${ruleName}' takes ${genericCount} generic argument${genericCount === 1 ? '' : 's'} and cannot be used as a validation target directly; reference it with concrete arguments from another rule instead`,\n path: '/',\n },\n ],\n };\n let valid: boolean;\n try {\n valid = matchRuleName(item, ruleName, undefined, [], ctx, 0);\n if (!valid && tags) tags.trail.length = 0;\n } catch (e) {\n if (tags) tags.trail.length = 0;\n if (!(e instanceof LimitExceeded)) throw e;\n return {\n valid: false,\n errors: [{ message: e.message, path: '/' }],\n ...(ctx.warnings.length ? { warnings: ctx.warnings } : {}),\n };\n }\n if (valid)\n return {\n valid: true,\n errors: [],\n ...(ctx.warnings.length ? { warnings: ctx.warnings } : {}),\n };\n const errors: CddlValidationError[] = ctx.best\n ? [(({ depth: _d, startKey: _s, ...rest }) => rest)(ctx.best)]\n : [\n {\n message: `value does not match rule '${ruleName}'`,\n path: '/',\n ...(item.start !== undefined\n ? { start: item.start, end: item.end }\n : {}),\n },\n ];\n return {\n valid: false,\n errors,\n ...(ctx.warnings.length ? { warnings: ctx.warnings } : {}),\n };\n}\n\nfunction withCtx<T>(\n schema: CddlSchema,\n options: ValidateOptions | undefined,\n run: (ctx: Ctx) => T\n): T | undefined {\n const ctx = new Ctx(\n schema,\n options?.maxDepth ?? 256,\n options?.maxSteps ?? 1_000_000,\n new Set(options?.features ?? [])\n );\n try {\n return run(ctx);\n } catch (e) {\n if (e instanceof LimitExceeded) return undefined;\n throw e;\n }\n}\n\n/**\n * Whether `item` matches `type` on its own, exactly as validation would\n * check it at a position of that type (no generic bindings). `undefined`\n * when the step/depth budget runs out.\n */\nexport function itemMatchesType(\n schema: CddlSchema,\n item: CborItem,\n type: CddlType,\n options?: ValidateOptions\n): boolean | undefined {\n return withCtx(schema, options, (ctx) =>\n matchType(item, type, undefined, [], ctx, 0)\n );\n}\n\n/** Opaque generic-parameter bindings in force at some point of a match. */\nexport type CddlEnv = Env;\n\n/**\n * The group member that consumed one map entry on the validator's own\n * successful path — its member key, value type, and the generic bindings\n * in force there.\n */\nexport interface MapMember {\n readonly memberKey: CddlMemberKey;\n readonly type: CddlType;\n readonly env: CddlEnv;\n}\n\n/** One map group a type can denote, with its generic bindings. */\nexport interface MapGroupTarget {\n readonly group: CddlGroup;\n readonly env: CddlEnv;\n}\n\n/**\n * Every map group (`{...}`) `type` can denote, following references,\n * parentheses, choices and generic bindings exactly as `matchType()` does.\n * `undefined` when some alternative could still match a map some *other*\n * way this can't see into — `any`/`#5`, a control operator, `~unwrap`, an\n * `&(...)` type, an undefined name — so no single group's assignment is\n * known to be the one validation used.\n */\nexport function mapGroupsOfType(\n schema: CddlSchema,\n type: CddlType,\n env: CddlEnv\n): MapGroupTarget[] | undefined {\n return withCtx(schema, undefined, (ctx) => {\n const out: MapGroupTarget[] = [];\n return collectMapGroups(type, env, ctx, [], out) ? out : undefined;\n });\n}\n\nfunction collectMapGroups(\n type: CddlType,\n env: Env,\n ctx: Ctx,\n stack: string[],\n out: MapGroupTarget[]\n): boolean {\n for (const t1 of type.alternatives) {\n if (t1.op) return false;\n if (!collectMapGroups2(t1.target, env, ctx, stack, out)) return false;\n }\n return true;\n}\n\nfunction collectMapGroups2(\n t2: CddlType2,\n env: Env,\n ctx: Ctx,\n stack: string[],\n out: MapGroupTarget[]\n): boolean {\n switch (t2.kind) {\n case 'map':\n out.push({ group: t2.group, env });\n return true;\n case 'paren':\n return collectMapGroups(t2.type, env, ctx, stack, out);\n case 'ref': {\n const binding = env?.get(t2.name);\n if (binding && !t2.genericArgs) {\n if (binding.type1.op) return false;\n return collectMapGroups2(\n binding.type1.target,\n binding.env,\n ctx,\n stack,\n out\n );\n }\n if (stack.length > 64) return false;\n if (!t2.genericArgs && stack.includes(t2.name)) return true;\n const defs = ruleDefs(ctx, t2.name);\n if (!defs) return false;\n stack.push(t2.name);\n try {\n for (const def of defs) {\n const defEnv = bindGenericsForDef(def, t2.genericArgs, env);\n if (isPlainTypeEntry(def.body)) {\n if (!collectMapGroups(def.body.value, defEnv, ctx, stack, out))\n return false;\n continue;\n }\n // Mirrors matchRuleName(): a group body is usable as a type only\n // when every choice is a single plain entry; otherwise it never\n // matches anything here.\n const choices = choicesOfBody(def.body);\n if (!choices.every((c) => c.length === 1 && isPlainTypeEntry(c[0]!)))\n continue;\n for (const [only] of choices)\n if (\n !collectMapGroups(\n (only as Extract<CddlGroupEntry, { kind: 'entry' }>).value,\n defEnv,\n ctx,\n stack,\n out\n )\n )\n return false;\n }\n } finally {\n stack.pop();\n }\n return true;\n }\n case 'major':\n return t2.major !== 5;\n case 'value':\n case 'array':\n case 'tagged': // requires a tag, never a bare map\n return true;\n default:\n return false; // any, unwrap, enum\n }\n}\n\n/**\n * The literal text a member key requires, when it requires exactly one:\n * `name:`, `\"name\":`, or `\"name\" =>` (a text-literal key type).\n */\nexport function plainTextSpelling(mk: CddlMemberKey): string | undefined {\n if (mk.kind === 'bareword') return mk.key;\n if (mk.kind === 'value')\n return mk.key.type === 'text' ? mk.key.value : undefined;\n const t2 = mk.key.target;\n return !mk.key.op && t2.kind === 'value' && t2.type === 'text'\n ? t2.value\n : undefined;\n}\n\n/**\n * Every spelling used as a plain text member key anywhere in `target`'s\n * group — `name:`, `\"name\":`, or a key type that accepts a text literal\n * (`\"name\" =>`, a rule or `/` choice of such literals, or a generic\n * parameter bound to one, e.g. `K => …` in `G<\"name\">`) — through inline\n * sub-groups, bare group references and `~unwrap`ped groups, expanded\n * exactly as matching expands them (`expandEntry()`), across every choice\n * and every distinct generic instantiation. `undefined` when the expansion\n * runs out of budget.\n */\nexport function plainTextMemberKeys(\n schema: CddlSchema,\n target: MapGroupTarget\n): ReadonlySet<string> | undefined {\n return withCtx(schema, undefined, (ctx) => {\n const names = new Set<string>();\n // The same group under the same (normalized) bindings can't add\n // anything new; under different bindings — `G<\"x\">` vs `G<\"y\">` — it\n // can, so both are part of the key.\n const visited = new Set<string>();\n const ids = new WeakMap<object, number>();\n let nextId = 0;\n const idOf = (node: object): number => {\n let id = ids.get(node);\n if (id === undefined) ids.set(node, (id = nextId++));\n return id;\n };\n const visit = (choices: readonly GroupChoice[], depth: number): void => {\n ctx.checkDepth(depth);\n for (const choice of choices) {\n const key = `${idOf(choice.entries)}|${envSignature(idOf, choice.env)}`;\n if (visited.has(key)) continue;\n visited.add(key);\n for (const entry of choice.entries) {\n ctx.step();\n const m = expandEntry(entry, choice.env, ctx);\n if (m.kind === 'group') visit(m.choices, depth + 1);\n else if (m.memberKey) {\n const texts = memberKeyTexts(m.memberKey, m.env, ctx);\n if (!texts) throw UNKNOWN_KEY;\n for (const t of texts.literals) names.add(t);\n }\n }\n }\n };\n try {\n visit(plainChoices(target.group, target.env), 0);\n } catch (e) {\n if (e === UNKNOWN_KEY) return undefined;\n throw e;\n }\n return names;\n });\n}\n\nconst UNKNOWN_KEY = new Error('member key type not resolvable');\n\n/**\n * A structural signature of `env`: each binding followed through bare\n * references to other bound parameters down to the type it finally stands\n * for, so a recursive instantiation (`G<T> = (…, ? G<T>)`) that re-binds a\n * parameter to the same thing yields the same signature at every level.\n */\nfunction envSignature(idOf: (node: object) => number, env: Env): string {\n if (!env) return '';\n const parts: string[] = [];\n for (const [name, binding] of env) {\n let b = binding;\n for (let hops = 0; hops < 64; hops++) {\n const t = b.type1;\n if (t.op || t.target.kind !== 'ref' || t.target.genericArgs) break;\n const next = b.env?.get(t.target.name);\n if (!next) break;\n b = next;\n }\n parts.push(`${name}=${idOf(b.type1)}(${envSignature(idOf, b.env)})`);\n }\n return parts.sort().join(',');\n}\n\n/**\n * What text a member-key type accepts: the specific text `literals` it\n * can equal, and whether it also accepts arbitrary text (`wildcard`, e.g.\n * `tstr`/`any` — not a plain spelling, so not a label conflict). A\n * function returning `undefined` means *unknown*: it might accept some\n * specific literal this can't see (e.g. a control operator narrowing\n * `tstr` to `\"x\"`), so no conclusion about any spelling can be drawn.\n */\ninterface KeyTexts {\n readonly literals: ReadonlySet<string>;\n readonly wildcard: boolean;\n}\n\nconst NO_TEXT: KeyTexts = { literals: new Set(), wildcard: false };\nconst ANY_TEXT: KeyTexts = { literals: new Set(), wildcard: true };\n\n/**\n * Control operators whose result is always a subset of their target's own\n * values — so on a target of known literals they can only drop some.\n */\nconst NARROWING_CONTROLS = new Set([\n 'size',\n 'bits',\n 'regexp',\n 'pcre',\n 'and',\n 'within',\n 'lt',\n 'le',\n 'gt',\n 'ge',\n 'eq',\n 'ne',\n 'default',\n 'feature',\n]);\n\nfunction mergeKeyTexts(a: KeyTexts, b: KeyTexts): KeyTexts {\n return {\n literals: new Set([...a.literals, ...b.literals]),\n wildcard: a.wildcard || b.wildcard,\n };\n}\n\nfunction memberKeyTexts(\n mk: CddlMemberKey,\n env: Env,\n ctx: Ctx\n): KeyTexts | undefined {\n if (mk.kind === 'bareword')\n return { literals: new Set([mk.key]), wildcard: false };\n if (mk.kind === 'value')\n return mk.key.type === 'text'\n ? { literals: new Set([mk.key.value]), wildcard: false }\n : NO_TEXT;\n return keyTextsOfType1(mk.key, env, ctx, []);\n}\n\nfunction keyTextsOfType(\n type: CddlType,\n env: Env,\n ctx: Ctx,\n stack: string[]\n): KeyTexts | undefined {\n let out = NO_TEXT;\n for (const alt of type.alternatives) {\n const t = keyTextsOfType1(alt, env, ctx, stack);\n if (!t) return undefined;\n out = mergeKeyTexts(out, t);\n }\n return out;\n}\n\nfunction keyTextsOfType1(\n t1: CddlType1,\n env: Env,\n ctx: Ctx,\n stack: string[]\n): KeyTexts | undefined {\n ctx.step();\n const target = keyTextsOfType2(t1.target, env, ctx, stack);\n if (!target || !t1.op) return target;\n // A control or range over a type that never holds text can't yield text.\n if (target.literals.size === 0 && !target.wildcard) return target;\n if (\n t1.op.kind === 'ctl' &&\n NARROWING_CONTROLS.has(t1.op.name) &&\n !target.wildcard\n )\n return target;\n // Could narrow arbitrary text down to one literal, or build a new one.\n return undefined;\n}\n\nfunction keyTextsOfType2(\n t2: CddlType2,\n env: Env,\n ctx: Ctx,\n stack: string[]\n): KeyTexts | undefined {\n switch (t2.kind) {\n case 'value':\n return t2.type === 'text'\n ? { literals: new Set([t2.value]), wildcard: false }\n : NO_TEXT;\n case 'paren':\n return keyTextsOfType(t2.type, env, ctx, stack);\n case 'ref': {\n const binding = env?.get(t2.name);\n if (binding && !t2.genericArgs)\n return keyTextsOfType1(binding.type1, binding.env, ctx, stack);\n ctx.checkDepth(stack.length);\n if (!t2.genericArgs && stack.includes(t2.name)) return NO_TEXT;\n const defs = ruleDefs(ctx, t2.name);\n if (!defs) return undefined;\n stack.push(t2.name);\n try {\n let out = NO_TEXT;\n for (const def of defs) {\n const defEnv = bindGenericsForDef(def, t2.genericArgs, env);\n // Mirrors matchRuleName(): a group body is usable as a type only\n // when every choice is a single plain entry.\n const types = isPlainTypeEntry(def.body)\n ? [def.body.value]\n : choicesOfBody(def.body).every(\n (c) => c.length === 1 && isPlainTypeEntry(c[0]!)\n )\n ? choicesOfBody(def.body).map(\n ([only]) =>\n (only as Extract<CddlGroupEntry, { kind: 'entry' }>).value\n )\n : [];\n for (const type of types) {\n const t = keyTextsOfType(type, defEnv, ctx, stack);\n if (!t) return undefined;\n out = mergeKeyTexts(out, t);\n }\n }\n return out;\n } finally {\n stack.pop();\n }\n }\n case 'enum': {\n // `&(a: \"x\", …)` accepts each entry's own value.\n if (t2.group.kind !== 'group') return undefined;\n let out = NO_TEXT;\n for (const choice of t2.group.choices)\n for (const entry of choice) {\n if (entry.kind !== 'entry' || !entry.memberKey) return undefined;\n const t = keyTextsOfType(entry.value, env, ctx, stack);\n if (!t) return undefined;\n out = mergeKeyTexts(out, t);\n }\n return out;\n }\n case 'unwrap': {\n const inner = resolveUnwrapTagType(t2.ref, env, ctx, 0);\n return inner\n ? keyTextsOfType(inner.type, inner.env, ctx, stack)\n : undefined;\n }\n case 'major':\n return t2.major === 3 ? ANY_TEXT : NO_TEXT;\n case 'any':\n return ANY_TEXT;\n default:\n return NO_TEXT; // map, array, tagged: never a text string\n }\n}\n\n/**\n * Match `map` against one map group exactly as validation does\n * (`matchMapGroup()`), returning which member consumed each of its entries\n * on the successful path (`false` for one left unconsumed, e.g. an elided\n * `...` entry). `null` when it doesn't match; `undefined` when the budget\n * runs out.\n */\nexport function traceMapGroup(\n schema: CddlSchema,\n map: CborMap,\n target: MapGroupTarget,\n options?: ValidateOptions\n): readonly (MapMember | false)[] | null | undefined {\n return withCtx(schema, options, (ctx) => {\n let owners: (MapMember | false)[] | undefined;\n const ok = matchMapGroup(map, target.group, target.env, [], ctx, 0, (c) => {\n owners = c.slice();\n });\n return ok && owners ? owners : null;\n });\n}\n\n// ─── Rule resolution ──────────────────────────────────────────────────────────\n\nfunction ruleDefs(ctx: Ctx, name: string): readonly CddlRule[] | undefined {\n const defs = ctx.schema.rules.get(name);\n if (defs) return defs;\n const preludeRule = getPreludeRules().get(name);\n return preludeRule ? [preludeRule] : undefined;\n}\n\nfunction isPlainTypeEntry(\n entry: CddlGroupEntry\n): entry is Extract<CddlGroupEntry, { kind: 'entry' }> {\n return entry.kind === 'entry' && !entry.occur && !entry.memberKey;\n}\n\n/** The group choices contributed by one rule definition body. */\nfunction choicesOfBody(entry: CddlGroupEntry): CddlGroupEntry[][] {\n if (entry.kind === 'entry-group' && !entry.occur) return entry.group.choices;\n return [[entry]];\n}\n\n/** Whether a set of rule definitions can only be used as a group. */\nfunction isGroupLike(defs: readonly CddlRule[]): boolean {\n return defs.some((d) => !isPlainTypeEntry(d.body));\n}\n\n/**\n * Bind one definition's own generic parameter names to the reference's\n * arguments. Each `/=` / `//=` extension may name its parameters\n * differently, so binding is per definition, never from `defs[0]` alone.\n */\nfunction bindGenericsForDef(\n def: CddlRule,\n genericArgs: readonly CddlType1[] | undefined,\n callerEnv: Env\n): Env {\n const params = def.generics;\n if (!params || !genericArgs) return undefined;\n const bound = new Map<string, { type1: CddlType1; env: Env }>();\n for (let i = 0; i < params.length && i < genericArgs.length; i++)\n bound.set(params[i]!, { type1: genericArgs[i]!, env: callerEnv });\n return bound;\n}\n\nfunction matchRuleName(\n item: CborItem,\n name: string,\n callerEnv: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number,\n refNode?: CddlNodeBase,\n genericArgs?: readonly CddlType1[]\n): boolean {\n const defs = ruleDefs(ctx, name);\n if (!defs)\n return ctx.fail(\n path,\n item,\n refNode,\n name.startsWith('$')\n ? `socket '${name}' has no definitions, so nothing matches it`\n : `'${name}' is not defined`\n );\n ctx.checkDepth(depth);\n const prevRule = ctx.ruleName;\n ctx.ruleName = name;\n const fromPrelude = !ctx.schema.rules.has(name);\n if (fromPrelude && ++ctx.preludeDepth === 1) ctx.preludeRef = refNode;\n const tryDefs = (): boolean => {\n for (const def of defs) {\n const env = bindGenericsForDef(def, genericArgs, callerEnv);\n if (isPlainTypeEntry(def.body)) {\n if (matchType(item, def.body.value, env, path, ctx, depth + 1))\n return true;\n continue;\n }\n // A group-bodied definition in type position: usable only when every\n // choice reduces to a single plain entry (a choice-of-types group).\n const choices = choicesOfBody(def.body);\n let usable = true;\n for (const choice of choices) {\n if (choice.length === 1 && isPlainTypeEntry(choice[0]!)) continue;\n usable = false;\n break;\n }\n if (!usable) {\n ctx.fail(\n path,\n item,\n def.body,\n `group rule '${name}' cannot be used as a type`\n );\n continue;\n }\n for (const choice of choices) {\n const only = choice[0]! as Extract<CddlGroupEntry, { kind: 'entry' }>;\n if (matchType(item, only.value, env, path, ctx, depth + 1)) return true;\n }\n }\n return false;\n };\n try {\n return defs.length > 1 || !isPlainTypeEntry(defs[0]!.body)\n ? ctx.strictFirst(tryDefs)\n : tryDefs();\n } finally {\n ctx.ruleName = prevRule;\n if (fromPrelude && --ctx.preludeDepth === 0) ctx.preludeRef = undefined;\n }\n}\n\n// ─── Type matching ────────────────────────────────────────────────────────────\n\n/**\n * See through transparent app-string sequence wrappers (`t1<<…>>`,\n * `b1<<…>>`, `ilbs`/`ilts`, `same<<…>>`): the wrapper only preserves the\n * CDN source spelling for re-serialization; the data-model item is its\n * `inner` result, which is what CDDL types describe.\n */\nfunction unwrapAppSeq(item: CborItem): CborItem {\n while (item instanceof CborAppSeqResult) item = item.inner;\n return item;\n}\n\n/** `unwrapAppSeq()`, plus seeing through any tag in `ctx.stripped`. */\nfunction viewItem(item: CborItem, ctx: Ctx): CborItem {\n for (;;) {\n item = unwrapAppSeq(item);\n if (!(ctx.stripped && item instanceof CborTag && ctx.stripped.has(item)))\n return item;\n item = item.content;\n }\n}\n\nfunction matchType(\n item: CborItem,\n type: CddlType,\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): boolean {\n const run = (): boolean => {\n const mark = ctx.trail?.length ?? 0;\n for (const alt of type.alternatives) {\n if (matchType1(item, alt, env, path, ctx, depth)) return true;\n if (ctx.trail) ctx.trail.length = mark;\n }\n return false;\n };\n return type.alternatives.length > 1 ? ctx.strictFirst(run) : run();\n}\n\nfunction matchType1(\n item: CborItem,\n t1: CddlType1,\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): boolean {\n if (!ctx.trail) return matchType1Inner(item, t1, env, path, ctx, depth);\n const mark = ctx.trail.length;\n if (matchType1Inner(item, t1, env, path, ctx, depth)) return true;\n ctx.trail.length = mark;\n return false;\n}\n\nfunction matchType1Inner(\n item: CborItem,\n t1: CddlType1,\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): boolean {\n ctx.step();\n // Unwrapped here (before control handlers see the item) and again in\n // matchType2, which is also entered directly from control plumbing.\n item = viewItem(item, ctx);\n if (!t1.op || !t1.controller)\n return matchType2(item, t1.target, env, path, ctx, depth);\n if (t1.op.kind === 'range')\n return matchRange(item, t1, env, path, ctx, depth);\n const handler = getControl(t1.op.name);\n const deps = makeControlDeps(env, ctx, depth);\n if (!handler) {\n ctx.warnOnce(\n `control operator .${t1.op.name} is not supported; matching the target only`,\n t1\n );\n return matchType2(item, t1.target, env, path, ctx, depth);\n }\n return handler(deps, item, t1.target, t1.controller, path, t1);\n}\n\nfunction matchType2(\n item: CborItem,\n t2: CddlType2,\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): boolean {\n item = viewItem(item, ctx);\n // A CDN elision stands for content that was deliberately left out.\n if (item instanceof CborEllipsis) return true;\n\n switch (t2.kind) {\n case 'any':\n return true;\n\n case 'value':\n return matchesLiteral(item, t2)\n ? true\n : ctx.fail(path, item, t2, `expected the value ${t2.raw}`);\n\n case 'ref': {\n const binding = env?.get(t2.name);\n if (binding && !t2.genericArgs)\n return matchType1(\n item,\n binding.type1,\n binding.env,\n path,\n ctx,\n depth + 1\n );\n return matchRuleName(\n item,\n t2.name,\n env,\n path,\n ctx,\n depth + 1,\n t2,\n t2.genericArgs\n );\n }\n\n case 'paren':\n return matchType(item, t2.type, env, path, ctx, depth);\n\n case 'map':\n if (!(item instanceof CborMap))\n return ctx.fail(path, item, t2, 'expected a map');\n return matchMapGroup(item, t2.group, env, path, ctx, depth + 1);\n\n case 'array':\n if (!(item instanceof CborArray))\n return ctx.fail(path, item, t2, 'expected an array');\n return matchArrayGroup(item, t2.group, env, path, ctx, depth + 1);\n\n case 'tagged': {\n // #6.n(type) denotes a *tagged data item* (RFC 8610 §3.6): an untagged\n // integer never matches #6.2/#6.3. (Value-level bignum equivalence\n // lives in literals/ranges/comparisons via intValueOf instead.)\n if (!(item instanceof CborTag)) {\n if (ctx.infer && typeof t2.tag === 'bigint') {\n const mark = ctx.trail?.length ?? 0;\n const layer = ctx.inferLayers.get(item) ?? 0;\n ctx.inferLayers.set(item, layer + 1);\n let ok: boolean;\n try {\n ok = matchType(item, t2.item, env, path, ctx, depth + 1);\n } finally {\n if (layer === 0) ctx.inferLayers.delete(item);\n else ctx.inferLayers.set(item, layer);\n }\n if (ok) {\n ctx.trail?.push({ item, tag: t2.tag, inferred: true, layer });\n return true;\n }\n if (ctx.trail) ctx.trail.length = mark;\n }\n return ctx.fail(path, item, t2, 'expected a tagged item');\n }\n if (typeof t2.tag === 'bigint') {\n if (item.tag !== t2.tag)\n return ctx.fail(\n path,\n item,\n t2,\n `expected tag ${t2.tag}, got ${item.tag}`\n );\n } else if (t2.tag !== undefined) {\n if (\n !matchType(new CborUint(item.tag), t2.tag, env, path, ctx, depth + 1)\n )\n return ctx.fail(\n path,\n item,\n t2,\n `tag number ${item.tag} does not match the head type`\n );\n }\n if (!matchType(item.content, t2.item, env, path, ctx, depth + 1))\n return false;\n if (typeof t2.tag === 'bigint')\n ctx.trail?.push({ item, tag: t2.tag, inferred: false, layer: 0 });\n return true;\n }\n\n case 'major':\n return matchMajor(item, t2, env, path, ctx, depth);\n\n case 'unwrap': {\n // Unwrapping a tag rule exposes the tagged content's type\n // (RFC 8610 §3.7, e.g. `my-uri = ~uri` is a tstr).\n const inner = resolveUnwrapTagType(t2.ref, env, ctx, 0);\n if (inner)\n return matchType(item, inner.type, inner.env, path, ctx, depth + 1);\n // Unwrapping an array/map splices a group into the enclosing\n // array/map; group matching resolves that before type matching, so\n // reaching this point means it was used where only a type can appear.\n ctx.warnOnce(\n `~${t2.ref.name} is used outside of an array/map group context`,\n t2\n );\n return ctx.fail(path, item, t2, `~${t2.ref.name} cannot match here`);\n }\n\n case 'enum': {\n const choices =\n t2.group.kind === 'ref'\n ? resolveGroupRef(t2.group, env, ctx)\n : plainChoices(t2.group, env);\n if (!choices)\n return ctx.fail(\n path,\n item,\n t2,\n `'&' target does not resolve to a group`\n );\n ctx.checkDepth(depth);\n if (matchEnum(item, choices, path, ctx, depth + 1)) return true;\n return ctx.fail(path, item, t2, 'no enumeration value matches');\n }\n }\n}\n\n/** Match an item against the set of entry values of an enum group. */\nfunction matchEnum(\n item: CborItem,\n choices: readonly GroupChoice[],\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): boolean {\n for (const { entries, env } of choices) {\n for (const entry of entries) {\n ctx.step();\n if (entry.kind === 'entry-group') {\n if (\n matchEnum(item, plainChoices(entry.group, env), path, ctx, depth + 1)\n )\n return true;\n continue;\n }\n // Nested group reference inside the enum.\n const groupRef = asBareGroupRef(entry, env, ctx);\n if (groupRef) {\n ctx.checkDepth(depth);\n if (matchEnum(item, groupRef, path, ctx, depth + 1)) return true;\n continue;\n }\n if (matchType(item, entry.value, env, path, ctx, depth + 1)) return true;\n }\n }\n return false;\n}\n\n// ─── Literal and numeric matching ─────────────────────────────────────────────\n\nexport function matchesLiteral(item: CborItem, v: CddlValue): boolean {\n switch (v.type) {\n case 'int':\n // Value comparison is numeric, including bignums: the only wire form\n // of an integer beyond ±(2^64) is its tag-2/3 representation.\n return intValueOf(item) === BigInt(v.value);\n case 'float':\n return (\n item instanceof CborFloat &&\n (item.value === v.value ||\n (Number.isNaN(item.value) && Number.isNaN(v.value)))\n );\n case 'text':\n return textValue(item) === v.value;\n case 'bytes': {\n const bytes = byteValue(item);\n return bytes !== undefined && bytesEqual(bytes, v.value);\n }\n }\n}\n\n/**\n * Resolve a type2 to a literal value, following parentheses, generic\n * bindings, and references to single-alternative value rules. Used for\n * range endpoints and computing control operators (.plus, .cat, …).\n */\nfunction resolveValue(\n t2: CddlType2,\n env: Env,\n ctx: Ctx,\n depth = 0\n): CddlValue | undefined {\n if (depth > 32) return undefined;\n if (t2.kind === 'value') return t2;\n if (t2.kind === 'paren') {\n const only =\n t2.type.alternatives.length === 1 ? t2.type.alternatives[0] : undefined;\n if (!only || only.op) return undefined;\n return resolveValue(only.target, env, ctx, depth + 1);\n }\n if (t2.kind !== 'ref') return undefined;\n const binding = env?.get(t2.name);\n if (binding && !t2.genericArgs) {\n if (binding.type1.op) return undefined;\n return resolveValue(binding.type1.target, binding.env, ctx, depth + 1);\n }\n const defs = ruleDefs(ctx, t2.name);\n if (!defs || defs.length !== 1) return undefined;\n const body = defs[0]!.body;\n if (!isPlainTypeEntry(body) || body.value.alternatives.length !== 1)\n return undefined;\n const only = body.value.alternatives[0]!;\n if (only.op) return undefined;\n const newEnv = bindGenericsForDef(defs[0]!, t2.genericArgs, env);\n return resolveValue(only.target, newEnv, ctx, depth + 1);\n}\n\n/**\n * Whether some integer ≥ `min` matches the type — i.e. whether the type's\n * integer set intersects [min, ∞). Used by `uint .size N` (which accepts\n * any byte count N ≥ the value's minimal length, with no upper limit on N).\n *\n * Tri-state: `undefined` means the type could not be analyzed structurally\n * (control operators, non-integer constructs, …) and the caller must fall\n * back to another strategy.\n */\nfunction existsIntGE(\n t2: CddlType2,\n min: bigint,\n env: Env,\n ctx: Ctx,\n depth = 0\n): boolean | undefined {\n return existsIntInRange(t2, min, undefined, env, ctx, depth);\n}\n\n/** Whether an integer in the inclusive interval [min, max] matches t2. */\nfunction existsIntInRange(\n t2: CddlType2,\n min: bigint,\n max: bigint | undefined,\n env: Env,\n ctx: Ctx,\n depth = 0\n): boolean | undefined {\n const found = findIntInRange(t2, min, max, env, ctx, depth);\n return found === undefined ? undefined : found !== null;\n}\n\n/**\n * The first integer in [min, max] matching t2. `null` means the analyzed\n * type has no such integer; `undefined` means it cannot be analyzed.\n */\nfunction findIntInRange(\n t2: CddlType2,\n min: bigint,\n max: bigint | undefined,\n env: Env,\n ctx: Ctx,\n depth = 0\n): bigint | null | undefined {\n if (max !== undefined && min > max) return null;\n if (depth > 32) return undefined;\n switch (t2.kind) {\n case 'value': {\n if (t2.type === 'int') {\n const value = BigInt(t2.value);\n return value >= min && (max === undefined || value <= max)\n ? value\n : null;\n }\n return null;\n }\n case 'any': {\n const candidate = min > 0n ? min : 0n;\n return max === undefined || candidate <= max ? candidate : null;\n }\n case 'major': {\n if (t2.ai !== undefined) return undefined;\n if (t2.major === 0) {\n const candidate = min > 0n ? min : 0n;\n return candidate <= 0xffff_ffff_ffff_ffffn &&\n (max === undefined || candidate <= max)\n ? candidate\n : null;\n }\n if (t2.major === 1) {\n const candidate =\n min > -0x1_0000_0000_0000_0000n ? min : -0x1_0000_0000_0000_0000n;\n return candidate <= -1n && (max === undefined || candidate <= max)\n ? candidate\n : null;\n }\n return null;\n }\n case 'paren':\n return findIntInRangeType(t2.type, min, max, env, ctx, depth + 1);\n case 'ref': {\n const binding = env?.get(t2.name);\n if (binding && !t2.genericArgs)\n return findIntInRangeType1(\n binding.type1,\n min,\n max,\n binding.env,\n ctx,\n depth + 1\n );\n const defs = ruleDefs(ctx, t2.name);\n if (!defs) return undefined;\n let sawUnknown = false;\n let best: bigint | null = null;\n for (const def of defs) {\n if (!isPlainTypeEntry(def.body)) {\n sawUnknown = true;\n continue;\n }\n const defEnv = bindGenericsForDef(def, t2.genericArgs, env);\n const r = findIntInRangeType(\n def.body.value,\n min,\n max,\n defEnv,\n ctx,\n depth + 1\n );\n if (typeof r === 'bigint' && (best === null || r < best)) best = r;\n if (r === undefined) sawUnknown = true;\n }\n return best ?? (sawUnknown ? undefined : null);\n }\n case 'enum': {\n const choices =\n t2.group.kind === 'ref'\n ? resolveGroupRef(t2.group, env, ctx)\n : plainChoices(t2.group, env);\n if (!choices) return undefined;\n let sawUnknown = false;\n let best: bigint | null = null;\n for (const { entries, env: choiceEnv } of choices) {\n for (const entry of entries) {\n if (entry.kind !== 'entry') {\n sawUnknown = true;\n continue;\n }\n const r = findIntInRangeType(\n entry.value,\n min,\n max,\n choiceEnv,\n ctx,\n depth + 1\n );\n if (typeof r === 'bigint' && (best === null || r < best)) best = r;\n if (r === undefined) sawUnknown = true;\n }\n }\n return best ?? (sawUnknown ? undefined : null);\n }\n default:\n return undefined;\n }\n}\n\nfunction findIntInRangeType(\n type: CddlType,\n min: bigint,\n max: bigint | undefined,\n env: Env,\n ctx: Ctx,\n depth: number\n): bigint | null | undefined {\n let sawUnknown = false;\n let best: bigint | null = null;\n for (const alt of type.alternatives) {\n const r = findIntInRangeType1(alt, min, max, env, ctx, depth);\n if (typeof r === 'bigint' && (best === null || r < best)) best = r;\n if (r === undefined) sawUnknown = true;\n }\n return best ?? (sawUnknown ? undefined : null);\n}\n\nfunction findIntInRangeType1(\n t1: CddlType1,\n min: bigint,\n max: bigint | undefined,\n env: Env,\n ctx: Ctx,\n depth: number\n): bigint | null | undefined {\n if (!t1.op) return findIntInRange(t1.target, min, max, env, ctx, depth);\n if (t1.op.kind === 'ctl') {\n if (t1.op.name === 'bits')\n return findBitsIntersection(\n t1.target,\n t1.controller!,\n min,\n max,\n env,\n ctx,\n depth + 1\n );\n if (t1.op.name === 'size') {\n const candidate = findIntInRange(\n t1.target,\n min > 0n ? min : 0n,\n max,\n env,\n ctx,\n depth + 1\n );\n if (candidate === undefined || candidate === null) return candidate;\n const fits = existsIntGE(\n t1.controller!,\n BigInt(uintByteLength(candidate)),\n env,\n ctx,\n depth + 1\n );\n return fits === undefined ? undefined : fits ? candidate : null;\n }\n if (t1.op.name === 'feature') {\n const name = featureName(\n makeControlDeps(env, ctx, depth),\n t1.controller!\n );\n if (name === undefined) return undefined;\n if (!ctx.features.has(name)) {\n ctx.warnOnce(\n `feature \"${name}\" is not enabled (pass it in options.features to accept it)`,\n t1\n );\n return null;\n }\n return findIntInRange(t1.target, min, max, env, ctx, depth + 1);\n }\n if (t1.op.name === 'and' || t1.op.name === 'within')\n return findIntIntersection(\n t1.target,\n t1.controller!,\n min,\n max,\n env,\n ctx,\n depth + 1\n );\n if (t1.op.name === 'plus') {\n const left = resolveValue(t1.target, env, ctx);\n const right = resolveValue(t1.controller!, env, ctx);\n if (\n !left ||\n !right ||\n left.type === 'text' ||\n left.type === 'bytes' ||\n right.type === 'text' ||\n right.type === 'bytes'\n )\n return undefined;\n // .plus converts the result to the target's numeric type. A float\n // target therefore cannot produce the integer byte count sought here;\n // an integer target floors a mixed float sum (RFC 9165 §2.1).\n if (left.type === 'float') return null;\n const sum =\n right.type === 'int'\n ? BigInt(left.value) + BigInt(right.value)\n : BigInt(Math.floor(Number(left.value) + right.value));\n return sum >= min && (max === undefined || sum <= max) ? sum : null;\n }\n const bound = resolveValue(t1.controller!, env, ctx);\n if (!bound || bound.type !== 'int') return undefined;\n const value = BigInt(bound.value);\n switch (t1.op.name) {\n case 'eq':\n return findIntInRange(\n t1.target,\n value > min ? value : min,\n max === undefined || value < max ? value : max,\n env,\n ctx,\n depth + 1\n );\n case 'ne':\n case 'default': {\n const below = findIntInRange(\n t1.target,\n min,\n max === undefined || value - 1n < max ? value - 1n : max,\n env,\n ctx,\n depth + 1\n );\n if (typeof below === 'bigint') return below;\n const above = findIntInRange(\n t1.target,\n value + 1n > min ? value + 1n : min,\n max,\n env,\n ctx,\n depth + 1\n );\n if (typeof above === 'bigint') return above;\n return below === undefined || above === undefined ? undefined : null;\n }\n case 'lt':\n case 'le': {\n const upper = value - (t1.op.name === 'lt' ? 1n : 0n);\n return findIntInRange(\n t1.target,\n min,\n max === undefined || upper < max ? upper : max,\n env,\n ctx,\n depth + 1\n );\n }\n case 'gt':\n case 'ge': {\n const lower = value + (t1.op.name === 'gt' ? 1n : 0n);\n return findIntInRange(\n t1.target,\n lower > min ? lower : min,\n max,\n env,\n ctx,\n depth + 1\n );\n }\n default:\n return undefined;\n }\n }\n const lo = resolveValue(t1.target, env, ctx);\n const hi = resolveValue(t1.controller!, env, ctx);\n if (!lo || !hi || lo.type !== 'int' || hi.type !== 'int') return undefined;\n const loV = BigInt(lo.value);\n const hiV = BigInt(hi.value) - (t1.op.inclusive ? 0n : 1n);\n const lower = loV > min ? loV : min;\n const upper = max === undefined || hiV < max ? hiV : max;\n return lower <= upper ? lower : null;\n}\n\n/** First integer in the intersection of two analyzable integer types. */\nfunction findIntIntersection(\n left: CddlType2,\n right: CddlType2,\n min: bigint,\n max: bigint | undefined,\n env: Env,\n ctx: Ctx,\n depth: number\n): bigint | null | undefined {\n let cursor = min;\n // Each iteration advances to a boundary returned by one side. The guard\n // only protects malformed/cyclic analyses; ordinary finite unions\n // converge in at most their combined number of alternatives.\n for (let i = 0; i < 256; i++) {\n const a = findIntInRange(left, cursor, max, env, ctx, depth + 1);\n const b = findIntInRange(right, cursor, max, env, ctx, depth + 1);\n if (a === null || b === null) return null;\n if (a === undefined || b === undefined) return undefined;\n if (a === b) return a;\n cursor = a > b ? a : b;\n }\n return undefined;\n}\n\n/** First uint in the target whose set bits are all admitted by controller. */\nfunction findBitsIntersection(\n target: CddlType2,\n controller: CddlType2,\n min: bigint,\n max: bigint | undefined,\n env: Env,\n ctx: Ctx,\n depth: number\n): bigint | null | undefined {\n let allowedMask = 0n;\n for (let bit = 0; bit < 64; bit++) {\n const allowed = findIntInRange(\n controller,\n BigInt(bit),\n BigInt(bit),\n env,\n ctx,\n depth + 1\n );\n if (allowed === undefined) return undefined;\n if (allowed !== null) allowedMask |= 1n << BigInt(bit);\n }\n\n let cursor = min > 0n ? min : 0n;\n const upper =\n max === undefined || max > 0xffff_ffff_ffff_ffffn\n ? 0xffff_ffff_ffff_ffffn\n : max;\n for (let i = 0; i < 256; i++) {\n const fromTarget = findIntInRange(\n target,\n cursor,\n upper,\n env,\n ctx,\n depth + 1\n );\n const fromBits = nextAllowedBitValue(cursor, upper, allowedMask);\n if (fromTarget === undefined) return undefined;\n if (fromTarget === null || fromBits === null) return null;\n if (fromTarget === fromBits) return fromTarget;\n cursor = fromTarget > fromBits ? fromTarget : fromBits;\n }\n return undefined;\n}\n\n/** Smallest value >= min, <= max whose one-bits are a subset of mask. */\nfunction nextAllowedBitValue(\n min: bigint,\n max: bigint,\n mask: bigint\n): bigint | null {\n if (min < 0n) min = 0n;\n if (min > max) return null;\n\n const visit = (\n bit: number,\n greater: boolean,\n value: bigint\n ): bigint | null => {\n if (bit < 0) return value <= max ? value : null;\n const minBit = Number((min >> BigInt(bit)) & 1n);\n for (let chosen = 0; chosen <= 1; chosen++) {\n if (chosen === 1 && (mask & (1n << BigInt(bit))) === 0n) continue;\n if (!greater && chosen < minBit) continue;\n const found = visit(\n bit - 1,\n greater || chosen > minBit,\n chosen === 1 ? value | (1n << BigInt(bit)) : value\n );\n if (found !== null) return found;\n }\n return null;\n };\n return visit(63, false, 0n);\n}\n\nfunction uintByteLength(value: bigint): number {\n let bytes = 0;\n for (let v = value; v > 0n; v >>= 8n) bytes++;\n return bytes;\n}\n\nfunction matchRange(\n item: CborItem,\n t1: CddlType1,\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): boolean {\n void depth;\n const op = t1.op as { kind: 'range'; inclusive: boolean };\n const lo = resolveValue(t1.target, env, ctx);\n const hi = resolveValue(t1.controller!, env, ctx);\n if (!lo || !hi) {\n ctx.warnOnce('range endpoints do not resolve to literal values', t1);\n return ctx.fail(path, item, t1, 'unresolvable range');\n }\n if (lo.type === 'int' && hi.type === 'int') {\n // Numeric comparison, including bignums (tags 2/3).\n const v = intValueOf(item);\n if (v === undefined)\n return ctx.fail(\n path,\n item,\n t1,\n `expected an integer in ${rangeText(t1)}`\n );\n const min = BigInt(lo.value);\n const max = BigInt(hi.value);\n if (v >= min && (op.inclusive ? v <= max : v < max)) return true;\n return ctx.fail(path, item, t1, `${v} is outside ${rangeText(t1)}`);\n }\n if (lo.type === 'float' && hi.type === 'float') {\n if (!(item instanceof CborFloat))\n return ctx.fail(path, item, t1, `expected a float in ${rangeText(t1)}`);\n const v = item.value;\n if (v >= lo.value && (op.inclusive ? v <= hi.value : v < hi.value))\n return true;\n return ctx.fail(path, item, t1, `${v} is outside ${rangeText(t1)}`);\n }\n ctx.warnOnce('range endpoints mix integer and float types', t1);\n return ctx.fail(path, item, t1, 'invalid range');\n}\n\nfunction rangeText(t1: CddlType1): string {\n const op = t1.op as { kind: 'range'; inclusive: boolean };\n return `${sourceText(t1.target)}${op.inclusive ? '..' : '...'}${sourceText(t1.controller!)}`;\n}\n\nfunction sourceText(t2: CddlType2): string {\n if (t2.kind === 'value') return t2.raw;\n if (t2.kind === 'ref') return t2.name;\n return '…';\n}\n\n// ─── Major types (#N[.ai]) ────────────────────────────────────────────────────\n\nconst FLOAT_AI: Record<string, bigint> = {\n half: 25n,\n single: 26n,\n double: 27n,\n};\n\nfunction matchMajor(\n item: CborItem,\n t2: Extract<CddlType2, { kind: 'major' }>,\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): boolean {\n const matchHead = (n: bigint): boolean => {\n if (t2.ai === undefined) return true;\n if (typeof t2.ai === 'bigint') return t2.ai === n;\n return matchType(new CborUint(n), t2.ai, env, path, ctx, depth + 1);\n };\n const failKind = (what: string): false =>\n ctx.fail(path, item, t2, `expected ${what} (#${t2.major})`);\n\n switch (t2.major) {\n case 0:\n if (!(item instanceof CborUint)) return failKind('an unsigned integer');\n break;\n case 1:\n if (!(item instanceof CborNint)) return failKind('a negative integer');\n break;\n case 2:\n if (byteValue(item) === undefined) return failKind('a byte string');\n break;\n case 3:\n if (textValue(item) === undefined) return failKind('a text string');\n break;\n case 4:\n if (!(item instanceof CborArray)) return failKind('an array');\n break;\n case 5:\n if (!(item instanceof CborMap)) return failKind('a map');\n break;\n case 6: {\n if (!(item instanceof CborTag)) return failKind('a tagged item');\n if (!matchHead(item.tag))\n return ctx.fail(\n path,\n item,\n t2,\n `tag ${item.tag} does not match ${sourceMajor(t2)}`\n );\n return true;\n }\n case 7: {\n if (item instanceof CborSimple) {\n if (matchHead(BigInt(item.value))) return true;\n return ctx.fail(\n path,\n item,\n t2,\n `simple(${item.value}) does not match ${sourceMajor(t2)}`\n );\n }\n if (item instanceof CborFloat) {\n if (t2.ai === undefined) return true;\n // When no width was recorded (e.g. CDN input without an encoding\n // suffix), use the smallest width that represents the value\n // losslessly — its preferred serialization.\n const precision =\n item.precision ?? autoSelectFloatPrecision(item.value);\n if (matchHead(FLOAT_AI[precision]!)) return true;\n return ctx.fail(\n path,\n item,\n t2,\n `float does not match ${sourceMajor(t2)}`\n );\n }\n return failKind('a simple value or float');\n }\n default:\n return ctx.fail(path, item, t2, `#${t2.major} is not a valid major type`);\n }\n // Majors 0–5: an additional-information constraint is about encoding,\n // which Phase 2 does not check.\n if (t2.ai !== undefined && t2.major <= 5)\n ctx.warnOnce(\n `the additional-information constraint ${sourceMajor(t2)} is not checked (encoding-level)`,\n t2\n );\n return true;\n}\n\nfunction sourceMajor(t2: Extract<CddlType2, { kind: 'major' }>): string {\n return t2.raw ?? `#${t2.major}`;\n}\n\n// ─── Group matching: shared expansion ─────────────────────────────────────────\n\ninterface Occ {\n min: number;\n max: number;\n}\n\n/**\n * One group choice with the environment its entries are evaluated in.\n * The env is per choice because `//=` extensions of a generic rule may\n * name their parameters differently per definition.\n */\ninterface GroupChoice {\n entries: readonly CddlGroupEntry[];\n env: Env;\n}\n\nconst plainChoices = (group: CddlGroup, env: Env): GroupChoice[] =>\n group.choices.map((entries) => ({ entries, env }));\n\ntype SeqMatcher =\n | {\n kind: 'type';\n occur: Occ;\n memberKey?: CddlMemberKey;\n type: CddlType;\n env: Env;\n node: CddlNodeBase;\n }\n | {\n kind: 'group';\n occur: Occ;\n choices: readonly GroupChoice[];\n node: CddlNodeBase;\n };\n\nconst ONE: Occ = { min: 1, max: 1 };\n\nfunction occOf(entry: CddlGroupEntry): Occ {\n const o = entry.occur;\n if (!o) return ONE;\n if (o.marker === '?') return { min: 0, max: 1 };\n if (o.marker === '+') return { min: 1, max: Infinity };\n return { min: o.min ?? 0, max: o.max ?? Infinity };\n}\n\n/** Resolve a bare reference to a group-like rule (for splicing). */\nfunction resolveGroupRef(\n ref: CddlRef,\n env: Env,\n ctx: Ctx\n): GroupChoice[] | undefined {\n const defs = ruleDefs(ctx, ref.name);\n if (!defs) return undefined;\n if (!isGroupLike(defs)) return undefined;\n const choices: GroupChoice[] = [];\n for (const def of defs) {\n const defEnv = bindGenericsForDef(def, ref.genericArgs, env);\n for (const entries of choicesOfBody(def.body))\n choices.push({ entries, env: defEnv });\n }\n return choices;\n}\n\n/**\n * When an entry is a bare single reference, return the group it stands for\n * (group rule or unwrap) — the caller splices it into the sequence.\n */\nfunction asBareGroupRef(\n entry: CddlGroupEntry,\n env: Env,\n ctx: Ctx\n): GroupChoice[] | undefined {\n if (entry.kind !== 'entry' || entry.memberKey) return undefined;\n if (entry.value.alternatives.length !== 1) return undefined;\n const t1 = entry.value.alternatives[0]!;\n if (t1.op) return undefined;\n const target = t1.target;\n if (target.kind === 'ref') {\n if (env?.has(target.name) && !target.genericArgs) return undefined;\n const resolved = resolveGroupRef(target, env, ctx);\n if (resolved) return resolved;\n // An unplugged group socket is a choice with zero alternatives: it\n // matches nothing (which is why sockets are used as `* $$name`).\n if (target.name.startsWith('$$') && !ruleDefs(ctx, target.name)) return [];\n return undefined;\n }\n if (target.kind === 'unwrap')\n return resolveUnwrapGroup(target.ref, env, ctx, 0);\n return undefined;\n}\n\n/** ~ref: follow references to a map/array type and return its group. */\nfunction resolveUnwrapGroup(\n ref: CddlRef,\n env: Env,\n ctx: Ctx,\n depth: number\n): GroupChoice[] | undefined {\n if (depth > 32) return undefined;\n const defs = ruleDefs(ctx, ref.name);\n if (!defs || defs.length !== 1) return undefined;\n const body = defs[0]!.body;\n const newEnv = bindGenericsForDef(defs[0]!, ref.genericArgs, env);\n if (!isPlainTypeEntry(body)) {\n // Unwrapping a group rule: the group itself.\n return choicesOfBody(body).map((entries) => ({ entries, env: newEnv }));\n }\n if (body.value.alternatives.length !== 1) return undefined;\n const t1 = body.value.alternatives[0]!;\n if (t1.op) return undefined;\n if (t1.target.kind === 'map' || t1.target.kind === 'array')\n return plainChoices(t1.target.group, newEnv);\n if (t1.target.kind === 'ref')\n return resolveUnwrapGroup(t1.target, newEnv, ctx, depth + 1);\n return undefined;\n}\n\n/**\n * ~ref where the target is a tag rule: unwrapping removes the tag, exposing\n * the content type (RFC 8610 §3.7, e.g. `my-uri = ~uri` is a tstr).\n */\nfunction resolveUnwrapTagType(\n ref: CddlRef,\n env: Env,\n ctx: Ctx,\n depth: number\n): { type: CddlType; env: Env } | undefined {\n if (depth > 32) return undefined;\n const defs = ruleDefs(ctx, ref.name);\n if (!defs || defs.length !== 1) return undefined;\n const body = defs[0]!.body;\n if (!isPlainTypeEntry(body) || body.value.alternatives.length !== 1)\n return undefined;\n const t1 = body.value.alternatives[0]!;\n if (t1.op) return undefined;\n const newEnv = bindGenericsForDef(defs[0]!, ref.genericArgs, env);\n if (t1.target.kind === 'tagged') return { type: t1.target.item, env: newEnv };\n if (t1.target.kind === 'ref')\n return resolveUnwrapTagType(t1.target, newEnv, ctx, depth + 1);\n return undefined;\n}\n\nfunction expandEntry(entry: CddlGroupEntry, env: Env, ctx: Ctx): SeqMatcher {\n const occur = occOf(entry);\n if (entry.kind === 'entry-group')\n return {\n kind: 'group',\n occur,\n choices: plainChoices(entry.group, env),\n node: entry,\n };\n const groupRef = asBareGroupRef(entry, env, ctx);\n if (groupRef)\n return {\n kind: 'group',\n occur,\n choices: groupRef,\n node: entry,\n };\n return {\n kind: 'type',\n occur,\n ...(entry.memberKey ? { memberKey: entry.memberKey } : {}),\n type: entry.value,\n env,\n node: entry,\n };\n}\n\n// ─── Group matching: arrays (sequences) ───────────────────────────────────────\n\nfunction matchArrayGroup(\n arr: CborArray,\n group: CddlGroup,\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): boolean {\n ctx.checkDepth(depth);\n const ends = seqEnds(\n arr.items,\n 0,\n plainChoices(group, env),\n path,\n ctx,\n depth\n );\n const records = ends.get(arr.items.length);\n if (records) {\n ctx.trail?.push(...records);\n return true;\n }\n return ctx.fail(\n path,\n arr,\n group,\n `array of ${arr.items.length} item(s) does not match the group`\n );\n}\n\n/**\n * All end positions reachable by matching the group's choices at `idx`,\n * each with the tag records (see `Ctx.trail`) of the first path found to\n * reach it. Exploration leaves `ctx.trail` itself unchanged.\n */\nfunction seqEnds(\n items: readonly CborItem[],\n idx: number,\n choices: readonly GroupChoice[],\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): Map<number, TagRecord[]> {\n const out = new Map<number, TagRecord[]>();\n const base = ctx.trail?.length ?? 0;\n for (const choice of choices) {\n const matchers = choice.entries.map((e) => expandEntry(e, choice.env, ctx));\n seqStep(items, idx, matchers, 0, path, ctx, depth, out, base);\n }\n return out;\n}\n\nfunction seqStep(\n items: readonly CborItem[],\n idx: number,\n ms: readonly SeqMatcher[],\n k: number,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number,\n out: Map<number, TagRecord[]>,\n base: number\n): void {\n if (k === ms.length) {\n if (!out.has(idx)) out.set(idx, ctx.trail?.slice(base) ?? []);\n return;\n }\n const m = ms[k]!;\n\n const tryCount = (count: number, at: number): void => {\n ctx.step();\n if (count >= m.occur.min)\n seqStep(items, at, ms, k + 1, path, ctx, depth, out, base);\n if (count >= m.occur.max || at >= items.length) return;\n for (const [end, records] of matchOnceEnds(\n items,\n at,\n m,\n path,\n ctx,\n depth\n )) {\n // An empty match makes no progress; recursing on it would loop.\n if (end === at) continue;\n const mark = ctx.trail?.length ?? 0;\n ctx.trail?.push(...records);\n tryCount(count + 1, end);\n if (ctx.trail) ctx.trail.length = mark;\n }\n };\n tryCount(0, idx);\n}\n\n/**\n * End positions from matching a single occurrence of `m` at `at`, each\n * with the tag records of that match (not left on `ctx.trail`).\n */\nfunction matchOnceEnds(\n items: readonly CborItem[],\n at: number,\n m: SeqMatcher,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): [number, TagRecord[]][] {\n if (m.kind === 'type') {\n const mark = ctx.trail?.length ?? 0;\n // Member keys inside arrays are documentation only (RFC 8610 §3.4).\n if (!matchType(items[at]!, m.type, m.env, [...path, at], ctx, depth))\n return [];\n return [[at + 1, ctx.trail?.splice(mark) ?? []]];\n }\n ctx.checkDepth(depth);\n const ends = seqEnds(items, at, m.choices, path, ctx, depth + 1);\n // Descending order: prefer greedy consumption first.\n return [...ends].sort((a, b) => b[0] - a[0]);\n}\n\n// ─── Group matching: maps ─────────────────────────────────────────────────────\n\nfunction matchMapGroup(\n map: CborMap,\n group: CddlGroup,\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number,\n onMatch?: (consumed: readonly (MapMember | false)[]) => void\n): boolean {\n ctx.checkDepth(depth);\n const consumed = new Array<MapMember | false>(map.entries.length).fill(false);\n const choices = plainChoices(group, env);\n const run = (): boolean => {\n for (const choice of choices) {\n consumed.fill(false);\n if (\n mapSeq(\n map,\n choice.entries,\n 0,\n consumed,\n choice.env,\n path,\n ctx,\n depth,\n () => {\n if (!mapFullyConsumed(map, consumed, path, ctx, group))\n return false;\n onMatch?.(consumed);\n return true;\n }\n )\n )\n return true;\n }\n return false;\n };\n return choices.length > 1 ? ctx.strictFirst(run) : run();\n}\n\nfunction mapFullyConsumed(\n map: CborMap,\n consumed: (MapMember | false)[],\n path: readonly PathSeg[],\n ctx: Ctx,\n node: CddlNodeBase\n): boolean {\n for (let i = 0; i < consumed.length; i++) {\n if (consumed[i]) continue;\n const [k, v] = map.entries[i]!;\n // Leftover elided entries are what \"...\" stands for — ignore them.\n if (k instanceof CborEllipsis) continue;\n ctx.fail(\n [...path, keySeg(k, i)],\n v,\n node,\n `entry ${describeItem(k)} is not allowed by the group`\n );\n return false;\n }\n return true;\n}\n\n/**\n * Match the entries of one group choice against the map, in continuation\n * style so that sub-group choices and occurrence counts can backtrack when\n * downstream matchers (or the final completeness check) fail.\n *\n * Entry-to-member assignment itself is greedy in definition order and is\n * not backtracked (a deliberate heuristic — put wildcard members last).\n */\nfunction mapSeq(\n map: CborMap,\n entries: readonly CddlGroupEntry[],\n k: number,\n consumed: (MapMember | false)[],\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number,\n cont: () => boolean\n): boolean {\n const mark = ctx.trail?.length ?? 0;\n if (mapSeqInner(map, entries, k, consumed, env, path, ctx, depth, cont))\n return true;\n if (ctx.trail) ctx.trail.length = mark;\n return false;\n}\n\nfunction mapSeqInner(\n map: CborMap,\n entries: readonly CddlGroupEntry[],\n k: number,\n consumed: (MapMember | false)[],\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number,\n cont: () => boolean\n): boolean {\n if (k === entries.length) return cont();\n const m = expandEntry(entries[k]!, env, ctx);\n\n if (m.kind === 'type') {\n if (!m.memberKey) {\n // A bare type as a map entry can only be `any` standing for a whole\n // entry — not expressible; report instead of silently ignoring.\n return ctx.fail(\n path,\n map,\n m.node,\n 'group entry without a member key cannot match a map entry'\n );\n }\n let count = 0;\n for (let i = 0; i < map.entries.length && count < m.occur.max; i++) {\n if (consumed[i]) continue;\n const [key, value] = map.entries[i]!;\n if (!keyMatches(m.memberKey, key, m.env, path, ctx, depth)) continue;\n const valuePath = [...path, keySeg(key, i)];\n if (matchType(value, m.type, m.env, valuePath, ctx, depth + 1)) {\n consumed[i] = { memberKey: m.memberKey, type: m.type, env: m.env };\n count++;\n continue;\n }\n if (m.memberKey.cut) {\n // Cut: the key committed this entry to this member; a value\n // mismatch fails the whole map (§3.5.4).\n return ctx.fail(\n valuePath,\n value,\n m.node,\n `value for ${describeKey(m.memberKey)} does not match`\n );\n }\n }\n if (count < m.occur.min)\n return ctx.fail(\n path,\n map,\n m.node,\n `missing required entry ${describeKey(m.memberKey)}`\n );\n return mapSeq(map, entries, k + 1, consumed, env, path, ctx, depth, cont);\n }\n\n // Sub-group with an occurrence: backtrack over stop-vs-repeat and over\n // the sub-group's choices.\n ctx.checkDepth(depth);\n const consumedCount = (): number => {\n let n = 0;\n for (const c of consumed) if (c) n++;\n return n;\n };\n const tryIter = (iter: number): boolean => {\n ctx.step();\n if (\n iter >= m.occur.min &&\n mapSeq(map, entries, k + 1, consumed, env, path, ctx, depth, cont)\n )\n return true;\n if (iter >= m.occur.max) return false;\n const snapshot = consumed.slice();\n const before = consumedCount();\n for (const sub of m.choices) {\n if (\n mapSeq(\n map,\n sub.entries,\n 0,\n consumed,\n sub.env,\n path,\n ctx,\n depth + 1,\n () => {\n if (consumedCount() === before)\n // An empty iteration makes no progress; repeating it cannot\n // help, so treat the occurrence as satisfied and move on.\n return mapSeq(\n map,\n entries,\n k + 1,\n consumed,\n env,\n path,\n ctx,\n depth,\n cont\n );\n return tryIter(iter + 1);\n }\n )\n )\n return true;\n for (let i = 0; i < consumed.length; i++) consumed[i] = snapshot[i]!;\n }\n return false;\n };\n return tryIter(0);\n}\n\nfunction keyMatches(\n mk: CddlMemberKey,\n key: CborItem,\n env: Env,\n path: readonly PathSeg[],\n ctx: Ctx,\n depth: number\n): boolean {\n key = unwrapAppSeq(key);\n if (key instanceof CborEllipsis) return true;\n switch (mk.kind) {\n case 'bareword':\n return textValue(key) === mk.key;\n case 'value':\n return matchesLiteral(key, mk.key);\n case 'type1':\n return matchType1(key, mk.key, env, path, ctx, depth + 1);\n }\n}\n\nfunction describeKey(mk: CddlMemberKey): string {\n switch (mk.kind) {\n case 'bareword':\n return `'${mk.key}'`;\n case 'value':\n return mk.key.raw;\n case 'type1':\n return sourceText(mk.key.target);\n }\n}\n\nfunction keySeg(key: CborItem, index: number): PathSeg {\n const text = textValue(key);\n if (text !== undefined) return text;\n if (key instanceof CborUint || key instanceof CborNint) {\n const v = key.value;\n if (\n v >= BigInt(Number.MIN_SAFE_INTEGER) &&\n v <= BigInt(Number.MAX_SAFE_INTEGER)\n )\n return Number(v);\n }\n return index;\n}\n\nfunction describeItem(item: CborItem): string {\n const text = textValue(item);\n if (text !== undefined) return JSON.stringify(text);\n if (item instanceof CborUint || item instanceof CborNint)\n return item.value.toString();\n return item.constructor.name.replace(/^Cbor/, '').toLowerCase();\n}\n\n// ─── Control operator plumbing ────────────────────────────────────────────────\n\nfunction makeControlDeps(env: Env, ctx: Ctx, depth: number): ControlDeps {\n return {\n matchType2: (item, t2, path) =>\n matchType2(item, t2, env, path, ctx, depth + 1),\n matchEmbedded: (item, t2, path) => {\n ctx.embeddedDepth++;\n try {\n return matchType2(item, t2, env, path, ctx, depth + 1);\n } finally {\n ctx.embeddedDepth--;\n }\n },\n resolveValue: (t2) => resolveValue(t2, env, ctx),\n existsIntGE: (t2, min) => existsIntGE(t2, min, env, ctx),\n matchesLiteral,\n fail: (path, item, node, message) => ctx.fail(path, item, node, message),\n warnOnce: (message, node) => ctx.warnOnce(message, node),\n features: ctx.features,\n uint: (n) => new CborUint(n),\n };\n}\n","/**\n * Position-aware `e'...'` name resolution (draft-ietf-cbor-edn-e-ref), used\n * by both `fromJS()`'s `eRefKeys` direction and `annotateERefKeys()`'s own\n * post-validation labeling — see `js/fromJS.ts` and `extensions/eref.ts`\n * for how each one drives this module.\n *\n * `getERefTables()` (`eref.ts`) builds one flat, whole-schema name table —\n * correct for `e'name'`'s own CDN *parse* direction (`byName`), since a\n * genuinely ambiguous or unreachable name simply fails to parse there. It\n * is **not** enough on its own for either the JS→CBOR (`fromJS()`) or the\n * annotation (`annotateERefKeys()`) direction: `fromJS()` *constructs* the\n * CBOR key from a JS property name before any validation happens, and\n * `annotateERefKeys()`'s own labeling must stay reversible through\n * `fromJS()` for a `toJS()` → `fromJS()` round trip to reproduce the exact\n * same wire bytes — so both directions need a name bound *anywhere* in the\n * schema, even in a rule the value has no structural relationship to,\n * *not* to convert/relabel, or the result silently diverges from the\n * original (a text key rewritten as an unrelated integer key, or vice\n * versa) rather than merely carrying a wrong display label.\n *\n * This module instead tracks which CDDL type actually governs the current\n * position in the value tree being walked — starting from the schema's own\n * root rule (or an explicit `ValidateOptions.rule`) and descending through\n * map types the same way the caller itself descends through nested plain\n * objects/maps — so a name is only ever eRefKeys-eligible at a position the\n * schema's own structure actually reaches. A position whose own type is a\n * `/`/`//` choice between *differently-shaped* alternatives (e.g. a\n * discriminated union) keeps every alternative **separate** rather than\n * merging their entries into one list — a name used as a plain text key in\n * one alternative and as an `&(name: value)` binding in another must not be\n * converted, since which alternative the data actually matches isn't known\n * without validating it (something this module deliberately doesn't\n * attempt — see `scopeNameToValue()`'s own doc for exactly how this is\n * decided).\n *\n * *Within* one alternative, though, an open/wildcard member key (e.g. a\n * `* tstr => any` catch-all, RFC 9290's own idiom for \"any other field\") no\n * longer blocks every name in that same alternative — only a member key at\n * or after it in the alternative's own declared order. `cddl/validator.ts`\n * assigns each wire key to a group entry greedily, in declaration order —\n * an entry earlier in the source always gets first claim on any key it can\n * match, before a later, more permissive one (the wildcard) ever sees it —\n * so a name declared *before* the wildcard is exactly as safe as if the\n * wildcard weren't there at all, while one declared *after* it isn't (the\n * wildcard could have already claimed that wire key first) — see\n * `firstOpenIndex()`'s own doc for the full reasoning. Declaration order\n * alone isn't the whole rule, though: the validator only lets an entry\n * claim a key whose *value* also matches that entry's type, passing it on\n * otherwise. Annotation, which has the decoded data, applies exactly that\n * via the validator's own traced assignment (`traceMapGroup()`, used by\n * `extensions/eref.ts`); the schema-only functions here remain for\n * `fromJS()`, which has no such data before it converts.\n *\n * That declaration-order relaxation is sound only for resolving an\n * *already-typed* wire value — annotating an existing integer key/value\n * with its name (`annotateERefKeys()`), since a text-matching wildcard like\n * `* tstr => any` structurally can't have consumed an *integer* wire key\n * first regardless of where it's declared. It is **not** sound for\n * `fromJS()`'s own forward direction: converting a JS property name —\n * always a string — into an integer key. There, if the wildcard's own key\n * type also matches text, that exact string is just as validly a literal\n * text key claimed by the wildcard as it is the named entry's integer\n * value; declaration order doesn't resolve this, because `fromJS()` is\n * *choosing* which shape the JS property becomes, not discovering it from\n * a value whose wire type is already fixed. Every function below that\n * depends on this distinction therefore takes an optional\n * `respectDeclarationOrder` parameter (default `true`, the relaxed\n * behavior above); `fromJS()` passes `false` for its own string-key\n * conversion and any nested-scope descent driven by it, falling back to\n * the older, blanket \"any open entry anywhere in this alternative blocks\n * every name in it\" behavior instead.\n *\n * Scope: deliberately conservative, not a full CDDL type resolver. It\n * understands map types (`{...}`), parenthesized types, and references to\n * other rules (including their `/=`/`//=` extensions) — enough for\n * realistic schemas built from named map rules. It also descends through\n * *fixed-shape* array types (`[a, b, c]`, including spliced-in group\n * references like `[Headers, payload]`) positionally, element by element —\n * but only when no array entry carries an occurrence indicator, since\n * `?`/`*`/`+` would make \"which entry does element *i* belong to\" depend on\n * matching the data (see `ERefArrayScope`'s own doc). It does **not**\n * attempt: generic type arguments (`rule<T>`/`rule<int>`), `~unwrap`, or\n * tagged types. Whenever a type can't be resolved this way, the affected position\n * (and everything nested inside it) simply has no eRefKeys-eligible names\n * at all — never a *wrong* guess, only a missed one; a name that isn't\n * converted here still becomes an ordinary text-string key, exactly like\n * any other property name the schema never named at all.\n */\n\nimport type { CddlSchema } from './schema';\nimport type {\n CddlGroup,\n CddlGroupEntry,\n CddlMemberKey,\n CddlRule,\n CddlType,\n CddlType1,\n CddlType2,\n} from './ast';\nimport type { CborItem } from '../ast/CborItem';\nimport { getERefTables, literalIntOfType } from './eref';\nimport { getPreludeRules } from './prelude';\nimport {\n itemMatchesType,\n plainTextSpelling,\n type ValidateOptions,\n} from './validator';\n\n/**\n * The CDDL type governing one position in a JS value tree — opaque outside\n * this module; obtain one via `resolveRootScope()`, then `resolveNestedScope()`\n * for each property that itself holds a nested object.\n */\nexport interface ERefScope {\n /**\n * Every distinct alternative shape this position's type could resolve\n * to — one array per `/`/`//` choice alternative (including every\n * `/=`/`//=` extension of the rule), each holding *that* alternative's\n * own complete group entries. Kept separate, not merged into one flat\n * list, so `scopeNameToValue()` can tell \"this name means the same thing\n * in every alternative that mentions it, and isn't plain text in any of\n * them\" (safe) apart from \"different alternatives disagree about it\"\n * (unsafe) — see the module doc.\n */\n readonly alternatives: readonly (readonly CddlGroupEntry[])[];\n}\n\n/**\n * The scope for the schema's own root rule (or `ruleName`, matching\n * `ValidateOptions.rule` — `fromJS()`'s own eRefKeys resolution should\n * start from the same rule the caller will actually validate against).\n * `undefined` when the named rule doesn't exist, isn't a map type, or\n * can't be resolved this way at all — see the module doc's Scope note.\n */\nexport function resolveRootScope(\n schema: CddlSchema,\n ruleName?: string\n): ERefScope | undefined {\n const name = ruleName ?? schema.root?.name;\n if (!name) return undefined;\n const resolved = resolveRuleMapEntries(schema, name, new Set());\n return resolved.kind === 'resolved'\n ? { alternatives: resolved.alternatives }\n : undefined;\n}\n\n/**\n * The CDDL type governing an *array* position — the counterpart of\n * `ERefScope` for a value that is a `CborArray`/JS array rather than a\n * map/object. One positional element-type list per array alternative this\n * position's type could resolve to (kept separate, the same way\n * `ERefScope.alternatives` is). Only produced for arrays whose every entry\n * is exactly one element (no `?`/`*`/`+`), so element *i* of an array of\n * length *n* is governed by entry *i* of every alternative of length *n* —\n * no matching against the data required. An alternative of a different\n * length simply can't be the one the data matched, so it's skipped\n * (`resolveElementPosition()`).\n */\nexport interface ERefArrayScope {\n readonly elementTypes: readonly (readonly CddlType[])[];\n}\n\n/**\n * Everything known about one position in the value tree: its scope if the\n * value there is a map (`map`), and its positional element types if it's an\n * array (`array`). Both may be set when the governing type is a `/` choice\n * between a map and an array; the walker uses whichever matches the value\n * actually found there.\n */\nexport interface ERefPosition {\n readonly map?: ERefScope;\n readonly array?: ERefArrayScope;\n}\n\n/** A position nothing is known about — no names apply anywhere below it. */\nexport const NO_POSITION: ERefPosition = {};\n\n/**\n * `resolveRootScope()`'s own counterpart covering an array root too —\n * e.g. `COSE_Sign1 = [protected: …, unprotected: header_map, …]`.\n */\nexport function resolveRootPosition(\n schema: CddlSchema,\n ruleName?: string\n): ERefPosition {\n const name = ruleName ?? schema.root?.name;\n if (!name) return NO_POSITION;\n const array = resolveRuleArrayTypes(schema, name, new Set());\n return {\n map: resolveRootScope(schema, ruleName),\n array:\n array.kind === 'resolved'\n ? { elementTypes: array.alternatives }\n : undefined,\n };\n}\n\n/**\n * `resolveNestedScope()`'s own counterpart covering an array value too —\n * the position of `identifier`'s own value within map scope `scope`.\n */\nexport function resolveNestedPosition(\n schema: CddlSchema,\n scope: ERefScope,\n identifier: string | bigint,\n respectDeclarationOrder = true\n): ERefPosition {\n const merged = matchingValueType(\n schema,\n scope,\n identifier,\n respectDeclarationOrder\n );\n return merged ? positionOfType(schema, merged) : NO_POSITION;\n}\n\n/**\n * The position of element `index` within an array of `length` elements\n * governed by `arrayScope` — the union of entry `index`'s own type across\n * every alternative of exactly that length (see `ERefArrayScope`'s own\n * doc). `NO_POSITION` when no alternative has that length.\n */\nexport function resolveElementPosition(\n schema: CddlSchema,\n arrayScope: ERefArrayScope,\n index: number,\n length: number\n): ERefPosition {\n const types = arrayScope.elementTypes\n .filter((alt) => alt.length === length)\n .map((alt) => alt[index]!);\n if (types.length === 0) return NO_POSITION;\n return positionOfType(schema, mergeTypes(types));\n}\n\n/**\n * The e-ref name a member key gives the integer key `keyValue` it\n * consumed — the member's own `&(name: value)` binding for that value (from\n * a fully literal enum group, the only kind that pins the key down to one\n * named value), or a bare reference to a constant rule with that value.\n * `undefined` for any other member key (a bareword/literal key, a wildcard,\n * a controlled or non-literal key), or when the reference is a generic\n * parameter (`paramBound`), which names no rule at all.\n */\nexport function memberKeyName(\n schema: CddlSchema,\n mk: CddlMemberKey,\n keyValue: bigint,\n paramBound: (name: string) => boolean\n): string | undefined {\n if (mk.kind !== 'type1' || mk.key.op) return undefined;\n const t2 = mk.key.target;\n if (t2.kind === 'enum' && t2.group.kind === 'group') {\n if (!enumGroupIsFullyLiteral(t2.group)) return undefined;\n const names = new Set(\n literalEnumBindings(t2.group)\n .filter(([, v]) => v === keyValue)\n .map(([n]) => n)\n );\n return names.size === 1 ? [...names][0] : undefined;\n }\n if (t2.kind === 'ref' && !t2.genericArgs?.length && !paramBound(t2.name))\n return getERefTables(schema).ruleConstantValues.get(t2.name) === keyValue\n ? t2.name\n : undefined;\n return undefined;\n}\n\n/** A type that is just a reference to rule `name` (the validation root). */\nexport function ruleRefType(name: string): CddlType {\n return {\n kind: 'type',\n start: 0,\n end: 0,\n alternatives: [\n {\n kind: 'type1',\n start: 0,\n end: 0,\n target: { kind: 'ref', name, start: 0, end: 0 },\n },\n ],\n };\n}\n\n/**\n * `type`'s own fixed-shape array alternatives (see `ERefArrayScope`), or\n * `undefined` when it may be an array of some other shape.\n */\nexport function arrayScopeOfType(\n schema: CddlSchema,\n type: CddlType\n): ERefArrayScope | undefined {\n const resolved = resolveArrayTypes(schema, type, new Set());\n return resolved.kind === 'resolved'\n ? { elementTypes: resolved.alternatives }\n : undefined;\n}\n\n/**\n * The array alternatives in `arrayScope` a decoded array's `items`\n * actually satisfy — same length, and every element matching its own\n * entry's type. An element whose check runs out of budget keeps its\n * alternative (including an extra alternative only ever makes annotation\n * more conservative, never wrong).\n */\nexport function matchingArrayAlternatives(\n schema: CddlSchema,\n arrayScope: ERefArrayScope,\n items: readonly CborItem[],\n options?: ValidateOptions\n): ERefArrayScope {\n return {\n elementTypes: arrayScope.elementTypes.filter(\n (alt) =>\n alt.length === items.length &&\n alt.every(\n (type, i) =>\n itemMatchesType(schema, items[i]!, type, options) !== false\n )\n ),\n };\n}\n\n/** The position governed by `type` — a map scope, array scope, or both. */\nfunction positionOfType(schema: CddlSchema, type: CddlType): ERefPosition {\n const map = resolveMapEntries(schema, type, new Set());\n const array = resolveArrayTypes(schema, type, new Set());\n return {\n map:\n map.kind === 'resolved' ? { alternatives: map.alternatives } : undefined,\n array:\n array.kind === 'resolved'\n ? { elementTypes: array.alternatives }\n : undefined,\n };\n}\n\n/**\n * `type`'s own `/` alternatives with parentheses and (non-generic) type-rule\n * references expanded in place — including every `/=` extension of a\n * referenced rule — so each result is a `type1` that is neither of those.\n * A controlled alternative (`bstr .cbor T`) is kept whole, never looked\n * into. `undefined` when some alternative can't be expanded this way (a\n * generic reference, a rule defined nowhere, or a group rule referenced as\n * a type). A reference cycle contributes no alternatives of its own.\n */\nexport function typeAlternatives(\n schema: CddlSchema,\n type: CddlType,\n seen: ReadonlySet<string> = new Set()\n): CddlType1[] | undefined {\n const result: CddlType1[] = [];\n for (const t1 of type.alternatives) {\n const t2 = t1.target;\n if (t1.op || (t2.kind !== 'paren' && t2.kind !== 'ref')) {\n result.push(t1);\n continue;\n }\n if (t2.kind === 'paren') {\n const inner = typeAlternatives(schema, t2.type, seen);\n if (!inner) return undefined;\n result.push(...inner);\n continue;\n }\n if (t2.genericArgs?.length) return undefined;\n if (seen.has(t2.name)) continue;\n const defs = ruleDefinitions(schema, t2.name);\n if (!defs) return undefined;\n const nextSeen = new Set(seen);\n nextSeen.add(t2.name);\n for (const def of defs) {\n if (!isTypeRule(def) || def.body.kind !== 'entry') return undefined;\n const inner = typeAlternatives(schema, def.body.value, nextSeen);\n if (!inner) return undefined;\n result.push(...inner);\n }\n }\n return result;\n}\n\n/** One `CddlType` whose alternatives are all of `types`' own, combined. */\nexport function mergeTypes(types: readonly CddlType[]): CddlType {\n return {\n kind: 'type',\n start: types[0]!.start,\n end: types[types.length - 1]!.end,\n alternatives: types.flatMap((t) => t.alternatives),\n };\n}\n\n/**\n * Name → value, from every `&(name: value)`/bare-constant-reference entry\n * directly at a member-key position among `scope`'s own alternatives (not\n * entries nested inside a further nested map) — the names `fromJS()` may\n * convert *this* object's own direct property names against.\n *\n * A name is included only when it's *consistently* eRefKeys-eligible\n * across every one of `scope`'s own alternatives: excluded entirely if\n * *any* alternative uses it as a plain bareword/quoted-text member key\n * (that alternative wants a literal text key there, and which alternative\n * the JS value being converted actually corresponds to isn't known without\n * validating it — something this module doesn't attempt), and excluded if\n * the alternatives that *do* bind it via `&(name: value)`/a bare\n * constant-rule reference disagree on the value. An alternative that\n * doesn't mention the name at all is simply silent on it, not a conflict.\n *\n * A `&(name: value)` binding's own value is computed fresh per scope —\n * unlike a bare reference to a constant rule (`? group_mode => bool`),\n * whose value comes from the rule's own, genuinely schema-wide definition,\n * so it's looked up via `getERefTables(schema).ruleConstantValues` — never\n * plain `byName`, which also mixes in any `&(name: value)` enum *label*\n * bound to `name` elsewhere in the schema (irrelevant here: a bare type\n * reference names a *rule*, not \"this spelling however it's used\n * anywhere\" — see `ruleConstantValues`'s own doc).\n *\n * This *value* is safe to use positionally as-is — it's exactly the\n * integer this position's own schema names, independent of anything\n * elsewhere in the document. Whether the resulting key should also be\n * *labeled* `e'name'` is a separate question `resolvesGloballyTo()`\n * answers — see its own doc for why.\n *\n * `respectDeclarationOrder` (default `true`) controls whether a name\n * declared before a same-alternative wildcard is included per that\n * relaxation — see the module doc's own note on why `fromJS()` must pass\n * `false` here instead, falling back to the plain \"any open entry anywhere\n * in this alternative excludes every name in it\" behavior.\n */\nexport function scopeNameToValue(\n schema: CddlSchema,\n scope: ERefScope,\n respectDeclarationOrder = true\n): ReadonlyMap<string, bigint> {\n const ruleConstantValues = getERefTables(schema).ruleConstantValues;\n const values = new Map<string, Set<bigint>>();\n const plainTextNames = new Set<string>();\n const addValue = (name: string, value: bigint): void => {\n let vals = values.get(name);\n if (!vals) {\n vals = new Set();\n values.set(name, vals);\n }\n vals.add(value);\n };\n\n // Each *open* alternative's own bindings declared before its wildcard. The\n // data might match any alternative; an open one only resolves a wire key\n // to `name` if it binds `name` itself ahead of its own wildcard (which\n // would otherwise claim that key first, meaning something else) — so a\n // name must appear in every open alternative's list to be safe. A closed\n // alternative that doesn't mention the name can't hold that key at all,\n // so it stays silent, as before.\n const openAltBindings: Map<string, Set<bigint>>[] = [];\n const openness = alternativeOpenness(schema, scope);\n for (let altIndex = 0; altIndex < scope.alternatives.length; altIndex++) {\n const alt = scope.alternatives[altIndex]!;\n const openIndex = respectDeclarationOrder\n ? firstOpenIndex(schema, alt)\n : openness[altIndex]\n ? 0\n : alt.length;\n const bindings = new Map<string, Set<bigint>>();\n if (openIndex < alt.length) openAltBindings.push(bindings);\n const bind = (name: string, value: bigint): void => {\n addValue(name, value);\n let vals = bindings.get(name);\n if (!vals) bindings.set(name, (vals = new Set()));\n vals.add(value);\n };\n for (let i = 0; i < alt.length; i++) {\n const entry = alt[i]!;\n if (entry.kind !== 'entry' || !entry.memberKey) continue;\n const mk = entry.memberKey;\n const plain = plainTextSpelling(mk);\n if (plain !== undefined) plainTextNames.add(plain);\n if (mk.kind !== 'type1') continue;\n // kind === 'type1'. An entry at or after the first open/wildcard\n // entry in its own alternative might never actually be reached by a\n // given wire key — see firstOpenIndex()'s own doc — so, unlike an\n // entry before it (guaranteed closed: not `op`-qualified, and either\n // a fully-literal enum group or a resolvable constant-rule\n // reference), it's skipped here entirely, the same way an open entry\n // itself already is.\n if (i >= openIndex) continue;\n const t2 = mk.key.target;\n if (t2.kind === 'enum' && t2.group.kind === 'group') {\n for (const [name, value] of literalEnumBindings(t2.group))\n bind(name, value);\n } else if (t2.kind === 'ref' && !t2.genericArgs?.length) {\n const value = ruleConstantValues.get(t2.name);\n if (value !== undefined) bind(t2.name, value);\n }\n }\n }\n\n const result = new Map<string, bigint>();\n for (const [name, vals] of values) {\n if (vals.size !== 1) continue; // conflicting values across alternatives\n if (plainTextNames.has(name)) continue; // plain text in some alternative\n const value = vals.values().next().value!;\n if (!openAltBindings.every((b) => b.get(name)?.has(value))) continue;\n result.set(name, value);\n }\n return result;\n}\n\n/**\n * Whether each of `scope`'s own alternatives, in order, has an open member\n * key *anywhere* in it (`firstOpenIndex()` returns less than its own\n * length) — regardless of *where* in that alternative's own declared order\n * it falls. Used to tell whether some *other* alternative could match the\n * data instead of the one a name/entry was actually found in — see\n * `scopeNameToValue()`/`matchingValueType()`'s own use of this for why that\n * matters even when the open entry is nowhere near the name in question.\n */\nfunction alternativeOpenness(\n schema: CddlSchema,\n scope: ERefScope\n): readonly boolean[] {\n return scope.alternatives.map(\n (alt) => firstOpenIndex(schema, alt) < alt.length\n );\n}\n\n/**\n * The index of the first member key within `alt` (one alternative's own,\n * already-flattened entry list) whose own shape isn't fully pinned down to\n * either a literal text/bareword key or a specific `&(name:\n * value)`/constant-rule binding — e.g. a wildcard `* tstr => any` catch-all,\n * or a key qualified by a range/control operator — or `alt.length` when\n * every entry is fully pinned down (no such entry at all).\n *\n * CDDL map-group matching in this library (`cddl/validator.ts`'s own\n * `mapSeq`) assigns each wire key to a group entry *greedily, in\n * declaration order*: an entry earlier in `alt` always gets first claim on\n * any wire key it can match, before a later, more permissive entry (a\n * wildcard, say) ever gets a chance at it — this is a documented, deliberate\n * heuristic (`mapSeq`'s own doc: \"put wildcard members last\"), not\n * backtracked. So an entry *before* this index is safe to resolve exactly\n * as written: no wire key it could match was ever at risk of being consumed\n * by something less specific first. An entry *at or after* this index,\n * though, might never actually be reached — the wire key it names could\n * just as well have already been claimed by the open entry instead, the\n * same \"wrong alternative\" risk `scopeNameToValue()`'s own doc describes\n * for a `/`-choice, just within one alternative's own declared order rather\n * than across separate ones — so it's excluded the same way an\n * unrecognized/open construct always is throughout this module.\n */\nfunction firstOpenIndex(\n schema: CddlSchema,\n alt: readonly CddlGroupEntry[]\n): number {\n const ruleConstantValues = getERefTables(schema).ruleConstantValues;\n for (let i = 0; i < alt.length; i++) {\n const entry = alt[i]!;\n if (entry.kind !== 'entry' || !entry.memberKey) continue;\n const mk = entry.memberKey;\n if (mk.kind === 'bareword' || mk.kind === 'value') continue;\n // kind === 'type1'\n if (mk.key.op) return i;\n const t2 = mk.key.target;\n if (t2.kind === 'enum' && t2.group.kind === 'group') {\n if (enumGroupIsFullyLiteral(t2.group)) continue;\n return i; // e.g. `&(raw: tstr)`: not a closed set of literal values\n }\n if (\n t2.kind === 'ref' &&\n !t2.genericArgs?.length &&\n ruleConstantValues.has(t2.name)\n )\n continue;\n return i; // e.g. `* tstr => any`, a generic ref, or another shape\n }\n return alt.length;\n}\n\n/**\n * Whether `name` labeling `value` here would also resolve the *same* way\n * through `parseAppString()` (`e'name'`'s own parse direction), which\n * consults `getERefTables(schema).byName` — a single, genuinely\n * schema-wide table, unlike `scopeNameToValue()`'s own position-scoped\n * one. A name can be locally unambiguous at one member-key position (safe\n * to use as *this* key's integer value — see `scopeNameToValue()`) while\n * being bound to a *different* value, or ambiguously to more than one, at\n * some other, unrelated member-key position elsewhere in the same schema.\n * Labeling the key `e'name'` in that case would round-trip incorrectly (or\n * not at all) through `fromCDN()` against the very same schema, so\n * `fromJS()` only does so when this returns `true` — otherwise the key\n * still gets the correct integer value, just as a plain, unlabeled\n * integer (see `js/fromJS.ts`'s own use of this).\n */\nexport function resolvesGloballyTo(\n schema: CddlSchema,\n name: string,\n value: bigint\n): boolean {\n return getERefTables(schema).byName.get(name) === value;\n}\n\n/**\n * `scopeNameToValue()`'s own result, inverted — dropping any value bound to\n * more than one *different* name at this position, since picking either\n * would be an arbitrary, unjustified choice this position's own schema\n * doesn't actually make (each individual name is still unambiguous on its\n * own — see `scopeNameToValue()`'s own doc — this is only about two\n * *different* names colliding on the same value). Used wherever a caller\n * already has an integer *value* (not a name) — e.g. an already-decoded map\n * key, or a `MapEntries` entry whose key is a plain number rather than a\n * string — and needs to know which name, if any, unambiguously describes\n * it at this position, so it can resolve a nested scope for that entry's\n * own value the same way a literal string key's name would (see\n * `extensions/eref.ts` and `js/fromJS.ts`'s own uses).\n */\nexport function scopeValueToName(\n schema: CddlSchema,\n scope: ERefScope\n): ReadonlyMap<bigint, string> {\n const byValue = new Map<bigint, string>();\n const ambiguous = new Set<bigint>();\n for (const [name, value] of scopeNameToValue(schema, scope)) {\n if (byValue.has(value)) {\n ambiguous.add(value);\n continue;\n }\n byValue.set(value, name);\n }\n for (const value of ambiguous) byValue.delete(value);\n return byValue;\n}\n\n/**\n * The scope for `identifier`'s own nested value — matching, across every\n * one of `scope`'s own alternatives, an entry whose member key is either a\n * literal bareword/quoted-text key equal to `identifier` (a `string`), the\n * `&(name: value)`/bare-reference entry that names it (only when\n * `identifier` is itself one of `scope`'s own `scopeNameToValue()` names),\n * *or* a differently-spelled member key that resolves to that exact same\n * integer value — e.g. a literal `1: …` entry in one alternative and\n * `&(data: 1) => …` in another both govern the same wire position, even\n * though only the second one *names* it. Passing `identifier` as a\n * `bigint` instead skips name resolution entirely and matches purely by\n * that integer value — for a wire key with no name of its own at all, e.g.\n * a literal `1: &(AES-CCM-16-64-128: 10)` entry, whose value can still be\n * resolved this way even though the key `1` itself was never eRefKeys\n * -eligible (see `extensions/eref.ts`'s own use of this for exactly this\n * case). Every matching entry's own value type is resolved into the\n * nested scope's own alternatives (kept separate from each other the same\n * way `scope`'s own were — see the module doc); `undefined` when nothing\n * matches `identifier` at all, when what matches doesn't resolve to a map\n * type anywhere, or when an open/wildcard member key (`firstOpenIndex()`)\n * at or before the matching entry, *within that same alternative*, could\n * equally claim the same wire key with a shape this resolver can't pin\n * down — see `firstOpenIndex()`'s own doc for exactly when that does and\n * doesn't apply. The object being converted might just as well belong to\n * that open entry instead of whichever named one matched literally, so\n * descending as if it definitely doesn't would risk exactly the same\n * \"wrong alternative\" misconversion `scopeNameToValue()`'s own doc\n * describes for `scope`'s own direct names.\n *\n * `respectDeclarationOrder` (default `true`) — see `scopeNameToValue()`'s\n * own doc; `fromJS()` passes `false` when descending from a JS property\n * name it hasn't (or can't) also convert to an integer key this same way,\n * so the nested scope it resolves stays consistent with that decision.\n */\nexport function resolveNestedScope(\n schema: CddlSchema,\n scope: ERefScope,\n identifier: string | bigint,\n respectDeclarationOrder = true\n): ERefScope | undefined {\n const merged = matchingValueType(\n schema,\n scope,\n identifier,\n respectDeclarationOrder\n );\n if (!merged) return undefined;\n const resolved = resolveMapEntries(schema, merged, new Set());\n return resolved.kind === 'resolved'\n ? { alternatives: resolved.alternatives }\n : undefined;\n}\n\n/**\n * `identifier`'s own entries' value types, matched and merged across every\n * one of `scope`'s own alternatives the same way `resolveNestedScope()`'s\n * own doc describes (literal spelling, a named `&(name: value)`/bare-\n * reference entry, or a differently-spelled entry resolving to the same\n * integer value). A `bigint` identifier matches purely by value, skipping\n * name resolution entirely (see `resolveNestedScope()`'s own doc) — one\n * combined `CddlType` representing every alternative's own value type for\n * this position. Within one alternative, only an entry *before* that\n * alternative's own `firstOpenIndex()` is matched — a later entry (at or\n * after an open/wildcard one) might never actually be reached for a given\n * wire key (see `firstOpenIndex()`'s own doc), so it's excluded the same\n * way an unrecognized construct always is. `undefined` when nothing\n * matches `identifier` at all this way. Shared by `resolveNestedScope()`\n * (resolved further into a nested map type) and `resolveValueEnumName()`\n * (resolved into a closed set of named integer constants instead — see its\n * own doc).\n */\nfunction matchingValueType(\n schema: CddlSchema,\n scope: ERefScope,\n identifier: string | bigint,\n respectDeclarationOrder = true\n): CddlType | undefined {\n const key = typeof identifier === 'string' ? identifier : undefined;\n const targetValue =\n typeof identifier === 'bigint'\n ? identifier\n : scopeNameToValue(schema, scope, respectDeclarationOrder).get(\n identifier\n );\n const valueTypes: CddlType[] = [];\n const openness = alternativeOpenness(schema, scope);\n for (let altIndex = 0; altIndex < scope.alternatives.length; altIndex++) {\n const alt = scope.alternatives[altIndex]!;\n const openIndex = respectDeclarationOrder\n ? firstOpenIndex(schema, alt)\n : openness[altIndex]\n ? 0\n : alt.length;\n let matched = false;\n for (let i = 0; i < openIndex; i++) {\n const entry = alt[i]!;\n if (entry.kind !== 'entry' || !entry.memberKey) continue;\n if (memberKeyMatches(schema, entry.memberKey, key, targetValue)) {\n valueTypes.push(entry.value);\n matched = true;\n }\n }\n // An open alternative that doesn't claim this key ahead of its own\n // wildcard could hand it to the wildcard instead — a value of some\n // other, unknown shape — so nothing can be said about it at all (the\n // same rule `scopeNameToValue()` applies to names). A closed one that\n // doesn't mention the key can't be what the data matched.\n if (!matched && openIndex < alt.length) return undefined;\n }\n return valueTypes.length === 0 ? undefined : mergeTypes(valueTypes);\n}\n\n/**\n * The name safely labeling `value` when it's the value of `identifier`'s\n * own entry within `scope` — resolving that entry's own value type\n * (`matchingValueType()`, the same position-aware matching\n * `resolveNestedScope()` uses) via `resolveEnumNames()`. Symmetric with\n * `resolveNestedScope()`, but for a value whose *type* is (or resolves to)\n * a closed `&(name: value)` choice of named integer constants — e.g.\n * `? &(gp_enc_alg: -4) => &(AES-CCM-16-64-128: 10, …)` — rather than a\n * nested map. `identifier` may be a `bigint` to match purely by the key's\n * own value when it has no name of its own at all (see\n * `resolveNestedScope()`'s own doc). `undefined` when no matching entry's\n * value type names `value` this way, when any matching entry's value type\n * can't be confidently resolved (see `resolveEnumNames()`'s own doc), or\n * when `scope` has an open/wildcard member key. Always uses the relaxed,\n * declaration-order-aware matching (see `scopeNameToValue()`'s own doc) —\n * every caller is on the annotation side, resolving an already-decoded\n * wire value, never `fromJS()`'s own forward conversion.\n */\nexport function resolveValueEnumName(\n schema: CddlSchema,\n scope: ERefScope,\n identifier: string | bigint,\n value: bigint\n): string | undefined {\n const merged = matchingValueType(schema, scope, identifier);\n return merged ? enumNameOfType(schema, merged, value) : undefined;\n}\n\n/**\n * The name `type` — a value's own type, e.g. the merged types of the members that consumed it —\n * safely gives integer `value`: resolved via `resolveEnumNames()`, so any\n * choice accepting the same integer under no name blocks it.\n */\nexport function enumNameOfType(\n schema: CddlSchema,\n type: CddlType,\n value: bigint\n): string | undefined {\n const resolved = resolveEnumNames(schema, type, new Set());\n if (resolved.kind !== 'resolved') return undefined;\n const name = resolved.names.get(value);\n return typeof name === 'string' ? name : undefined;\n}\n\n/**\n * Whether `mk` governs the same wire position as `key`/`targetValue` —\n * either by literal spelling (a bareword/quoted-text key equal to `key`,\n * matched regardless of `targetValue`, only possible when `key` is\n * defined) or, when `targetValue` is defined, by *value*: a literal\n * integer key equal to `targetValue`, an `&(name: value)`/enum entry\n * naming `targetValue` (whether or not that entry's own name is `key` —\n * two different names can both resolve to the same value, and either one\n * governs this same position), or a bare constant-rule reference whose\n * value is `targetValue`. Without this, an alternative that spells the\n * *same* wire key a different way (e.g. a literal `1: …` where another\n * alternative uses `&(data: 1) => …`) would be missed entirely, silently\n * omitting a shape that could equally apply — see `resolveNestedScope()`'s\n * own doc. `key` is `undefined` when the caller only has a raw integer\n * value and no name at all — value-based matching still applies, just\n * never the literal-spelling branches.\n */\nfunction memberKeyMatches(\n schema: CddlSchema,\n mk: CddlMemberKey,\n key: string | undefined,\n targetValue: bigint | undefined\n): boolean {\n if (mk.kind === 'bareword') return key !== undefined && mk.key === key;\n if (mk.kind === 'value') {\n if (mk.key.type === 'text')\n return key !== undefined && mk.key.value === key;\n if (mk.key.type === 'int' && targetValue !== undefined) {\n const v =\n typeof mk.key.value === 'bigint' ? mk.key.value : BigInt(mk.key.value);\n return v === targetValue;\n }\n return false;\n }\n // kind === 'type1'\n if (targetValue === undefined || mk.key.op) return false;\n const t2 = mk.key.target;\n if (t2.kind === 'enum' && t2.group.kind === 'group') {\n return literalEnumBindings(t2.group).some(\n ([name, value]) =>\n (key !== undefined && name === key) || value === targetValue\n );\n }\n if (t2.kind === 'ref' && !t2.genericArgs?.length) {\n if (key !== undefined && t2.name === key) return true;\n return (\n getERefTables(schema).ruleConstantValues.get(t2.name) === targetValue\n );\n }\n return false;\n}\n\n/** Every `name: <int literal>` entry directly in one `&(...)` literal group. */\nfunction literalEnumBindings(group: CddlGroup): [string, bigint][] {\n const result: [string, bigint][] = [];\n for (const choice of group.choices) {\n for (const entry of choice) {\n const binding = literalEnumBinding(entry);\n if (binding) result.push(binding);\n }\n }\n return result;\n}\n\n/** `entry`'s own `name: <int literal>` binding, if it is exactly that. */\nfunction literalEnumBinding(\n entry: CddlGroupEntry\n): [string, bigint] | undefined {\n if (entry.kind !== 'entry' || !entry.memberKey) return undefined;\n const mk = entry.memberKey;\n const name =\n mk.kind === 'bareword'\n ? mk.key\n : mk.kind === 'value' && mk.key.type === 'text'\n ? mk.key.value\n : undefined;\n if (name === undefined) return undefined;\n const value = literalIntOfType(entry.value);\n return value === undefined ? undefined : [name, value];\n}\n\n/**\n * Whether every entry in `group` (an `&(...)` literal enum group used at a\n * member-key position) has a literal bareword/text name bound to a literal\n * integer value — `literalEnumBindings()`'s own contract, just checked for\n * completeness by comparing its result's length against the group's own\n * entry count. A group with even one entry that doesn't (a non-literal\n * value like `raw: tstr`, a missing/non-text member key, a nested group\n * reference, …) doesn't actually pin the key down to a closed set of\n * literal values the way `&(name: value)` normally does — effectively an\n * open/wildcard key, the same class of risk a `* tstr => any` catch-all is\n * — see `firstOpenIndex()`'s own use of this.\n */\nfunction enumGroupIsFullyLiteral(group: CddlGroup): boolean {\n let total = 0;\n for (const choice of group.choices) total += choice.length;\n return literalEnumBindings(group).length === total;\n}\n\n/**\n * The outcome of trying to resolve one CDDL type expression to its own map\n * entries: `'resolved'` when it names definite map alternatives; `'none'`\n * when it definitely does **not** describe a map (a literal value, an\n * array, …) and so safely contributes nothing to a merge; `'open'` when it\n * might *still* describe a map despite not resolving to one here — `any`\n * (including the bare `#` token and an unshadowed reference to the CDDL\n * prelude's own `any = #`), and `~unwrap`/tagged types, which this\n * simplified resolver doesn't look inside (see the module doc's Scope\n * note). The distinction matters only when merging several alternatives\n * (`resolveMapEntries`): silently treating `'open'` the same as `'none'`\n * would let a name from some *other*, resolvable alternative through even\n * though this alternative could equally apply to the value being\n * converted — see `resolveMapEntries`'s own use of this.\n */\ntype MapResolution =\n | { readonly kind: 'resolved'; readonly alternatives: CddlGroupEntry[][] }\n | { readonly kind: 'open' }\n | { readonly kind: 'none' };\n\nconst NO_MAP: MapResolution = { kind: 'none' };\nconst OPEN_MAP: MapResolution = { kind: 'open' };\n\n/**\n * `name`'s own map-type alternatives — every `=`/`/=`/`//=` definition of\n * that name, each contributing one or more alternatives of its own (a\n * plain-type definition is resolved recursively via `resolveMapEntries`,\n * which may itself have several `/` alternatives; a group-shaped\n * definition, from a `//=` group-choice extension, contributes each of its\n * own `//` choices as a separate alternative; a single bare group entry —\n * `rule //= foo: 1` — contributes one alternative containing just that\n * entry). `'none'` when the name isn't defined at all, only cycles back to\n * itself, or none of its definitions resolve to a map type at all. `'open'`\n * for the CDDL prelude's own `any` (see `MapResolution`'s own doc) or a\n * bare reference to a name only ever defined generically (`box<T> = …`\n * referenced as plain `box`, missing its own type argument) — this\n * resolver doesn't attempt generics (see the module doc's Scope note), so\n * such a reference's actual shape is unknown, not ruled out.\n */\nfunction resolveRuleMapEntries(\n schema: CddlSchema,\n name: string,\n seen: ReadonlySet<string>\n): MapResolution {\n if (seen.has(name)) return NO_MAP;\n const defs = schema.ast.filter((r) => r.name === name && !r.generics?.length);\n if (defs.length === 0) {\n if (name === 'any') return OPEN_MAP;\n const onlyGeneric = schema.ast.some(\n (r) => r.name === name && r.generics?.length\n );\n return onlyGeneric ? OPEN_MAP : NO_MAP;\n }\n const nextSeen = new Set(seen);\n nextSeen.add(name);\n const alternatives: CddlGroupEntry[][] = [];\n for (const def of defs) {\n if (def.body.kind === 'entry' && !def.body.occur && !def.body.memberKey) {\n const resolved = resolveMapEntries(schema, def.body.value, nextSeen);\n if (resolved.kind === 'open') return OPEN_MAP;\n if (resolved.kind === 'resolved')\n alternatives.push(...resolved.alternatives);\n } else if (def.body.kind === 'entry-group') {\n for (const choice of def.body.group.choices) {\n const flat = flattenAlternative(schema, choice, nextSeen);\n if (flat.kind === 'open') return OPEN_MAP;\n alternatives.push(...flat.alternatives);\n }\n } else {\n const flat = flattenAlternative(schema, [def.body], nextSeen);\n if (flat.kind === 'open') return OPEN_MAP;\n alternatives.push(...flat.alternatives);\n }\n }\n return alternatives.length > 0 ? { kind: 'resolved', alternatives } : NO_MAP;\n}\n\nfunction resolveMapEntries(\n schema: CddlSchema,\n type: CddlType,\n seen: ReadonlySet<string>\n): MapResolution {\n const alternatives: CddlGroupEntry[][] = [];\n for (const t1 of type.alternatives) {\n if (t1.op) return OPEN_MAP; // range/control operator: shape unknown, not ruled out\n const resolved = resolveMapEntriesType2(schema, t1.target, seen);\n if (resolved.kind === 'open') return OPEN_MAP;\n if (resolved.kind === 'resolved')\n alternatives.push(...resolved.alternatives);\n }\n return alternatives.length > 0 ? { kind: 'resolved', alternatives } : NO_MAP;\n}\n\nfunction resolveMapEntriesType2(\n schema: CddlSchema,\n t2: CddlType2,\n seen: ReadonlySet<string>\n): MapResolution {\n switch (t2.kind) {\n case 'map': {\n // Flatten each choice, splicing in any bare group reference or\n // inline parenthesized group it contains — see flattenAlternative()'s\n // own doc for why this can't just take t2.group.choices as-is.\n const alternatives: CddlGroupEntry[][] = [];\n for (const choice of t2.group.choices) {\n const flat = flattenAlternative(schema, choice, seen);\n if (flat.kind === 'open') return OPEN_MAP;\n alternatives.push(...flat.alternatives);\n }\n return { kind: 'resolved', alternatives };\n }\n case 'paren':\n return resolveMapEntries(schema, t2.type, seen);\n case 'ref':\n // A generic instantiation (`box<T>`) isn't resolved by this\n // simplified resolver (see the module doc's Scope note) — but unlike\n // a name that simply isn't defined, `box`'s own definition might\n // still be a map (e.g. `box<T> = { * tstr => T }`), so this can't be\n // ruled out the way an unresolvable reference otherwise safely is.\n if (t2.genericArgs?.length) return OPEN_MAP;\n return resolveRuleMapEntries(schema, t2.name, seen);\n case 'any':\n return OPEN_MAP;\n case 'unwrap':\n case 'tagged':\n // Wraps further content this simplified resolver doesn't look inside\n // — see the module doc's Scope note — so, unlike a type we're sure\n // can never be a map, this can't be ruled out either.\n return OPEN_MAP;\n case 'major':\n // `#5[...]` denotes any item of major type 5 — a map, unconstrained —\n // so, like `any`, it can't be ruled out; every other major number\n // (array, text/byte string, integers, tag, simple/float) never is one.\n return t2.major === 5 ? OPEN_MAP : NO_MAP;\n case 'enum':\n // `&(group)` used as a bare *type* (not at a member-key position) is\n // a choice over the group's own entries' *value* types — e.g.\n // `&(raw: { * tstr => any })` reduces to that one entry's map type.\n // This resolver doesn't attempt to look inside and resolve those\n // value types individually (see the module doc's Scope note), so —\n // unlike a `value`/`array`, which can never be a map regardless of\n // what's inside them — this can't be ruled out either.\n return OPEN_MAP;\n default:\n // value/array: never (resolved as) a map type.\n return NO_MAP;\n }\n}\n\n/**\n * Expand one alternative's own entries into every fully-flattened shape\n * implied by any bare group reference (`{ name }`) or inline parenthesized\n * group entry (`{ (a: 1 // b: 2) }`) it contains, recursively — CDDL group\n * inclusion splices the referenced group's own entries in at that point\n * (see `CddlEntryValue`'s own doc: \"grpent … also covers bare group\n * references\"), and — for a `//`-choice, whether from a named rule's own\n * `//=` extensions or an inline group — each choice becomes its own fully\n * expanded alternative here, the same way any other `/`/`//` choice does\n * (see the module doc). Without this, a spliced-in entry (e.g. a plain\n * bareword key the referenced group names) would silently vanish from\n * every consumer that only recognizes an entry with its own `memberKey` —\n * exactly the same \"silently drop what we can't immediately classify\"\n * mistake `any`/wildcard handling elsewhere in this module guards against.\n *\n * `'open'` when any such reference can't be confidently resolved this way\n * (an unresolvable name, a generic, `any`, a controlled type, …) — the\n * whole alternative (and therefore the whole merge it's part of) must then\n * be treated as unsafe, not silently missing just the one entry.\n */\nfunction flattenAlternative(\n schema: CddlSchema,\n entries: readonly CddlGroupEntry[],\n seen: ReadonlySet<string>\n): { kind: 'resolved'; alternatives: CddlGroupEntry[][] } | { kind: 'open' } {\n let results: CddlGroupEntry[][] = [[]];\n for (const entry of entries) {\n if (entry.kind === 'entry' && entry.memberKey) {\n results = results.map((r) => [...r, entry]);\n continue;\n }\n let subChoices: CddlGroupEntry[][];\n if (entry.kind === 'entry-group') {\n subChoices = entry.group.choices;\n } else {\n const resolved = resolveMapEntries(schema, entry.value, seen);\n if (resolved.kind !== 'resolved') return { kind: 'open' };\n subChoices = resolved.alternatives;\n }\n const expanded: CddlGroupEntry[][] = [];\n for (const choice of subChoices) {\n const flat = flattenAlternative(schema, choice, seen);\n if (flat.kind === 'open') return { kind: 'open' };\n expanded.push(...flat.alternatives);\n }\n const next: CddlGroupEntry[][] = [];\n for (const r of results)\n for (const sub of expanded) next.push([...r, ...sub]);\n results = next;\n }\n return { kind: 'resolved', alternatives: results };\n}\n\n/**\n * The outcome of resolving one CDDL type expression to its own fixed-shape\n * array alternatives — `'resolved'` with one positional element-type list\n * per alternative; `'none'` when it definitely isn't an array (a map, a\n * literal value, a scalar prelude type, …); `'open'` when it might still be\n * one whose element positions can't be pinned down (`any`, `#4`, an array\n * entry with an occurrence indicator, a generic, a controlled/tagged/\n * unwrapped type, …). Same three-way contract as `MapResolution`: an open\n * alternative poisons the whole merge rather than being silently skipped.\n */\ntype ArrayResolution =\n | { readonly kind: 'resolved'; readonly alternatives: CddlType[][] }\n | { readonly kind: 'open' }\n | { readonly kind: 'none' };\n\nconst NO_ARRAY: ArrayResolution = { kind: 'none' };\nconst OPEN_ARRAY: ArrayResolution = { kind: 'open' };\n\n/**\n * `name`'s own definitions (user rules first, else the prelude's) —\n * `undefined` when defined nowhere, or only generically.\n */\nfunction ruleDefinitions(\n schema: CddlSchema,\n name: string\n): readonly CddlRule[] | undefined {\n let defs: readonly CddlRule[] = schema.ast.filter((r) => r.name === name);\n if (defs.length === 0) {\n const preludeRule = getPreludeRules().get(name);\n defs = preludeRule ? [preludeRule] : [];\n }\n if (defs.length === 0 || defs.some((r) => r.generics?.length))\n return undefined;\n return defs;\n}\n\n/** Whether `def`'s body is a plain type rather than a group. */\nfunction isTypeRule(def: CddlRule): boolean {\n return def.body.kind === 'entry' && !def.body.occur && !def.body.memberKey;\n}\n\nfunction resolveRuleArrayTypes(\n schema: CddlSchema,\n name: string,\n seen: ReadonlySet<string>\n): ArrayResolution {\n if (seen.has(name)) return NO_ARRAY;\n const defs = ruleDefinitions(schema, name);\n if (!defs) return OPEN_ARRAY;\n const nextSeen = new Set(seen);\n nextSeen.add(name);\n const alternatives: CddlType[][] = [];\n for (const def of defs) {\n // A group-shaped rule referenced as a type isn't something this\n // resolver attempts.\n if (!isTypeRule(def) || def.body.kind !== 'entry') return OPEN_ARRAY;\n const resolved = resolveArrayTypes(schema, def.body.value, nextSeen);\n if (resolved.kind === 'open') return OPEN_ARRAY;\n if (resolved.kind === 'resolved')\n alternatives.push(...resolved.alternatives);\n }\n return alternatives.length > 0\n ? { kind: 'resolved', alternatives }\n : NO_ARRAY;\n}\n\nfunction resolveArrayTypes(\n schema: CddlSchema,\n type: CddlType,\n seen: ReadonlySet<string>\n): ArrayResolution {\n const alternatives: CddlType[][] = [];\n for (const t1 of type.alternatives) {\n if (t1.op) return OPEN_ARRAY;\n const resolved = resolveArrayTypesType2(schema, t1.target, seen);\n if (resolved.kind === 'open') return OPEN_ARRAY;\n if (resolved.kind === 'resolved')\n alternatives.push(...resolved.alternatives);\n }\n return alternatives.length > 0\n ? { kind: 'resolved', alternatives }\n : NO_ARRAY;\n}\n\nfunction resolveArrayTypesType2(\n schema: CddlSchema,\n t2: CddlType2,\n seen: ReadonlySet<string>\n): ArrayResolution {\n switch (t2.kind) {\n case 'array': {\n const alternatives: CddlType[][] = [];\n for (const choice of t2.group.choices) {\n const flat = flattenArrayElements(schema, choice, seen);\n if (!flat) return OPEN_ARRAY;\n alternatives.push(...flat);\n }\n return { kind: 'resolved', alternatives };\n }\n case 'paren':\n return resolveArrayTypes(schema, t2.type, seen);\n case 'ref':\n if (t2.genericArgs?.length) return OPEN_ARRAY;\n return resolveRuleArrayTypes(schema, t2.name, seen);\n case 'major':\n return t2.major === 4 ? OPEN_ARRAY : NO_ARRAY;\n case 'map':\n case 'value':\n return NO_ARRAY;\n default:\n // any/unwrap/tagged/enum: might still be an array, shape unknown.\n return OPEN_ARRAY;\n }\n}\n\n/**\n * One array alternative's entries, as every fully-expanded positional list\n * of element types — splicing in inline `( … )` groups and bare group\n * references (`[Headers, payload]` with `Headers = (protected: …, …)`), one\n * expanded list per `//` choice they contain. `undefined` when any entry\n * carries an occurrence indicator (element positions would then depend on\n * the data), uses a `type1 =>` member key, or references a group this\n * resolver can't expand.\n */\nfunction flattenArrayElements(\n schema: CddlSchema,\n entries: readonly CddlGroupEntry[],\n seen: ReadonlySet<string>\n): CddlType[][] | undefined {\n let results: CddlType[][] = [[]];\n for (const entry of entries) {\n if (entry.occur) return undefined;\n let expanded: CddlType[][];\n if (entry.kind === 'entry-group') {\n expanded = [];\n for (const choice of entry.group.choices) {\n const flat = flattenArrayElements(schema, choice, seen);\n if (!flat) return undefined;\n expanded.push(...flat);\n }\n } else if (entry.memberKey) {\n // `label: type` in an array just names the element.\n if (entry.memberKey.kind === 'type1') return undefined;\n expanded = [[entry.value]];\n } else {\n const groupName = groupReferenceName(schema, entry.value);\n if (groupName === null) return undefined;\n if (groupName === undefined) {\n expanded = [[entry.value]];\n } else {\n if (seen.has(groupName)) return undefined;\n const nextSeen = new Set(seen);\n nextSeen.add(groupName);\n expanded = [];\n for (const def of ruleDefinitions(schema, groupName)!) {\n const choices =\n def.body.kind === 'entry-group'\n ? def.body.group.choices\n : [[def.body]];\n for (const choice of choices) {\n const flat = flattenArrayElements(schema, choice, nextSeen);\n if (!flat) return undefined;\n expanded.push(...flat);\n }\n }\n }\n }\n const next: CddlType[][] = [];\n for (const r of results)\n for (const sub of expanded) next.push([...r, ...sub]);\n results = next;\n }\n return results;\n}\n\n/**\n * When `type` (a member-keyless array entry's own type) is a bare reference\n * to a group-shaped rule — one to splice in, not a single element — that\n * rule's name; `undefined` when it's an ordinary element type; `null` when\n * it can't be told apart safely (a rule mixing group- and type-shaped\n * definitions, or a generic group reference).\n */\nfunction groupReferenceName(\n schema: CddlSchema,\n type: CddlType\n): string | null | undefined {\n if (type.alternatives.length !== 1) return undefined;\n const t1 = type.alternatives[0]!;\n if (t1.op || t1.target.kind !== 'ref') return undefined;\n const name = t1.target.name;\n if (\n t1.target.genericArgs?.length ||\n schema.ast.some((r) => r.name === name && r.generics?.length)\n )\n return null; // could be a generic group: element count unknown\n const defs = ruleDefinitions(schema, name);\n if (!defs) return undefined; // resolved (as open) by the element's own type\n const groupShaped = defs.filter((d) => !isTypeRule(d)).length;\n if (groupShaped === 0) return undefined;\n return groupShaped === defs.length ? name : null;\n}\n\n/**\n * The outcome of trying to resolve one CDDL type expression to the closed\n * set of named integer constants it could represent — `'resolved'` when it\n * names at least one such value (via an `&(name: value)` literal enum used\n * as a bare *type*, not at a member-key position); `'none'` when it\n * definitely never names *any* value this way, and never even structurally\n * holds a bare integer at all (a map, array, or a prelude type like\n * `bool`/`tstr`, none of which a decoded `CborUint`/`CborNint` could ever\n * be an instance of); `'open'` when some alternative *could* still explain\n * the same integer under no name at all — `any`, a prelude integer type\n * (`uint`/`nint`/`int`/`number`/`integer`/…), an unconstrained `#0`/`#1`\n * major-type constraint, a range or other controlled type (including one\n * inside the `&(...)` group itself, e.g. `reserved: 0..10`), a generic\n * instantiation, `~unwrap`/tagged content this simplified resolver doesn't\n * look inside, … (an unnamed integer *literal* instead cancels only a name\n * for that same value — see `UNNAMED`)\n * — labeling the value would then be misleading (it might just be an\n * ordinary, unrelated integer here, the same concern `annotateERefKeys()`'s\n * own doc raises for a value that merely *coincides* with some unrelated\n * name elsewhere), so it can't be ruled out the way a type we're sure never\n * even holds a bare integer safely is — see `resolveEnumNames()`'s own use\n * of this.\n */\ntype EnumResolution =\n | { readonly kind: 'resolved'; readonly names: ReadonlyMap<bigint, EnumName> }\n | { readonly kind: 'open' }\n | { readonly kind: 'none' };\n\nconst NO_ENUM_NAMES: EnumResolution = { kind: 'none' };\nconst OPEN_ENUM_NAMES: EnumResolution = { kind: 'open' };\n\n/**\n * Merge `names` into `into`, in place, moving a value to `conflicting`\n * (and dropping it from `into`) the instant two *different* names both\n * claim it — narrower than `resolveMapEntries()`'s own \"one open\n * alternative poisons everything\" approach: a naming conflict for one\n * specific value doesn't cast doubt on any *other*, unrelated value this\n * same type also names unambiguously, since (unlike a member-key merge)\n * the value being labeled is already known, not being guessed at.\n */\nfunction mergeEnumNames(\n into: Map<bigint, EnumName>,\n conflicting: Set<bigint>,\n names: ReadonlyMap<bigint, EnumName>\n): void {\n for (const [value, name] of names) {\n const existing = into.get(value);\n if (existing !== undefined && existing !== name) {\n conflicting.add(value);\n continue;\n }\n into.set(value, name);\n }\n}\n\n/**\n * `type`'s own closed set of named integer constants — every `/`\n * alternative's own contribution (`resolveEnumNamesType2()`) merged\n * together via `mergeEnumNames()`. A controlled alternative (`t1.op`)\n * forces the *whole* type `'open'` (see `EnumResolution`'s own doc for why\n * a naming conflict and a genuinely unresolvable alternative are handled\n * differently).\n */\nfunction resolveEnumNames(\n schema: CddlSchema,\n type: CddlType,\n seen: ReadonlySet<string>\n): EnumResolution {\n const names = new Map<bigint, EnumName>();\n const conflicting = new Set<bigint>();\n for (const t1 of type.alternatives) {\n if (t1.op) return OPEN_ENUM_NAMES;\n const resolved = resolveEnumNamesType2(schema, t1.target, seen);\n if (resolved.kind === 'open') return OPEN_ENUM_NAMES;\n if (resolved.kind === 'resolved')\n mergeEnumNames(names, conflicting, resolved.names);\n }\n for (const value of conflicting) names.delete(value);\n return names.size > 0 ? { kind: 'resolved', names } : NO_ENUM_NAMES;\n}\n\nfunction resolveEnumNamesType2(\n schema: CddlSchema,\n t2: CddlType2,\n seen: ReadonlySet<string>\n): EnumResolution {\n switch (t2.kind) {\n case 'enum': {\n // `&groupname<genericarg>` (a reference, not a literal group): this\n // resolver doesn't attempt group-reference resolution here.\n if (t2.group.kind !== 'group') return OPEN_ENUM_NAMES;\n // Every entry is one choice of the enum's own value set. A\n // `name: <int literal>` entry names its value; any other entry (a\n // range like `reserved: 0..10`, a `uint`-typed one, an unnamed\n // literal, …) is resolved as a type in its own right, so one that\n // could accept the same integer under no name poisons the result\n // exactly as a sibling `/` alternative would.\n const names = new Map<bigint, EnumName>();\n const conflicting = new Set<bigint>();\n for (const choice of t2.group.choices) {\n for (const entry of choice) {\n if (entry.kind !== 'entry') return OPEN_ENUM_NAMES;\n const binding = literalEnumBinding(entry);\n if (binding) {\n const [name, value] = binding;\n mergeEnumNames(names, conflicting, new Map([[value, name]]));\n continue;\n }\n const resolved = resolveEnumNames(schema, entry.value, seen);\n if (resolved.kind === 'open') return OPEN_ENUM_NAMES;\n if (resolved.kind === 'resolved')\n mergeEnumNames(names, conflicting, resolved.names);\n }\n }\n for (const value of conflicting) names.delete(value);\n return names.size > 0 ? { kind: 'resolved', names } : NO_ENUM_NAMES;\n }\n case 'paren':\n return resolveEnumNames(schema, t2.type, seen);\n case 'ref': {\n // A generic instantiation isn't resolved by this simplified resolver\n // (see the module doc's Scope note), so it might still accept this\n // integer under no name — open. A name with no user definition falls\n // back to the prelude's own (user rules shadow it), resolved the same\n // way as any other rule: `uint = #0`, `int = uint / nint`, `number`,\n // `integer`, `any = #`, … all come out open (they accept a bare\n // integer under no name), while `bool`/`tstr`/`float`/… come out none\n // (they never hold one). A name defined nowhere at all is open too —\n // its shape is unknown, not ruled out.\n if (t2.genericArgs?.length) return OPEN_ENUM_NAMES;\n if (seen.has(t2.name)) return NO_ENUM_NAMES;\n let defs = schema.ast.filter((r) => r.name === t2.name);\n if (defs.length === 0) {\n const preludeRule = getPreludeRules().get(t2.name);\n defs = preludeRule ? [preludeRule] : [];\n }\n if (defs.length === 0 || defs.some((r) => r.generics?.length))\n return OPEN_ENUM_NAMES;\n const nextSeen = new Set(seen);\n nextSeen.add(t2.name);\n const names = new Map<bigint, EnumName>();\n const conflicting = new Set<bigint>();\n for (const def of defs) {\n if (def.body.kind !== 'entry' || def.body.occur || def.body.memberKey)\n return OPEN_ENUM_NAMES; // an unusual rule-body shape: not attempted\n const resolved = resolveEnumNames(schema, def.body.value, nextSeen);\n if (resolved.kind === 'open') return OPEN_ENUM_NAMES;\n if (resolved.kind === 'resolved')\n mergeEnumNames(names, conflicting, resolved.names);\n }\n for (const value of conflicting) names.delete(value);\n return names.size > 0 ? { kind: 'resolved', names } : NO_ENUM_NAMES;\n }\n case 'any':\n case 'unwrap':\n case 'tagged':\n // `any` (the bare `#` token) structurally accepts *any* value under\n // no name, the same risk as an unshadowed `ref` to it above;\n // `unwrap`/tagged wrap further content this simplified resolver\n // doesn't look inside (see the module doc's Scope note) — none of\n // these can be ruled out the way a type we're sure never even\n // structurally holds an integer safely is.\n return OPEN_ENUM_NAMES;\n case 'major':\n // `#0[...]`/`#1[...]` denote any item of major type 0/1 — an\n // unsigned/negative integer, unconstrained, the same \"could be any\n // integer under no name\" risk as `any` itself; every other major\n // number (bytes/text/array/map/tag/simple) can never even\n // structurally be the bare integer this resolver is trying to name.\n return t2.major === 0 || t2.major === 1 ? OPEN_ENUM_NAMES : NO_ENUM_NAMES;\n case 'value': {\n // An integer literal accepts exactly that one integer, under no name\n // — recorded as UNNAMED so it conflicts with (and so cancels) any\n // name another choice gives the same value, while leaving every other\n // value alone. Any other literal (text/bytes/float) never matches a\n // bare integer at all.\n const v = literalIntOfType2(t2);\n return v === undefined\n ? NO_ENUM_NAMES\n : { kind: 'resolved', names: new Map([[v, UNNAMED]]) };\n }\n default:\n // map/array: never structurally the bare integer being named.\n return NO_ENUM_NAMES;\n }\n}\n\n/**\n * Placeholder \"name\" for an integer some choice accepts without naming it\n * (see `resolveEnumNamesType2()`'s `value` case) — never a real label;\n * `resolveValueEnumName()` treats it as no name at all. A `Symbol`, not a\n * string, so it can never collide with a genuine name — including the\n * empty string, which `&(\"\": 1)` legitimately binds.\n */\nconst UNNAMED: unique symbol = Symbol('unnamed');\n\ntype EnumName = string | typeof UNNAMED;\n\nfunction literalIntOfType2(\n t2: Extract<CddlType2, { kind: 'value' }>\n): bigint | undefined {\n if (t2.type !== 'int') return undefined;\n return typeof t2.value === 'bigint' ? t2.value : BigInt(t2.value);\n}\n","/**\n * `e'...'` external-reference CDN app-extension\n * (draft-ietf-cbor-edn-e-ref): resolves a mnemonic name to the integer value\n * a CDDL model binds it to — a constant rule (`title = -1`) or a named\n * group-enumeration entry (`? &(title: -1) => oltext`) — and, in the other\n * direction, lets a CBOR/CDN integer map key that CDDL validation matched\n * against such a named *member-key* entry round-trip back through `toCDN()`\n * as `e'title'` instead of the bare integer (see `cddl/eref.ts`'s module\n * doc for exactly which CDDL constructs feed which direction).\n *\n * Scope: only integer-valued names are resolved. The draft frames `e'...'`\n * more broadly, as referencing any CDDL constant value, but this library's\n * first target is CDDL models that label map-entry integer keys (the\n * draft's own `problem-details` example); a name bound to a float, text, or\n * byte-string constant is not collected by `getERefTables()` at all, so\n * `e'name'` for one fails to resolve (`parseAppString` below) with a \"not\n * defined\" error rather than producing that constant's value. Broadening\n * this to arbitrary CDDL literal values is unimplemented future work, not a\n * bug. A map *value* whose own type is a closed `&(name: value)` choice of\n * named integer constants (not merely coinciding with some unrelated\n * name elsewhere) is annotated too — see `eRefValueFor()`'s own doc.\n *\n * Unlike the other bundled extensions (`dt`, `ip`, …), this one is not a\n * fixed singleton: `e'...'` names are only meaningful relative to a specific\n * CDDL model, so `createERefExtension(schema)` builds one bound to that\n * schema's own `getERefTables()` result. `CBOR.fromCDN()`/`fromCBOR()`/\n * `fromJS()` register it automatically whenever the `cddl` option is set —\n * see `cbor.ts`'s own `withERefExtension()`/`assertCddl()`.\n *\n * A fourth direction — a plain JS object's own property name converting\n * *to* the integer key it names, e.g. `fromJS({ title: \"x\" }, { cddl })`\n * producing the same map `{-1: \"x\"}` that `fromCDN()` parsing\n * `{e'title': \"x\"}` would (both `eRefKeys` options default to on, so\n * neither needs spelling out explicitly) — is implemented in `js/fromJS.ts`\n * (`FromJSOptions.eRefKeys`) rather than here, since it needs to intercept\n * `fromJS()`'s own plain-object-to-`CborMap` conversion directly. It can't\n * safely use `ERefTables.nameToValue` (a single, whole-schema table)\n * as-is, since it runs *before* validation — it instead resolves names\n * positionally, per `cddl/eRefScope.ts`, only consulting names bound within\n * the CDDL type actually reachable at each position as it recurses. It\n * still builds `CborERefUint`/`CborERefNint` nodes from this file, so the\n * resulting key round-trips through `toCDN()`/`toJS()` exactly the same way\n * an `annotateERefKeys()`-annotated one does.\n *\n * `annotateERefKeys()` (below) resolves names the *same*, positional way —\n * not the flat `ERefTables.byValue` table its own earlier design used —\n * for exactly the same reason: a name that exists *somewhere* in the\n * schema but isn't reachable from a given key's own structural position is\n * exactly the kind of name `fromJS()`'s `eRefKeys` direction refuses to\n * convert back, so labeling it here would make a `toJS()` → `fromJS()`\n * round-trip silently change that key's actual value — not merely its\n * display label — see `annotateERefKeys()`'s own doc for the full story.\n */\n\nimport type { FromCBOROptions, ToCDNOptions, ToJSOptions } from '../types';\nimport type { CborExtension } from './types';\nimport type { CborItem } from '../ast/CborItem';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborArray } from '../ast/CborArray';\nimport { CborMap } from '../ast/CborMap';\nimport { CborTag } from '../ast/CborTag';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborEmbeddedCBOR } from '../ast/CborEmbeddedCBOR';\nimport { decodeCBOR } from '../cbor/decoder';\nimport type { EncodingWidth } from '../cbor/encode';\nimport {\n resolveEiSuffix,\n canonicalEncodingWidth,\n escapeAppString,\n} from '../cdn/serialize-utils';\nimport { getERefTables } from '../cddl/eref';\nimport type { CddlSchema } from '../cddl/schema';\nimport type { CddlType, CddlType1 } from '../cddl/ast';\nimport {\n itemMatchesType,\n mapGroupsOfType,\n plainTextMemberKeys,\n traceMapGroup,\n type CddlEnv,\n type MapGroupTarget,\n type MapMember,\n type ValidateOptions,\n} from '../cddl/validator';\nimport {\n NO_POSITION,\n arrayScopeOfType,\n enumNameOfType,\n matchingArrayAlternatives,\n mergeTypes,\n memberKeyName,\n resolveElementPosition,\n resolveNestedPosition,\n resolveRootPosition,\n ruleRefType,\n scopeNameToValue,\n resolvesGloballyTo,\n typeAlternatives,\n type ERefPosition,\n} from '../cddl/eRefScope';\n\nexport const PREFIX_EREF = 'e';\n\n// ─── CborItem subclasses ─────────────────────────────────────────────────────\n\ninterface ERefNodeOptions {\n encodingWidth?: EncodingWidth;\n ednSource?: string;\n /**\n * Whether `toJS()` may use `refName` as this key's JS property name —\n * `false` when `fromJS()` would *not* convert that name back to this\n * integer key at this position (its string-key conversion is stricter\n * than annotation — see `cddl/eRefScope.ts`'s module doc), so a\n * `toJS()` → `fromJS()` round trip would otherwise silently turn the key\n * into literal text. The `e'name'` label is then display-only: `toCDN()`\n * still emits it, while `toJS()` treats the key as the plain integer it\n * is. Set by `annotateERefKeys()`; defaults to `true`.\n */\n jsKey?: boolean;\n}\n\nfunction eRefJsObjectKey(\n node: CborERefUint | CborERefNint,\n options: ToJSOptions | undefined\n): string | undefined {\n if (options?.eRefKeys === false) return node.value.toString();\n if (node.jsKey) return node.refName;\n // Not object-eligible under 'auto' (so the map falls back to MapEntries\n // with the integer key intact); an explicit `mapAs: 'object'` gets the\n // same numeric property name a plain integer key would.\n return options?.mapAs === 'object' ? node.value.toString() : undefined;\n}\n\n/**\n * A non-negative integer whose value a CDDL model names — `_toCDN()` emits\n * `e'name'` notation unless `appPrefix` is `false`.\n */\nexport class CborERefUint extends CborUint {\n readonly refName: string;\n\n /** See `ERefNodeOptions.jsKey`. */\n readonly jsKey: boolean;\n\n constructor(\n value: number | bigint,\n refName: string,\n options?: ERefNodeOptions\n ) {\n super(value, options);\n this.refName = refName;\n this.jsKey = options?.jsKey ?? true;\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.value)\n );\n return `${PREFIX_EREF}${escapeAppString(this.refName)}${suffix}`;\n }\n\n override _jsObjectKey(options: ToJSOptions | undefined): string | undefined {\n // Default true: this key only exists in the first place because a\n // schema named it, so `eRefKeys` unset means \"use the name\" — unless\n // `jsKey` says `fromJS()` couldn't convert that name back here.\n return eRefJsObjectKey(this, options);\n }\n}\n\n/**\n * A negative integer whose value a CDDL model names — `_toCDN()` emits\n * `e'name'` notation unless `appPrefix` is `false`.\n */\nexport class CborERefNint extends CborNint {\n readonly refName: string;\n\n /** See `ERefNodeOptions.jsKey`. */\n readonly jsKey: boolean;\n\n constructor(\n value: number | bigint,\n refName: string,\n options?: ERefNodeOptions\n ) {\n super(value, options);\n this.refName = refName;\n this.jsKey = options?.jsKey ?? true;\n }\n\n override _toCDN(\n options: ToCDNOptions | undefined,\n depth: number,\n path?: readonly unknown[]\n ): string {\n if (options?.appPrefix === false) return super._toCDN(options, depth, path);\n const suffix = resolveEiSuffix(options, this.encodingWidth, () =>\n canonicalEncodingWidth(this.argument)\n );\n return `${PREFIX_EREF}${escapeAppString(this.refName)}${suffix}`;\n }\n\n override _jsObjectKey(options: ToJSOptions | undefined): string | undefined {\n // Default true: this key only exists in the first place because a\n // schema named it, so `eRefKeys` unset means \"use the name\" — unless\n // `jsKey` says `fromJS()` couldn't convert that name back here.\n return eRefJsObjectKey(this, options);\n }\n}\n\n// ─── Factory ──────────────────────────────────────────────────────────────────\n\n/**\n * Build the `e'...'` `CborExtension` for one compiled CDDL schema.\n *\n * `parseAppString('e', 'title', …)` resolves `title` via the schema's\n * `getERefTables().byName` and returns the appropriately-signed\n * `CborERefUint`/`CborERefNint`. A name the schema does not define (or\n * defines ambiguously — bound to more than one value — or defines only as a\n * non-integer constant; see the module doc's Scope note) is a hard parse\n * error, always thrown regardless of `onError`: there is no best-effort\n * value to fall back to.\n */\nexport function createERefExtension(schema: CddlSchema): CborExtension {\n const tables = getERefTables(schema);\n return {\n appStringPrefixes: [PREFIX_EREF],\n parseAppString(_prefix: string, content: string): CborItem {\n const value = tables.byName.get(content);\n if (value === undefined) {\n const msg = tables.ambiguousNames.has(content)\n ? `e'${content}': ambiguous — the CDDL model binds '${content}' to more than one value`\n : `e'${content}': not defined as an integer constant or named group entry in the CDDL model ` +\n `(only integer-valued names are resolved; a name bound to a float, text, or byte-string ` +\n `constant is not currently supported)`;\n throw new SyntaxError(msg);\n }\n return value >= 0n\n ? new CborERefUint(value, content)\n : new CborERefNint(value, content);\n },\n };\n}\n\n// ─── Post-validation annotation ────────────────────────────────────────────────\n\n/**\n * Walk a CDDL-validated item tree and, for every plain (not already\n * annotated) `CborUint`/`CborNint` used as a `CborMap` key — or as a map\n * *value* whose own type is a closed `&(name: value)` choice of named\n * integer constants (see `eRefValueFor()`'s own doc) — replace that node\n * in place with the corresponding `CborERefUint`/`CborERefNint` — so\n * `toCDN()` naturally emits `e'name'` notation (and, for a key, `toJS()`\n * naturally uses `name` as the plain-object key — both by default;\n * `appPrefix: false` / `eRefKeys: false` opt back out), without the caller\n * having to spell `e'...'` in the original CBOR/CDN/JS source at all.\n *\n * Position-aware, exactly like `FromJSOptions.eRefKeys`'s own reverse\n * direction (`cddl/eRefScope.ts`): starting from the schema's root rule (or\n * `ruleName`, matching `ValidateOptions.rule` — the same rule the item was\n * actually validated against), a key is only annotated with a name bound at\n * a member-key position within the CDDL type actually reachable at *that*\n * key's own structural position, descending through nested maps the same\n * way this walk itself does — never a name that merely exists *somewhere*\n * in the schema. This is deliberate, not merely cosmetic: a name that\n * exists elsewhere in the schema but isn't reachable from this position is\n * exactly the kind of name `fromJS()`'s `eRefKeys` option (correctly)\n * refuses to convert back, so annotating with it here would make\n * `toJS()` → `fromJS()` silently turn the original integer key into a\n * *different*, wrong one (a plain text key, if the name isn't reachable at\n * all) instead of round-tripping it byte-for-byte. A name reachable at this\n * position also always satisfies `resolvesGloballyTo()` — the same\n * schema-wide-uniqueness check `fromJS()` applies before labeling — so\n * `e'name'` here always parses back to the same value via `fromCDN()`\n * against the same schema too. A value's own label doesn't carry this same\n * round-trip risk at all (see `eRefValueFor()`'s own doc for why), but is\n * still gated by `resolvesGloballyTo()` for the CDN-reparse property alone.\n *\n * Data-aware, too: a key takes a name only from the group entry that\n * actually consumed it in validation — read back from the validator's own\n * map matching (`traceMapGroup()`), so value types, occurrence limits,\n * entries already consumed and sub-group backtracking all count exactly as\n * they did there — and nested content is only\n * resolved against the value types that really matched. `ruleOrOptions`\n * takes the same `ValidateOptions` validation used (`rule`, `features`, …)\n * so those checks agree with it.\n *\n * Only descends through `CborArray`/`CborMap`/`CborTag` — the structural\n * containers a CDDL-validated data model is built from — plus embedded\n * CBOR: an array element or map value whose type is `bstr .cbor T` (or\n * `.cborseq`) — e.g. COSE's `protected: bstr .cbor header_map` — is\n * replaced by a `<<…>>` `CborEmbeddedCBOR` of its decoded content (only\n * when that re-encodes to exactly the same bytes, so `toCBOR()`/`toJS()`\n * are unchanged), and it, or a `<<…>>` already in CDN source, is annotated\n * against `T` in turn (see `expandEmbedded()`/`walkEmbedded()`). Other node\n * types (e.g. an indefinite-length string chunk) are left untouched, and\n * their contents are not searched for map keys of their own. A map key is itself\n * walked too (after any replacement of its own) — CBOR permits a map or\n * array as a key, and an integer key nested inside *that* still needs\n * annotating, e.g. `{{-1: \"a\"}: \"b\"}` — but never with a *positional*\n * scope, the same way `fromJS()`'s own reverse direction never resolves\n * `eRefKeys` names for a map key either (only this module's Scope note\n * applies: a key reached this way simply gets no eRefKeys-eligible names of\n * its own).\n *\n * `decodeOptions` are the caller's own decode-time extension settings\n * (`extensions`/`builtinExtensions`, as given to `fromCBOR()`/`fromCDN()`/\n * …), forwarded to the decode of embedded content — like tag 24's own\n * (`extensions/cbordata.ts`) — so e.g. a bundled extension disabled via\n * `builtinExtensions: false` stays disabled inside `<<…>>` too. Any other\n * field is ignored; the inner decode is always strict, and content that\n * doesn't decode that way is simply left as its bytes.\n *\n * Mutates `item` (and its descendants) in place; call only on a tree the\n * caller exclusively owns and has not yet handed to anyone else — this is\n * exactly the state a freshly decoded/parsed/constructed item is in right\n * after CDDL validation succeeds, which is the only place this is called\n * from (see `cbor.ts`'s `assertCddl()`).\n */\nexport function annotateERefKeys(\n item: CborItem,\n schema: CddlSchema,\n ruleOrOptions?: string | ValidateOptions,\n decodeOptions?: Pick<FromCBOROptions, 'extensions' | 'builtinExtensions'>\n): void {\n const options =\n typeof ruleOrOptions === 'string' ? { rule: ruleOrOptions } : ruleOrOptions;\n const ruleName = options?.rule ?? schema.root?.name;\n const candidates = ruleName\n ? [{ type: ruleRefType(ruleName), env: undefined }]\n : undefined;\n walkAnnotate(\n item,\n {\n schema,\n options,\n decodeOptions: {\n extensions: decodeOptions?.extensions,\n builtinExtensions: decodeOptions?.builtinExtensions,\n },\n seen: new WeakSet(),\n },\n candidates,\n resolveRootPosition(schema, options?.rule)\n );\n}\n\ninterface AnnotateContext {\n readonly schema: CddlSchema;\n readonly options: ValidateOptions | undefined;\n /** Forwarded to each embedded-content decode (see `annotateERefKeys()`). */\n readonly decodeOptions: FromCBOROptions;\n readonly seen: WeakSet<CborItem>;\n}\n\n/**\n * The types that may have governed one node during validation — the real\n * one is always among them — or `undefined` when that isn't known (the\n * node gets no names at all).\n */\ntype Candidates = readonly { readonly type: CddlType; readonly env: CddlEnv }[];\n\n/**\n * `candidates` drive annotation itself: a map's own entries take names only\n * from the validator's actual assignment (`traceMapEntries()`). `jsPos` is\n * the (never larger) position `fromJS()` is guaranteed to reach for the\n * same node when converting this tree's own `toJS()` output back — it has\n * no data to check and resolves a JS *string* key strictly, without the\n * declaration-order relaxation (see `cddl/eRefScope.ts`'s module doc). A\n * key's label is only offered to `toJS()` as a property name (`jsKey`) when\n * `jsPos` alone would convert that name back to the same integer.\n */\nfunction walkAnnotate(\n item: CborItem,\n ctx: AnnotateContext,\n candidates: Candidates | undefined,\n jsPos: ERefPosition\n): CborItem | undefined {\n if (ctx.seen.has(item)) return undefined;\n ctx.seen.add(item);\n const { schema } = ctx;\n if (item instanceof CborMap) {\n const traced = candidates\n ? traceMapEntries(ctx, item, candidates)\n : undefined;\n const jsScope = jsPos.map;\n const jsNames = jsScope\n ? scopeNameToValue(schema, jsScope, false)\n : undefined;\n item.entries.forEach((entry, i) => {\n const [key, value] = entry;\n const members = traced?.owners.map((o) => o[i]);\n const owners =\n members && members.every((m) => m !== false)\n ? (members as MapMember[])\n : undefined;\n const keyValue =\n key instanceof CborUint || key instanceof CborNint\n ? key.value\n : undefined;\n const name =\n owners && keyValue !== undefined\n ? agreedName(schema, owners, keyValue, traced!.plainNames)\n : undefined;\n const keyReplacement = eRefKeyFor(key, schema, name, jsNames);\n if (keyReplacement) entry[0] = keyReplacement;\n if (owners && owners.every((o) => o.env === undefined)) {\n const valueReplacement = eRefValueFor(\n value,\n schema,\n mergeTypes(owners.map((o) => o.type))\n );\n if (valueReplacement) entry[1] = valueReplacement;\n }\n const jsIdentifier = jsIdentifierOf(entry[0]);\n const jsNested =\n jsScope && jsIdentifier !== undefined\n ? resolveNestedPosition(schema, jsScope, jsIdentifier, false)\n : NO_POSITION;\n walkAnnotate(entry[0], ctx, undefined, NO_POSITION);\n const expanded = walkAnnotate(\n entry[1],\n ctx,\n owners?.map((o) => ({ type: o.type, env: o.env })),\n jsNested\n );\n if (expanded) entry[1] = expanded;\n });\n return undefined;\n }\n if (item instanceof CborArray) {\n // Elements are positioned by index against a fixed-shape array type\n // (see `ERefArrayScope`) — for annotation, only the alternatives the\n // data actually satisfies; for `jsPos`, by length alone, the same way\n // `fromJS()` itself positions them.\n const { items } = item;\n const length = items.length;\n const alternatives = candidates\n ? arrayAlternatives(ctx, candidates, items)\n : undefined;\n items.forEach((child, i) => {\n const expanded = walkAnnotate(\n child,\n ctx,\n alternatives?.map((alt) => ({ type: alt[i]!, env: undefined })),\n jsPos.array\n ? resolveElementPosition(schema, jsPos.array, i, length)\n : NO_POSITION\n );\n if (expanded) items[i] = expanded;\n });\n return undefined;\n }\n if (item instanceof CborTag) {\n walkAnnotate(\n item.content,\n ctx,\n candidates ? tagContentTypes(ctx, item, candidates) : undefined,\n NO_POSITION\n );\n return undefined;\n }\n if (item instanceof CborEmbeddedCBOR) {\n if (candidates)\n walkEmbedded(item, ctx, embeddedTypes(ctx, item, candidates));\n return undefined;\n }\n // Only a plain byte string — never an extension's own subclass (`ip'…'`,\n // …), which already renders its bytes some more specific way.\n if (candidates && Object.getPrototypeOf(item) === CborByteString.prototype)\n return expandEmbedded(item as CborByteString, ctx, candidates);\n return undefined;\n}\n\n/**\n * The content types of every `#6.N(T)` alternative among `candidates` that\n * `tag` actually matches (tag number included) — so a tag-wrapped schema\n * like `COSE_Sign1_Tagged = #6.18(COSE_Sign1)` still names keys inside it.\n * `undefined` when some *other* kind of alternative (`any`, a control\n * operator, …) accepts `tag` too, since the content's type is then unknown.\n */\nfunction tagContentTypes(\n ctx: AnnotateContext,\n tag: CborTag,\n candidates: Candidates\n): Candidates | undefined {\n const contents: { type: CddlType; env: undefined }[] = [];\n for (const c of candidates) {\n if (c.env !== undefined) return undefined;\n const alts = typeAlternatives(ctx.schema, c.type);\n if (!alts) return undefined;\n for (const t1 of alts) {\n const matches = itemMatchesType(\n ctx.schema,\n tag,\n { kind: 'type', start: t1.start, end: t1.end, alternatives: [t1] },\n ctx.options\n );\n if (matches === false) continue;\n if (t1.op || t1.target.kind !== 'tagged') return undefined;\n contents.push({ type: t1.target.item, env: undefined });\n }\n }\n return contents.length > 0 ? contents : undefined;\n}\n\n/**\n * What a byte string (or `<<…>>`) validated against one of `candidates`\n * holds, when that's `.cbor`/`.cborseq`-typed: `controllers` are the\n * controller types of every such alternative `item` actually satisfies —\n * all of one kind (`seq`) — and `exclusive` says no *other* alternative\n * (a plain `bstr`, …) accepts `item` too, i.e. the content's own type is\n * really among `controllers`, so names may be taken from them. `undefined`\n * when no `.cbor`/`.cborseq` alternative matches, both kinds do, or the\n * candidates can't be expanded (see `typeAlternatives()`).\n */\ninterface EmbeddedTypes {\n readonly controllers: Candidates;\n readonly seq: boolean;\n readonly exclusive: boolean;\n}\n\nfunction embeddedTypes(\n ctx: AnnotateContext,\n item: CborItem,\n candidates: Candidates\n): EmbeddedTypes | undefined {\n const alternatives: CddlType1[] = [];\n for (const c of candidates) {\n if (c.env !== undefined) return undefined;\n const alts = typeAlternatives(ctx.schema, c.type);\n if (!alts) return undefined;\n alternatives.push(...alts);\n }\n const controllers: { type: CddlType; env: undefined }[] = [];\n const kinds = new Set<boolean>();\n let exclusive = true;\n for (const t1 of alternatives) {\n const matches = itemMatchesType(\n ctx.schema,\n item,\n { kind: 'type', start: t1.start, end: t1.end, alternatives: [t1] },\n ctx.options\n );\n if (matches === false) continue;\n const ctl = t1.op?.kind === 'ctl' ? t1.op.name : undefined;\n if (matches && (ctl === 'cbor' || ctl === 'cborseq') && t1.controller) {\n kinds.add(ctl === 'cborseq');\n const c = t1.controller;\n controllers.push({\n type: {\n kind: 'type',\n start: c.start,\n end: c.end,\n alternatives: [\n { kind: 'type1', start: c.start, end: c.end, target: c },\n ],\n },\n env: undefined,\n });\n } else {\n exclusive = false;\n }\n }\n if (controllers.length === 0 || kinds.size !== 1) return undefined;\n return { controllers, seq: kinds.has(true), exclusive };\n}\n\n/**\n * `bytes` as a `<<…>>` node when its type says it holds encoded CBOR\n * (`bstr .cbor T`/`.cborseq T`) — so `toCDN()` shows the decoded content\n * instead of opaque `h'…'`, annotated in turn (`walkEmbedded()`). Kept as\n * given unless the decoded items re-encode to exactly the same bytes, so\n * the replacement never changes `toCBOR()`. Like tag 24's own `<<…>>`\n * (`extensions/cbordata.ts`), the decoded items' byte offsets are relative\n * to the byte string's own content.\n */\nfunction expandEmbedded(\n bytes: CborByteString,\n ctx: AnnotateContext,\n candidates: Candidates\n): CborEmbeddedCBOR | undefined {\n const types = embeddedTypes(ctx, bytes, candidates);\n if (!types) return undefined;\n let items: CborItem[];\n try {\n items = types.seq\n ? decodeSequence(bytes.value, ctx.decodeOptions)\n : [decodeCBOR(bytes.value, ctx.decodeOptions)];\n } catch {\n return undefined;\n }\n const node = new CborEmbeddedCBOR(items, {\n encodingWidth: bytes.encodingWidth,\n });\n if (!sameBytes(node.toCBOR(), bytes.toCBOR())) return undefined;\n node.start = bytes.start;\n node.end = bytes.end;\n node.comments = bytes.comments;\n node.blankLineBefore = bytes.blankLineBefore;\n walkEmbedded(node, ctx, types);\n return node;\n}\n\n/**\n * Annotate a `<<…>>` node's own items against its content types — only\n * when those are known exactly (`EmbeddedTypes.exclusive`); otherwise its\n * items are left entirely as given, including any explicit `e'…'` labels.\n */\nfunction walkEmbedded(\n node: CborEmbeddedCBOR,\n ctx: AnnotateContext,\n types: EmbeddedTypes | undefined\n): void {\n if (!types?.exclusive) return;\n const { items } = node;\n if (!types.seq) {\n if (items.length !== 1) return;\n const expanded = walkAnnotate(\n items[0]!,\n ctx,\n types.controllers,\n NO_POSITION\n );\n if (expanded) items[0] = expanded;\n return;\n }\n const alternatives = arrayAlternatives(ctx, types.controllers, items);\n if (!alternatives) return;\n items.forEach((child, i) => {\n const expanded = walkAnnotate(\n child,\n ctx,\n alternatives.map((alt) => ({ type: alt[i]!, env: undefined })),\n NO_POSITION\n );\n if (expanded) items[i] = expanded;\n });\n}\n\n/** Every item of a CBOR Sequence (RFC 8742), decoded strictly. */\nfunction decodeSequence(\n bytes: Uint8Array,\n options: FromCBOROptions\n): CborItem[] {\n const items: CborItem[] = [];\n let offset = 0;\n while (offset < bytes.length) {\n const item = decodeCBOR(bytes, { ...options, offset, allowTrailing: true });\n items.push(item);\n offset = item.end!;\n }\n return items;\n}\n\nfunction sameBytes(a: Uint8Array, b: Uint8Array): boolean {\n return a.length === b.length && a.every((byte, i) => byte === b[i]);\n}\n\n/**\n * The validator's own assignment of `map`'s entries, for every map group\n * any candidate type denotes that `map` actually matches (`traceMapGroup()`\n * — exactly `matchMapGroup()`, so occurrence limits, entries already\n * consumed, sub-group backtracking, cuts and value types all behave as in\n * validation). `undefined` when that can't be pinned down: a candidate\n * could match a map some way that has no such assignment (`any`, a control\n * operator, …), the budget runs out, or no group matches.\n */\nfunction traceMapEntries(\n ctx: AnnotateContext,\n map: CborMap,\n candidates: Candidates\n):\n | {\n owners: (readonly (MapMember | false)[])[];\n plainNames: ReadonlySet<string>;\n }\n | undefined {\n const groups: MapGroupTarget[] = [];\n for (const c of candidates) {\n const found = mapGroupsOfType(ctx.schema, c.type, c.env);\n if (!found) return undefined;\n groups.push(...found);\n }\n const owners: (readonly (MapMember | false)[])[] = [];\n for (const g of groups) {\n const t = traceMapGroup(ctx.schema, map, g, ctx.options);\n if (t === undefined) return undefined;\n if (t) owners.push(t);\n }\n if (owners.length === 0) return undefined;\n const plainNames = new Set<string>();\n for (const g of groups) {\n const names = plainTextMemberKeys(ctx.schema, g);\n if (!names) return undefined;\n for (const n of names) plainNames.add(n);\n }\n return { owners, plainNames };\n}\n\n/**\n * The one e-ref name every consuming member gives key `keyValue` — none\n * when they disagree, any names none, or the spelling is also a plain text\n * key in this map (see `plainTextMemberKeys()`).\n */\nfunction agreedName(\n schema: CddlSchema,\n owners: readonly MapMember[],\n keyValue: bigint,\n plainNames: ReadonlySet<string>\n): string | undefined {\n const names = new Set(\n owners.map((o) =>\n memberKeyName(schema, o.memberKey, keyValue, (n) => !!o.env?.has(n))\n )\n );\n const [name] = names;\n return names.size === 1 && name !== undefined && !plainNames.has(name)\n ? name\n : undefined;\n}\n\n/**\n * The fixed-shape array alternatives the candidates denote that `items`\n * actually satisfy, or `undefined` when that isn't known (a generic\n * binding in force, or a shape `arrayScopeOfType()` can't pin down).\n */\nfunction arrayAlternatives(\n ctx: AnnotateContext,\n candidates: Candidates,\n items: readonly CborItem[]\n): readonly (readonly CddlType[])[] | undefined {\n const elementTypes: (readonly CddlType[])[] = [];\n for (const c of candidates) {\n if (c.env !== undefined) return undefined;\n const scope = arrayScopeOfType(ctx.schema, c.type);\n if (!scope) return undefined;\n elementTypes.push(...scope.elementTypes);\n }\n return matchingArrayAlternatives(\n ctx.schema,\n { elementTypes },\n items,\n ctx.options\n ).elementTypes;\n}\n\n/**\n * How `fromJS()` will identify `key` when converting this map's own\n * `toJS()` output back: by name for a text key or a label `toJS()` offers\n * as a property name (`jsKey`), by integer value for any other integer key\n * (`toJS()` emits it as a number, in a `MapEntries`). `undefined` for any\n * other key.\n */\nfunction jsIdentifierOf(key: CborItem): string | bigint | undefined {\n if ((key instanceof CborERefUint || key instanceof CborERefNint) && key.jsKey)\n return key.refName;\n if (key instanceof CborTextString) return key.value;\n if (key instanceof CborUint || key instanceof CborNint) return key.value;\n return undefined;\n}\n\n/**\n * The replacement key node for `key`, or `undefined` to leave it exactly as\n * given. `name` is what the member that actually consumed this entry names\n * it (`traceMapGroup()`), if\n * anything named it. Two directions:\n *\n * - A plain `CborUint`/`CborNint`: labeled `e'name'` when `name` is set\n * *and* also satisfies `resolvesGloballyTo()` (so the label parses back to\n * the same value via `fromCDN()` against this same schema too).\n * - An *already*-labeled `CborERefUint`/`CborERefNint` — only ever produced\n * by `e'name'` written explicitly in CDN source, resolved via\n * `createERefExtension()`'s flat, schema-wide `byName` table at *parse*\n * time, entirely independent of structural position. Kept only when the\n * entry that actually claimed it carries that same name; otherwise the\n * label describes a group entry the data didn't match, so it's\n * downgraded to a plain, unlabeled key (never re-derived as a\n * *different* label of our own).\n *\n * Either way, a kept label's `jsKey` records whether `fromJS()` would\n * convert the name back at this position (`jsNames`), so `toJS()` only\n * uses it as a property name when that round trip holds.\n */\nfunction eRefKeyFor(\n key: CborItem,\n schema: CddlSchema,\n name: string | undefined,\n jsNames: ReadonlyMap<string, bigint> | undefined\n): CborItem | undefined {\n let node: CborItem;\n if (key instanceof CborERefUint || key instanceof CborERefNint) {\n if (name === key.refName) {\n const jsKey = jsNames?.get(key.refName) === key.value;\n if (key.jsKey === jsKey) return undefined;\n node = eRefNode(key.value, key.refName, key, jsKey);\n } else {\n node =\n key instanceof CborERefUint\n ? new CborUint(key.value, {\n encodingWidth: key.encodingWidth,\n ednSource: key.ednSource,\n })\n : new CborNint(key.value, {\n encodingWidth: key.encodingWidth,\n ednSource: key.ednSource,\n });\n }\n } else {\n let value: bigint;\n if (key instanceof CborUint) value = key.value;\n else if (key instanceof CborNint) value = key.value;\n else return undefined;\n if (name === undefined || !resolvesGloballyTo(schema, name, value))\n return undefined;\n node = eRefNode(\n value,\n name,\n key as CborUint | CborNint,\n jsNames?.get(name) === value\n );\n }\n node.start = key.start;\n node.end = key.end;\n node.comments = key.comments;\n node.blankLineBefore = key.blankLineBefore;\n return node;\n}\n\n/** A labeled integer node carrying `from`'s own encoding details. */\nfunction eRefNode(\n value: bigint,\n name: string,\n from: CborUint | CborNint,\n jsKey?: boolean\n): CborERefUint | CborERefNint {\n const options = {\n encodingWidth: from.encodingWidth,\n ednSource: from.ednSource,\n jsKey,\n };\n return value >= 0n\n ? new CborERefUint(value, name, options)\n : new CborERefNint(value, name, options);\n}\n\n/**\n * The replacement node for `value` — the current entry's own value, whose\n * consuming members' value types are `valueType` (see `traceMapGroup()`) —\n * or `undefined` to leave it exactly as given. Unlike `eRefKeyFor()`, only\n * one direction: a plain `CborUint`/`CborNint` is labeled `e'name2'` when\n * `valueType` (e.g. `&(AES-CCM-16-64-128: 10, …)` from `? &(gp_enc_alg: -4)\n * => …`) names this exact value (`enumNameOfType()`), and that name also\n * satisfies `resolvesGloballyTo()` (so the label parses back to the same\n * value via `fromCDN()` against this same schema too).\n *\n * An *already*-labeled value (from `e'...'` written explicitly in CDN\n * source) is left untouched, never downgraded the way an unreachable *key*\n * label is: a value's own label never changes what `toJS()` produces for\n * it (`CborERefUint`/`CborERefNint` only override `_jsObjectKey()`, used\n * for a *key*'s own JS property name — a value converts through the\n * ordinary, unlabeled `CborUint`/`CborNint` numeric path regardless), so\n * there's no `toJS()` → `fromJS()` round-trip this label could corrupt —\n * `parseAppString()` already guarantees it's globally unambiguous, which is\n * the only safety property that matters for a value's own label.\n */\nfunction eRefValueFor(\n value: CborItem,\n schema: CddlSchema,\n valueType: CddlType\n): CborItem | undefined {\n if (value instanceof CborERefUint || value instanceof CborERefNint)\n return undefined;\n let v: bigint;\n if (value instanceof CborUint) v = value.value;\n else if (value instanceof CborNint) v = value.value;\n else return undefined;\n const refName = enumNameOfType(schema, valueType, v);\n if (refName === undefined || !resolvesGloballyTo(schema, refName, v))\n return undefined;\n const node = eRefNode(v, refName, value as CborUint | CborNint);\n node.start = value.start;\n node.end = value.end;\n node.comments = value.comments;\n node.blankLineBefore = value.blankLineBefore;\n return node;\n}\n","import type { FromJSOptions } from '../types';\nimport { CBOR_OMIT } from '../types';\nimport type { CborItem } from '../ast/CborItem';\nimport type { CborExtension } from '../extensions/types';\nimport { resolveBuiltinExtensions } from '../extensions/builtins';\nimport { CborUint } from '../ast/CborUint';\nimport { CborNint } from '../ast/CborNint';\nimport { CborBigUint, CborBigNint } from '../ast/CborBignum';\nimport { CborByteString } from '../ast/CborByteString';\nimport { CborTextString } from '../ast/CborTextString';\nimport { CborArray } from '../ast/CborArray';\nimport { CborMap } from '../ast/CborMap';\nimport { CborFloat } from '../ast/CborFloat';\nimport { CborSimple } from '../ast/CborSimple';\nimport { CborTag } from '../ast/CborTag';\nimport { Tag } from '../tag';\nimport { Simple } from '../simple';\nimport { MapEntries } from '../mapEntries';\nimport { CborERefUint, CborERefNint } from '../extensions/eref';\nimport {\n resolveElementPosition,\n resolveNestedPosition,\n resolveRootPosition,\n scopeNameToValue,\n resolvesGloballyTo,\n type ERefPosition,\n} from '../cddl/eRefScope';\nimport type { CddlSchema } from '../cddl/schema';\n\n/**\n * `schema` plus the CDDL type currently governing this position in the JS\n * value tree — see `cddl/eRefScope.ts`'s own module doc for why this is\n * position-aware rather than a single flat, whole-schema table the way\n * `toJS()`'s own `ERefTables` is. `undefined` means \"no eRefKeys context\n * here\" — either `eRefKeys` is off, there's no schema, or this position\n * (or an ancestor of it) couldn't be resolved to a map or fixed-shape array\n * type at all.\n */\ninterface ActiveERefScope {\n readonly schema: CddlSchema;\n readonly pos: ERefPosition;\n}\n\nfunction activeScope(\n schema: CddlSchema,\n pos: ERefPosition\n): ActiveERefScope | undefined {\n return pos.map || pos.array ? { schema, pos } : undefined;\n}\n\n/**\n * Extension hooks used by _fromJS, pre-filtered so the per-node loops touch\n * only extensions that actually implement each hook.\n */\ninterface ResolvedExtensions {\n /** Extensions with a fromJS hook (user extensions first). */\n fromJS: readonly CborExtension[];\n /** Extensions with a parseTag hook (user extensions first). */\n parseTag: readonly CborExtension[];\n}\n\n/**\n * Default resolved builtins (no `builtinExtensions` override) pre-filtered\n * per hook, cached after first use. Lazy (not module-level) because\n * mapEntries.ts imports fromJS.ts, forming a cycle that leaves the builtins\n * module's exports undefined at module init time.\n */\nlet _defaultResolvedExts: ResolvedExtensions | undefined;\nfunction getBuiltinResolvedExts(\n builtinExtensions: CborExtension[] | false | undefined\n): ResolvedExtensions {\n if (builtinExtensions === undefined) {\n if (_defaultResolvedExts) return _defaultResolvedExts;\n const resolved = resolveBuiltinExtensions(undefined);\n return (_defaultResolvedExts = {\n fromJS: resolved.filter((ext) => ext.fromJS !== undefined),\n parseTag: resolved.filter((ext) => ext.parseTag !== undefined),\n });\n }\n const resolved = resolveBuiltinExtensions(builtinExtensions);\n return {\n fromJS: resolved.filter((ext) => ext.fromJS !== undefined),\n parseTag: resolved.filter((ext) => ext.parseTag !== undefined),\n };\n}\n\n/**\n * Build the hook lists once per fromJS() entry call — _fromJS recursion is\n * per-node, so rebuilding a spread extension array there is measurably slow.\n */\nfunction resolveExtensions(\n options: FromJSOptions | undefined\n): ResolvedExtensions {\n const user = options?.extensions;\n const builtin = getBuiltinResolvedExts(options?.builtinExtensions);\n if (!user?.length) return builtin;\n return {\n fromJS: [\n ...user.filter((ext) => ext.fromJS !== undefined),\n ...builtin.fromJS,\n ],\n parseTag: [\n ...user.filter((ext) => ext.parseTag !== undefined),\n ...builtin.parseTag,\n ],\n };\n}\n\n/**\n * Convert a plain JavaScript value to a CborItem AST node.\n *\n * Type dispatch order:\n * object with [Tag.symbol] symbol → CborTag (wraps the inner value)\n * null / undefined / boolean → CborSimple\n * bigint → CborUint / CborNint / CborBigUint / CborBigNint\n * number → CborFloat, or CborUint/CborNint if integerAs='int' (default)\n * string → CborTextString\n * Number / Boolean / String / BigInt object → unwrapped primitive (recurse)\n * Tag.Null / Tag.Undefined → CborSimple.NULL / UNDEFINED\n * ArrayBuffer / SharedArrayBuffer → CborByteString\n * ArrayBufferView (TypedArray, DataView, …) → CborByteString (Uint8Array respects uint8ArrayAs)\n * Array → CborArray (recursive)\n * Map → CborMap (keys also converted recursively)\n * plain object → CborMap (string keys → CborTextString)\n */\n/**\n * `schema` is an already-resolved (compiled, and — for string `cddl` —\n * cached) CDDL schema, supplied by `cbor.ts`'s `CBOR.fromJS()` when\n * `options.cddl` is set; this internal entry point never resolves `options.\n * cddl` itself (`cbor.ts` owns the compile-and-cache step, same as it does\n * for `fromCDN()`'s `e'...'` extension registration — see `resolveCddl()`\n * there). Only consulted when `schema` is defined at all (i.e. `options.\n * cddl` was set) — `options.eRefKeys` defaults to `true` and only an\n * explicit `false` turns this back off — see `FromJSOptions.eRefKeys`.\n * The scope this starts from is the schema's own root rule, or\n * `options.cddlValidationOptions.rule` when set — the same rule\n * `assertCddl()`'s own subsequent validation will actually check the\n * result against (see `cddl/eRefScope.ts`'s own module doc).\n */\nexport function fromJS(\n value: unknown,\n options?: FromJSOptions,\n schema?: CddlSchema\n): CborItem {\n if (options?.replacer) {\n const { replacer, ...rest } = options;\n const replaced = _applyReplacer(\n value,\n replacer,\n rest.extensions,\n rest.undefinedOmits,\n rest.builtinExtensions\n );\n if (replaced === CBOR_OMIT) return CborSimple.UNDEFINED;\n return fromJS(\n replaced,\n Object.keys(rest).length > 0 ? (rest as FromJSOptions) : undefined,\n schema\n );\n }\n const eRefScope: ActiveERefScope | undefined =\n options?.eRefKeys !== false && schema\n ? resolveActiveScope(schema, options?.cddlValidationOptions?.rule)\n : undefined;\n return _fromJS(value, options, true, resolveExtensions(options), eRefScope);\n}\n\n/**\n * Wrap `inner` in tag `tag` exactly as converting a JS value carrying that\n * tag would (`parseTag()` hooks first, so e.g. tag 1 becomes the `dt`\n * extension's `DT'…'` node) — used for tags a CDDL schema implies (see\n * `FromJSOptions.implicitTags`).\n */\nexport function tagFromJS(\n tag: bigint,\n inner: CborItem,\n options?: FromJSOptions\n): CborItem {\n for (const ext of resolveExtensions(options).parseTag) {\n const result = ext.parseTag!(tag, inner);\n if (result !== undefined) return result;\n }\n return new CborTag(tag, inner);\n}\n\nfunction resolveActiveScope(\n schema: CddlSchema,\n ruleName: string | undefined\n): ActiveERefScope | undefined {\n return activeScope(schema, resolveRootPosition(schema, ruleName));\n}\n\n/**\n * `respectDeclarationOrder` must be `false` whenever `key` is itself a JS\n * string that has not (and will not) also be converted to an integer key\n * this same way — a MapEntries/plain-object string key, preserved or left\n * as literal text — since a same-alternative wildcard whose own key type\n * matches text could equally have claimed that exact string, and resolving\n * the nested scope as if the *named* entry definitely matched instead would\n * make nested content convert inconsistently with the key that governs it\n * staying text. `true` is safe only when `key` was derived from an\n * *already-integer* wire/JS value (see `cddl/eRefScope.ts`'s own module doc\n * on why declaration order only disambiguates an already-typed value).\n */\nfunction nestActiveScope(\n ctx: ActiveERefScope,\n key: string | bigint,\n respectDeclarationOrder: boolean\n): ActiveERefScope | undefined {\n if (!ctx.pos.map) return undefined;\n return activeScope(\n ctx.schema,\n resolveNestedPosition(ctx.schema, ctx.pos.map, key, respectDeclarationOrder)\n );\n}\n\n/** The scope for element `index` of a JS array of `length` elements. */\nfunction elementActiveScope(\n ctx: ActiveERefScope | undefined,\n index: number,\n length: number\n): ActiveERefScope | undefined {\n if (!ctx?.pos.array) return undefined;\n return activeScope(\n ctx.schema,\n resolveElementPosition(ctx.schema, ctx.pos.array, index, length)\n );\n}\n\nfunction _fromJS(\n value: unknown,\n options: FromJSOptions | undefined,\n checkTag: boolean,\n exts: ResolvedExtensions,\n eRefScope: ActiveERefScope | undefined\n): CborItem {\n // ── Extension fromJS hooks ───────────────────────────────────────────────────\n for (const ext of exts.fromJS) {\n const result = ext.fromJS!(value, options ?? {});\n if (result !== undefined) return result;\n }\n\n // ── CBOR tag annotation (Symbol key) ────────────────────────────────────────\n // checkTag=false on the recursive call to skip this branch and convert the\n // inner value normally, avoiding infinite recursion.\n // After converting the inner value, try parseTag() hooks so that e.g.\n // dt / ip can produce their specialised subclasses without needing\n // a separate fromJS() hook on the extension.\n if (\n checkTag &&\n typeof value === 'object' &&\n value !== null &&\n Tag.symbol in (value as object)\n ) {\n const tag = (value as Record<symbol, bigint>)[Tag.symbol];\n const innerValue = _fromJS(value, options, false, exts, eRefScope);\n for (const ext of exts.parseTag) {\n const result = ext.parseTag!(tag, innerValue);\n if (result !== undefined) return result;\n }\n return new CborTag(tag, innerValue);\n }\n\n // ── Null wrapper (from CborTag.toJS() of tagged null) ───────────────────────\n // Must come AFTER the Tag.symbol check so that Tag.Null (which carries\n // a [Tag.symbol] symbol) is first wrapped in CborTag, then unwrapped as NULL\n // in the recursive checkTag=false call.\n if (value instanceof Tag.Null) return CborSimple.NULL;\n if (value instanceof Tag.Undefined) return CborSimple.UNDEFINED;\n if (value instanceof Simple) return new CborSimple(value.value);\n\n // ── Primitives ───────────────────────────────────────────────────────────────\n if (value === null) return CborSimple.NULL;\n if (value === undefined) return CborSimple.UNDEFINED;\n if (value === true) return CborSimple.TRUE;\n if (value === false) return CborSimple.FALSE;\n\n if (typeof value === 'bigint') {\n if (value > 0xffff_ffff_ffff_ffffn) return new CborBigUint(value);\n if (value < -(0xffff_ffff_ffff_ffffn + 1n)) return new CborBigNint(value);\n return value >= 0n ? new CborUint(value) : new CborNint(value);\n }\n\n if (typeof value === 'number') {\n const integerAs = options?.encodeIntegerAs ?? 'int';\n if (\n integerAs === 'int' &&\n Number.isInteger(value) &&\n !Object.is(value, -0)\n ) {\n if (value >= 0) return new CborUint(BigInt(value));\n return new CborNint(BigInt(value));\n }\n return new CborFloat(value);\n }\n\n if (typeof value === 'string') return new CborTextString(value);\n\n // ── Boxed primitives — unwrap and recurse ───────────────────────────────────\n // Same eRefScope: unwrapping a box doesn't change the schema position.\n if (value instanceof Number)\n return _fromJS(value.valueOf(), options, false, exts, eRefScope);\n if (value instanceof Boolean)\n return _fromJS(value.valueOf(), options, false, exts, eRefScope);\n if (value instanceof String)\n return _fromJS(value.valueOf(), options, false, exts, eRefScope);\n // Object(bigint) — detected via Object.prototype.toString\n if (Object.prototype.toString.call(value) === '[object BigInt]')\n return _fromJS(\n (value as { valueOf(): bigint }).valueOf(),\n options,\n false,\n exts,\n eRefScope\n );\n\n // ── ArrayBuffer / SharedArrayBuffer ─────────────────────────────────────────\n if (\n value instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' &&\n value instanceof SharedArrayBuffer)\n ) {\n return new CborByteString(new Uint8Array(value as ArrayBuffer));\n }\n\n // ── ArrayBufferView (TypedArray variants, DataView) ─────────────────────────\n if (ArrayBuffer.isView(value)) {\n if (value instanceof Uint8Array && options?.uint8ArrayAs === 'array') {\n return new CborArray(Array.from(value, (b) => new CborUint(BigInt(b))));\n }\n return new CborByteString(\n new Uint8Array(value.buffer, value.byteOffset, value.byteLength)\n );\n }\n\n if (value instanceof MapEntries) {\n // Keys are preserved exactly as given — MapEntries round-trips CBOR map\n // entries verbatim, unlike a plain object's own properties below, so a\n // key never gets an eRefScope (isn't looked up as a name at all) and\n // never converts to an e-ref key itself: a MapEntries key isn't\n // necessarily even a string `resolveNestedScope()` could match against,\n // and preserving entries *exactly* is the whole point of using\n // MapEntries over a plain object in the first place. The key still\n // identifies a nested scope for its own *value*, though: a string key\n // by spelling, an integer key by value — whether a schema name spells\n // it (`&(data: 1) => …`) or it's a bare literal key (`1: …`), matched\n // the same way `annotateERefKeys()` matches a decoded integer key — so\n // a map `toJS()` produced as MapEntries (see `annotateERefKeys()`'s own\n // doc) still lets that nested content convert back correctly.\n return new CborMap(\n [...value].map(([k, v]): [CborItem, CborItem] => {\n const isStringKey = typeof k === 'string';\n const name = isStringKey\n ? k\n : typeof k === 'bigint'\n ? k\n : typeof k === 'number' && Number.isInteger(k)\n ? BigInt(k)\n : undefined;\n // A string key is preserved verbatim (see the doc above) — never\n // converted to an integer the way a plain-object property is — so\n // nested descent from it must use the same strict,\n // non-declaration-order matching `fromJS()`'s own string-key\n // conversion does (see `nestActiveScope()`'s own doc), not the\n // relaxed one a genuinely already-integer key safely gets.\n const nestedScope =\n eRefScope && name !== undefined && v !== null && typeof v === 'object'\n ? nestActiveScope(eRefScope, name, !isStringKey)\n : undefined;\n return [\n _fromJS(k, options, true, exts, undefined),\n _fromJS(v, options, true, exts, nestedScope),\n ];\n })\n );\n }\n\n if (Array.isArray(value)) {\n // Elements are positioned by index against a fixed-shape array type —\n // the same way `annotateERefKeys()` walks a decoded array, so a\n // `toJS()` → `fromJS()` round trip converts back exactly the names it\n // labeled (see `cddl/eRefScope.ts`'s `ERefArrayScope`).\n return new CborArray(\n value.map((item, i) =>\n _fromJS(\n item,\n options,\n true,\n exts,\n elementActiveScope(eRefScope, i, value.length)\n )\n )\n );\n }\n\n if (typeof value === 'object') {\n const entries: [CborItem, CborItem][] = [];\n // `false`: a JS property name is always a string that could equally be\n // preserved as a literal text key by a same-alternative wildcard whose\n // own key type matches text — declaration order alone can't tell which\n // shape the author meant (see `cddl/eRefScope.ts`'s own module doc), so\n // this must use the strict, non-relaxed matching, unlike the annotation\n // direction's own `scopeNameToValue()` calls.\n const localNames = eRefScope?.pos.map\n ? scopeNameToValue(eRefScope.schema, eRefScope.pos.map, false)\n : undefined;\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n const keyItem =\n eRefKeyItemFor(k, localNames, eRefScope?.schema) ??\n new CborTextString(k);\n const nestedScope =\n eRefScope && v !== null && typeof v === 'object'\n ? nestActiveScope(eRefScope, k, false)\n : undefined;\n entries.push([keyItem, _fromJS(v, options, true, exts, nestedScope)]);\n }\n return new CborMap(entries);\n }\n\n throw new TypeError(`fromJS: unsupported value type: ${typeof value}`);\n}\n\n/**\n * `FromJSOptions.eRefKeys` support: resolve a plain object's own property\n * name to the integer key it names, via the *current position's own*\n * `scopeNameToValue()` result (see `cddl/eRefScope.ts`) — already\n * restricted to unambiguous, member-key-position names reachable from\n * this exact position, not the whole schema. Returns `undefined` (falling\n * through to the ordinary `CborTextString` key) for a name this scope\n * doesn't know, or when there's no scope in effect at all.\n *\n * The resulting key is only *labeled* `e'name'` (a `CborERefUint`/\n * `CborERefNint`) when `resolvesGloballyTo()` confirms `e'name'` would\n * resolve back to this exact value via `parseAppString()`'s own,\n * genuinely schema-wide table too — otherwise the position-local value is\n * still correct and still used, just as a plain, unlabeled integer (a\n * `CborUint`/`CborNint`), so it always round-trips through `fromCDN()`\n * against the same schema instead of risking `e'name'` notation that\n * fails to re-parse, or re-parses to a different value, there.\n */\nfunction eRefKeyItemFor(\n name: string,\n localNames: ReadonlyMap<string, bigint> | undefined,\n schema: CddlSchema | undefined\n): CborItem | undefined {\n const value = localNames?.get(name);\n if (value === undefined) return undefined;\n if (schema && resolvesGloballyTo(schema, name, value)) {\n return value >= 0n\n ? new CborERefUint(value, name)\n : new CborERefNint(value, name);\n }\n return value >= 0n ? new CborUint(value) : new CborNint(value);\n}\n\n// ─── Replacer helper ────────────────────────────────────────────────────────\n\ntype _FnReplacer = (this: unknown, key: unknown, value: unknown) => unknown;\ntype _Replacer = _FnReplacer | (string | number)[];\n\n/** True for values that _fromJS handles via a dedicated branch (not Object.entries). */\nfunction _isNativelyHandled(v: object): boolean {\n return (\n ArrayBuffer.isView(v) ||\n v instanceof ArrayBuffer ||\n (typeof SharedArrayBuffer !== 'undefined' &&\n v instanceof SharedArrayBuffer) ||\n v instanceof Number ||\n v instanceof Boolean ||\n v instanceof String ||\n Object.prototype.toString.call(v) === '[object BigInt]' ||\n v instanceof Tag.Null ||\n v instanceof Tag.Undefined ||\n v instanceof Simple\n );\n}\n\nexport function _applyReplacer(\n value: unknown,\n replacer: _Replacer,\n extensions?: readonly CborExtension[],\n undefinedOmits?: boolean,\n builtinExtensions?: CborExtension[] | false\n): unknown {\n // Only isJSType hooks are consulted below; filter once, not per node.\n const jsTypeExts: readonly CborExtension[] = [\n ...(extensions ?? []),\n ...resolveBuiltinExtensions(builtinExtensions),\n ].filter((ext) => ext.isJSType !== undefined);\n\n /** True when a replacer/reviver result should cause the entry to be dropped. */\n function _omits(v: unknown): boolean {\n return v === CBOR_OMIT || (undefinedOmits === true && v === undefined);\n }\n\n if (Array.isArray(replacer)) {\n const allowed = (replacer as (string | number)[]).map(String);\n function filterKeys(v: unknown): unknown {\n if (v === null || typeof v !== 'object') return v;\n if (v instanceof MapEntries)\n return MapEntries.from(\n v,\n ([k, val]) => [k, filterKeys(val)] as [unknown, unknown]\n );\n if (Array.isArray(v)) return v.map(filterKeys);\n // Tagged objects pass through so fromJS can encode the tag natively.\n if (Tag.symbol in (v as object)) return v;\n // Built-in types pass through so fromJS can handle them natively.\n if (_isNativelyHandled(v as object)) return v;\n // Extension-owned values pass through so fromJS can handle them natively.\n if (jsTypeExts.some((ext) => ext.isJSType!(v))) return v;\n // Plain objects only: honor toJSON() first (matches JSON.stringify semantics).\n const proto = Object.getPrototypeOf(v as object) as unknown;\n if (proto === Object.prototype || proto === null) {\n const toJSON = (v as Record<string, unknown>)['toJSON'];\n if (typeof toJSON === 'function')\n return filterKeys((toJSON as () => unknown).call(v));\n }\n const result: Record<string, unknown> = {};\n for (const k of allowed) {\n if (Object.prototype.hasOwnProperty.call(v, k))\n result[k] = filterKeys((v as Record<string, unknown>)[k]);\n }\n return result;\n }\n return filterKeys(value);\n }\n\n const fn = replacer as _FnReplacer;\n function applyFn(val: unknown, key: unknown, holder: unknown): unknown {\n // Call toJSON() only on plain objects (proto === Object.prototype or null).\n // Non-plain objects (Date, TypedArray, extension-backed classes…) pass\n // through so fromJS extensions can handle them; MapEntries is also skipped\n // so its integer keys and structure are preserved for CBOR encoding.\n if (\n val !== null &&\n typeof val === 'object' &&\n !(val instanceof MapEntries)\n ) {\n const proto = Object.getPrototypeOf(val as object) as unknown;\n if (proto === Object.prototype || proto === null) {\n const toJSON = (val as Record<string, unknown>)['toJSON'];\n if (typeof toJSON === 'function')\n val = (toJSON as (k: unknown) => unknown).call(val, key);\n }\n }\n val = fn.call(holder, key, val);\n if (val !== null && typeof val === 'object') {\n // Tagged objects pass through so fromJS can encode the tag natively.\n if (Tag.symbol in (val as object)) return val;\n if (val instanceof MapEntries) {\n const result = new MapEntries();\n for (const [k, v] of val) {\n const newV = applyFn(v, k, val);\n if (!_omits(newV)) result.push([k, newV]);\n }\n return result;\n }\n if (Array.isArray(val)) {\n return (val as unknown[]).map((v, i) => {\n const child = applyFn(v, String(i), val);\n // CBOR.OMIT / undefined-omits in arrays → null (matches JSON.stringify).\n return _omits(child) ? null : child;\n });\n }\n // Built-in types pass through to fromJS unchanged.\n if (_isNativelyHandled(val as object)) return val;\n // Extension-owned values pass through so fromJS can handle them natively.\n if (jsTypeExts.some((ext) => ext.isJSType!(val))) return val;\n const result: Record<string, unknown> = {};\n for (const k of Object.keys(val as object)) {\n const child = applyFn((val as Record<string, unknown>)[k], k, val);\n if (!_omits(child)) result[k] = child;\n }\n return result;\n }\n return val;\n }\n return applyFn(value, '', { '': value });\n}\n","import { fromJS } from './js/fromJS';\n\nexport class MapEntries extends Array<[unknown, unknown]> {\n toJSON(): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [k, v] of this) {\n const key = typeof k === 'string' ? k : fromJS(k).toCDN();\n if (key === '__proto__') {\n Object.defineProperty(result, key, {\n value: v,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n } else {\n result[key] = v;\n }\n }\n return result;\n }\n}\n"],"mappings":"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"}
|