@cosyte/synth 0.0.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/README.md +21 -12
  3. package/dist/astm/index.cjs +18 -6
  4. package/dist/astm/index.cjs.map +1 -1
  5. package/dist/astm/index.d.cts +2 -2
  6. package/dist/astm/index.d.ts +2 -2
  7. package/dist/astm/index.mjs +18 -6
  8. package/dist/astm/index.mjs.map +1 -1
  9. package/dist/ccda/index.cjs +23 -7
  10. package/dist/ccda/index.cjs.map +1 -1
  11. package/dist/ccda/index.d.cts +2 -2
  12. package/dist/ccda/index.d.ts +2 -2
  13. package/dist/ccda/index.mjs +23 -7
  14. package/dist/ccda/index.mjs.map +1 -1
  15. package/dist/deid/index.cjs +26 -8
  16. package/dist/deid/index.cjs.map +1 -1
  17. package/dist/deid/index.d.cts +2 -2
  18. package/dist/deid/index.d.ts +2 -2
  19. package/dist/deid/index.mjs +26 -8
  20. package/dist/deid/index.mjs.map +1 -1
  21. package/dist/fhir/index.cjs +174 -7
  22. package/dist/fhir/index.cjs.map +1 -1
  23. package/dist/fhir/index.d.cts +163 -2
  24. package/dist/fhir/index.d.ts +163 -2
  25. package/dist/fhir/index.mjs +171 -9
  26. package/dist/fhir/index.mjs.map +1 -1
  27. package/dist/hl7/index.cjs +18 -6
  28. package/dist/hl7/index.cjs.map +1 -1
  29. package/dist/hl7/index.d.cts +2 -2
  30. package/dist/hl7/index.d.ts +2 -2
  31. package/dist/hl7/index.mjs +18 -6
  32. package/dist/hl7/index.mjs.map +1 -1
  33. package/dist/index.cjs +37 -6
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +172 -38
  36. package/dist/index.d.ts +172 -38
  37. package/dist/index.mjs +36 -7
  38. package/dist/index.mjs.map +1 -1
  39. package/dist/ncpdp/index.cjs +18 -6
  40. package/dist/ncpdp/index.cjs.map +1 -1
  41. package/dist/ncpdp/index.d.cts +1 -1
  42. package/dist/ncpdp/index.d.ts +1 -1
  43. package/dist/ncpdp/index.mjs +18 -6
  44. package/dist/ncpdp/index.mjs.map +1 -1
  45. package/dist/{providers-B9uVinAe.d.cts → providers-BQtPk3PN.d.cts} +18 -4
  46. package/dist/{providers-B9uVinAe.d.ts → providers-BQtPk3PN.d.ts} +18 -4
  47. package/dist/{quirk-HZdznAkM.d.ts → quirk-Bzx9g8KG.d.ts} +1 -1
  48. package/dist/{quirk-IaHp4z7N.d.cts → quirk-C_lZrspq.d.cts} +1 -1
  49. package/dist/x12/index.cjs +18 -6
  50. package/dist/x12/index.cjs.map +1 -1
  51. package/dist/x12/index.d.cts +1 -1
  52. package/dist/x12/index.d.ts +1 -1
  53. package/dist/x12/index.mjs +18 -6
  54. package/dist/x12/index.mjs.map +1 -1
  55. package/package.json +54 -30
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/rng/splitmix32.ts","../../src/rng/sfc32.ts","../../src/codes.ts","../../src/rng/rng.ts","../../src/corpus.ts","../../src/safe/reserved.ts","../../src/safe/names-pool.ts","../../src/safe/providers.ts","../../src/safe/index.ts","../../src/astm/identity.ts","../../src/astm/example-codes.ts","../../src/astm/message.ts","../../src/astm/round-trip.ts","../../src/select.ts","../../src/profile.ts","../../src/quirk.ts","../../src/astm/quirk.ts","../../src/astm/index.ts"],"names":["buildAstmMessage","composeAstmFrames","parseAstmRecords","serializeAstmRecords","parseFramedAstm","serializeFramedAstm","name","astmProfiles"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * `splitmix32`: a tiny, well-studied 32-bit mixing PRNG used **only** to expand a single integer\n * seed into the four 32-bit state words that seed {@link ../rng/sfc32.sfc32}. It is not the corpus\n * generator itself (that is `sfc32`); it exists so that a one-number seed deterministically produces a\n * well-distributed 128-bit `sfc32` state, avoiding the poor low-bit behavior of naive\n * `state = seed`-style initialization.\n *\n * Zero-dependency, `Math.random`-free (lint-enforced): the whole point of the library is that a seed,\n * and only the seed, determines the output, on any machine, any run.\n *\n * @module\n */\n\n/**\n * A stateful `splitmix32` step function. Each call advances the internal 32-bit state and returns the\n * next unsigned 32-bit integer. Deterministic for a given seed.\n *\n * @param seed - The 32-bit seed. Coerced to a 32-bit integer via `| 0`.\n * @returns A nullary function returning the next `uint32` in the stream.\n * @example\n * ```ts\n * import { splitmix32 } from \"@cosyte/synth\";\n * const next = splitmix32(12345);\n * const a = next(); // deterministic uint32\n * ```\n */\nexport function splitmix32(seed: number): () => number {\n let a = seed | 0;\n return function next(): number {\n a = (a + 0x9e3779b9) | 0;\n let t = a ^ (a >>> 16);\n t = Math.imul(t, 0x21f0aaad);\n t = t ^ (t >>> 15);\n t = Math.imul(t, 0x735a2d97);\n t = t ^ (t >>> 15);\n return t >>> 0;\n };\n}\n","/**\n * `sfc32` (Small Fast Counter, 32-bit, 128-bit state): the deterministic, non-cryptographic PRNG that\n * drives every value `@cosyte/synth` generates. Chosen over `mulberry32` (whose author flags that it\n * skips ~1/3 of 32-bit outputs) and over a CSPRNG (`node:crypto`, which is **not seedable** and would\n * defeat reproducibility). A synthetic-fixture generator has **no secrets**: statistical quality plus\n * byte-for-byte reproducibility is exactly the right trade.\n *\n * The state is four 32-bit words. This module exposes the raw step function; {@link ../rng/rng.Rng}\n * wraps it with a seed-expansion ({@link ./splitmix32.splitmix32}) and the ergonomic draw helpers.\n *\n * @module\n */\n\n/**\n * The mutable four-word `sfc32` state. Threaded explicitly (never global) by {@link ../rng/rng.Rng}.\n */\nexport interface Sfc32State {\n /** State word `a`. */\n a: number;\n /** State word `b`. */\n b: number;\n /** State word `c`. */\n c: number;\n /** Counter word `d`. */\n d: number;\n}\n\n/**\n * Advance an {@link Sfc32State} in place by one step and return the next unsigned 32-bit integer.\n *\n * This is the canonical `sfc32` step. The state object is mutated (the counter `d` increments and the\n * mixing words rotate); callers that need reproducible independence hold their own state and never\n * share it: {@link ../rng/rng.Rng} creates a fresh state per seed so two runs from the same seed are\n * identical.\n *\n * @param s - The state to advance. Mutated in place.\n * @returns The next `uint32` in the stream.\n * @example\n * ```ts\n * import { sfc32Next, type Sfc32State } from \"@cosyte/synth\";\n * const s: Sfc32State = { a: 1, b: 2, c: 3, d: 4 };\n * const x = sfc32Next(s); // uint32\n * ```\n */\nexport function sfc32Next(s: Sfc32State): number {\n s.a |= 0;\n s.b |= 0;\n s.c |= 0;\n s.d |= 0;\n const t = (((s.a + s.b) | 0) + s.d) | 0;\n s.d = (s.d + 1) | 0;\n s.a = s.b ^ (s.b >>> 9);\n s.b = (s.c + (s.c << 3)) | 0;\n s.c = (s.c << 21) | (s.c >>> 11);\n s.c = (s.c + t) | 0;\n return t >>> 0;\n}\n","/**\n * Stable diagnostic codes for `@cosyte/synth` and the {@link SynthError} they travel on.\n *\n * Unlike a parser (which recovers from bad *input* into Tier-2 warnings), a **generator** has no input\n * to tolerate: its reflex is *synthetic-by-construction* and *fail-closed on impossibility*. So the\n * codes here are **fatal**: a caller asked for something the library cannot honor spec-clean, and the\n * only safe answer is to throw, never to silently fabricate a value or a byte workaround. Codes are `key ===\n * value` and part of the public contract:\n * renaming one is a breaking change.\n *\n * @module\n */\n\n/**\n * The stable **fatal** code registry. Additions-only thereafter.\n *\n * @example\n * ```ts\n * import { SYNTH_FATAL_CODES, SynthError } from \"@cosyte/synth\";\n * try {\n * // ...generate...\n * } catch (err) {\n * if (err instanceof SynthError && err.code === SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_FORMAT) {\n * // handle an unsupported format request\n * }\n * }\n * ```\n */\nexport const SYNTH_FATAL_CODES = {\n /**\n * A format was requested that this build cannot generate through a real parser builder/serializer.\n * Fatal, never a hand-written byte fallback.\n *\n * **No code path in this build raises it.** All six formats generate, so it is reserved for a\n * future format that does not, and is kept because removing a published code is a breaking change.\n * An unsupported *kind* within a format that does generate is `SYNTH_UNSUPPORTED_KIND`.\n */\n SYNTH_UNSUPPORTED_FORMAT: \"SYNTH_UNSUPPORTED_FORMAT\",\n /**\n * A vendor quirk was requested that the target format's profile system does not support. Fatal,\n * never a silent no-op and never a fabricated quirk.\n */\n SYNTH_UNSUPPORTED_QUIRK: \"SYNTH_UNSUPPORTED_QUIRK\",\n /**\n * A quirk transform found no structural anchor to mutate, so the fixture would not carry the\n * deviation it is labelled with. Fatal: a golden file that lies about its parser verdict is worse\n * than no golden file.\n */\n SYNTH_QUIRK_ANCHOR_ABSENT: \"SYNTH_QUIRK_ANCHOR_ABSENT\",\n /**\n * A bare parse of a freshly-generated quirk artifact did not produce exactly the declared intended\n * warning code(s). Fatal, never emit a mislabeled fixture.\n */\n SYNTH_INTENDED_WARNING_MISMATCH: \"SYNTH_INTENDED_WARNING_MISMATCH\",\n /** A concept's code-system URI has no OID mapping in the C-CDA example-code table. Fatal. */\n SYNTH_UNMAPPED_CODE_SYSTEM: \"SYNTH_UNMAPPED_CODE_SYSTEM\",\n /** A money value could not be read as an X12 decimal. Fatal: a generator never rounds to a float. */\n SYNTH_INVALID_DECIMAL: \"SYNTH_INVALID_DECIMAL\",\n /** An integer range was requested with its maximum below its minimum. Fatal. */\n SYNTH_INVALID_RANGE: \"SYNTH_INVALID_RANGE\",\n /** A value was drawn from an empty pool. Fatal, never a fabricated substitute. */\n SYNTH_EMPTY_POOL: \"SYNTH_EMPTY_POOL\",\n /** A `defineSynthProfile` spec was not usable (a missing or blank `name`). Fatal. */\n SYNTH_INVALID_PROFILE: \"SYNTH_INVALID_PROFILE\",\n /**\n * A caller-supplied selector (a message kind, a document type, a corpus mix entry, a claim\n * variant, a Bundle type, a resource profile) is not in the closed set that governs it. Fatal:\n * see `resolveKind`: a selector union is erased at run time, and a selector that falls through\n * either mislabels the fixture or hands the value to a peer builder that quotes it back.\n */\n SYNTH_UNSUPPORTED_KIND: \"SYNTH_UNSUPPORTED_KIND\",\n} as const;\n\n/**\n * A value from {@link SYNTH_FATAL_CODES}: the type carried by a thrown {@link SynthError}.\n */\nexport type SynthFatalCode = (typeof SYNTH_FATAL_CODES)[keyof typeof SYNTH_FATAL_CODES];\n\n/**\n * The **frozen message registry**: the only place a {@link SynthError} message can come from.\n *\n * A message here is a fixed string. It never quotes the request that produced it, and there is no\n * parameter through which it could: {@link SynthError} takes a code and nothing else. That is the\n * whole mechanism, and it is deliberately a mechanism rather than a habit. Every one of these\n * messages used to be assembled by interpolating the caller's value into a template, and the reason\n * that was safe was not the design: it was that the caller happened to be passing a quirk name.\n *\n * The trade is real and is accepted: a fatal no longer tells you *which* value it rejected. It tells\n * you which rule refused, on `err.code`, and the stack frame tells you where. The caller already\n * holds the value it passed.\n *\n * @example\n * ```ts\n * import { SYNTH_FATAL_CODES, SYNTH_FATAL_MESSAGES } from \"@cosyte/synth\";\n * SYNTH_FATAL_MESSAGES[SYNTH_FATAL_CODES.SYNTH_EMPTY_POOL]; // => \"A value was drawn from an empty pool.\"\n * ```\n */\nexport const SYNTH_FATAL_MESSAGES: Readonly<Record<SynthFatalCode, string>> = Object.freeze({\n SYNTH_UNSUPPORTED_FORMAT:\n \"The requested format is not generable by this build. A generator has no byte fallback: it \" +\n \"builds through a parser's own serializer or it refuses.\",\n SYNTH_UNSUPPORTED_QUIRK:\n \"The requested vendor quirk is not in the target format's quirk registry. Compare the request \" +\n \"against that format's exported registry (HL7_QUIRKS, CCDA_QUIRKS, ASTM_QUIRKS).\",\n SYNTH_QUIRK_ANCHOR_ABSENT:\n \"The quirk transform found no structural anchor to mutate, so the fixture would not carry the \" +\n \"deviation it is labelled with. Refusing to emit a mislabeled fixture.\",\n SYNTH_INTENDED_WARNING_MISMATCH:\n \"A bare parse of the generated quirk artifact did not produce exactly the declared intended \" +\n \"warning code(s). Refusing to emit a mislabeled fixture.\",\n SYNTH_UNMAPPED_CODE_SYSTEM:\n \"The concept's code-system URI has no OID mapping in the C-CDA example-code table.\",\n SYNTH_INVALID_DECIMAL: \"The value could not be read as an X12 decimal.\",\n SYNTH_INVALID_RANGE: \"An integer range was requested with its maximum below its minimum.\",\n SYNTH_EMPTY_POOL: \"A value was drawn from an empty pool.\",\n SYNTH_INVALID_PROFILE: \"defineSynthProfile requires a non-empty string name.\",\n SYNTH_UNSUPPORTED_KIND:\n \"The requested kind, document type, corpus mix entry, variant or profile is not one this \" +\n \"generator supports. The supported set is the exported union for that option.\",\n});\n\n/**\n * The typed error every fatal `@cosyte/synth` condition throws. Carries a stable\n * {@link SynthFatalCode} so callers branch on `err.code` without matching message text.\n *\n * It takes **no value parameter**. The message is whatever {@link SYNTH_FATAL_MESSAGES} holds for the\n * code, so no caller-supplied string can reach a diagnostic surface by any route, not `message`, not\n * `stack`, not a field on the thrown object.\n *\n * @example\n * ```ts\n * import { SynthError, SYNTH_FATAL_CODES } from \"@cosyte/synth\";\n * throw new SynthError(SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_FORMAT);\n * ```\n */\nexport class SynthError extends Error {\n /** The stable fatal code. */\n public readonly code: SynthFatalCode;\n\n /**\n * @param code - The stable {@link SynthFatalCode}. The message comes from the frozen registry.\n */\n public constructor(code: SynthFatalCode) {\n super(SYNTH_FATAL_MESSAGES[code]);\n this.name = \"SynthError\";\n this.code = code;\n }\n}\n","/**\n * `Rng`: the seeded, deterministic random source every `@cosyte/synth` provider draws from.\n *\n * **The reproducibility contract.** A seed, and only the seed, determines the output.\n * `createRng(seed)` expands the integer seed through {@link ./splitmix32.splitmix32} into the four\n * `sfc32` state words, then every draw advances that state via {@link ./sfc32.sfc32Next}. Two `Rng`s\n * created from the same seed emit the **identical** sequence on any machine, any run: the property\n * the parsers', `transform`'s, and `deid`'s regression suites depend on.\n *\n * **Explicit, never global.** An `Rng` is a value you thread through a build; there is no ambient\n * shared generator and **`Math.random` is lint-banned** in `src/` (it is not seedable: its seed is\n * engine-chosen and cannot be reset, so a corpus built on it is not reproducible). Because each\n * generation creates a fresh `Rng` from its seed, generations are independent and parallel-safe.\n *\n * The `Rng` object is stateful by nature (a PRNG advances). Immutability in this library lives where it\n * is testable and matters: the generated **artifacts and the `Corpus` are deep-frozen** (see\n * `../corpus.ts`). Determinism, not object-immutability, is the `Rng`'s guarantee.\n *\n * @module\n */\n\nimport { splitmix32 } from \"./splitmix32.js\";\nimport { sfc32Next, type Sfc32State } from \"./sfc32.js\";\nimport { SYNTH_FATAL_CODES, SynthError } from \"../codes.js\";\n\n/**\n * A seeded, deterministic random source. Created via {@link createRng}; passed explicitly to every\n * provider. All draw methods advance the internal state deterministically.\n */\nexport interface Rng {\n /** The integer seed this generator was created from (part of the `Corpus` manifest). */\n readonly seed: number;\n /** The next unsigned 32-bit integer. */\n nextUint32(): number;\n /** The next float in `[0, 1)`. */\n float(): number;\n /**\n * A uniformly-distributed integer in the inclusive range `[min, max]`.\n *\n * @param min - Inclusive lower bound (integer).\n * @param max - Inclusive upper bound (integer, `>= min`).\n */\n int(min: number, max: number): number;\n /** `true` with probability `p` (default `0.5`). */\n bool(p?: number): boolean;\n /**\n * Pick one element from a non-empty array.\n *\n * @param items - A non-empty readonly array.\n */\n pick<T>(items: readonly T[]): T;\n /**\n * A string of `n` decimal digits (`0`–`9`), each drawn uniformly.\n *\n * @param n - The number of digits (`>= 0`).\n */\n digits(n: number): string;\n}\n\n/**\n * The concrete {@link Rng}. Holds the mutable `sfc32` state; every method advances it deterministically.\n */\nclass Sfc32Rng implements Rng {\n public readonly seed: number;\n readonly #state: Sfc32State;\n\n public constructor(seed: number) {\n this.seed = seed | 0;\n // Expand the single seed into four well-distributed state words. Seeding sfc32 directly from the\n // raw seed gives poor low-bit behavior; splitmix32 is the standard fix (bryc / roadmap §5).\n const mix = splitmix32(this.seed);\n this.#state = { a: mix(), b: mix(), c: mix(), d: mix() };\n // A short warm-up so nearby seeds diverge immediately.\n for (let i = 0; i < 8; i += 1) sfc32Next(this.#state);\n }\n\n public nextUint32(): number {\n return sfc32Next(this.#state);\n }\n\n public float(): number {\n return this.nextUint32() / 0x1_0000_0000;\n }\n\n public int(min: number, max: number): number {\n if (max < min) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INVALID_RANGE);\n const span = max - min + 1;\n return min + Math.floor(this.float() * span);\n }\n\n public bool(p = 0.5): boolean {\n return this.float() < p;\n }\n\n public pick<T>(items: readonly T[]): T {\n if (items.length === 0) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_EMPTY_POOL);\n // `int(0, length-1)` is always in-bounds on a non-empty array, so this access cannot be a hole;\n // the cast discharges `noUncheckedIndexedAccess`'s `T | undefined` without a runtime re-check.\n return items[this.int(0, items.length - 1)] as T;\n }\n\n public digits(n: number): string {\n let out = \"\";\n for (let i = 0; i < n; i += 1) out += String(this.int(0, 9));\n return out;\n }\n}\n\n/**\n * Create a seeded, deterministic {@link Rng}. The same `seed` yields the same sequence everywhere.\n *\n * @param seed - The integer seed. Coerced to a 32-bit integer.\n * @returns A fresh, independent {@link Rng}.\n * @example\n * ```ts\n * import { createRng } from \"@cosyte/synth\";\n * const rng = createRng(12345);\n * rng.int(1, 6); // deterministic for seed 12345\n * ```\n */\nexport function createRng(seed: number): Rng {\n return new Sfc32Rng(seed);\n}\n","/**\n * The `Corpus` abstraction: a seed plus a self-describing manifest of what was generated, so a\n * fixture set is itself reproducible and regenerable. A downstream repo pins a seed\n * and gets a stable fixture set that regenerates identically.\n *\n * Generated artifacts and the `Corpus` are **deep-frozen**: this is where the archetype's immutability\n * invariant lives in a generator: a consumer cannot mutate a shared fixture out from under\n * another test.\n *\n * @module\n */\n\n/** The format an artifact was generated for. */\nexport type SynthFormat = \"hl7v2\" | \"fhir\" | \"ccda\" | \"x12\" | \"ncpdp\" | \"astm\";\n\n/**\n * One generated artifact: the serialized wire text plus the metadata needed to reproduce and check\n * it. `warnings` records what the artifact's own parser reported on the round-trip (zero for a\n * spec-clean artifact).\n */\nexport interface Artifact {\n /** The format this artifact belongs to. */\n readonly format: SynthFormat;\n /** A format-specific kind label (e.g. `\"ADT^A01\"`). */\n readonly kind: string;\n /** The serialized wire text, produced by the parser's own conservative serializer. */\n readonly content: string;\n /** The warning codes the parser emitted when the artifact was round-tripped (empty = spec-clean). */\n readonly warnings: readonly string[];\n}\n\n/** A self-describing manifest of a {@link Corpus}. */\nexport interface CorpusManifest {\n /** The formats present in the corpus. */\n readonly formats: readonly SynthFormat[];\n /** Per-kind artifact counts (e.g. `{ \"ADT^A01\": 3 }`). */\n readonly counts: Readonly<Record<string, number>>;\n /** The quirk names applied. */\n readonly quirks: readonly string[];\n}\n\n/** A reproducible, self-describing set of generated artifacts. */\nexport interface Corpus {\n /** The seed the corpus was generated from: regenerating from it yields byte-identical artifacts. */\n readonly seed: number;\n /** The manifest describing what was generated. */\n readonly manifest: CorpusManifest;\n /** The generated artifacts, in generation order. */\n readonly artifacts: readonly Artifact[];\n}\n\n/**\n * Assemble a deep-frozen {@link Corpus} from a seed and its artifacts, deriving the manifest.\n *\n * @param seed - The seed the artifacts were generated from.\n * @param artifacts - The generated artifacts, in order.\n * @param quirks - The quirk names applied (default none).\n * @returns A deep-frozen, self-describing {@link Corpus}.\n * @example\n * ```ts\n * import { makeCorpus } from \"@cosyte/synth\";\n * const corpus = makeCorpus(1, [{ format: \"hl7v2\", kind: \"ADT^A01\", content, warnings: [] }]);\n * corpus.manifest.counts[\"ADT^A01\"]; // 1\n * ```\n */\nexport function makeCorpus(\n seed: number,\n artifacts: readonly Artifact[],\n quirks: readonly string[] = [],\n): Corpus {\n const counts: Record<string, number> = {};\n const formats = new Set<SynthFormat>();\n const frozenArtifacts = artifacts.map((a) => {\n counts[a.kind] = (counts[a.kind] ?? 0) + 1;\n formats.add(a.format);\n return Object.freeze({ ...a, warnings: Object.freeze([...a.warnings]) });\n });\n const manifest: CorpusManifest = Object.freeze({\n formats: Object.freeze([...formats]),\n counts: Object.freeze(counts),\n quirks: Object.freeze([...quirks]),\n });\n return Object.freeze({\n seed,\n manifest,\n artifacts: Object.freeze(frozenArtifacts),\n });\n}\n","/**\n * The reserved / never-collide identifier facts that make a `@cosyte/synth` value **provably\n * synthetic**: the ground truth behind the synthetic-safety invariant.\n *\n * These are **facts**, not copyrighted prose: authoritative ranges published by SSA, NANPA, and the\n * IETF that are guaranteed never to denote a real person or a real routable resource. Every provider\n * draws only from these; the predicates here are the executable half of the CI synthetic-safety gate:\n * they let a test assert that no emitted value falls **outside** a reserved source.\n *\n * Sources:\n * - **SSN**, SSA never issues area numbers `000`, `666`, or `900–999`; the `987-65-4320…4329` block\n * is SSA's explicitly-reserved advertising range. (ssa.gov)\n * - **Phone**, NANP reserves `555-0100…555-0199` as the fictional/non-working line range. (nanpa.com)\n * - **Email/domain**, RFC 2606 / RFC 6761 reserved: `example.com`/`.net`/`.org` and the `.example`,\n * `.test`, `.invalid`, `.localhost` TLDs.\n * - **IP**, RFC 5737 IPv4 TEST-NET-1/2/3 (`192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`) and\n * RFC 3849 IPv6 documentation prefix `2001:db8::/32`.\n * - **NPI**, a real National Provider Identifier is a 10-digit number whose last digit is a Luhn\n * check digit computed over the `80840` prefix + the 9-digit base (CMS NPI check-digit rule, ISO\n * 7812). A number whose check digit is **wrong** therefore cannot be a NPPES-issued NPI. `synth`\n * emits NPIs with a deliberately-invalid check digit, so no generated NPI can collide with a real\n * provider.\n *\n * @module\n */\n\n/**\n * The synthetic **assigning authority** `@cosyte/synth` mints MRNs / account / member identifiers\n * under. There is **no** reserved MRN range (an MRN is unique only within its assigning-authority /\n * OID namespace), so, as a documented design decision, every synthetic identifier\n * is scoped to a namespace that clearly cannot be a real facility's: a `SYNTH`-labelled authority whose\n * OID lives under HL7's designated **example** root `2.16.840.1.113883.19`. A value under this AA can\n * never collide with a real record because the *namespace itself* is synthetic.\n */\nexport const SYNTHETIC_ASSIGNING_AUTHORITY = Object.freeze({\n /** The human-readable assigning-authority namespace id (HL7 HD.1). */\n namespaceId: \"COSYTE-SYNTH\",\n /** The universal id, an OID under HL7's example arc `2.16.840.1.113883.19` (HD.2). */\n universalId: \"2.16.840.1.113883.19.999\",\n /** The universal id type (HD.3). */\n universalIdType: \"ISO\",\n});\n\n/** RFC 2606 / 6761 reserved email domains `@cosyte/synth` draws from. */\nexport const RESERVED_EMAIL_DOMAINS: readonly string[] = Object.freeze([\n \"example.com\",\n \"example.org\",\n \"example.net\",\n]);\n\n/** RFC 5737 IPv4 documentation (TEST-NET) `/24` network prefixes. */\nexport const TEST_NET_V4_PREFIXES: readonly string[] = Object.freeze([\n \"192.0.2\", // TEST-NET-1\n \"198.51.100\", // TEST-NET-2\n \"203.0.113\", // TEST-NET-3\n]);\n\n/** RFC 3849 IPv6 documentation prefix. */\nexport const DOC_V6_PREFIX = \"2001:db8\";\n\n/**\n * The `80840` prefix prepended to a 10-digit NPI before the Luhn check (the CMS NPI check-digit\n * rule: `80840` is the ISO 7812 issuer identifier for the US health-application namespace). A real\n * NPI satisfies `luhn(\"80840\" + npi) ≡ 0 (mod 10)`.\n */\nexport const NPI_LUHN_PREFIX = \"80840\";\n\n/**\n * The Luhn sum (mod 10) of a numeric string, doubling every second digit from the right. Used to\n * verify (or deliberately break) an NPI check digit.\n *\n * @param digits - A string of decimal digits.\n * @returns The Luhn sum modulo 10 (0 ⇒ the string passes the Luhn check).\n * @internal\n */\nexport function luhnMod10(digits: string): number {\n let sum = 0;\n // Standard Luhn: the RIGHTMOST digit is never doubled; doubling starts one position in and\n // alternates. For a full payload+check string this makes a Luhn-valid string sum to 0 (mod 10);\n // for a payload with a `0` placeholder in the check position it yields the complement of the\n // correct check digit.\n let double = false;\n for (let i = digits.length - 1; i >= 0; i -= 1) {\n let d = digits.charCodeAt(i) - 48;\n if (d < 0 || d > 9) continue;\n if (double) {\n d *= 2;\n if (d > 9) d -= 9;\n }\n sum += d;\n double = !double;\n }\n return sum % 10;\n}\n\n/**\n * The correct NPI check digit for a 9-digit base: the value that makes `80840` + base + check pass\n * the Luhn check.\n *\n * @param base9 - The 9-digit NPI base (positions 1–9).\n * @returns The check digit (`0`–`9`) a real NPI would carry for this base.\n * @example\n * ```ts\n * import { npiCheckDigit } from \"@cosyte/synth\";\n * npiCheckDigit(\"123456789\"); // 3, so 1234567893 is a Luhn-valid NPI shape\n * ```\n */\nexport function npiCheckDigit(base9: string): number {\n // Luhn over \"80840\" + base9 with a trailing 0 check placeholder; the check digit closes the sum.\n const partial = luhnMod10(`${NPI_LUHN_PREFIX}${base9}0`);\n return (10 - partial) % 10;\n}\n\n/**\n * The DEA-registration prefix letters `@cosyte/synth` draws a synthetic DEA number's first character\n * from. A real DEA number is `<registrant-type><last-name-initial>` + 7 digits; the first letter is the\n * registrant type (A/B/F/G/M/P/R/X are the widely-published values; the second letter is the\n * registrant's last-name initial). These letters are a **fact** about the number's shape, not\n * copyrighted prose: they only shape the value; the synthetic guarantee is the deliberately-**invalid\n * checksum** (see {@link dea} / {@link isSyntheticDea}).\n */\nexport const DEA_REGISTRANT_TYPES: readonly string[] = Object.freeze([\n \"A\",\n \"B\",\n \"F\",\n \"G\",\n \"M\",\n \"P\",\n \"R\",\n \"X\",\n]);\n\n/**\n * The correct DEA check digit for a 7-digit numeric base. The published DEA checksum is\n * `(d1 + d3 + d5) + 2·(d2 + d4 + d6)`, whose **units digit** is the 7th (check) digit. A real DEA\n * number satisfies this; a number whose 7th digit differs cannot be a validly-issued DEA registration.\n *\n * @param base6 - The first 6 digits of the DEA number (positions 1–6).\n * @returns The check digit (`0`–`9`) a real DEA number would carry for this base.\n * @example\n * ```ts\n * import { deaCheckDigit } from \"@cosyte/synth\";\n * deaCheckDigit(\"123456\"); // the units digit of (1+3+5) + 2·(2+4+6)\n * ```\n */\nexport function deaCheckDigit(base6: string): number {\n let odd = 0;\n let even = 0;\n for (let i = 0; i < 6; i += 1) {\n const digit = base6.charCodeAt(i) - 48;\n if (i % 2 === 0) odd += digit;\n else even += digit;\n }\n return (odd + 2 * even) % 10;\n}\n\n/**\n * Whether a DEA number (`XX` + 7 digits, case-insensitive) is **provably synthetic**: its check digit\n * (the 7th digit) does **not** match the published DEA checksum, so it cannot be a validly-issued DEA\n * registration. A checksum-valid DEA number (which *could* denote a real prescriber) returns `false`; a\n * value that is not the DEA shape returns `false`.\n *\n * @param value - The candidate DEA number (with or without incidental separators).\n * @returns `true` when the DEA number's checksum is wrong (never a real DEA registration).\n * @example\n * ```ts\n * import { isSyntheticDea } from \"@cosyte/synth\";\n * isSyntheticDea(\"AF1234561\"); // depends on the base: true when the 7th digit is wrong\n * ```\n */\nexport function isSyntheticDea(value: string): boolean {\n const compact = value.replace(/[\\s-]/g, \"\").toUpperCase();\n if (!/^[A-Z]{2}\\d{7}$/.test(compact)) return false;\n const digits = compact.slice(2);\n const check = digits.charCodeAt(6) - 48;\n return deaCheckDigit(digits.slice(0, 6)) !== check;\n}\n\n/**\n * Whether a 10-digit NPI is **provably synthetic**, i.e. its check digit is invalid, so it cannot be\n * a NPPES-issued NPI. A Luhn-valid 10-digit NPI (which *could* denote a real registered provider)\n * returns `false`; a non-10-digit value returns `false` (not an NPI shape).\n *\n * @param value - The candidate NPI (digits only, or with incidental separators).\n * @returns `true` when the NPI's check digit is wrong (never a real NPI).\n * @example\n * ```ts\n * import { isSyntheticNpi } from \"@cosyte/synth\";\n * isSyntheticNpi(\"1234567894\"); // true: invalid check digit (valid would be 1234567893)\n * isSyntheticNpi(\"1234567893\"); // false: Luhn-valid, could be a real NPI\n * ```\n */\nexport function isSyntheticNpi(value: string): boolean {\n const digits = value.replace(/\\D/g, \"\");\n if (digits.length !== 10) return false;\n return luhnMod10(`${NPI_LUHN_PREFIX}${digits}`) !== 0;\n}\n\n/**\n * Whether a `ddd-dd-dddd` (or `ddddddddd`) SSN string is drawn from an SSA never-issued / reserved\n * space: area `000`, `666`, or `900–999`. A real, issuable SSN returns `false`.\n *\n * @param value - The candidate SSN (dashes optional).\n * @returns `true` when the SSN is provably synthetic.\n * @example\n * ```ts\n * import { isSyntheticSsn } from \"@cosyte/synth\";\n * isSyntheticSsn(\"900-12-3456\"); // true (never issued)\n * isSyntheticSsn(\"123456789\"); // false (issuable area 123)\n * ```\n */\nexport function isSyntheticSsn(value: string): boolean {\n const digits = value.replace(/\\D/g, \"\");\n if (digits.length !== 9) return false;\n const area = Number(digits.slice(0, 3));\n return area === 0 || area === 666 || area >= 900;\n}\n\n/**\n * Whether a phone string contains the NANP `555-0100…555-0199` reserved fictional line range.\n *\n * @param value - The candidate phone (any formatting).\n * @returns `true` when the number is in the reserved fictional block.\n * @example\n * ```ts\n * import { isSyntheticPhone } from \"@cosyte/synth\";\n * isSyntheticPhone(\"(202) 555-0142\"); // true\n * ```\n */\nexport function isSyntheticPhone(value: string): boolean {\n const digits = value.replace(/\\D/g, \"\");\n // The reserved guarantee is the 7-digit tail: exchange 555 + line 01NN.\n const tail = digits.slice(-7);\n return /^555 ?01\\d\\d$/.test(tail) || /^55501\\d\\d$/.test(tail);\n}\n\n/**\n * Whether an email's domain is an RFC 2606 / 6761 reserved / test domain.\n *\n * @param value - The candidate email address.\n * @returns `true` when the domain is reserved (never real).\n * @example\n * ```ts\n * import { isSyntheticEmail } from \"@cosyte/synth\";\n * isSyntheticEmail(\"faux.testerson@example.com\"); // true\n * ```\n */\nexport function isSyntheticEmail(value: string): boolean {\n const at = value.lastIndexOf(\"@\");\n if (at < 0) return false;\n const domain = value.slice(at + 1).toLowerCase();\n if (RESERVED_EMAIL_DOMAINS.includes(domain)) return true;\n return /\\.(example|test|invalid|localhost)$/.test(domain);\n}\n\n/**\n * Whether an IP string is in an RFC 5737 (IPv4 TEST-NET) or RFC 3849 (IPv6 documentation) reserved\n * block. A real routable address returns `false`.\n *\n * @param value - The candidate IPv4 or IPv6 address.\n * @returns `true` when the address is a reserved documentation address.\n * @example\n * ```ts\n * import { isSyntheticIp } from \"@cosyte/synth\";\n * isSyntheticIp(\"192.0.2.44\"); // true (TEST-NET-1)\n * isSyntheticIp(\"8.8.8.8\"); // false (real)\n * ```\n */\nexport function isSyntheticIp(value: string): boolean {\n if (value.toLowerCase().startsWith(`${DOC_V6_PREFIX}:`)) return true;\n return TEST_NET_V4_PREFIXES.some((prefix) => value.startsWith(`${prefix}.`));\n}\n","/**\n * The shipped **clearly-fake name pool**: `@cosyte/synth`'s own license-clean synthetic data.\n *\n * Deliberately **not** a `faker`-style realistic-name corpus (which could match a real person at a real\n * address: the exact hazard the synthetic-safety invariant forbids). Every token is\n * an obviously-invented, fixture-flavoured word: a reader can tell at a glance it names no one. The pool\n * is small on purpose: structural coverage, not demographic realism, is the goal.\n *\n * `# synthetic: true`\n *\n * @module\n */\n\n/** Obviously-synthetic given names. None is a plausible real person's name. */\nexport const SYNTHETIC_GIVEN_NAMES: readonly string[] = Object.freeze([\n \"Testina\",\n \"Fixtura\",\n \"Synthos\",\n \"Placeholda\",\n \"Sampleton\",\n \"Prototius\",\n \"Stubbina\",\n \"Exampla\",\n \"Quilliam\",\n \"Fabrica\",\n \"Simula\",\n \"Testry\",\n \"Seedwin\",\n \"Corpora\",\n \"Reprodo\",\n \"Mocktavia\",\n \"Dummett\",\n \"Voidwin\",\n \"Deteria\",\n \"Randomir\",\n]);\n\n/** Obviously-synthetic family names. None is a plausible real surname at a real address. */\nexport const SYNTHETIC_FAMILY_NAMES: readonly string[] = Object.freeze([\n \"Testerson\",\n \"Fauxman\",\n \"Placeholt\",\n \"Mockridge\",\n \"Fixtingham\",\n \"Synthwell\",\n \"Dummerton\",\n \"Examplewood\",\n \"Fabricant\",\n \"Simulacre\",\n \"Nonesuch\",\n \"Seedman\",\n \"Corpusworth\",\n \"Reprodus\",\n \"Voidmark\",\n \"Deterwood\",\n \"Randomson\",\n \"Quillfeather\",\n \"Notreal\",\n \"Genfield\",\n]);\n\n/** Obviously-synthetic street names for structured address fields. */\nexport const SYNTHETIC_STREET_NAMES: readonly string[] = Object.freeze([\n \"Fixture Lane\",\n \"Sample Street\",\n \"Placeholder Avenue\",\n \"Synthetic Way\",\n \"Example Boulevard\",\n \"Testing Terrace\",\n \"Mock Road\",\n \"Prototype Court\",\n]);\n\n/**\n * Obviously-synthetic city names. Combined only ever with a synthetic street + a fake name (the\n * *combination* is what identifies, and the combination is always synthetic).\n */\nexport const SYNTHETIC_CITY_NAMES: readonly string[] = Object.freeze([\n \"Faketon\",\n \"Synthville\",\n \"Exampleburg\",\n \"Testford\",\n \"Mockhaven\",\n \"Fixtureton\",\n]);\n","/**\n * The synthetic-safety provider layer: every identifier, contact point, name, and date\n * `@cosyte/synth` emits is minted here, and **only** from a guaranteed-non-colliding source. There is no code\n * path that returns a value not drawn from a reserved range or the\n * shipped fake-name pool. This is the inverse of a parser's liberality: the generator is *closed-world*\n * on its data sources, so no output *can* be real or plausibly-real PHI.\n *\n * All providers are pure functions of an explicit {@link ../rng/rng.Rng}, same seed, same values.\n *\n * @module\n */\n\nimport type { Rng } from \"../rng/rng.js\";\n\nimport {\n RESERVED_EMAIL_DOMAINS,\n TEST_NET_V4_PREFIXES,\n DOC_V6_PREFIX,\n SYNTHETIC_ASSIGNING_AUTHORITY,\n npiCheckDigit,\n deaCheckDigit,\n DEA_REGISTRANT_TYPES,\n} from \"./reserved.js\";\nimport {\n SYNTHETIC_GIVEN_NAMES,\n SYNTHETIC_FAMILY_NAMES,\n SYNTHETIC_STREET_NAMES,\n SYNTHETIC_CITY_NAMES,\n} from \"./names-pool.js\";\n\n/** A synthetic person name drawn from the shipped fake-name pool. */\nexport interface SyntheticName {\n /** A clearly-fake given name. */\n readonly given: string;\n /** A clearly-fake family name. */\n readonly family: string;\n}\n\n/** A synthetic postal address: synthetic street + city, a fixed non-real ZIP. */\nexport interface SyntheticAddress {\n /** A clearly-fake street line. */\n readonly street: string;\n /** A clearly-fake city. */\n readonly city: string;\n /** A US state abbreviation (structural only; never combined with a real street + name + DOB). */\n readonly state: string;\n /** A reserved non-real ZIP (`00000`). */\n readonly zip: string;\n}\n\n/** A synthetic identifier scoped to the synthetic assigning authority. */\nexport interface SyntheticIdentifier {\n /** The identifier value (digits): unique only within the synthetic namespace. */\n readonly value: string;\n /** HL7 identifier type code (`MR` = medical record, `AN` = account, `MB` = member). */\n readonly typeCode: \"MR\" | \"AN\" | \"MB\";\n /** The synthetic assigning-authority namespace id. */\n readonly assigningAuthority: string;\n /** The synthetic assigning-authority OID (HL7 example arc). */\n readonly assigningAuthorityOid: string;\n}\n\n/** Which SSN reserved space to draw from. */\nexport type SsnBlock = \"never-issued\" | \"advertising\";\n\n/**\n * A **synthetic SSN**: dashed `AAA-GG-SSSS`. Default draws the SSA never-issued area space\n * (`900–999`); `block: \"advertising\"` draws SSA's reserved advertising block (`987-65-4320…4329`).\n * A value from this function can never be a real SSN.\n *\n * @param rng - The seeded generator.\n * @param block - Which reserved space to draw from. Defaults to `\"never-issued\"`.\n * @returns A dashed synthetic SSN string.\n * @example\n * ```ts\n * import { createRng, ssn } from \"@cosyte/synth\";\n * ssn(createRng(1)); // e.g. a 900-area, never-issued SSN\n * ```\n */\nexport function ssn(rng: Rng, block: SsnBlock = \"never-issued\"): string {\n if (block === \"advertising\") {\n // SSA's explicitly-reserved advertising block: last digit 0..9 within -4320..-4329.\n return `987-65-432${String(rng.int(0, 9))}`;\n }\n const area = rng.int(900, 999); // SSA never issues 900-999.\n const group = rng.digits(2);\n const serial = rng.digits(4);\n return `${String(area)}-${group}-${serial}`;\n}\n\n/**\n * A **synthetic phone** in the NANP reserved fictional block: `(AAA) 555-01NN`. The reserved\n * guarantee is the `555-01NN` tail (exchange 555, line 0100–0199); the area code is any NANP-valid\n * `NXX`. Can never be a working number.\n *\n * @param rng - The seeded generator.\n * @returns A formatted synthetic phone string.\n * @example\n * ```ts\n * import { createRng, phone } from \"@cosyte/synth\";\n * phone(createRng(1)); // e.g. \"(2XX) 555-01NN\"\n * ```\n */\nexport function phone(rng: Rng): string {\n const area = `${String(rng.int(2, 9))}${rng.digits(2)}`; // NXX area code.\n const line = `01${rng.digits(2)}`; // reserved 0100-0199.\n return `(${area}) 555-${line}`;\n}\n\n/**\n * A **synthetic name** drawn from the shipped clearly-fake pool.\n *\n * @param rng - The seeded generator.\n * @returns A {@link SyntheticName}.\n * @example\n * ```ts\n * import { createRng, name } from \"@cosyte/synth\";\n * const { given, family } = name(createRng(1));\n * ```\n */\nexport function name(rng: Rng): SyntheticName {\n return { given: rng.pick(SYNTHETIC_GIVEN_NAMES), family: rng.pick(SYNTHETIC_FAMILY_NAMES) };\n}\n\n/**\n * A **synthetic email** at an RFC 2606 / 6761 reserved domain: `<slug>@example.com`.\n *\n * @param rng - The seeded generator.\n * @param person - Optional name to derive the local-part slug from; otherwise a random slug is used.\n * @returns A synthetic email address.\n * @example\n * ```ts\n * import { createRng, email, name } from \"@cosyte/synth\";\n * email(createRng(1), name(createRng(1))); // \"<given>.<family>@example.com\"\n * ```\n */\nexport function email(rng: Rng, person?: SyntheticName): string {\n const domain = rng.pick(RESERVED_EMAIL_DOMAINS);\n const slug = person ? `${person.given}.${person.family}`.toLowerCase() : `synth${rng.digits(6)}`;\n return `${slug}@${domain}`;\n}\n\n/**\n * A **synthetic IPv4** in an RFC 5737 TEST-NET block, never routable.\n *\n * @param rng - The seeded generator.\n * @returns A TEST-NET IPv4 address string.\n * @example\n * ```ts\n * import { createRng, ipv4 } from \"@cosyte/synth\";\n * ipv4(createRng(1)); // e.g. \"192.0.2.NN\"\n * ```\n */\nexport function ipv4(rng: Rng): string {\n return `${rng.pick(TEST_NET_V4_PREFIXES)}.${String(rng.int(1, 254))}`;\n}\n\n/**\n * A **synthetic IPv6** in the RFC 3849 documentation prefix `2001:db8::/32`, never routable.\n *\n * @param rng - The seeded generator.\n * @returns A documentation-prefix IPv6 address string.\n * @example\n * ```ts\n * import { createRng, ipv6 } from \"@cosyte/synth\";\n * ipv6(createRng(1)); // e.g. \"2001:db8::NNNN\"\n * ```\n */\nexport function ipv6(rng: Rng): string {\n const tail = rng.nextUint32().toString(16).padStart(4, \"0\").slice(-4);\n return `${DOC_V6_PREFIX}::${tail}`;\n}\n\n/**\n * A **deterministic UUIDv4-shaped** surrogate key from the seeded generator. Because it is seeded (not\n * from `node:crypto`, which is not reproducible), the cryptographic non-collision argument is weaker,\n * acceptable because the identifier namespace is synthetic anyway, and noted honestly.\n *\n * @param rng - The seeded generator.\n * @returns A canonical `8-4-4-4-12` lowercase-hex UUID string with version `4` and RFC 4122 variant.\n * @example\n * ```ts\n * import { createRng, uuid } from \"@cosyte/synth\";\n * uuid(createRng(1)); // \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\"\n * ```\n */\nexport function uuid(rng: Rng): string {\n const bytes = new Uint8Array(16);\n for (let i = 0; i < 16; i += 1) bytes[i] = rng.int(0, 255);\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40; // version 4\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80; // variant 10xx\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\"));\n return `${hex.slice(0, 4).join(\"\")}-${hex.slice(4, 6).join(\"\")}-${hex.slice(6, 8).join(\"\")}-${hex.slice(8, 10).join(\"\")}-${hex.slice(10, 16).join(\"\")}`;\n}\n\n/**\n * A **synthetic NPI**: a 10-digit National Provider Identifier with a **deliberately-invalid Luhn\n * check digit**, so it can never be a NPPES-issued NPI (a real NPI must satisfy the `80840`-prefixed\n * Luhn check). The 9-digit base is drawn from the seeded generator; the check digit is\n * set to `(correct + 1) mod 10`, guaranteeing the full value fails validation.\n *\n * @param rng - The seeded generator.\n * @returns A 10-digit NPI-shaped string that is provably not a real NPI.\n * @example\n * ```ts\n * import { createRng, npi, isSyntheticNpi } from \"@cosyte/synth\";\n * isSyntheticNpi(npi(createRng(1))); // true: invalid check digit by construction\n * ```\n */\nexport function npi(rng: Rng): string {\n const base9 = rng.digits(9);\n const wrongCheck = (npiCheckDigit(base9) + 1) % 10;\n return `${base9}${String(wrongCheck)}`;\n}\n\n/**\n * A **synthetic DEA number**: `<registrant-type><initial>` + 7 digits with a **deliberately-invalid\n * checksum**, so it can never be a validly-issued DEA registration (a real DEA number's 7th digit\n * satisfies the published DEA checksum). The first letter is a registrant-type letter, the\n * second is derived from `person` (its family initial) when supplied so the number reads plausibly; the\n * 6-digit base is seeded and the check digit is set to `(correct + 1) mod 10`, guaranteeing the value\n * fails validation. NCPDP carries prescriber DEA, and this is the identity locus a refuter attacks\n * hardest, so, like {@link npi}, non-collision is a construction-level guarantee, not a heuristic.\n *\n * @param rng - The seeded generator.\n * @param person - Optional name whose family initial becomes the DEA's second letter.\n * @returns A DEA-shaped string that is provably not a real DEA registration.\n * @example\n * ```ts\n * import { createRng, dea, isSyntheticDea } from \"@cosyte/synth\";\n * isSyntheticDea(dea(createRng(1))); // true: invalid checksum by construction\n * ```\n */\nexport function dea(rng: Rng, person?: SyntheticName): string {\n const type = rng.pick(DEA_REGISTRANT_TYPES);\n const initialSource = person?.family ?? rng.pick(SYNTHETIC_FAMILY_NAMES);\n const initial = initialSource.slice(0, 1).toUpperCase();\n const base6 = rng.digits(6);\n const wrongCheck = (deaCheckDigit(base6) + 1) % 10;\n return `${type}${initial}${base6}${String(wrongCheck)}`;\n}\n\n/**\n * A **synthetic identifier** (MRN / account / member id) scoped to the synthetic assigning authority.\n * There is no reserved MRN range, so non-collision is guaranteed by the *namespace*, not the value: the\n * identifier lives under a `SYNTH` authority no real facility uses.\n *\n * @param rng - The seeded generator.\n * @param typeCode - The HL7 identifier type: `MR` (default), `AN`, or `MB`.\n * @returns A {@link SyntheticIdentifier}.\n * @example\n * ```ts\n * import { createRng, identifier } from \"@cosyte/synth\";\n * identifier(createRng(1), \"MR\"); // { value, typeCode: \"MR\", assigningAuthority: \"COSYTE-SYNTH\", ... }\n * ```\n */\nexport function identifier(\n rng: Rng,\n typeCode: SyntheticIdentifier[\"typeCode\"] = \"MR\",\n): SyntheticIdentifier {\n return {\n value: rng.digits(8),\n typeCode,\n assigningAuthority: SYNTHETIC_ASSIGNING_AUTHORITY.namespaceId,\n assigningAuthorityOid: SYNTHETIC_ASSIGNING_AUTHORITY.universalId,\n };\n}\n\n/**\n * A **synthetic address**: a fake street + city, a reserved non-real ZIP (`00000`). A real state\n * abbreviation may appear (structural only) but is never combined with a real street + name + DOB.\n *\n * @param rng - The seeded generator.\n * @returns A {@link SyntheticAddress}.\n * @example\n * ```ts\n * import { createRng, address } from \"@cosyte/synth\";\n * address(createRng(1)); // { street, city, state, zip: \"00000\" }\n * ```\n */\nexport function address(rng: Rng): SyntheticAddress {\n const number = rng.int(1, 9999);\n return {\n street: `${String(number)} ${rng.pick(SYNTHETIC_STREET_NAMES)}`,\n city: rng.pick(SYNTHETIC_CITY_NAMES),\n state: rng.pick(US_STATES),\n zip: \"00000\",\n };\n}\n\n/**\n * A **synthetic date** in HL7 `YYYYMMDD` form, drawn uniformly within an inclusive year range. Comes\n * from the seeded generator (never wall-clock), so it is reproducible and implies no real event.\n *\n * @param rng - The seeded generator.\n * @param minYear - Inclusive lower year bound (default `1930`).\n * @param maxYear - Inclusive upper year bound (default `2010`).\n * @returns An `YYYYMMDD` date string (always a valid calendar day).\n * @example\n * ```ts\n * import { createRng, dateYmd } from \"@cosyte/synth\";\n * dateYmd(createRng(1), 1970, 2000); // \"YYYYMMDD\"\n * ```\n */\nexport function dateYmd(rng: Rng, minYear = 1930, maxYear = 2010): string {\n const year = rng.int(minYear, maxYear);\n const month = rng.int(1, 12);\n const daysInMonth = new Date(Date.UTC(year, month, 0)).getUTCDate();\n const day = rng.int(1, daysInMonth);\n return `${String(year).padStart(4, \"0\")}${String(month).padStart(2, \"0\")}${String(day).padStart(2, \"0\")}`;\n}\n\n/** US state abbreviations: structural only (see {@link address}). */\nconst US_STATES: readonly string[] = Object.freeze([\n \"AL\",\n \"AK\",\n \"AZ\",\n \"AR\",\n \"CA\",\n \"CO\",\n \"CT\",\n \"DE\",\n \"FL\",\n \"GA\",\n \"HI\",\n \"ID\",\n \"IL\",\n \"IN\",\n \"IA\",\n \"KS\",\n \"KY\",\n \"LA\",\n \"ME\",\n \"MD\",\n \"MA\",\n \"MI\",\n \"MN\",\n \"MS\",\n \"MO\",\n \"MT\",\n \"NE\",\n \"NV\",\n \"NH\",\n \"NJ\",\n \"NM\",\n \"NY\",\n \"NC\",\n \"ND\",\n \"OH\",\n \"OK\",\n \"OR\",\n \"PA\",\n \"RI\",\n \"SC\",\n \"SD\",\n \"TN\",\n \"TX\",\n \"UT\",\n \"VT\",\n \"VA\",\n \"WA\",\n \"WV\",\n \"WI\",\n \"WY\",\n]);\n","/**\n * The `safe` namespace: the single entry point for every synthetic-by-construction value provider.\n *\n * Grouped under one object so a consumer reads `safe.ssn(rng)` / `safe.phone(rng)` and it is\n * self-evident that the value is drawn from a guaranteed-non-colliding synthetic source.\n * The individual functions and the reserved-range predicates are also exported by name from the\n * package root for direct import.\n *\n * @module\n */\n\nimport {\n ssn,\n phone,\n name,\n email,\n ipv4,\n ipv6,\n uuid,\n identifier,\n address,\n dateYmd,\n npi,\n dea,\n} from \"./providers.js\";\n\nexport * from \"./providers.js\";\nexport * from \"./reserved.js\";\nexport * from \"./names-pool.js\";\n\n/**\n * The synthetic-safety provider namespace. Every function draws only from a reserved range or the\n * shipped fake-name pool, no value it returns can be real or plausibly-real PHI.\n *\n * @example\n * ```ts\n * import { createRng, safe } from \"@cosyte/synth\";\n * const rng = createRng(42);\n * safe.ssn(rng); // never-issued SSN\n * safe.phone(rng); // reserved 555-01NN number\n * ```\n */\nexport const safe = Object.freeze({\n ssn,\n phone,\n name,\n email,\n ipv4,\n ipv6,\n uuid,\n identifier,\n address,\n dateYmd,\n npi,\n dea,\n});\n","/**\n * Synthetic identity for ASTM (E1394 / CLSI LIS02) messages: every value `synth` puts into a `P`\n * (patient) record, an `O` (order) accession, or the `H` header is minted here, and **only** from the\n * synthetic-safety providers. ASTM's PHI-dense locus is the **`P` record**: it carries the\n * patient **name** (`Last^First^Middle`), **birthdate**, **sex**, and the **practice-assigned** and\n * **laboratory-assigned** patient IDs, which must stay\n * **distinct** (the parser keeps them distinct; a generator that let one default from the other would\n * defeat that). Every identifier is scoped to the synthetic assigning authority: there is no reserved\n * patient-ID range for ASTM (as for MRNs generally), so the **namespace** is the\n * guarantee. The IDs carry a clearly-synthetic prefix (`PRA` / `LAB` / `ACC`) so the `phi-scan` ASTM\n * arm can recognize them as synthetic-AA-scoped and a real bare numeric MRN can never masquerade as one.\n *\n * @module\n */\n\nimport type { Rng } from \"../rng/rng.js\";\nimport { safe, type SyntheticName } from \"../safe/index.js\";\n\n/** Clearly-fictional middle initials, so a `P`-record name can carry the full `Last^First^Middle`. */\nconst SYNTHETIC_MIDDLE_INITIALS: readonly string[] = Object.freeze([\n \"A\",\n \"B\",\n \"C\",\n \"J\",\n \"M\",\n \"R\",\n \"T\",\n]);\n\n/** Clearly-synthetic sender / analyzer identifiers for the `H` header (never a real site or instrument). */\nconst SYNTHETIC_SENDERS: readonly string[] = Object.freeze([\n \"SYNTH-LIS\",\n \"FIXTURE-HOST\",\n \"PLACEHOLDER-LAB\",\n]);\n\n/** Clearly-synthetic analyzer model strings for the `H` header (Universal Test ID sender component). */\nconst SYNTHETIC_ANALYZERS: readonly string[] = Object.freeze([\n \"SYNTH-ANALYZER^ModelS^1\",\n \"MOCK-CHEM^ModelC^2\",\n \"FIXTURE-HEMA^ModelH^1\",\n]);\n\n/** A synthetic ASTM patient: every field drawn from `../safe`. */\nexport interface AstmPatient {\n /** Name from the shipped fake-name pool, plus a fictional middle initial. */\n readonly person: SyntheticName;\n /** Middle initial (clearly synthetic). */\n readonly middle: string;\n /** Birthdate `YYYYMMDD`, from the seeded generator (no real event implied). */\n readonly birthDate: string;\n /** Sex code, emitted verbatim (`M` / `F`, structural, never defaulted by the builder). */\n readonly sex: \"M\" | \"F\";\n /** Practice-assigned patient ID, synthetic-AA scoped (`PRA`-prefixed). Distinct from the lab ID. */\n readonly practiceAssignedId: string;\n /** Laboratory-assigned patient ID, synthetic-AA scoped (`LAB`-prefixed). Distinct from the practice ID. */\n readonly laboratoryAssignedId: string;\n}\n\n/** A synthetic ASTM order identity: the specimen / accession id and priority. */\nexport interface AstmOrder {\n /** Specimen / accession id: synthetic-AA scoped (`ACC`-prefixed). */\n readonly specimenId: string;\n /** Priority code, emitted verbatim (`R` routine, `S` stat). */\n readonly priority: \"R\" | \"S\";\n}\n\n/** A synthetic ASTM header identity: the sender and analyzer strings for the `H` record. */\nexport interface AstmHeaderIdentity {\n /** The sending system id (clearly synthetic). */\n readonly sender: string;\n /** The analyzer / instrument string (clearly synthetic). */\n readonly analyzer: string;\n}\n\n/**\n * Mint a synthetic patient for a `P` record. Fixed draw order (name → middle → DOB → sex → practice id\n * → lab id) so the same seed yields the same patient. The two patient IDs are minted from\n * **independent** synthetic-identifier draws, so they are distinct by construction.\n *\n * @param rng - The seeded generator.\n * @returns A synthetic {@link AstmPatient}.\n * @example\n * ```ts\n * import { createRng } from \"@cosyte/synth\";\n * import { astmPatient } from \"@cosyte/synth/astm\";\n * const { person, practiceAssignedId, laboratoryAssignedId } = astmPatient(createRng(1));\n * ```\n */\nexport function astmPatient(rng: Rng): AstmPatient {\n const person = safe.name(rng);\n const middle = rng.pick(SYNTHETIC_MIDDLE_INITIALS);\n const birthDate = safe.dateYmd(rng, 1935, 2010);\n const sex = rng.pick([\"M\", \"F\"] as const);\n const practiceAssignedId = `PRA${safe.identifier(rng, \"MR\").value}`;\n const laboratoryAssignedId = `LAB${safe.identifier(rng, \"MR\").value}`;\n return { person, middle, birthDate, sex, practiceAssignedId, laboratoryAssignedId };\n}\n\n/**\n * Mint a synthetic order identity for an `O` record: a synthetic-AA-scoped accession id and a priority.\n *\n * @param rng - The seeded generator.\n * @returns A synthetic {@link AstmOrder}.\n * @example\n * ```ts\n * import { createRng } from \"@cosyte/synth\";\n * import { astmOrder } from \"@cosyte/synth/astm\";\n * const { specimenId } = astmOrder(createRng(1));\n * ```\n */\nexport function astmOrder(rng: Rng): AstmOrder {\n const specimenId = `ACC${rng.digits(8)}`;\n const priority = rng.pick([\"R\", \"S\"] as const);\n return { specimenId, priority };\n}\n\n/**\n * Mint a synthetic header identity for the `H` record: a clearly-synthetic sender and analyzer.\n *\n * @param rng - The seeded generator.\n * @returns A synthetic {@link AstmHeaderIdentity}.\n * @example\n * ```ts\n * import { createRng } from \"@cosyte/synth\";\n * import { astmHeaderIdentity } from \"@cosyte/synth/astm\";\n * const { sender } = astmHeaderIdentity(createRng(1));\n * ```\n */\nexport function astmHeaderIdentity(rng: Rng): AstmHeaderIdentity {\n const sender = rng.pick(SYNTHETIC_SENDERS);\n const analyzer = rng.pick(SYNTHETIC_ANALYZERS);\n return { sender, analyzer };\n}\n","/**\n * A small, **license-clean** pool of example ASTM laboratory tests: the analyte codes, units, and\n * plausible value ranges `synth` draws on when populating `O` (order) and `R` (result) records. The\n * codes are **facts** (a LOINC number is a public identifier, and the local analyzer codes here are\n * invented), never a bundled terminology table. Nothing clinical is asserted: a `synth` result pairs a value\n * and a code with no claim of clinical coherence: the pool exists only to make a *structurally* realistic\n * result record.\n *\n * @module\n */\n\n/** One example laboratory analyte: its codes, units, reference range, and a seeded value window. */\nexport interface AstmExampleTest {\n /** A local analyzer test code (invented, never a real vendor assay id). */\n readonly localCode: string;\n /** The public LOINC identifier for the analyte (a fact, not bundled terminology prose). */\n readonly loinc: string;\n /** The human-readable test name, emitted in the Universal Test ID name component. */\n readonly name: string;\n /** The units string, emitted verbatim in `R`-field 5 (never converted or guessed). */\n readonly units: string;\n /** The reference range text, emitted verbatim in `R`-field 6. */\n readonly referenceRange: string;\n /** Inclusive integer low bound of the seeded synthetic value (structural, not clinical). */\n readonly valueLow: number;\n /** Inclusive integer high bound of the seeded synthetic value. */\n readonly valueHigh: number;\n /** Number of decimal places to render the synthetic value with. */\n readonly decimals: number;\n}\n\n/**\n * The example test pool. A handful of common chemistry/hematology analytes, each with a public LOINC\n * code, invented local code, units, and a value window the seeded generator samples. Frozen: the pool\n * is shared, immutable data.\n *\n * @example\n * ```ts\n * import { EXAMPLE_ASTM_TESTS } from \"@cosyte/synth/astm\";\n * EXAMPLE_ASTM_TESTS[0]?.name; // \"Glucose\"\n * ```\n */\nexport const EXAMPLE_ASTM_TESTS: readonly AstmExampleTest[] = Object.freeze([\n {\n localCode: \"GLU\",\n loinc: \"2345-7\",\n name: \"Glucose\",\n units: \"mg/dL\",\n referenceRange: \"70-110\",\n valueLow: 55,\n valueHigh: 260,\n decimals: 0,\n },\n {\n localCode: \"K\",\n loinc: \"2823-3\",\n name: \"Potassium\",\n units: \"mmol/L\",\n referenceRange: \"3.5-5.1\",\n valueLow: 28,\n valueHigh: 62,\n decimals: 1,\n },\n {\n localCode: \"NA\",\n loinc: \"2951-2\",\n name: \"Sodium\",\n units: \"mmol/L\",\n referenceRange: \"136-145\",\n valueLow: 125,\n valueHigh: 155,\n decimals: 0,\n },\n {\n localCode: \"CREA\",\n loinc: \"2160-0\",\n name: \"Creatinine\",\n units: \"mg/dL\",\n referenceRange: \"0.6-1.3\",\n valueLow: 4,\n valueHigh: 32,\n decimals: 1,\n },\n {\n localCode: \"HGB\",\n loinc: \"718-7\",\n name: \"Hemoglobin\",\n units: \"g/dL\",\n referenceRange: \"12.0-17.5\",\n valueLow: 80,\n valueHigh: 190,\n decimals: 1,\n },\n {\n localCode: \"WBC\",\n loinc: \"6690-2\",\n name: \"Leukocytes\",\n units: \"10*3/uL\",\n referenceRange: \"4.5-11.0\",\n valueLow: 30,\n valueHigh: 150,\n decimals: 1,\n },\n {\n localCode: \"TSH\",\n loinc: \"3016-3\",\n name: \"Thyrotropin\",\n units: \"mIU/L\",\n referenceRange: \"0.40-4.50\",\n valueLow: 2,\n valueHigh: 90,\n decimals: 2,\n },\n {\n localCode: \"ALT\",\n loinc: \"1742-6\",\n name: \"Alanine aminotransferase\",\n units: \"U/L\",\n referenceRange: \"7-56\",\n valueLow: 5,\n valueHigh: 120,\n decimals: 0,\n },\n]);\n\n/** HL7 Table 0078 abnormal-flag codes `synth` draws from (emitted verbatim; never defaulted). */\nexport const ASTM_ABNORMAL_FLAGS: readonly string[] = Object.freeze([\"N\", \"L\", \"H\", \"A\"]);\n\n/** Result-status codes `synth` draws from (`F` final, `P` preliminary, `C` correction). */\nexport const ASTM_RESULT_STATUSES: readonly string[] = Object.freeze([\"F\", \"P\", \"C\"]);\n\n/** Free-text result comments: clearly synthetic, carry no PHI. */\nexport const ASTM_COMMENT_TEXT: readonly string[] = Object.freeze([\n \"Synthetic fixture comment - not a clinical observation.\",\n \"Sample generated by @cosyte/synth.\",\n \"Placeholder result comment for conformance testing.\",\n]);\n","/**\n * Spec-clean ASTM (E1394 / CLSI LIS02) message generation: the `H`/`P`/`O`/`R`/`C`/`L` record report,\n * built through `@cosyte/astm`'s `buildAstmMessage` so the delimiter declaration (`H|\\^&`), the record\n * type letters, the per-type sequence counters, the `L` terminator, and every escape are the parser's\n * own conservative emit. Nothing clinical is defaulted: a\n * result's status/flag/units/value are supplied from the example pool, never invented by the builder.\n *\n * A framed **E1381 / CLSI LIS01** variant is also offered ({@link generateAstmResultFramed}) via\n * `composeAstmFrames`, which frames each record into `<STX> FN text <ETB|ETX> CS <CR><LF>` with the\n * **modulo-256 checksum and the `0`–`7` frame number computed by the parser**, never faked. Both round\n * trip through `@cosyte/astm` cleanly (`parseAstmRecords` / `parseFramedAstm`: see `./round-trip`).\n *\n * Every value at a PHI-bearing locus (the `P` record's name / DOB / practice+lab IDs) is\n * drawn from the synthetic-safety providers via `./identity`, so no output can be real or plausibly-real\n * PHI. `synth` is a **format/conformance generator, not a clinical simulator**: a generated\n * result pairs a code and a value with no claim of clinical coherence.\n *\n * @module\n */\n\nimport {\n buildAstmMessage,\n composeAstmFrames,\n type AstmRecordInput,\n type MessageInput,\n} from \"@cosyte/astm\";\n\nimport { createRng, type Rng } from \"../rng/rng.js\";\nimport { astmPatient, astmOrder, astmHeaderIdentity } from \"./identity.js\";\nimport { EXAMPLE_ASTM_TESTS, ASTM_ABNORMAL_FLAGS, ASTM_COMMENT_TEXT } from \"./example-codes.js\";\n\n/** Options for the ASTM message generators. */\nexport interface GenerateAstmOptions {\n /** The seed (deterministic: same seed yields a byte-identical message). */\n readonly seed: number;\n /** How many `R` (result) records to emit. Defaults to a seeded 1–4. */\n readonly resultCount?: number;\n /** Whether to append a `C` (comment) record after the results. Defaults to `true`. */\n readonly comment?: boolean;\n}\n\n/** Render a seeded synthetic numeric result value with the analyte's decimal precision. */\nfunction resultValue(rng: Rng, low: number, high: number, decimals: number): string {\n const raw = rng.int(low, high);\n if (decimals === 0) return String(raw);\n const scale = 10 ** decimals;\n return (raw / scale).toFixed(decimals);\n}\n\n/**\n * Assemble the typed record inputs (P → O → R… → C?) for a result message from a seeded generator. The\n * header and terminator are added by {@link buildAstmMessage}; this builds the body plus the header\n * fields so both the record and framed emitters share one construction.\n */\nfunction buildResultInput(options: GenerateAstmOptions): MessageInput {\n const rng = createRng(options.seed);\n const head = astmHeaderIdentity(rng);\n const patient = astmPatient(rng);\n const order = astmOrder(rng);\n const resultCount = options.resultCount ?? rng.int(1, 4);\n\n const records: AstmRecordInput[] = [\n {\n type: \"P\",\n practiceAssignedId: patient.practiceAssignedId,\n laboratoryAssignedId: patient.laboratoryAssignedId,\n name: { last: patient.person.family, first: patient.person.given, middle: patient.middle },\n birthDate: patient.birthDate,\n sex: patient.sex,\n },\n {\n type: \"O\",\n specimenId: order.specimenId,\n universalTestId: [\"\", \"\", \"\", \"ALL\"],\n priority: order.priority,\n actionCode: \"N\",\n reportType: \"F\",\n },\n ];\n\n for (let i = 0; i < resultCount; i += 1) {\n const test = rng.pick(EXAMPLE_ASTM_TESTS);\n records.push({\n type: \"R\",\n universalTestId: [\"\", \"\", \"\", test.localCode, test.name, test.loinc],\n value: resultValue(rng, test.valueLow, test.valueHigh, test.decimals),\n units: test.units,\n referenceRange: test.referenceRange,\n abnormalFlags: rng.pick(ASTM_ABNORMAL_FLAGS),\n resultStatus: \"F\",\n });\n }\n\n if (options.comment ?? true) {\n records.push({ type: \"C\", source: \"L\", text: rng.pick(ASTM_COMMENT_TEXT), commentType: \"G\" });\n }\n\n return {\n header: { fields: [head.sender, head.analyzer] },\n records,\n terminationCode: \"N\",\n };\n}\n\n/**\n * Generate a spec-clean ASTM **result message**: an `H`/`P`/`O`/`R`…/`C`/`L` record stream, built\n * through `@cosyte/astm`'s `buildAstmMessage`. Every identity value is synthetic-by-construction; the message\n * round-trips through `parseAstmRecords` with zero warnings and re-serializes\n * byte-identically (see `./round-trip`).\n *\n * @param options - The seed, optional result count, and whether to append a comment.\n * @returns The `CR`-terminated ASTM record stream.\n * @example\n * ```ts\n * import { generateAstmResult } from \"@cosyte/synth/astm\";\n * const raw = generateAstmResult({ seed: 42 });\n * ```\n */\nexport function generateAstmResult(options: GenerateAstmOptions): string {\n return buildAstmMessage(buildResultInput(options));\n}\n\n/**\n * Generate a spec-clean ASTM **order message**: an `H`/`P`/`O`/`L` record stream with no results, for\n * the order side of the flow. Built through `buildAstmMessage`; synthetic-by-construction; round-trips\n * clean.\n *\n * @param options - The seed.\n * @returns The `CR`-terminated ASTM record stream.\n * @example\n * ```ts\n * import { generateAstmOrder } from \"@cosyte/synth/astm\";\n * const raw = generateAstmOrder({ seed: 7 });\n * ```\n */\nexport function generateAstmOrder(options: GenerateAstmOptions): string {\n return generateAstmResult({ ...options, resultCount: 0, comment: false });\n}\n\n/**\n * Generate a spec-clean **framed** ASTM result message: the same `H`/`P`/`O`/`R`…/`C`/`L` records,\n * wrapped in the **E1381 / CLSI LIS01** frame envelope (`<STX> FN text <ETB|ETX> CS <CR><LF>`) via\n * `@cosyte/astm`'s `composeAstmFrames`. The **modulo-256 checksum and the `0`–`7` frame number are\n * computed by the parser** (never hand-written), and a record over 240 bytes is split across frames,\n * so the bytes round-trip through `parseFramedAstm` with zero frame **and** record warnings (see\n * `./round-trip`). Each record is framed independently (one `ETX`-closed run per record), mirroring what\n * `decodeAstmFrames` reassembles.\n *\n * @param options - The seed, optional result count, and whether to append a comment.\n * @returns The framed byte stream.\n * @example\n * ```ts\n * import { generateAstmResultFramed } from \"@cosyte/synth/astm\";\n * const bytes = generateAstmResultFramed({ seed: 42 }); // Uint8Array, E1381 framed\n * ```\n */\nexport function generateAstmResultFramed(options: GenerateAstmOptions): Uint8Array {\n const raw = generateAstmResult(options);\n // Split the built stream into its per-record `CR`-terminated lines and frame each independently, so\n // decode reassembles exactly one record per frame run (mirrors `@cosyte/astm`'s `serializeFramedAstm`).\n const recordLines = raw\n .split(\"\\r\")\n .filter((line) => line.length > 0)\n .map((line) => `${line}\\r`);\n return composeAstmFrames(recordLines);\n}\n","/**\n * The **round-trip-through-the-parser harness** for ASTM: the headline gate for the synthetic-fixture\n * generator. A generated ASTM record stream (or framed byte stream) is \"spec-clean\" only\n * if `@cosyte/astm`, not `@cosyte/synth`'s own opinion, reads it back cleanly. Each harness parses the\n * generated wire straight back through the parser and reports what it found, so a false \"spec-clean\"\n * claim cannot hide.\n *\n * The **record** layer (E1394) and the **frame** layer (E1381) are separate concerns, so each gets its\n * own harness; both report the same {@link AstmRoundTripResult} shape (the framed one additionally folds\n * the frame-layer warnings (bad checksum, sequence gap, unterminated, oversize) into `warnings`, so a\n * framing defect is caught by the same gate).\n *\n * @module\n */\n\nimport {\n parseAstmRecords,\n serializeAstmRecords,\n parseFramedAstm,\n serializeFramedAstm,\n} from \"@cosyte/astm\";\n\n/** The verdict of one round-trip through `@cosyte/astm`. */\nexport interface AstmRoundTripResult {\n /** The serialized ASTM wire text (records: the `CR`-terminated stream; framed: the raw bytes as latin1). */\n readonly content: string;\n /** The warning codes the parser emitted on re-parse (record + frame layers). Empty ⇒ spec-clean. */\n readonly warnings: readonly string[];\n /** Whether re-serializing the re-parsed message is byte-identical to the input. */\n readonly byteStable: boolean;\n /** `true` iff the artifact is spec-clean: zero warnings **and** byte-stable. */\n readonly specClean: boolean;\n}\n\n/**\n * Round-trip a generated ASTM **record** stream through parse → serialize and report the verdict. A\n * spec-clean message re-parses with **zero warnings** and re-serializes byte-identically.\n *\n * @param raw - The ASTM record stream (typically from `generateAstmResult` / `generateAstmOrder`).\n * @returns The {@link AstmRoundTripResult}.\n * @example\n * ```ts\n * import { generateAstmResult, astmRoundTrip } from \"@cosyte/synth/astm\";\n * const { specClean } = astmRoundTrip(generateAstmResult({ seed: 1 })); // specClean === true\n * ```\n */\nexport function astmRoundTrip(raw: string): AstmRoundTripResult {\n const message = parseAstmRecords(raw);\n const warnings = message.warnings.map((w) => String(w.code));\n const byteStable = serializeAstmRecords(message) === raw;\n return { content: raw, warnings, byteStable, specClean: warnings.length === 0 && byteStable };\n}\n\n/**\n * Round-trip a generated **framed** ASTM byte stream (E1381) through decode+parse → re-frame and report\n * the verdict. A spec-clean framed message re-parses with **zero record and zero frame warnings** (every\n * modulo-256 checksum verifies, no sequence gap, no unterminated/oversize frame) and re-frames\n * byte-identically.\n *\n * @param bytes - The framed byte stream (typically from `generateAstmResultFramed`).\n * @returns The {@link AstmRoundTripResult}: `content` holds the framed bytes decoded as latin1.\n * @example\n * ```ts\n * import { generateAstmResultFramed, astmFramedRoundTrip } from \"@cosyte/synth/astm\";\n * const { specClean } = astmFramedRoundTrip(generateAstmResultFramed({ seed: 1 })); // true\n * ```\n */\nexport function astmFramedRoundTrip(bytes: Uint8Array): AstmRoundTripResult {\n const { message, frameWarnings } = parseFramedAstm(bytes);\n const warnings = [\n ...frameWarnings.map((w) => String(w.code)),\n ...message.warnings.map((w) => String(w.code)),\n ];\n const reframed = serializeFramedAstm(message);\n const byteStable = bytesEqual(reframed, bytes);\n const content = latin1(bytes);\n return { content, warnings, byteStable, specClean: warnings.length === 0 && byteStable };\n}\n\n/** Byte-for-byte equality of two frame streams. */\nfunction bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i += 1) if (a[i] !== b[i]) return false;\n return true;\n}\n\n/** Decode a frame stream as latin1 for a lossless `string` view (the frame envelope is single-byte). */\nfunction latin1(bytes: Uint8Array): string {\n let out = \"\";\n for (const b of bytes) out += String.fromCharCode(b);\n return out;\n}\n","/**\n * The **selector chokepoint**. A generator's options are almost all *selectors*: a message kind, a\n * document type, a corpus mix, a claim variant, a Bundle type, a profile. Each is typed as a closed\n * union, and every one of those unions is **erased at run time**, so a JavaScript caller (or a\n * `as never` in someone's test) reaches the branch with any string at all.\n *\n * Three things went wrong when that was left unchecked, and they are all the same bug:\n *\n * 1. **The value reached a diagnostic.** An unrecognised `documentType` travelled into\n * `@cosyte/ccda`'s `buildCcda`, which is entitled to quote it back in its own `TypeError` and\n * does. This package then has a caller-supplied string on an `err.message` and an `err.stack`,\n * through its own public entry point, having taken no care of it.\n * 2. **The value reached the model.** A corpus mix entry becomes an `Artifact.kind` and a\n * `manifest.counts` key, which is precisely the structural-identifier position a downstream\n * package interpolates to describe a location.\n * 3. **The fixture was silently mislabeled.** An exhaustive `switch` over an erased union takes no\n * branch and returns `undefined`, or a trailing `else` quietly generates something else. A corpus\n * whose manifest says it holds one transaction and holds another is a golden file that lies.\n *\n * So a selector is resolved against its own set, once, before anything is generated, and an\n * unrecognised one is a fatal `SYNTH_UNSUPPORTED_KIND`. Like every fatal here it carries a code and a\n * fixed message, and quotes neither the request nor the set.\n *\n * @module\n */\n\nimport { SYNTH_FATAL_CODES, SynthError } from \"./codes.js\";\n\n/**\n * Resolve one caller-supplied selector against the closed set that governs it, or **fail closed**.\n *\n * @param allowed - Every value the selector may take.\n * @param requested - The selector the caller supplied.\n * @returns `requested`, narrowed to the union.\n * @throws SynthError `SYNTH_UNSUPPORTED_KIND` when `requested` is not in `allowed`.\n * @example\n * ```ts\n * import { resolveKind } from \"@cosyte/synth\";\n * resolveKind([\"ccd\", \"referralNote\"] as const, \"ccd\"); // \"ccd\"\n * ```\n */\nexport function resolveKind<T extends string>(allowed: readonly T[], requested: string): T {\n const match = allowed.find((value) => value === requested);\n if (match === undefined) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_KIND);\n return match;\n}\n\n/**\n * Resolve every entry of a caller-supplied corpus mix, in order, or **fail closed** on the first\n * unrecognised one.\n *\n * It substitutes the default **only** when the caller supplied nothing, which is exactly what the\n * `??` it replaced did. An empty array is a supplied mix and is returned as one. An earlier version\n * of this function also treated `[]` as \"nothing supplied\", on the stated grounds that it matched the\n * previous behaviour; it did not: `??` fires on `undefined` and never on `[]`, and it changed the\n * result of six published entry points, turning an explicit empty selection into \"generate one of\n * everything\". A convenience that fails open is not a convenience.\n *\n * @param allowed - Every kind the corpus may generate.\n * @param requested - The mix the caller supplied, or `undefined` for the default.\n * @param fallback - The default mix, used only when `requested` is `undefined`.\n * @returns The resolved mix.\n * @throws SynthError `SYNTH_UNSUPPORTED_KIND` on the first unrecognised entry.\n * @example\n * ```ts\n * import { resolveMix } from \"@cosyte/synth\";\n * resolveMix([\"Result\", \"Order\"] as const, [\"Order\"], [\"Result\", \"Order\"]); // [\"Order\"]\n * ```\n */\nexport function resolveMix<T extends string>(\n allowed: readonly T[],\n requested: readonly string[] | undefined,\n fallback: readonly T[],\n): readonly T[] {\n if (requested === undefined) return fallback;\n return requested.map((entry) => resolveKind(allowed, entry));\n}\n","/**\n * `defineSynthProfile`: the growth-loop hook for site/vendor fixture recipes. A profile bundles the\n * value pools and the quirk recipe a fixture set should use, authored through the same public API as\n * the built-ins: a validated, frozen `SynthProfile` carrying a name, optional value overrides, and the\n * quirk names a format's quirk corpus should apply.\n *\n * @module\n */\n\nimport { SYNTH_FATAL_CODES, SynthError } from \"./codes.js\";\n\n/** The user-authored spec passed to {@link defineSynthProfile}. */\nexport interface SynthProfileSpec {\n /** A stable, human-readable profile name (e.g. `\"acme-hospital\"`). Required, non-empty. */\n readonly name: string;\n /** Optional given-name pool override (clearly-synthetic names only, see the safety invariant). */\n readonly givenNames?: readonly string[];\n /** Optional family-name pool override (clearly-synthetic names only). */\n readonly familyNames?: readonly string[];\n /**\n * The vendor quirk recipe names this profile requests. Validated against the target format's quirk\n * registry when the profile drives a quirk corpus (an unsupported quirk is a fatal\n * `SYNTH_UNSUPPORTED_QUIRK`, never a silent no-op).\n */\n readonly quirks?: readonly string[];\n}\n\n/** A frozen, validated fixture recipe produced by {@link defineSynthProfile}. */\nexport interface SynthProfile {\n /** The profile name. */\n readonly name: string;\n /** The given-name pool this profile draws from (overrides or the built-in default). */\n readonly givenNames?: readonly string[];\n /** The family-name pool this profile draws from. */\n readonly familyNames?: readonly string[];\n /** The requested quirk recipe names. */\n readonly quirks: readonly string[];\n}\n\n/**\n * Define a reusable, frozen synthetic-fixture profile.\n *\n * @param spec - The profile spec; `name` is required and non-empty.\n * @returns A deep-frozen {@link SynthProfile}.\n * @throws SynthError `SYNTH_INVALID_PROFILE` when `name` is missing or blank.\n * @example\n * ```ts\n * import { defineSynthProfile } from \"@cosyte/synth\";\n * const acme = defineSynthProfile({ name: \"acme-hospital\", quirks: [] });\n * ```\n */\nexport function defineSynthProfile(spec: SynthProfileSpec): SynthProfile {\n if (typeof spec.name !== \"string\" || spec.name.trim().length === 0) {\n throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INVALID_PROFILE);\n }\n return Object.freeze({\n name: spec.name,\n ...(spec.givenNames ? { givenNames: Object.freeze([...spec.givenNames]) } : {}),\n ...(spec.familyNames ? { familyNames: Object.freeze([...spec.familyNames]) } : {}),\n quirks: Object.freeze([...(spec.quirks ?? [])]),\n });\n}\n","/**\n * The **quirk core**. Where the spec-clean generators prove\n * *synthetic-by-construction* through each parser's own builder, the quirk layer proves the mirror\n * property: a **deliberately off-spec** fixture round-trips to **exactly the intended parser warning\n * code(s)**, no more, no fewer. The quirk vocabulary **is the parsers' own profile systems**\n * (`hl7.defineProfile`, `ccda.defineCcdaProfile`, `astm.defineAstmProfile`): a quirk exercises exactly\n * the tolerance the corresponding parser profile encodes, so a quirk fixture is never a fiction, it\n * targets a documented, coded leniency (the **intended-warning contract**).\n *\n * This module is the **format-agnostic** part: the descriptor a quirk carries, the artifact a quirk\n * generator returns, the round-trip verdict shape, and the `SYNTH_UNSUPPORTED_QUIRK` fail-closed. Each\n * format's concrete quirk recipes + transforms live behind its own subpath (`@cosyte/synth/hl7`, …).\n *\n * @module\n */\n\nimport type { SynthFormat } from \"./corpus.js\";\nimport { SYNTH_FATAL_CODES, SynthError } from \"./codes.js\";\nimport type { SynthProfile } from \"./profile.js\";\n\n/**\n * How the parser's matching profile treats a quirk once it is active: the three shapes the parsers'\n * profile systems actually exhibit (verified firsthand against each parser):\n *\n * - `\"suppressed\"`, the profile makes the warning **disappear** (HL7 v2: a `defineProfile`\n * `customSegments` claim suppresses `UNKNOWN_SEGMENT` for a declared Z-segment).\n * - `\"rebadged\"`, the profile **downgrades** the warning to the value-free `PROFILE_QUIRK_APPLIED`\n * marker with `expected: true` (C-CDA `defineCcdaProfile` / ASTM `defineAstmProfile`\n * `profileQuirkApplied`).\n * - `\"bare\"`, no shipped profile tolerates it; the quirk targets a real coded leniency a consumer can\n * tolerate via their own `defineProfile`/`defineAstmProfile`, but no built-in re-badges it.\n */\nexport type QuirkProfileDisposition = \"suppressed\" | \"rebadged\" | \"bare\";\n\n/**\n * The stable, value-free re-badge code the C-CDA and ASTM parsers emit when a profile tolerates a\n * quirk. HL7 v2 has no equivalent (it suppresses instead: see {@link QuirkProfileDisposition}).\n */\nexport const PROFILE_QUIRK_APPLIED = \"PROFILE_QUIRK_APPLIED\";\n\n/**\n * A public, grounded description of one vendor quirk: the metadata that binds a quirk recipe to a real\n * parser warning code and a **publicly-groundable** deviation (cited-public, never a private\n * vendor corpus).\n */\nexport interface QuirkDescriptor {\n /** The quirk recipe name (e.g. `\"unknown-zsegment\"`). Stable; part of the public contract. */\n readonly name: string;\n /** The format this quirk applies to. */\n readonly format: SynthFormat;\n /**\n * The **exact** parser warning code(s) a bare parse (no profile) surfaces for this quirk, the\n * intended-warning contract. A quirk that produces any other code, or none, is a generation bug.\n */\n readonly intendedWarnings: readonly string[];\n /**\n * The **public** grounding for this quirk, the spec clause or the parser's public profile that\n * documents the tolerance. Never a private vendor-attributed corpus.\n */\n readonly grounding: string;\n /** The parser profile that tolerates this quirk (when a built-in public one exists). */\n readonly toleratingProfile?: string;\n /** How {@link toleratingProfile} treats the quirk. */\n readonly disposition: QuirkProfileDisposition;\n}\n\n/** One generated quirk artifact: the off-spec wire text plus the contract it is meant to satisfy. */\nexport interface QuirkArtifact {\n /** The format this artifact belongs to. */\n readonly format: SynthFormat;\n /** The quirk recipe applied. */\n readonly quirk: string;\n /** The underlying spec-clean message kind the quirk was injected into (e.g. `\"ORU^R01\"`). */\n readonly kind: string;\n /** The **quirked** wire text (deterministic in the seed + quirk). */\n readonly content: string;\n /** The exact parser warning code(s) this artifact is meant to round-trip to. */\n readonly intendedWarnings: readonly string[];\n}\n\n/** The verdict of a bare parse under the tolerating profile, if any. */\nexport interface QuirkProfiledVerdict {\n /** The profile applied. */\n readonly profileName: string;\n /** How the profile treats the quirk. */\n readonly disposition: QuirkProfileDisposition;\n /** The warning codes the parser emitted with the profile active. */\n readonly warnings: readonly string[];\n /**\n * `true` iff the profile handled the quirk as its disposition declares: `\"suppressed\"` ⇒ the intended\n * code is gone; `\"rebadged\"` ⇒ the intended code is gone and `PROFILE_QUIRK_APPLIED` is present.\n */\n readonly tolerated: boolean;\n}\n\n/** The verdict of round-tripping a quirk artifact through its parser. */\nexport interface QuirkRoundTripResult {\n /** The quirked wire text that was parsed. */\n readonly content: string;\n /** The warning codes a **bare** parse (no profile) emitted. */\n readonly warnings: readonly string[];\n /** The exact code(s) the quirk is meant to produce. */\n readonly intendedWarnings: readonly string[];\n /**\n * `true` iff the bare parse produced **exactly** the intended code(s), the intended-warning contract.\n */\n readonly intendedWarningHeld: boolean;\n /** The verdict under the tolerating profile, when a built-in public one exists. */\n readonly withProfile?: QuirkProfiledVerdict;\n}\n\n/**\n * Exact multiset (order-independent) equality of two code lists: the intended-warning comparison.\n *\n * @param a - The first code list.\n * @param b - The second code list.\n * @returns `true` iff the two lists contain the same codes with the same multiplicities.\n * @example\n * ```ts\n * import { sameCodeSet } from \"@cosyte/synth\";\n * sameCodeSet([\"A\", \"B\"], [\"B\", \"A\"]); // true\n * ```\n */\nexport function sameCodeSet(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) return false;\n const counts = new Map<string, number>();\n for (const c of a) counts.set(c, (counts.get(c) ?? 0) + 1);\n for (const c of b) {\n const n = counts.get(c);\n if (n === undefined) return false;\n if (n === 1) counts.delete(c);\n else counts.set(c, n - 1);\n }\n return counts.size === 0;\n}\n\n/**\n * Resolve a requested quirk name against a format's registry, or **fail closed**. A quirk the format's\n * profile system does not support is a fatal `SYNTH_UNSUPPORTED_QUIRK`, never a silent no-op and never\n * a fabricated quirk with a made-up warning.\n *\n * The refusal names neither the request nor the registry. `registry`, `format` and `name` are all\n * caller-supplied, and a diagnostic that quotes its input is a diagnostic that can be made to carry\n * anything the caller was holding, which for a fixture generator wired into someone else's pipeline\n * is not a hypothetical. Branch on `err.code`; the supported set is the registry you passed\n * (`HL7_QUIRKS`, `CCDA_QUIRKS`, `ASTM_QUIRKS`), which you can enumerate directly.\n *\n * @param registry - The format's quirk descriptors, keyed by name.\n * @param format - The format being generated.\n * @param name - The requested quirk name.\n * @returns The matching {@link QuirkDescriptor}.\n * @throws SynthError with code `SYNTH_UNSUPPORTED_QUIRK` when `name` is not a supported quirk.\n * @example\n * ```ts\n * import { resolveQuirk } from \"@cosyte/synth\";\n * import { HL7_QUIRKS } from \"@cosyte/synth/hl7\";\n * resolveQuirk(HL7_QUIRKS, \"hl7v2\", \"unknown-zsegment\").intendedWarnings; // [\"UNKNOWN_SEGMENT\"]\n * ```\n */\nexport function resolveQuirk(\n registry: Readonly<Record<string, QuirkDescriptor>>,\n format: SynthFormat,\n name: string,\n): QuirkDescriptor {\n const descriptor = registry[name];\n // `format` is compared, never rendered. A descriptor found under the wrong format's registry is a\n // mislabeled fixture waiting to happen, so the mismatch fails closed on the same code.\n if (descriptor === undefined || descriptor.format !== format) {\n throw new SynthError(SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_QUIRK);\n }\n return descriptor;\n}\n\n/**\n * Evaluate whether a profiled parse tolerated a quirk as its disposition declares. Shared across the\n * formats so the \"suppressed vs re-badged\" logic lives in exactly one place.\n *\n * @param disposition - The quirk's declared profile disposition.\n * @param intendedWarnings - The bare-parse intended code(s).\n * @param warningsUnderProfile - The code(s) the parser emitted with the profile active.\n * @returns `true` iff the profile handled the quirk correctly for its disposition.\n * @example\n * ```ts\n * import { profileTolerated } from \"@cosyte/synth\";\n * profileTolerated(\"suppressed\", [\"UNKNOWN_SEGMENT\"], []); // true: the profile suppressed it\n * ```\n */\nexport function profileTolerated(\n disposition: QuirkProfileDisposition,\n intendedWarnings: readonly string[],\n warningsUnderProfile: readonly string[],\n): boolean {\n const stillHasIntended = intendedWarnings.some((c) => warningsUnderProfile.includes(c));\n switch (disposition) {\n case \"suppressed\":\n return !stillHasIntended;\n case \"rebadged\":\n return !stillHasIntended && warningsUnderProfile.includes(PROFILE_QUIRK_APPLIED);\n case \"bare\":\n return false;\n }\n}\n\n/**\n * Assert a freshly-generated quirk artifact **actually** round-trips to its intended warning(s), or\n * **fail closed**. This is the generator's self-check on the intended-warning contract: a\n * fixture whose bare parse does not produce exactly the declared code(s) is a *mislabeled* fixture, a\n * golden file that lies about the parser verdict it anchors, and must never be emitted. It is a\n * stronger guard than \"the transform changed some bytes\": a transform can mutate the wrong element (a\n * template a given document type does not key its warning on) and still change bytes while producing no\n * warning. Every format's `generate*Quirk` calls this after transforming, so the contract is enforced at\n * generation time, not merely at round-trip time.\n *\n * It no longer takes the quirk name. That parameter existed for one reason, to be interpolated into\n * the refusal, and a parameter whose only job is to reach a message is the exact shape this package\n * is removing, so it is gone rather than merely unused. The refusal names neither code list either;\n * both are caller-supplied, and the caller reads the comparison back off the arguments it holds.\n *\n * @param intendedWarnings - The declared intended code(s).\n * @param bareWarnings - The code(s) a bare parse of the generated artifact actually produced.\n * @throws SynthError `SYNTH_INTENDED_WARNING_MISMATCH` when the bare parse did not produce exactly\n * the intended code(s).\n * @example\n * ```ts\n * import { assertIntendedWarnings } from \"@cosyte/synth\";\n * assertIntendedWarnings([\"UNKNOWN_SEGMENT\"], [\"UNKNOWN_SEGMENT\"]); // ok\n * ```\n */\nexport function assertIntendedWarnings(\n intendedWarnings: readonly string[],\n bareWarnings: readonly string[],\n): void {\n if (!sameCodeSet(bareWarnings, intendedWarnings)) {\n throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INTENDED_WARNING_MISMATCH);\n }\n}\n\n/**\n * Validate the quirk names carried by a {@link SynthProfile} against a format's registry, failing closed\n * on the first unsupported one. Lets a consumer author a fixture recipe with `defineSynthProfile` and\n * have its quirks checked against the *parser's* real tolerance before any fixture is generated.\n *\n * @param profile - The synth profile whose `quirks` to validate.\n * @param registry - The format's quirk descriptors.\n * @param format - The format being generated.\n * @returns The validated quirk names (the profile's, in order).\n * @throws SynthError `SYNTH_UNSUPPORTED_QUIRK` for the first unsupported quirk.\n * @example\n * ```ts\n * import { validateProfileQuirks, defineSynthProfile } from \"@cosyte/synth\";\n * import { HL7_QUIRKS } from \"@cosyte/synth/hl7\";\n * const p = defineSynthProfile({ name: \"site\", quirks: [\"unknown-zsegment\"] });\n * validateProfileQuirks(p, HL7_QUIRKS, \"hl7v2\"); // [\"unknown-zsegment\"]\n * ```\n */\nexport function validateProfileQuirks(\n profile: SynthProfile,\n registry: Readonly<Record<string, QuirkDescriptor>>,\n format: SynthFormat,\n): readonly string[] {\n for (const name of profile.quirks) resolveQuirk(registry, format, name);\n return profile.quirks;\n}\n","/**\n * ASTM E1394 **vendor-quirk generation**. A quirk deviates the\n * *structure* of an otherwise spec-clean record report (built through `@cosyte/astm`'s\n * `buildAstmMessage`) so it round-trips through `parseAstmRecords` to **exactly** one intended, stable\n * warning code: a code in the parser's `defineAstmProfile` tolerable set. Where a built-in public\n * profile tolerates the quirk, the warning is **re-badged** to the value-free `PROFILE_QUIRK_APPLIED`\n * marker (`expected: true`), exactly as the parser's `profileQuirkApplied` does.\n *\n * The deviation is applied **post-serialize** on the record stream. Two quirks ship:\n *\n * - **`unknown-escape`** → `ASTM_UNKNOWN_ESCAPE_SEQUENCE` (profile `referenceCorpus`). A non-standard\n * `&Z&` escape body is injected into a result's units field. Grounded on `@cosyte/astm`'s public\n * `referenceCorpus` profile (the redistributable kxepal/python-astm + senaite OSS corpus), which\n * re-badges it.\n * - **`unknown-record-type`** → `ASTM_RECORD_UNKNOWN_TYPE`. A record's leading type letter is changed to\n * a site-defined `Z`: a real ASTM tolerance (the parser's tolerable set includes this code), but no\n * built-in profile tolerates it, so it is a `\"bare\"` quirk (a consumer authors a `defineAstmProfile`\n * to re-badge it).\n *\n * A quirk **never** introduces a real-looking value: it changes an escape body or a record type letter,\n * never a P-record identity locus, so the synthetic-safety gate still runs and stays zero.\n *\n * @module\n */\n\nimport { parseAstmRecords, astmProfiles, type AstmProfile } from \"@cosyte/astm\";\n\nimport { createRng } from \"../rng/rng.js\";\nimport { makeCorpus, type Corpus } from \"../corpus.js\";\nimport { defineSynthProfile, type SynthProfile } from \"../profile.js\";\nimport { SYNTH_FATAL_CODES, SynthError } from \"../codes.js\";\nimport {\n resolveQuirk,\n sameCodeSet,\n profileTolerated,\n validateProfileQuirks,\n assertIntendedWarnings,\n type QuirkDescriptor,\n type QuirkArtifact,\n type QuirkRoundTripResult,\n} from \"../quirk.js\";\n\nimport { generateAstmResult } from \"./message.js\";\nimport { resolveKind } from \"../select.js\";\n\n/** Every ASTM quirk this package ships. */\nexport type AstmQuirkName = \"unknown-escape\" | \"unknown-record-type\";\n\n/**\n * Both shipped ASTM quirks are **result-report** deviations: `unknown-escape` targets an `R` record's\n * units field and `unknown-record-type` a `C` (comment) record, neither of which an *order* report\n * carries. So the quirk base is always a result report (`generateAstmResult`).\n */\nexport type AstmQuirkKind = \"Result\";\n\n/** Every value {@link AstmQuirkKind} admits. Erased at run time, so it is resolved, not trusted. */\nconst ALL_QUIRK_KINDS: readonly AstmQuirkKind[] = Object.freeze([\"Result\"]);\n\n/** The ASTM quirk registry: each recipe bound to the exact `@cosyte/astm` warning code it targets. */\nexport const ASTM_QUIRKS: Readonly<Record<AstmQuirkName, QuirkDescriptor>> = Object.freeze({\n \"unknown-escape\": Object.freeze({\n name: \"unknown-escape\",\n format: \"astm\",\n intendedWarnings: Object.freeze([\"ASTM_UNKNOWN_ESCAPE_SEQUENCE\"]),\n grounding:\n \"ASTM E1394 escape delimiter (&); a non-standard &Z& body is preserved verbatim and flagged. \" +\n \"Re-badged by @cosyte/astm's public `referenceCorpus` profile (kxepal/python-astm + senaite OSS).\",\n toleratingProfile: \"referenceCorpus\",\n disposition: \"rebadged\",\n }),\n \"unknown-record-type\": Object.freeze({\n name: \"unknown-record-type\",\n format: \"astm\",\n intendedWarnings: Object.freeze([\"ASTM_RECORD_UNKNOWN_TYPE\"]),\n grounding:\n \"ASTM E1394 permits manufacturer/site-defined record types; a Z record is surfaced as unsupported. \" +\n \"A tolerable code (in the parser's defineAstmProfile allow-list): a consumer authors a profile to \" +\n \"re-badge it; no built-in public profile does.\",\n disposition: \"bare\",\n }),\n});\n\n/** The tolerating ASTM profile object for a quirk, when a built-in public one exists. */\nfunction toleratingProfile(quirk: AstmQuirkName): AstmProfile | undefined {\n return quirk === \"unknown-escape\" ? astmProfiles.referenceCorpus : undefined;\n}\n\n/** The E1394 record separator. */\nconst CR = \"\\r\";\n\n/** The post-serialize transform for each quirk: a pure, deterministic function of the clean record stream. */\nfunction applyQuirk(quirk: AstmQuirkName, records: string): string {\n const lines = records.split(CR);\n switch (quirk) {\n case \"unknown-escape\": {\n // Inject a non-standard &Z& escape into the units field (field 5, index 4) of the first R record.\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i];\n if (line !== undefined && line.startsWith(\"R|\")) {\n const fields = line.split(\"|\");\n const units = fields[4];\n if (units !== undefined && units.length > 0) {\n fields[4] = `&Z&${units}`;\n lines[i] = fields.join(\"|\");\n return lines.join(CR);\n }\n }\n }\n return records;\n }\n case \"unknown-record-type\": {\n // Change the first comment (C) record's leading type letter to a site-defined Z.\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i];\n if (line !== undefined && line.startsWith(\"C|\")) {\n lines[i] = `Z${line.slice(1)}`;\n return lines.join(CR);\n }\n }\n return records;\n }\n }\n}\n\n/** Options for {@link generateAstmQuirk}. */\nexport interface GenerateAstmQuirkOptions {\n /** The seed: the same seed + quirk yields a byte-identical record stream. Defaults to `0`. */\n readonly seed?: number;\n /** The quirk to inject. Required. */\n readonly quirk: AstmQuirkName;\n /** The spec-clean base report kind. Always `\"Result\"` (see {@link AstmQuirkKind}). */\n readonly kind?: AstmQuirkKind;\n}\n\n/**\n * Generate one ASTM **quirk** artifact: a spec-clean record report (built through `@cosyte/astm`) with\n * the requested vendor deviation injected post-serialize. Deterministic in `seed` + `quirk` + `kind`.\n *\n * @param options - Seed, quirk, and base kind. See {@link GenerateAstmQuirkOptions}.\n * @returns The {@link QuirkArtifact}: its `content` round-trips to `intendedWarnings` exactly.\n * @throws SynthError `SYNTH_UNSUPPORTED_QUIRK` if `quirk` is not a supported ASTM quirk.\n * @throws Error if the base report does not contain the structural anchor the quirk targets.\n * @example\n * ```ts\n * import { generateAstmQuirk, astmQuirkRoundTrip } from \"@cosyte/synth/astm\";\n * const rt = astmQuirkRoundTrip(generateAstmQuirk({ seed: 1, quirk: \"unknown-escape\" }));\n * rt.withProfile?.tolerated; // true, `referenceCorpus` re-badges ASTM_UNKNOWN_ESCAPE_SEQUENCE\n * ```\n */\nexport function generateAstmQuirk(options: GenerateAstmQuirkOptions): QuirkArtifact {\n const seed = options.seed ?? 0;\n const kind: AstmQuirkKind = resolveKind(ALL_QUIRK_KINDS, options.kind ?? \"Result\");\n const descriptor = resolveQuirk(ASTM_QUIRKS, \"astm\", options.quirk);\n const clean = generateAstmResult({ seed });\n const content = applyQuirk(options.quirk, clean);\n if (content === clean) {\n throw new SynthError(SYNTH_FATAL_CODES.SYNTH_QUIRK_ANCHOR_ABSENT);\n }\n // Self-check the intended-warning contract at generation time, never emit a mislabeled fixture.\n assertIntendedWarnings(\n descriptor.intendedWarnings,\n parseAstmRecords(content).warnings.map((w) => String(w.code)),\n );\n return Object.freeze({\n format: \"astm\" as const,\n quirk: descriptor.name,\n kind,\n content,\n intendedWarnings: descriptor.intendedWarnings,\n });\n}\n\n/**\n * Round-trip an ASTM quirk artifact through `@cosyte/astm` and report the intended-warning verdict: a bare\n * parse must produce **exactly** the intended code, and, when a built-in public\n * profile tolerates the quirk, the profiled parse must re-badge it to `PROFILE_QUIRK_APPLIED`.\n *\n * @param artifact - The quirk artifact (from {@link generateAstmQuirk}).\n * @returns The {@link QuirkRoundTripResult}.\n * @example\n * ```ts\n * import { generateAstmQuirk, astmQuirkRoundTrip } from \"@cosyte/synth/astm\";\n * astmQuirkRoundTrip(generateAstmQuirk({ seed: 1, quirk: \"unknown-escape\" })).intendedWarningHeld;\n * ```\n */\nexport function astmQuirkRoundTrip(artifact: QuirkArtifact): QuirkRoundTripResult {\n const quirk = artifact.quirk as AstmQuirkName;\n const descriptor = resolveQuirk(ASTM_QUIRKS, \"astm\", quirk);\n const bare = parseAstmRecords(artifact.content).warnings.map((w) => String(w.code));\n const profile = toleratingProfile(quirk);\n const withProfile =\n profile !== undefined && descriptor.toleratingProfile !== undefined\n ? (() => {\n const warnings = parseAstmRecords(artifact.content, { profile }).warnings.map((w) =>\n String(w.code),\n );\n return {\n profileName: descriptor.toleratingProfile,\n disposition: descriptor.disposition,\n warnings,\n tolerated: profileTolerated(\n descriptor.disposition,\n artifact.intendedWarnings,\n warnings,\n ),\n };\n })()\n : undefined;\n return {\n content: artifact.content,\n warnings: bare,\n intendedWarnings: artifact.intendedWarnings,\n intendedWarningHeld: sameCodeSet(bare, artifact.intendedWarnings),\n ...(withProfile ? { withProfile } : {}),\n };\n}\n\n/** Options for {@link astmQuirkCorpus}. */\nexport interface AstmQuirkCorpusOptions {\n /** The seed for the whole corpus (deterministic). */\n readonly seed: number;\n /** How many quirk artifacts to generate. Defaults to the number of quirks. */\n readonly count?: number;\n /** The quirk names to cycle through. Defaults to every ASTM quirk. Validated; unsupported ⇒ fatal. */\n readonly quirks?: readonly AstmQuirkName[];\n /** A {@link SynthProfile} whose `quirks` drive the corpus (validated). Takes precedence over `quirks`. */\n readonly profile?: SynthProfile;\n}\n\nconst ALL_ASTM_QUIRKS: readonly AstmQuirkName[] = Object.freeze(\n Object.keys(ASTM_QUIRKS) as AstmQuirkName[],\n);\n\n/**\n * Build a reproducible {@link Corpus} of ASTM quirk artifacts. Each artifact's `warnings` record the\n * intended code for its quirk; the manifest lists the applied quirk names.\n *\n * @param options - Seed, count, and the quirk selection. See {@link AstmQuirkCorpusOptions}.\n * @returns A deep-frozen {@link Corpus}.\n * @example\n * ```ts\n * import { astmQuirkCorpus } from \"@cosyte/synth/astm\";\n * astmQuirkCorpus({ seed: 42 }).manifest.quirks; // the applied quirk names\n * ```\n */\nexport function astmQuirkCorpus(options: AstmQuirkCorpusOptions): Corpus {\n const quirks: readonly string[] = options.profile\n ? validateProfileQuirks(options.profile, ASTM_QUIRKS, \"astm\")\n : (options.quirks ?? ALL_ASTM_QUIRKS);\n const names = quirks.length > 0 ? quirks : ALL_ASTM_QUIRKS;\n // Resolve the WHOLE list here, not lazily per generated artifact. `count` can be below\n // `names.length`, and the tail then never reaches this module's own `resolveQuirk`\n // while still landing on `manifest.quirks` verbatim. A manifest that names a quirk the\n // corpus does not contain is the same mislabeled-fixture defect the intended-warning\n // contract exists to prevent, and `manifest.quirks` is a derived identifier.\n for (const name of names) resolveQuirk(ASTM_QUIRKS, \"astm\", name);\n const count = options.count ?? names.length;\n const seedStream = createRng(options.seed);\n const artifacts = Array.from({ length: count }, (_unused, i) => {\n const quirk = names[i % names.length] as AstmQuirkName;\n const artifactSeed = seedStream.nextUint32();\n const artifact = generateAstmQuirk({ seed: artifactSeed, quirk });\n return {\n format: \"astm\" as const,\n kind: `Result~${quirk}`,\n content: artifact.content,\n warnings: artifact.intendedWarnings,\n };\n });\n return makeCorpus(options.seed, artifacts, [...new Set(names)]);\n}\n\n/** A ready-made {@link SynthProfile} requesting every built-in ASTM quirk. */\nexport const astmQuirkProfile: SynthProfile = defineSynthProfile({\n name: \"cosyte-astm-quirks\",\n quirks: [...ALL_ASTM_QUIRKS],\n});\n","/**\n * `@cosyte/synth/astm`: the ASTM generation surface, exposed as its own subpath so importing the\n * package root does **not** pull `@cosyte/astm`. This is the **lazy, per-format** boundary: a consumer\n * who only needs ASTM fixtures imports `@cosyte/synth/astm`; one who needs only the core primitives\n * never loads a parser.\n * `@cosyte/astm` is an **optional peer dependency**, present only for this subpath.\n *\n * This subpath ships spec-clean generation of the E1394 record report and its E1381 framed twin, each\n * built through `@cosyte/astm`'s own emit surface:\n *\n * - **Records (E1394):** `generateAstmResult` (`H`/`P`/`O`/`R`…/`C`/`L`) and `generateAstmOrder`\n * (`H`/`P`/`O`/`L`) via `buildAstmMessage`, each round-tripping through `parseAstmRecords` with zero\n * warnings and byte-stable, and carrying a `P` record whose name / DOB / practice+lab IDs are all\n * synthetic-by-construction. The practice- and laboratory-assigned patient IDs are\n * minted independently, so they stay **distinct**.\n * - **Framing (E1381):** `generateAstmResultFramed` via `composeAstmFrames`, the modulo-256 checksum\n * and the `0`–`7` frame number are **computed by the parser, never faked**, and the bytes round-trip\n * through `parseFramedAstm` with zero frame **and** record warnings.\n *\n * @module\n */\n\nimport { createRng } from \"../rng/rng.js\";\nimport { makeCorpus, type Corpus } from \"../corpus.js\";\n\nimport { generateAstmResult, generateAstmOrder } from \"./message.js\";\nimport { astmRoundTrip } from \"./round-trip.js\";\nimport { resolveMix } from \"../select.js\";\n\nexport {\n generateAstmResult,\n generateAstmOrder,\n generateAstmResultFramed,\n type GenerateAstmOptions,\n} from \"./message.js\";\nexport { astmRoundTrip, astmFramedRoundTrip, type AstmRoundTripResult } from \"./round-trip.js\";\nexport {\n astmPatient,\n astmOrder,\n astmHeaderIdentity,\n type AstmPatient,\n type AstmOrder,\n type AstmHeaderIdentity,\n} from \"./identity.js\";\nexport {\n EXAMPLE_ASTM_TESTS,\n ASTM_ABNORMAL_FLAGS,\n ASTM_RESULT_STATUSES,\n ASTM_COMMENT_TEXT,\n type AstmExampleTest,\n} from \"./example-codes.js\";\nexport {\n generateAstmQuirk,\n astmQuirkRoundTrip,\n astmQuirkCorpus,\n astmQuirkProfile,\n ASTM_QUIRKS,\n type AstmQuirkName,\n type AstmQuirkKind,\n type GenerateAstmQuirkOptions,\n type AstmQuirkCorpusOptions,\n} from \"./quirk.js\";\n\n/** Every ASTM message kind {@link astmCorpus} generates: the label used as the corpus `kind`. */\nexport type AstmCorpusKind = \"Result\" | \"Order\";\n\n/** Every kind {@link astmCorpus} accepts, and the default mix: a result report and an order. */\nconst ALL_KINDS: readonly AstmCorpusKind[] = Object.freeze([\"Result\", \"Order\"]);\nconst DEFAULT_MIX = ALL_KINDS;\n\n/** Generate one message of the given kind from a sub-seed, returning the round-trip verdict. */\nfunction generateKind(kind: AstmCorpusKind, seed: number): ReturnType<typeof astmRoundTrip> {\n switch (kind) {\n case \"Result\":\n return astmRoundTrip(generateAstmResult({ seed }));\n case \"Order\":\n return astmRoundTrip(generateAstmOrder({ seed }));\n }\n}\n\n/** Options for {@link astmCorpus}. */\nexport interface AstmCorpusOptions {\n /** The seed for the whole corpus (deterministic). */\n readonly seed: number;\n /** How many messages to generate. Defaults to the length of the mix. */\n readonly count?: number;\n /** The message kinds to cycle through. Defaults to one of each. */\n readonly mix?: readonly AstmCorpusKind[];\n}\n\n/**\n * Build a reproducible {@link Corpus} of spec-clean ASTM messages. Each message is generated from a\n * distinct sub-seed derived from the corpus seed (so the set is deterministic) and round-tripped through\n * `@cosyte/astm`; the per-artifact `warnings` record the parser's verdict (empty ⇒ spec-clean).\n *\n * @param options - Seed, count, and the message mix. See {@link AstmCorpusOptions}.\n * @returns A deep-frozen {@link Corpus}.\n * @example\n * ```ts\n * import { astmCorpus } from \"@cosyte/synth/astm\";\n * const corpus = astmCorpus({ seed: 42 });\n * corpus.artifacts.every((a) => a.warnings.length === 0); // true, spec-clean\n * ```\n */\nexport function astmCorpus(options: AstmCorpusOptions): Corpus {\n const { seed } = options;\n const mix = resolveMix(ALL_KINDS, options.mix, DEFAULT_MIX);\n const count = options.count ?? mix.length;\n const seedStream = createRng(seed);\n const artifacts = Array.from({ length: count }, (_unused, i) => {\n const kind = mix[i % mix.length] ?? \"Result\";\n const msgSeed = seedStream.nextUint32();\n const rt = generateKind(kind, msgSeed);\n return {\n format: \"astm\" as const,\n kind,\n content: rt.content,\n warnings: rt.warnings,\n };\n });\n return makeCorpus(seed, artifacts);\n}\n"]}
1
+ {"version":3,"sources":["../../src/rng/splitmix32.ts","../../src/rng/sfc32.ts","../../src/codes.ts","../../src/rng/rng.ts","../../src/corpus.ts","../../src/safe/reserved.ts","../../src/safe/names-pool.ts","../../src/safe/providers.ts","../../src/safe/index.ts","../../src/astm/identity.ts","../../src/astm/example-codes.ts","../../src/astm/message.ts","../../src/astm/round-trip.ts","../../src/select.ts","../../src/profile.ts","../../src/quirk.ts","../../src/astm/quirk.ts","../../src/astm/index.ts"],"names":["buildAstmMessage","composeAstmFrames","parseAstmRecords","serializeAstmRecords","parseFramedAstm","serializeFramedAstm","name","astmProfiles"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * `splitmix32`: a tiny, well-studied 32-bit mixing PRNG used **only** to expand a single integer\n * seed into the four 32-bit state words that seed {@link ../rng/sfc32.sfc32}. It is not the corpus\n * generator itself (that is `sfc32`); it exists so that a one-number seed deterministically produces a\n * well-distributed 128-bit `sfc32` state, avoiding the poor low-bit behavior of naive\n * `state = seed`-style initialization.\n *\n * Zero-dependency, `Math.random`-free (lint-enforced): the whole point of the library is that a seed,\n * and only the seed, determines the output, on any machine, any run.\n *\n * @module\n */\n\n/**\n * A stateful `splitmix32` step function. Each call advances the internal 32-bit state and returns the\n * next unsigned 32-bit integer. Deterministic for a given seed.\n *\n * @param seed - The 32-bit seed. Coerced to a 32-bit integer via `| 0`.\n * @returns A nullary function returning the next `uint32` in the stream.\n * @example\n * ```ts\n * import { splitmix32 } from \"@cosyte/synth\";\n * const next = splitmix32(12345);\n * const a = next(); // deterministic uint32\n * ```\n */\nexport function splitmix32(seed: number): () => number {\n let a = seed | 0;\n return function next(): number {\n a = (a + 0x9e3779b9) | 0;\n let t = a ^ (a >>> 16);\n t = Math.imul(t, 0x21f0aaad);\n t = t ^ (t >>> 15);\n t = Math.imul(t, 0x735a2d97);\n t = t ^ (t >>> 15);\n return t >>> 0;\n };\n}\n","/**\n * `sfc32` (Small Fast Counter, 32-bit, 128-bit state): the deterministic, non-cryptographic PRNG that\n * drives every value `@cosyte/synth` generates. Chosen over `mulberry32` (whose author flags that it\n * skips ~1/3 of 32-bit outputs) and over a CSPRNG (`node:crypto`, which is **not seedable** and would\n * defeat reproducibility). A synthetic-fixture generator has **no secrets**: statistical quality plus\n * byte-for-byte reproducibility is exactly the right trade.\n *\n * The state is four 32-bit words. This module exposes the raw step function; {@link ../rng/rng.Rng}\n * wraps it with a seed-expansion ({@link ./splitmix32.splitmix32}) and the ergonomic draw helpers.\n *\n * @module\n */\n\n/**\n * The mutable four-word `sfc32` state. Threaded explicitly (never global) by {@link ../rng/rng.Rng}.\n */\nexport interface Sfc32State {\n /** State word `a`. */\n a: number;\n /** State word `b`. */\n b: number;\n /** State word `c`. */\n c: number;\n /** Counter word `d`. */\n d: number;\n}\n\n/**\n * Advance an {@link Sfc32State} in place by one step and return the next unsigned 32-bit integer.\n *\n * This is the canonical `sfc32` step. The state object is mutated (the counter `d` increments and the\n * mixing words rotate); callers that need reproducible independence hold their own state and never\n * share it: {@link ../rng/rng.Rng} creates a fresh state per seed so two runs from the same seed are\n * identical.\n *\n * @param s - The state to advance. Mutated in place.\n * @returns The next `uint32` in the stream.\n * @example\n * ```ts\n * import { sfc32Next, type Sfc32State } from \"@cosyte/synth\";\n * const s: Sfc32State = { a: 1, b: 2, c: 3, d: 4 };\n * const x = sfc32Next(s); // uint32\n * ```\n */\nexport function sfc32Next(s: Sfc32State): number {\n s.a |= 0;\n s.b |= 0;\n s.c |= 0;\n s.d |= 0;\n const t = (((s.a + s.b) | 0) + s.d) | 0;\n s.d = (s.d + 1) | 0;\n s.a = s.b ^ (s.b >>> 9);\n s.b = (s.c + (s.c << 3)) | 0;\n s.c = (s.c << 21) | (s.c >>> 11);\n s.c = (s.c + t) | 0;\n return t >>> 0;\n}\n","/**\n * Stable diagnostic codes for `@cosyte/synth` and the {@link SynthError} they travel on.\n *\n * Unlike a parser (which recovers from bad *input* into Tier-2 warnings), a **generator** has no input\n * to tolerate: its reflex is *synthetic-by-construction* and *fail-closed on impossibility*. So the\n * codes here are **fatal**: a caller asked for something the library cannot honor spec-clean, and the\n * only safe answer is to throw, never to silently fabricate a value or a byte workaround. Codes are `key ===\n * value` and part of the public contract:\n * renaming one is a breaking change.\n *\n * @module\n */\n\n/**\n * The stable **fatal** code registry. Additions-only thereafter.\n *\n * @example\n * ```ts\n * import { SYNTH_FATAL_CODES, SynthError } from \"@cosyte/synth\";\n * try {\n * // ...generate...\n * } catch (err) {\n * if (err instanceof SynthError && err.code === SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_FORMAT) {\n * // handle an unsupported format request\n * }\n * }\n * ```\n */\nexport const SYNTH_FATAL_CODES = {\n /**\n * A format was requested that this build cannot generate through a real parser builder/serializer.\n * Fatal, never a hand-written byte fallback.\n *\n * **No code path in this build raises it.** All six formats generate, so it is reserved for a\n * future format that does not, and is kept because removing a published code is a breaking change.\n * An unsupported *kind* within a format that does generate is `SYNTH_UNSUPPORTED_KIND`.\n */\n SYNTH_UNSUPPORTED_FORMAT: \"SYNTH_UNSUPPORTED_FORMAT\",\n /**\n * A vendor quirk was requested that the target format's profile system does not support. Fatal,\n * never a silent no-op and never a fabricated quirk.\n */\n SYNTH_UNSUPPORTED_QUIRK: \"SYNTH_UNSUPPORTED_QUIRK\",\n /**\n * A quirk transform found no structural anchor to mutate, so the fixture would not carry the\n * deviation it is labelled with. Fatal: a golden file that lies about its parser verdict is worse\n * than no golden file.\n */\n SYNTH_QUIRK_ANCHOR_ABSENT: \"SYNTH_QUIRK_ANCHOR_ABSENT\",\n /**\n * A bare parse of a freshly-generated quirk artifact did not produce exactly the declared intended\n * warning code(s). Fatal, never emit a mislabeled fixture.\n */\n SYNTH_INTENDED_WARNING_MISMATCH: \"SYNTH_INTENDED_WARNING_MISMATCH\",\n /** A concept's code-system URI has no OID mapping in the C-CDA example-code table. Fatal. */\n SYNTH_UNMAPPED_CODE_SYSTEM: \"SYNTH_UNMAPPED_CODE_SYSTEM\",\n /** A money value could not be read as an X12 decimal. Fatal: a generator never rounds to a float. */\n SYNTH_INVALID_DECIMAL: \"SYNTH_INVALID_DECIMAL\",\n /** An integer range was requested with its maximum below its minimum. Fatal. */\n SYNTH_INVALID_RANGE: \"SYNTH_INVALID_RANGE\",\n /** A value was drawn from an empty pool. Fatal, never a fabricated substitute. */\n SYNTH_EMPTY_POOL: \"SYNTH_EMPTY_POOL\",\n /** A `defineSynthProfile` spec was not usable (a missing or blank `name`). Fatal. */\n SYNTH_INVALID_PROFILE: \"SYNTH_INVALID_PROFILE\",\n /**\n * A caller-supplied selector (a message kind, a document type, a corpus mix entry, a claim\n * variant, a Bundle type, a resource profile) is not in the closed set that governs it. Fatal:\n * see `resolveKind`: a selector union is erased at run time, and a selector that falls through\n * either mislabels the fixture or hands the value to a peer builder that quotes it back.\n */\n SYNTH_UNSUPPORTED_KIND: \"SYNTH_UNSUPPORTED_KIND\",\n /**\n * A requested profile IS published by the adopted implementation guide, and this build does not\n * generate it. Deliberately distinct from `SYNTH_UNSUPPORTED_KIND`, which says the name is not in\n * the adopted set at all: \"the guide does not publish this\" and \"we do not generate this yet\" are\n * different answers, and a caller building to a regulatory profile set has to be able to tell them\n * apart without matching message text. Fatal, and raised **before** anything is generated: a\n * mislabelled artifact is worse than no artifact.\n */\n SYNTH_PROFILE_NOT_GENERATED: \"SYNTH_PROFILE_NOT_GENERATED\",\n} as const;\n\n/**\n * A value from {@link SYNTH_FATAL_CODES}: the type carried by a thrown {@link SynthError}.\n */\nexport type SynthFatalCode = (typeof SYNTH_FATAL_CODES)[keyof typeof SYNTH_FATAL_CODES];\n\n/**\n * The **frozen message registry**: the only place a {@link SynthError} message can come from.\n *\n * A message here is a fixed string. It never quotes the request that produced it, and there is no\n * parameter through which it could: {@link SynthError} takes a code and nothing else. That is the\n * whole mechanism, and it is deliberately a mechanism rather than a habit. Every one of these\n * messages used to be assembled by interpolating the caller's value into a template, and the reason\n * that was safe was not the design: it was that the caller happened to be passing a quirk name.\n *\n * The trade is real and is accepted: a fatal no longer tells you *which* value it rejected. It tells\n * you which rule refused, on `err.code`, and the stack frame tells you where. The caller already\n * holds the value it passed.\n *\n * @example\n * ```ts\n * import { SYNTH_FATAL_CODES, SYNTH_FATAL_MESSAGES } from \"@cosyte/synth\";\n * SYNTH_FATAL_MESSAGES[SYNTH_FATAL_CODES.SYNTH_EMPTY_POOL]; // => \"A value was drawn from an empty pool.\"\n * ```\n */\nexport const SYNTH_FATAL_MESSAGES: Readonly<Record<SynthFatalCode, string>> = Object.freeze({\n SYNTH_UNSUPPORTED_FORMAT:\n \"The requested format is not generable by this build. A generator has no byte fallback: it \" +\n \"builds through a parser's own serializer or it refuses.\",\n SYNTH_UNSUPPORTED_QUIRK:\n \"The requested vendor quirk is not in the target format's quirk registry. Compare the request \" +\n \"against that format's exported registry (HL7_QUIRKS, CCDA_QUIRKS, ASTM_QUIRKS).\",\n SYNTH_QUIRK_ANCHOR_ABSENT:\n \"The quirk transform found no structural anchor to mutate, so the fixture would not carry the \" +\n \"deviation it is labelled with. Refusing to emit a mislabeled fixture.\",\n SYNTH_INTENDED_WARNING_MISMATCH:\n \"A bare parse of the generated quirk artifact did not produce exactly the declared intended \" +\n \"warning code(s). Refusing to emit a mislabeled fixture.\",\n SYNTH_UNMAPPED_CODE_SYSTEM:\n \"The concept's code-system URI has no OID mapping in the C-CDA example-code table.\",\n SYNTH_INVALID_DECIMAL: \"The value could not be read as an X12 decimal.\",\n SYNTH_INVALID_RANGE: \"An integer range was requested with its maximum below its minimum.\",\n SYNTH_EMPTY_POOL: \"A value was drawn from an empty pool.\",\n SYNTH_INVALID_PROFILE: \"defineSynthProfile requires a non-empty string name.\",\n SYNTH_UNSUPPORTED_KIND:\n \"The requested kind, document type, corpus mix entry, variant or profile is not one this \" +\n \"generator supports. The supported set is the exported union for that option.\",\n SYNTH_PROFILE_NOT_GENERATED:\n \"The requested profile is published by the adopted implementation guide, and this build does \" +\n \"not generate it. The coverage surface reports, per adopted profile, whether it is generated.\",\n});\n\n/**\n * The typed error every fatal `@cosyte/synth` condition throws. Carries a stable\n * {@link SynthFatalCode} so callers branch on `err.code` without matching message text.\n *\n * It takes **no value parameter**. The message is whatever {@link SYNTH_FATAL_MESSAGES} holds for the\n * code, so no caller-supplied string can reach a diagnostic surface by any route, not `message`, not\n * `stack`, not a field on the thrown object.\n *\n * @example\n * ```ts\n * import { SynthError, SYNTH_FATAL_CODES } from \"@cosyte/synth\";\n * throw new SynthError(SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_FORMAT);\n * ```\n */\nexport class SynthError extends Error {\n /** The stable fatal code. */\n public readonly code: SynthFatalCode;\n\n /**\n * @param code - The stable {@link SynthFatalCode}. The message comes from the frozen registry.\n */\n public constructor(code: SynthFatalCode) {\n super(SYNTH_FATAL_MESSAGES[code]);\n this.name = \"SynthError\";\n this.code = code;\n }\n}\n","/**\n * `Rng`: the seeded, deterministic random source every `@cosyte/synth` provider draws from.\n *\n * **The reproducibility contract.** A seed, and only the seed, determines the output.\n * `createRng(seed)` expands the integer seed through {@link ./splitmix32.splitmix32} into the four\n * `sfc32` state words, then every draw advances that state via {@link ./sfc32.sfc32Next}. Two `Rng`s\n * created from the same seed emit the **identical** sequence on any machine, any run: the property\n * the parsers', `transform`'s, and `deid`'s regression suites depend on.\n *\n * **Explicit, never global.** An `Rng` is a value you thread through a build; there is no ambient\n * shared generator and **`Math.random` is lint-banned** in `src/` (it is not seedable: its seed is\n * engine-chosen and cannot be reset, so a corpus built on it is not reproducible). Because each\n * generation creates a fresh `Rng` from its seed, generations are independent and parallel-safe.\n *\n * The `Rng` object is stateful by nature (a PRNG advances). Immutability in this library lives where it\n * is testable and matters: the generated **artifacts and the `Corpus` are deep-frozen** (see\n * `../corpus.ts`). Determinism, not object-immutability, is the `Rng`'s guarantee.\n *\n * @module\n */\n\nimport { splitmix32 } from \"./splitmix32.js\";\nimport { sfc32Next, type Sfc32State } from \"./sfc32.js\";\nimport { SYNTH_FATAL_CODES, SynthError } from \"../codes.js\";\n\n/**\n * A seeded, deterministic random source. Created via {@link createRng}; passed explicitly to every\n * provider. All draw methods advance the internal state deterministically.\n */\nexport interface Rng {\n /** The integer seed this generator was created from (part of the `Corpus` manifest). */\n readonly seed: number;\n /** The next unsigned 32-bit integer. */\n nextUint32(): number;\n /** The next float in `[0, 1)`. */\n float(): number;\n /**\n * A uniformly-distributed integer in the inclusive range `[min, max]`.\n *\n * @param min - Inclusive lower bound (integer).\n * @param max - Inclusive upper bound (integer, `>= min`).\n */\n int(min: number, max: number): number;\n /** `true` with probability `p` (default `0.5`). */\n bool(p?: number): boolean;\n /**\n * Pick one element from a non-empty array.\n *\n * @param items - A non-empty readonly array.\n */\n pick<T>(items: readonly T[]): T;\n /**\n * A string of `n` decimal digits (`0`–`9`), each drawn uniformly.\n *\n * @param n - The number of digits (`>= 0`).\n */\n digits(n: number): string;\n}\n\n/**\n * The concrete {@link Rng}. Holds the mutable `sfc32` state; every method advances it deterministically.\n */\nclass Sfc32Rng implements Rng {\n public readonly seed: number;\n readonly #state: Sfc32State;\n\n public constructor(seed: number) {\n this.seed = seed | 0;\n // Expand the single seed into four well-distributed state words. Seeding sfc32 directly from the\n // raw seed gives poor low-bit behavior; splitmix32 is the standard fix (bryc / roadmap §5).\n const mix = splitmix32(this.seed);\n this.#state = { a: mix(), b: mix(), c: mix(), d: mix() };\n // A short warm-up so nearby seeds diverge immediately.\n for (let i = 0; i < 8; i += 1) sfc32Next(this.#state);\n }\n\n public nextUint32(): number {\n return sfc32Next(this.#state);\n }\n\n public float(): number {\n return this.nextUint32() / 0x1_0000_0000;\n }\n\n public int(min: number, max: number): number {\n if (max < min) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INVALID_RANGE);\n const span = max - min + 1;\n return min + Math.floor(this.float() * span);\n }\n\n public bool(p = 0.5): boolean {\n return this.float() < p;\n }\n\n public pick<T>(items: readonly T[]): T {\n if (items.length === 0) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_EMPTY_POOL);\n // `int(0, length-1)` is always in-bounds on a non-empty array, so this access cannot be a hole;\n // the cast discharges `noUncheckedIndexedAccess`'s `T | undefined` without a runtime re-check.\n return items[this.int(0, items.length - 1)] as T;\n }\n\n public digits(n: number): string {\n let out = \"\";\n for (let i = 0; i < n; i += 1) out += String(this.int(0, 9));\n return out;\n }\n}\n\n/**\n * Create a seeded, deterministic {@link Rng}. The same `seed` yields the same sequence everywhere.\n *\n * @param seed - The integer seed. Coerced to a 32-bit integer.\n * @returns A fresh, independent {@link Rng}.\n * @example\n * ```ts\n * import { createRng } from \"@cosyte/synth\";\n * const rng = createRng(12345);\n * rng.int(1, 6); // deterministic for seed 12345\n * ```\n */\nexport function createRng(seed: number): Rng {\n return new Sfc32Rng(seed);\n}\n","/**\n * The `Corpus` abstraction: a seed plus a self-describing manifest of what was generated, so a\n * fixture set is itself reproducible and regenerable. A downstream repo pins a seed\n * and gets a stable fixture set that regenerates identically.\n *\n * Generated artifacts and the `Corpus` are **deep-frozen**: this is where the archetype's immutability\n * invariant lives in a generator: a consumer cannot mutate a shared fixture out from under\n * another test.\n *\n * @module\n */\n\n/** The format an artifact was generated for. */\nexport type SynthFormat = \"hl7v2\" | \"fhir\" | \"ccda\" | \"x12\" | \"ncpdp\" | \"astm\";\n\n/**\n * One generated artifact: the serialized wire text plus the metadata needed to reproduce and check\n * it. `warnings` records what the artifact's own parser reported on the round-trip (zero for a\n * spec-clean artifact).\n */\nexport interface Artifact {\n /** The format this artifact belongs to. */\n readonly format: SynthFormat;\n /** A format-specific kind label (e.g. `\"ADT^A01\"`). */\n readonly kind: string;\n /** The serialized wire text, produced by the parser's own conservative serializer. */\n readonly content: string;\n /** The warning codes the parser emitted when the artifact was round-tripped (empty = spec-clean). */\n readonly warnings: readonly string[];\n}\n\n/** A self-describing manifest of a {@link Corpus}. */\nexport interface CorpusManifest {\n /** The formats present in the corpus. */\n readonly formats: readonly SynthFormat[];\n /** Per-kind artifact counts (e.g. `{ \"ADT^A01\": 3 }`). */\n readonly counts: Readonly<Record<string, number>>;\n /** The quirk names applied. */\n readonly quirks: readonly string[];\n}\n\n/** A reproducible, self-describing set of generated artifacts. */\nexport interface Corpus {\n /** The seed the corpus was generated from: regenerating from it yields byte-identical artifacts. */\n readonly seed: number;\n /** The manifest describing what was generated. */\n readonly manifest: CorpusManifest;\n /** The generated artifacts, in generation order. */\n readonly artifacts: readonly Artifact[];\n}\n\n/**\n * Assemble a deep-frozen {@link Corpus} from a seed and its artifacts, deriving the manifest.\n *\n * @param seed - The seed the artifacts were generated from.\n * @param artifacts - The generated artifacts, in order.\n * @param quirks - The quirk names applied (default none).\n * @returns A deep-frozen, self-describing {@link Corpus}.\n * @example\n * ```ts\n * import { makeCorpus } from \"@cosyte/synth\";\n * const corpus = makeCorpus(1, [{ format: \"hl7v2\", kind: \"ADT^A01\", content, warnings: [] }]);\n * corpus.manifest.counts[\"ADT^A01\"]; // 1\n * ```\n */\nexport function makeCorpus(\n seed: number,\n artifacts: readonly Artifact[],\n quirks: readonly string[] = [],\n): Corpus {\n const counts: Record<string, number> = {};\n const formats = new Set<SynthFormat>();\n const frozenArtifacts = artifacts.map((a) => {\n counts[a.kind] = (counts[a.kind] ?? 0) + 1;\n formats.add(a.format);\n return Object.freeze({ ...a, warnings: Object.freeze([...a.warnings]) });\n });\n const manifest: CorpusManifest = Object.freeze({\n formats: Object.freeze([...formats]),\n counts: Object.freeze(counts),\n quirks: Object.freeze([...quirks]),\n });\n return Object.freeze({\n seed,\n manifest,\n artifacts: Object.freeze(frozenArtifacts),\n });\n}\n","/**\n * The reserved / never-collide identifier facts that make a `@cosyte/synth` value **provably\n * synthetic**: the ground truth behind the synthetic-safety invariant.\n *\n * These are **facts**, not copyrighted prose: ranges and check-digit rules published by SSA, the\n * IRS, HHS, NANPA and the IETF that are guaranteed never to denote a real person or a real routable\n * resource. Where two authorities share one number space (SSN and ITIN), a value must be outside\n * both. Every provider draws only from these; the predicates here are the executable half of the CI\n * synthetic-safety gate: they let a test assert that no emitted value falls **outside** a reserved\n * source.\n *\n * Every entry below names its authority by that authority's **own published identifier**, never by a\n * bare hostname, so a reader can open the text and check the claim instead of taking this module's\n * word for it. Two loci have no reserving authority and one rests on a source that is not the\n * issuing agency; each says so at the point of use rather than being left out of this list.\n *\n * Sources:\n * - **SSN**, SSA POMS RM 10201.035 (Invalid Social Security Numbers (SSNs)) defines an invalid SSN\n * as \"one that we never assigned\", and identifies one by a first three digits (former area number)\n * of `000`, `666`, or \"in the 900 series\", or a second group of two digits (former group number)\n * of `00`. <https://secure.ssa.gov/poms.nsf/lnx/0110201035>\n * - **ITIN**, an IRS Individual Taxpayer Identification Number shares the SSN number space by\n * construction: it is a `9NN-GG-NNNN` value whose group `GG` falls in a published ITIN group\n * range. Area `900-999` alone therefore does not prove a value cannot be a federally issued\n * identifier, so a synthetic SSN also keeps its group outside every published range. IRS Internal\n * Revenue Manual 3.21.263: \"An ITIN begins with a `9` and the 4th and 5th digits are 50-65, 70-88,\n * 90-92 and 94-99\". <https://www.irs.gov/irm/part3/irm_03-021-263r>\n * - **Phone**, NANPA's 555 Line Numbers page: \"The fictitious, non-working numbers, 555-0100 through\n * 555-0199, will remain reserved for entertainment/advertising.\"\n * <https://nanpa.com/numbering/555-line-numbers>\n * - **Email/domain**, RFC 2606 (Reserved Top Level DNS Names) reserves the `.test`, `.example`,\n * `.invalid` and `.localhost` top-level names and the second-level names `example.com`/`.net`/\n * `.org`; RFC 6761 section 6.5 carries the example domains into the special-use registry.\n * <https://datatracker.ietf.org/doc/html/rfc2606>,\n * <https://datatracker.ietf.org/doc/html/rfc6761>\n * - **IP**, RFC 5737: the blocks `192.0.2.0/24` (TEST-NET-1), `198.51.100.0/24` (TEST-NET-2) and\n * `203.0.113.0/24` (TEST-NET-3) \"are provided for use in documentation\"; RFC 3849: \"The prefix\n * allocated for documentation purposes is 2001:DB8::/32\".\n * <https://datatracker.ietf.org/doc/html/rfc5737>,\n * <https://datatracker.ietf.org/doc/html/rfc3849>\n * - **NPI**, a real National Provider Identifier is a 10-digit number whose last digit is a Luhn\n * check digit computed over the `80840` prefix + the 9-digit base. The rule is 69 FR 3434, the\n * final rule adopting the NPI (FR Doc 04-1149, docket CMS-0045-F), whose issuing agency that\n * document records as \"Centers for Medicare & Medicaid Services, HHS\": \"the NPI check digit\n * calculation must always be performed as though the NPI is preceded by\" `80840`, and the check\n * digit is \"calculated using the ISO standard Luhn check digit algorithm\". A number whose check\n * digit is **wrong** therefore cannot be a validly issued NPI. `synth` emits NPIs with a\n * deliberately-invalid check digit, so no generated NPI can collide with a real provider.\n * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>\n * - **DEA**, the check-digit formula is **not** attributed to the DEA and no DEA-published text\n * stating it is cited anywhere here. See {@link deaCheckDigit}, which names the non-normative\n * source the claim does rest on, and what that source is not.\n * - **MRN / member / account**, **no authority reserves this locus**: there is no reserved MRN range\n * and none is claimed. See {@link SYNTHETIC_ASSIGNING_AUTHORITY} for what the floor rests on\n * instead.\n *\n * @module\n */\n\n/**\n * The synthetic **assigning authority** `@cosyte/synth` mints MRNs / account / member identifiers\n * under.\n *\n * **No authority reserves this locus.** An MRN is unique only within its assigning-authority / OID\n * namespace, no registry reserves a range of them, and none is cited here. What the floor rests on\n * instead is the *namespace*, as a documented design decision: every synthetic identifier is scoped\n * to a namespace that clearly cannot be a real facility's, a `SYNTH`-labelled authority this package\n * mints and no real facility uses. A value under this AA can never collide with a real record\n * whatever its digits are, because the namespace itself is synthetic.\n *\n * The OID is **uncited for the same reason**. `2.16.840.1.113883.19.999` is a value this package\n * chose; no published text designating the root `2.16.840.1.113883.19` for example use could be\n * shown, so this module claims no such designation and the guarantee above does not rest on one.\n */\nexport const SYNTHETIC_ASSIGNING_AUTHORITY = Object.freeze({\n /** The human-readable assigning-authority namespace id (HL7 HD.1). */\n namespaceId: \"COSYTE-SYNTH\",\n /** The universal id, an OID this package chose under the root `2.16.840.1.113883.19` (HD.2). */\n universalId: \"2.16.840.1.113883.19.999\",\n /** The universal id type (HD.3). */\n universalIdType: \"ISO\",\n});\n\n/** RFC 2606 / 6761 reserved email domains `@cosyte/synth` draws from. */\nexport const RESERVED_EMAIL_DOMAINS: readonly string[] = Object.freeze([\n \"example.com\",\n \"example.org\",\n \"example.net\",\n]);\n\n/** RFC 5737 IPv4 documentation (TEST-NET) `/24` network prefixes. */\nexport const TEST_NET_V4_PREFIXES: readonly string[] = Object.freeze([\n \"192.0.2\", // TEST-NET-1\n \"198.51.100\", // TEST-NET-2\n \"203.0.113\", // TEST-NET-3\n]);\n\n/** RFC 3849 IPv6 documentation prefix. */\nexport const DOC_V6_PREFIX = \"2001:db8\";\n\n/**\n * The published **IRS ITIN group ranges**, inclusive `[min, max]` bands over the two group digits\n * (positions 4 and 5) of a `9NN-GG-NNNN` value. An Individual Taxpayer Identification Number is an\n * SSN-format number that begins with `9` and carries a group inside one of these bands, so these\n * bands are what separates an SSN the SSA manual calls invalid from a validly formatted ITIN.\n *\n * These are **facts** about the number's shape, not copyrighted prose (IRS Internal Revenue Manual\n * 3.21.263). Group values `89` and `93` sit between the bands on purpose: the IRM records them as\n * reserved for other IRS programs rather than for ITINs, so a value carrying one is **not**\n * ITIN-formatted (see {@link isItinFormatted}).\n */\nexport const ITIN_GROUP_RANGES: readonly Readonly<{ min: number; max: number }>[] = Object.freeze([\n Object.freeze({ min: 50, max: 65 }),\n Object.freeze({ min: 70, max: 88 }),\n Object.freeze({ min: 90, max: 92 }),\n Object.freeze({ min: 94, max: 99 }),\n]);\n\n/**\n * The two group values the IRM records as reserved for other IRS programs rather than for ITINs.\n * They are **not** ITIN-formatted (so {@link isItinFormatted} must not claim them), and they are\n * still an issuing authority's space, so {@link SSN_SYNTHETIC_GROUPS} does not draw from them\n * either: the generator stays out of every federally used group, not merely out of the ITIN ones.\n *\n * @internal\n */\nconst ITIN_EXCLUDED_GROUPS: readonly number[] = Object.freeze([89, 93]);\n\n/**\n * The two-digit **group values a synthetic SSN may carry**: every value from `00` to `99` that is\n * outside every band in {@link ITIN_GROUP_RANGES} and outside {@link ITIN_EXCLUDED_GROUPS}. Derived\n * from those two lists rather than written out, so the pool can never drift from the published\n * ranges it is defined against.\n *\n * Combined with an area in the `900-999` band, a value drawn from this pool is provably outside both\n * issuing authorities that share the number space: SSA POMS RM 10201.035 identifies that area as\n * marking an **invalid** SSN, and a group outside every published ITIN band is not ITIN-formatted.\n *\n * @internal\n */\nexport const SSN_SYNTHETIC_GROUPS: readonly string[] = Object.freeze(\n Array.from({ length: 100 }, (_unused, group) => group)\n .filter(\n (group) =>\n !ITIN_GROUP_RANGES.some((range) => group >= range.min && group <= range.max) &&\n !ITIN_EXCLUDED_GROUPS.includes(group),\n )\n .map((group) => String(group).padStart(2, \"0\")),\n);\n\n/**\n * The `80840` prefix prepended to a 10-digit NPI before the Luhn check. A real NPI satisfies\n * `luhn(\"80840\" + npi) ≡ 0 (mod 10)`.\n *\n * The rule is **69 FR 3434**, the final rule adopting the NPI (FR Doc 04-1149, docket CMS-0045-F),\n * issued by the agency that document names as \"Centers for Medicare & Medicaid Services, HHS\": \"the\n * NPI check digit calculation must always be performed as though the NPI is preceded by\" `80840`.\n * The prefix itself is not that rule's: it credits the NCITS.284 standard health care identification\n * card, which \"requires that the first five digits of the card issuer identifier be\" `80840`, \"where\n * the initial two digits, 80, signify health applications, the next three digits, 840, signify\n * United States\". The rule cites no ISO document number for the prefix or for the check digit, and\n * neither does this module.\n * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>\n */\nexport const NPI_LUHN_PREFIX = \"80840\";\n\n/**\n * The Luhn sum (mod 10) of a numeric string, doubling every second digit from the right. Used to\n * verify (or deliberately break) an NPI check digit.\n *\n * @param digits - A string of decimal digits.\n * @returns The Luhn sum modulo 10 (0 ⇒ the string passes the Luhn check).\n * @internal\n */\nexport function luhnMod10(digits: string): number {\n let sum = 0;\n // Standard Luhn: the RIGHTMOST digit is never doubled; doubling starts one position in and\n // alternates. For a full payload+check string this makes a Luhn-valid string sum to 0 (mod 10);\n // for a payload with a `0` placeholder in the check position it yields the complement of the\n // correct check digit.\n let double = false;\n for (let i = digits.length - 1; i >= 0; i -= 1) {\n let d = digits.charCodeAt(i) - 48;\n if (d < 0 || d > 9) continue;\n if (double) {\n d *= 2;\n if (d > 9) d -= 9;\n }\n sum += d;\n double = !double;\n }\n return sum % 10;\n}\n\n/**\n * The correct NPI check digit for a 9-digit base: the value that makes `80840` + base + check pass\n * the Luhn check.\n *\n * The algorithm this inverts is cited: 69 FR 3434 (FR Doc 04-1149) requires the check digit to be\n * \"calculated using the ISO standard Luhn check digit algorithm\", a modulus 10 double-add-double\n * algorithm, performed as though the NPI were preceded by {@link NPI_LUHN_PREFIX}. That rule names\n * the algorithm and its behaviour but no ISO document number, and points onward for the step-by-step\n * form: \"The specification for calculation of the NPI check digit will be made available on the CMS\n * Web site\". What this function implements is the rule's own description, modulus 10 Luhn over the\n * prefixed digits; no separate specification is cited for it.\n * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>\n *\n * @param base9 - The 9-digit NPI base (positions 1 to 9).\n * @returns The check digit (`0`–`9`) a real NPI would carry for this base.\n * @example\n * ```ts\n * import { npiCheckDigit } from \"@cosyte/synth\";\n * npiCheckDigit(\"123456789\"); // 3, so 1234567893 is a Luhn-valid NPI shape\n * ```\n */\nexport function npiCheckDigit(base9: string): number {\n // Luhn over \"80840\" + base9 with a trailing 0 check placeholder; the check digit closes the sum.\n const partial = luhnMod10(`${NPI_LUHN_PREFIX}${base9}0`);\n return (10 - partial) % 10;\n}\n\n/**\n * The DEA-registration prefix letters `@cosyte/synth` draws a synthetic DEA number's first character\n * from. A real DEA number is `<registrant-type><last-name-initial>` + 7 digits; the first letter is the\n * registrant type (A/B/F/G/M/P/R/X are the widely-published values; the second letter is the\n * registrant's last-name initial). These letters are a **fact** about the number's shape, not\n * copyrighted prose: they only shape the value; the synthetic guarantee is the deliberately-**invalid\n * checksum** (see {@link dea} / {@link isSyntheticDea}).\n */\nexport const DEA_REGISTRANT_TYPES: readonly string[] = Object.freeze([\n \"A\",\n \"B\",\n \"F\",\n \"G\",\n \"M\",\n \"P\",\n \"R\",\n \"X\",\n]);\n\n/**\n * The correct DEA check digit for a 7-digit numeric base. The checksum is\n * `(d1 + d3 + d5) + 2·(d2 + d4 + d6)`, whose **units digit** is the 7th (check) digit. A real DEA\n * number satisfies this; a number whose 7th digit differs cannot be a validly-issued DEA registration.\n *\n * **NON-NORMATIVELY SOURCED, and this is the one locus in this module that is.** The formula above\n * is quoted from a pharmacy journal article, Gabay, \"Federal Controlled Substances Act: Controlled\n * Substances Prescriptions\", Hospital Pharmacy (PMC3847977): \"add the sum of the first, third, and\n * fifth digits to twice the sum of the second, fourth, and sixth digits. The total should be a\n * number whose last digit is the same as the last digit of the DEA number.\"\n * <https://pmc.ncbi.nlm.nih.gov/articles/PMC3847977/>\n *\n * **That article is not the DEA.** It is a secondary description of the agency's algorithm, not the\n * agency's own statement of it, and no DEA-published text stating the algorithm is cited here. The\n * consequence is stated rather than hidden: if the formula is wrong, a value this package builds to\n * fail it may in fact **pass** the real check, and the generator would then emit a checksum-valid\n * DEA number while {@link isSyntheticDea} asserts the opposite. Every other entry in this module's\n * `Sources:` list names the issuing authority's own text; this one cannot.\n *\n * @param base6 - The first 6 digits of the DEA number (positions 1 to 6).\n * @returns The check digit (`0`–`9`) a real DEA number would carry for this base.\n * @example\n * ```ts\n * import { deaCheckDigit } from \"@cosyte/synth\";\n * deaCheckDigit(\"123456\"); // the units digit of (1+3+5) + 2·(2+4+6)\n * ```\n */\nexport function deaCheckDigit(base6: string): number {\n let odd = 0;\n let even = 0;\n for (let i = 0; i < 6; i += 1) {\n const digit = base6.charCodeAt(i) - 48;\n if (i % 2 === 0) odd += digit;\n else even += digit;\n }\n return (odd + 2 * even) % 10;\n}\n\n/**\n * Whether a DEA number (`XX` + 7 digits, case-insensitive) is **provably synthetic**: its check digit\n * (the 7th digit) does **not** match the checksum {@link deaCheckDigit} computes, so it cannot be a\n * validly-issued DEA registration. A checksum-valid DEA number (which *could* denote a real\n * prescriber) returns `false`; a value that is not the DEA shape returns `false`.\n *\n * **NON-NORMATIVELY SOURCED.** This predicate is only as strong as the algorithm it inverts, and\n * that algorithm is cited to a pharmacy journal article (PMC3847977), **not to the DEA**: no\n * DEA-published statement of it is cited anywhere in this package. Read `true` as \"fails the\n * formula {@link deaCheckDigit} implements\", never as \"the DEA could not have issued this\". The\n * full citation and the consequence of the formula being wrong are on {@link deaCheckDigit}.\n *\n * @param value - The candidate DEA number (with or without incidental separators).\n * @returns `true` when the DEA number's checksum is wrong (never a real DEA registration).\n * @example\n * ```ts\n * import { isSyntheticDea } from \"@cosyte/synth\";\n * isSyntheticDea(\"AF1234561\"); // depends on the base: true when the 7th digit is wrong\n * ```\n */\nexport function isSyntheticDea(value: string): boolean {\n const compact = value.replace(/[\\s-]/g, \"\").toUpperCase();\n if (!/^[A-Z]{2}\\d{7}$/.test(compact)) return false;\n const digits = compact.slice(2);\n const check = digits.charCodeAt(6) - 48;\n return deaCheckDigit(digits.slice(0, 6)) !== check;\n}\n\n/**\n * Whether a 10-digit NPI is **provably synthetic**, i.e. its check digit is invalid, so it cannot be\n * a validly issued NPI. A Luhn-valid 10-digit NPI (which *could* denote a real registered provider)\n * returns `false`; a non-10-digit value returns `false` (not an NPI shape).\n *\n * The check this inverts is the one 69 FR 3434 (FR Doc 04-1149) requires: the Luhn check digit,\n * computed as though the NPI were preceded by {@link NPI_LUHN_PREFIX}. Unlike the DEA locus, this\n * one cites the issuing rule itself.\n * <https://www.federalregister.gov/documents/full_text/text/2004/01/23/04-1149.txt>\n *\n * @param value - The candidate NPI (digits only, or with incidental separators).\n * @returns `true` when the NPI's check digit is wrong (never a real NPI).\n * @example\n * ```ts\n * import { isSyntheticNpi } from \"@cosyte/synth\";\n * isSyntheticNpi(\"1234567894\"); // true: invalid check digit (valid would be 1234567893)\n * isSyntheticNpi(\"1234567893\"); // false: Luhn-valid, could be a real NPI\n * ```\n */\nexport function isSyntheticNpi(value: string): boolean {\n const digits = value.replace(/\\D/g, \"\");\n if (digits.length !== 10) return false;\n return luhnMod10(`${NPI_LUHN_PREFIX}${digits}`) !== 0;\n}\n\n/**\n * Whether a `ddd-dd-dddd` (or `ddddddddd`) SSN string carries an area SSA's own manual identifies\n * as **invalid**: `000`, `666`, or \"in the 900 series\". A real, issuable SSN returns `false`.\n *\n * The citable claim is SSA POMS RM 10201.035, which defines an invalid SSN as \"one that we never\n * assigned\" and lists those three areas as identifying one. The wording here says invalid rather\n * than never-issued because invalidity is what the manual states.\n * <https://secure.ssa.gov/poms.nsf/lnx/0110201035>\n *\n * @param value - The candidate SSN (dashes optional).\n * @returns `true` when the SSN is provably synthetic.\n * @example\n * ```ts\n * import { isSyntheticSsn } from \"@cosyte/synth\";\n * isSyntheticSsn(\"900-12-3456\"); // true (the 900 series marks an invalid SSN)\n * isSyntheticSsn(\"123456789\"); // false (issuable area 123)\n * ```\n */\nexport function isSyntheticSsn(value: string): boolean {\n const digits = value.replace(/\\D/g, \"\");\n if (digits.length !== 9) return false;\n const area = Number(digits.slice(0, 3));\n return area === 0 || area === 666 || area >= 900;\n}\n\n/**\n * Whether a `ddd-dd-dddd` (or `ddddddddd`) value is a **validly formatted IRS ITIN**: it begins\n * with `9` and its group digits (positions 4 and 5) fall inside a published ITIN group range\n * ({@link ITIN_GROUP_RANGES}). This is the second issuing authority sharing the SSN number space,\n * so `isSyntheticSsn(v) && !isItinFormatted(v)` is the full \"cannot be a federally issued national\n * id\" guarantee, of which the area rule alone is only half.\n *\n * `true` means the value is ITIN-shaped and therefore **must not** be emitted at an SSN locus. A\n * value that is not exactly 9 digits once separators are stripped returns `false` (not an SSN/ITIN\n * shape) rather than throwing, as do the group values `89` and `93`, which the IRM reserves for\n * other IRS programs rather than for ITINs.\n *\n * @param value - The candidate national id (dashes and other separators optional).\n * @returns `true` when the value is formatted as a valid ITIN.\n * @example\n * ```ts\n * import { isItinFormatted } from \"@cosyte/synth\";\n * isItinFormatted(\"912-70-1234\"); // true: group 70 is inside a published ITIN range\n * isItinFormatted(\"912-66-1234\"); // false: group 66 is outside every published ITIN range\n * ```\n */\nexport function isItinFormatted(value: string): boolean {\n const digits = value.replace(/\\D/g, \"\");\n if (digits.length !== 9) return false;\n if (!digits.startsWith(\"9\")) return false;\n const group = Number(digits.slice(3, 5));\n return ITIN_GROUP_RANGES.some((range) => group >= range.min && group <= range.max);\n}\n\n/**\n * Whether a phone string contains the NANP `555-0100…555-0199` reserved fictional line range.\n *\n * @param value - The candidate phone (any formatting).\n * @returns `true` when the number is in the reserved fictional block.\n * @example\n * ```ts\n * import { isSyntheticPhone } from \"@cosyte/synth\";\n * isSyntheticPhone(\"(202) 555-0142\"); // true\n * ```\n */\nexport function isSyntheticPhone(value: string): boolean {\n const digits = value.replace(/\\D/g, \"\");\n // The reserved guarantee is the 7-digit tail: exchange 555 + line 01NN.\n const tail = digits.slice(-7);\n return /^555 ?01\\d\\d$/.test(tail) || /^55501\\d\\d$/.test(tail);\n}\n\n/**\n * Whether an email's domain is an RFC 2606 / 6761 reserved / test domain.\n *\n * @param value - The candidate email address.\n * @returns `true` when the domain is reserved (never real).\n * @example\n * ```ts\n * import { isSyntheticEmail } from \"@cosyte/synth\";\n * isSyntheticEmail(\"faux.testerson@example.com\"); // true\n * ```\n */\nexport function isSyntheticEmail(value: string): boolean {\n const at = value.lastIndexOf(\"@\");\n if (at < 0) return false;\n const domain = value.slice(at + 1).toLowerCase();\n if (RESERVED_EMAIL_DOMAINS.includes(domain)) return true;\n return /\\.(example|test|invalid|localhost)$/.test(domain);\n}\n\n/**\n * Whether an IP string is in an RFC 5737 (IPv4 TEST-NET) or RFC 3849 (IPv6 documentation) reserved\n * block. A real routable address returns `false`.\n *\n * @param value - The candidate IPv4 or IPv6 address.\n * @returns `true` when the address is a reserved documentation address.\n * @example\n * ```ts\n * import { isSyntheticIp } from \"@cosyte/synth\";\n * isSyntheticIp(\"192.0.2.44\"); // true (TEST-NET-1)\n * isSyntheticIp(\"8.8.8.8\"); // false (real)\n * ```\n */\nexport function isSyntheticIp(value: string): boolean {\n if (value.toLowerCase().startsWith(`${DOC_V6_PREFIX}:`)) return true;\n return TEST_NET_V4_PREFIXES.some((prefix) => value.startsWith(`${prefix}.`));\n}\n","/**\n * The shipped **clearly-fake name pool**: `@cosyte/synth`'s own license-clean synthetic data.\n *\n * Deliberately **not** a `faker`-style realistic-name corpus (which could match a real person at a real\n * address: the exact hazard the synthetic-safety invariant forbids). Every token is\n * an obviously-invented, fixture-flavoured word: a reader can tell at a glance it names no one. The pool\n * is small on purpose: structural coverage, not demographic realism, is the goal.\n *\n * `# synthetic: true`\n *\n * @module\n */\n\n/** Obviously-synthetic given names. None is a plausible real person's name. */\nexport const SYNTHETIC_GIVEN_NAMES: readonly string[] = Object.freeze([\n \"Testina\",\n \"Fixtura\",\n \"Synthos\",\n \"Placeholda\",\n \"Sampleton\",\n \"Prototius\",\n \"Stubbina\",\n \"Exampla\",\n \"Quilliam\",\n \"Fabrica\",\n \"Simula\",\n \"Testry\",\n \"Seedwin\",\n \"Corpora\",\n \"Reprodo\",\n \"Mocktavia\",\n \"Dummett\",\n \"Voidwin\",\n \"Deteria\",\n \"Randomir\",\n]);\n\n/** Obviously-synthetic family names. None is a plausible real surname at a real address. */\nexport const SYNTHETIC_FAMILY_NAMES: readonly string[] = Object.freeze([\n \"Testerson\",\n \"Fauxman\",\n \"Placeholt\",\n \"Mockridge\",\n \"Fixtingham\",\n \"Synthwell\",\n \"Dummerton\",\n \"Examplewood\",\n \"Fabricant\",\n \"Simulacre\",\n \"Nonesuch\",\n \"Seedman\",\n \"Corpusworth\",\n \"Reprodus\",\n \"Voidmark\",\n \"Deterwood\",\n \"Randomson\",\n \"Quillfeather\",\n \"Notreal\",\n \"Genfield\",\n]);\n\n/** Obviously-synthetic street names for structured address fields. */\nexport const SYNTHETIC_STREET_NAMES: readonly string[] = Object.freeze([\n \"Fixture Lane\",\n \"Sample Street\",\n \"Placeholder Avenue\",\n \"Synthetic Way\",\n \"Example Boulevard\",\n \"Testing Terrace\",\n \"Mock Road\",\n \"Prototype Court\",\n]);\n\n/**\n * Obviously-synthetic city names. Combined only ever with a synthetic street + a fake name (the\n * *combination* is what identifies, and the combination is always synthetic).\n */\nexport const SYNTHETIC_CITY_NAMES: readonly string[] = Object.freeze([\n \"Faketon\",\n \"Synthville\",\n \"Exampleburg\",\n \"Testford\",\n \"Mockhaven\",\n \"Fixtureton\",\n]);\n","/**\n * The synthetic-safety provider layer: every identifier, contact point, name, and date\n * `@cosyte/synth` emits is minted here, and **only** from a guaranteed-non-colliding source. There is no code\n * path that returns a value not drawn from a reserved range or the\n * shipped fake-name pool. This is the inverse of a parser's liberality: the generator is *closed-world*\n * on its data sources, so no output *can* be real or plausibly-real PHI.\n *\n * All providers are pure functions of an explicit {@link ../rng/rng.Rng}, same seed, same values.\n *\n * @module\n */\n\nimport type { Rng } from \"../rng/rng.js\";\n\nimport {\n RESERVED_EMAIL_DOMAINS,\n TEST_NET_V4_PREFIXES,\n DOC_V6_PREFIX,\n SYNTHETIC_ASSIGNING_AUTHORITY,\n npiCheckDigit,\n deaCheckDigit,\n DEA_REGISTRANT_TYPES,\n SSN_SYNTHETIC_GROUPS,\n} from \"./reserved.js\";\nimport {\n SYNTHETIC_GIVEN_NAMES,\n SYNTHETIC_FAMILY_NAMES,\n SYNTHETIC_STREET_NAMES,\n SYNTHETIC_CITY_NAMES,\n} from \"./names-pool.js\";\n\n/** A synthetic person name drawn from the shipped fake-name pool. */\nexport interface SyntheticName {\n /** A clearly-fake given name. */\n readonly given: string;\n /** A clearly-fake family name. */\n readonly family: string;\n}\n\n/** A synthetic postal address: synthetic street + city, a fixed non-real ZIP. */\nexport interface SyntheticAddress {\n /** A clearly-fake street line. */\n readonly street: string;\n /** A clearly-fake city. */\n readonly city: string;\n /** A US state abbreviation (structural only; never combined with a real street + name + DOB). */\n readonly state: string;\n /** A reserved non-real ZIP (`00000`). */\n readonly zip: string;\n}\n\n/** A synthetic identifier scoped to the synthetic assigning authority. */\nexport interface SyntheticIdentifier {\n /** The identifier value (digits): unique only within the synthetic namespace. */\n readonly value: string;\n /** HL7 identifier type code (`MR` = medical record, `AN` = account, `MB` = member). */\n readonly typeCode: \"MR\" | \"AN\" | \"MB\";\n /** The synthetic assigning-authority namespace id. */\n readonly assigningAuthority: string;\n /** The synthetic assigning-authority OID (HL7 example arc). */\n readonly assigningAuthorityOid: string;\n}\n\n/** Which SSN reserved space to draw from. */\nexport type SsnBlock = \"never-issued\" | \"advertising\";\n\n/**\n * A **synthetic SSN**: dashed `AAA-GG-SSSS`, drawn so it can be neither an SSA-assignable Social\n * Security number nor a validly formatted IRS ITIN. Two authorities share this number space: SSA\n * never issues area `900-999`, and the IRS issues ITINs *inside* that area, distinguished by the\n * group digits. So the area rule alone is only half the guarantee, and both blocks below also keep\n * the group outside every published ITIN group range (see {@link isItinFormatted}).\n *\n * Default draws the never-issued area space (`900-999`) with a group from\n * {@link SSN_SYNTHETIC_GROUPS}; `block: \"advertising\"` returns the fixed display block\n * `987-00-4320` to `987-00-4329`, whose group `00` is one SSA never assigns and one no published\n * ITIN range contains.\n *\n * **`\"advertising\"` no longer means SSA's own advertising block.** That published block is\n * `987-65-4320` to `987-65-4329`, and group `65` sits inside a published ITIN group range, so every\n * value in it is ITIN-formatted and none of them can be emitted here. The option keeps its name\n * (renaming it would break call sites for a property no test asserts) and keeps its purpose, a fixed\n * ten-value block safe to print on screen, but it is a display block of this package's choosing now,\n * not a citation of SSA's. Do not reintroduce the `65` group to recover the provenance.\n *\n * @param rng - The seeded generator.\n * @param block - Which reserved space to draw from. Defaults to `\"never-issued\"`.\n * @returns A dashed synthetic SSN string.\n * @example\n * ```ts\n * import { createRng, ssn } from \"@cosyte/synth\";\n * ssn(createRng(1)); // e.g. a 900-area, never-issued, never-ITIN-formatted SSN\n * ```\n */\nexport function ssn(rng: Rng, block: SsnBlock = \"never-issued\"): string {\n if (block === \"advertising\") {\n // The fixed display block: last digit 0..9 within -4320..-4329, group 00 so no value here is\n // ITIN-formatted (the previous group, 65, sat inside the published ITIN range 50-65).\n return `987-00-432${String(rng.int(0, 9))}`;\n }\n const area = rng.int(900, 999); // SSA never issues 900-999.\n // Never a bare two-digit draw: 44 of the 100 group values would make the result a validly\n // formatted ITIN. The pool is the complement, so an ITIN-shaped candidate is never produced\n // rather than produced and rejected (generation never fails for a seed).\n const group = rng.pick(SSN_SYNTHETIC_GROUPS);\n const serial = rng.digits(4);\n return `${String(area)}-${group}-${serial}`;\n}\n\n/**\n * A **synthetic phone** in the NANP reserved fictional block: `(AAA) 555-01NN`. The reserved\n * guarantee is the `555-01NN` tail (exchange 555, line 0100–0199); the area code is any NANP-valid\n * `NXX`. Can never be a working number.\n *\n * @param rng - The seeded generator.\n * @returns A formatted synthetic phone string.\n * @example\n * ```ts\n * import { createRng, phone } from \"@cosyte/synth\";\n * phone(createRng(1)); // e.g. \"(2XX) 555-01NN\"\n * ```\n */\nexport function phone(rng: Rng): string {\n const area = `${String(rng.int(2, 9))}${rng.digits(2)}`; // NXX area code.\n const line = `01${rng.digits(2)}`; // reserved 0100-0199.\n return `(${area}) 555-${line}`;\n}\n\n/**\n * A **synthetic name** drawn from the shipped clearly-fake pool.\n *\n * @param rng - The seeded generator.\n * @returns A {@link SyntheticName}.\n * @example\n * ```ts\n * import { createRng, name } from \"@cosyte/synth\";\n * const { given, family } = name(createRng(1));\n * ```\n */\nexport function name(rng: Rng): SyntheticName {\n return { given: rng.pick(SYNTHETIC_GIVEN_NAMES), family: rng.pick(SYNTHETIC_FAMILY_NAMES) };\n}\n\n/**\n * A **synthetic email** at an RFC 2606 / 6761 reserved domain: `<slug>@example.com`.\n *\n * @param rng - The seeded generator.\n * @param person - Optional name to derive the local-part slug from; otherwise a random slug is used.\n * @returns A synthetic email address.\n * @example\n * ```ts\n * import { createRng, email, name } from \"@cosyte/synth\";\n * email(createRng(1), name(createRng(1))); // \"<given>.<family>@example.com\"\n * ```\n */\nexport function email(rng: Rng, person?: SyntheticName): string {\n const domain = rng.pick(RESERVED_EMAIL_DOMAINS);\n const slug = person ? `${person.given}.${person.family}`.toLowerCase() : `synth${rng.digits(6)}`;\n return `${slug}@${domain}`;\n}\n\n/**\n * A **synthetic IPv4** in an RFC 5737 TEST-NET block, never routable.\n *\n * @param rng - The seeded generator.\n * @returns A TEST-NET IPv4 address string.\n * @example\n * ```ts\n * import { createRng, ipv4 } from \"@cosyte/synth\";\n * ipv4(createRng(1)); // e.g. \"192.0.2.NN\"\n * ```\n */\nexport function ipv4(rng: Rng): string {\n return `${rng.pick(TEST_NET_V4_PREFIXES)}.${String(rng.int(1, 254))}`;\n}\n\n/**\n * A **synthetic IPv6** in the RFC 3849 documentation prefix `2001:db8::/32`, never routable.\n *\n * @param rng - The seeded generator.\n * @returns A documentation-prefix IPv6 address string.\n * @example\n * ```ts\n * import { createRng, ipv6 } from \"@cosyte/synth\";\n * ipv6(createRng(1)); // e.g. \"2001:db8::NNNN\"\n * ```\n */\nexport function ipv6(rng: Rng): string {\n const tail = rng.nextUint32().toString(16).padStart(4, \"0\").slice(-4);\n return `${DOC_V6_PREFIX}::${tail}`;\n}\n\n/**\n * A **deterministic UUIDv4-shaped** surrogate key from the seeded generator. Because it is seeded (not\n * from `node:crypto`, which is not reproducible), the cryptographic non-collision argument is weaker,\n * acceptable because the identifier namespace is synthetic anyway, and noted honestly.\n *\n * @param rng - The seeded generator.\n * @returns A canonical `8-4-4-4-12` lowercase-hex UUID string with version `4` and RFC 4122 variant.\n * @example\n * ```ts\n * import { createRng, uuid } from \"@cosyte/synth\";\n * uuid(createRng(1)); // \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\"\n * ```\n */\nexport function uuid(rng: Rng): string {\n const bytes = new Uint8Array(16);\n for (let i = 0; i < 16; i += 1) bytes[i] = rng.int(0, 255);\n bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40; // version 4\n bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80; // variant 10xx\n const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\"));\n return `${hex.slice(0, 4).join(\"\")}-${hex.slice(4, 6).join(\"\")}-${hex.slice(6, 8).join(\"\")}-${hex.slice(8, 10).join(\"\")}-${hex.slice(10, 16).join(\"\")}`;\n}\n\n/**\n * A **synthetic NPI**: a 10-digit National Provider Identifier with a **deliberately-invalid Luhn\n * check digit**, so it can never be a NPPES-issued NPI (a real NPI must satisfy the `80840`-prefixed\n * Luhn check). The 9-digit base is drawn from the seeded generator; the check digit is\n * set to `(correct + 1) mod 10`, guaranteeing the full value fails validation.\n *\n * @param rng - The seeded generator.\n * @returns A 10-digit NPI-shaped string that is provably not a real NPI.\n * @example\n * ```ts\n * import { createRng, npi, isSyntheticNpi } from \"@cosyte/synth\";\n * isSyntheticNpi(npi(createRng(1))); // true: invalid check digit by construction\n * ```\n */\nexport function npi(rng: Rng): string {\n const base9 = rng.digits(9);\n const wrongCheck = (npiCheckDigit(base9) + 1) % 10;\n return `${base9}${String(wrongCheck)}`;\n}\n\n/**\n * A **synthetic DEA number**: `<registrant-type><initial>` + 7 digits with a **deliberately-invalid\n * checksum**, so it can never be a validly-issued DEA registration (a real DEA number's 7th digit\n * satisfies the published DEA checksum). The first letter is a registrant-type letter, the\n * second is derived from `person` (its family initial) when supplied so the number reads plausibly; the\n * 6-digit base is seeded and the check digit is set to `(correct + 1) mod 10`, guaranteeing the value\n * fails validation. NCPDP carries prescriber DEA, and this is the identity locus a refuter attacks\n * hardest, so, like {@link npi}, non-collision is a construction-level guarantee, not a heuristic.\n *\n * @param rng - The seeded generator.\n * @param person - Optional name whose family initial becomes the DEA's second letter.\n * @returns A DEA-shaped string that is provably not a real DEA registration.\n * @example\n * ```ts\n * import { createRng, dea, isSyntheticDea } from \"@cosyte/synth\";\n * isSyntheticDea(dea(createRng(1))); // true: invalid checksum by construction\n * ```\n */\nexport function dea(rng: Rng, person?: SyntheticName): string {\n const type = rng.pick(DEA_REGISTRANT_TYPES);\n const initialSource = person?.family ?? rng.pick(SYNTHETIC_FAMILY_NAMES);\n const initial = initialSource.slice(0, 1).toUpperCase();\n const base6 = rng.digits(6);\n const wrongCheck = (deaCheckDigit(base6) + 1) % 10;\n return `${type}${initial}${base6}${String(wrongCheck)}`;\n}\n\n/**\n * A **synthetic identifier** (MRN / account / member id) scoped to the synthetic assigning authority.\n * There is no reserved MRN range, so non-collision is guaranteed by the *namespace*, not the value: the\n * identifier lives under a `SYNTH` authority no real facility uses.\n *\n * @param rng - The seeded generator.\n * @param typeCode - The HL7 identifier type: `MR` (default), `AN`, or `MB`.\n * @returns A {@link SyntheticIdentifier}.\n * @example\n * ```ts\n * import { createRng, identifier } from \"@cosyte/synth\";\n * identifier(createRng(1), \"MR\"); // { value, typeCode: \"MR\", assigningAuthority: \"COSYTE-SYNTH\", ... }\n * ```\n */\nexport function identifier(\n rng: Rng,\n typeCode: SyntheticIdentifier[\"typeCode\"] = \"MR\",\n): SyntheticIdentifier {\n return {\n value: rng.digits(8),\n typeCode,\n assigningAuthority: SYNTHETIC_ASSIGNING_AUTHORITY.namespaceId,\n assigningAuthorityOid: SYNTHETIC_ASSIGNING_AUTHORITY.universalId,\n };\n}\n\n/**\n * A **synthetic address**: a fake street + city, a reserved non-real ZIP (`00000`). A real state\n * abbreviation may appear (structural only) but is never combined with a real street + name + DOB.\n *\n * @param rng - The seeded generator.\n * @returns A {@link SyntheticAddress}.\n * @example\n * ```ts\n * import { createRng, address } from \"@cosyte/synth\";\n * address(createRng(1)); // { street, city, state, zip: \"00000\" }\n * ```\n */\nexport function address(rng: Rng): SyntheticAddress {\n const number = rng.int(1, 9999);\n return {\n street: `${String(number)} ${rng.pick(SYNTHETIC_STREET_NAMES)}`,\n city: rng.pick(SYNTHETIC_CITY_NAMES),\n state: rng.pick(US_STATES),\n zip: \"00000\",\n };\n}\n\n/**\n * A **synthetic date** in HL7 `YYYYMMDD` form, drawn uniformly within an inclusive year range. Comes\n * from the seeded generator (never wall-clock), so it is reproducible and implies no real event.\n *\n * @param rng - The seeded generator.\n * @param minYear - Inclusive lower year bound (default `1930`).\n * @param maxYear - Inclusive upper year bound (default `2010`).\n * @returns An `YYYYMMDD` date string (always a valid calendar day).\n * @example\n * ```ts\n * import { createRng, dateYmd } from \"@cosyte/synth\";\n * dateYmd(createRng(1), 1970, 2000); // \"YYYYMMDD\"\n * ```\n */\nexport function dateYmd(rng: Rng, minYear = 1930, maxYear = 2010): string {\n const year = rng.int(minYear, maxYear);\n const month = rng.int(1, 12);\n const daysInMonth = new Date(Date.UTC(year, month, 0)).getUTCDate();\n const day = rng.int(1, daysInMonth);\n return `${String(year).padStart(4, \"0\")}${String(month).padStart(2, \"0\")}${String(day).padStart(2, \"0\")}`;\n}\n\n/** US state abbreviations: structural only (see {@link address}). */\nconst US_STATES: readonly string[] = Object.freeze([\n \"AL\",\n \"AK\",\n \"AZ\",\n \"AR\",\n \"CA\",\n \"CO\",\n \"CT\",\n \"DE\",\n \"FL\",\n \"GA\",\n \"HI\",\n \"ID\",\n \"IL\",\n \"IN\",\n \"IA\",\n \"KS\",\n \"KY\",\n \"LA\",\n \"ME\",\n \"MD\",\n \"MA\",\n \"MI\",\n \"MN\",\n \"MS\",\n \"MO\",\n \"MT\",\n \"NE\",\n \"NV\",\n \"NH\",\n \"NJ\",\n \"NM\",\n \"NY\",\n \"NC\",\n \"ND\",\n \"OH\",\n \"OK\",\n \"OR\",\n \"PA\",\n \"RI\",\n \"SC\",\n \"SD\",\n \"TN\",\n \"TX\",\n \"UT\",\n \"VT\",\n \"VA\",\n \"WA\",\n \"WV\",\n \"WI\",\n \"WY\",\n]);\n","/**\n * The `safe` namespace: the single entry point for every synthetic-by-construction value provider.\n *\n * Grouped under one object so a consumer reads `safe.ssn(rng)` / `safe.phone(rng)` and it is\n * self-evident that the value is drawn from a guaranteed-non-colliding synthetic source.\n * The individual functions and the reserved-range predicates are also exported by name from the\n * package root for direct import.\n *\n * @module\n */\n\nimport {\n ssn,\n phone,\n name,\n email,\n ipv4,\n ipv6,\n uuid,\n identifier,\n address,\n dateYmd,\n npi,\n dea,\n} from \"./providers.js\";\n\nexport * from \"./providers.js\";\nexport * from \"./reserved.js\";\nexport * from \"./names-pool.js\";\n\n/**\n * The synthetic-safety provider namespace. Every function draws only from a reserved range or the\n * shipped fake-name pool, no value it returns can be real or plausibly-real PHI.\n *\n * @example\n * ```ts\n * import { createRng, safe } from \"@cosyte/synth\";\n * const rng = createRng(42);\n * safe.ssn(rng); // never-issued SSN\n * safe.phone(rng); // reserved 555-01NN number\n * ```\n */\nexport const safe = Object.freeze({\n ssn,\n phone,\n name,\n email,\n ipv4,\n ipv6,\n uuid,\n identifier,\n address,\n dateYmd,\n npi,\n dea,\n});\n","/**\n * Synthetic identity for ASTM (E1394 / CLSI LIS02) messages: every value `synth` puts into a `P`\n * (patient) record, an `O` (order) accession, or the `H` header is minted here, and **only** from the\n * synthetic-safety providers. ASTM's PHI-dense locus is the **`P` record**: it carries the\n * patient **name** (`Last^First^Middle`), **birthdate**, **sex**, and the **practice-assigned** and\n * **laboratory-assigned** patient IDs, which must stay\n * **distinct** (the parser keeps them distinct; a generator that let one default from the other would\n * defeat that). Every identifier is scoped to the synthetic assigning authority: there is no reserved\n * patient-ID range for ASTM (as for MRNs generally), so the **namespace** is the\n * guarantee. The IDs carry a clearly-synthetic prefix (`PRA` / `LAB` / `ACC`) so the `phi-scan` ASTM\n * arm can recognize them as synthetic-AA-scoped and a real bare numeric MRN can never masquerade as one.\n *\n * @module\n */\n\nimport type { Rng } from \"../rng/rng.js\";\nimport { safe, type SyntheticName } from \"../safe/index.js\";\n\n/** Clearly-fictional middle initials, so a `P`-record name can carry the full `Last^First^Middle`. */\nconst SYNTHETIC_MIDDLE_INITIALS: readonly string[] = Object.freeze([\n \"A\",\n \"B\",\n \"C\",\n \"J\",\n \"M\",\n \"R\",\n \"T\",\n]);\n\n/** Clearly-synthetic sender / analyzer identifiers for the `H` header (never a real site or instrument). */\nconst SYNTHETIC_SENDERS: readonly string[] = Object.freeze([\n \"SYNTH-LIS\",\n \"FIXTURE-HOST\",\n \"PLACEHOLDER-LAB\",\n]);\n\n/** Clearly-synthetic analyzer model strings for the `H` header (Universal Test ID sender component). */\nconst SYNTHETIC_ANALYZERS: readonly string[] = Object.freeze([\n \"SYNTH-ANALYZER^ModelS^1\",\n \"MOCK-CHEM^ModelC^2\",\n \"FIXTURE-HEMA^ModelH^1\",\n]);\n\n/** A synthetic ASTM patient: every field drawn from `../safe`. */\nexport interface AstmPatient {\n /** Name from the shipped fake-name pool, plus a fictional middle initial. */\n readonly person: SyntheticName;\n /** Middle initial (clearly synthetic). */\n readonly middle: string;\n /** Birthdate `YYYYMMDD`, from the seeded generator (no real event implied). */\n readonly birthDate: string;\n /** Sex code, emitted verbatim (`M` / `F`, structural, never defaulted by the builder). */\n readonly sex: \"M\" | \"F\";\n /** Practice-assigned patient ID, synthetic-AA scoped (`PRA`-prefixed). Distinct from the lab ID. */\n readonly practiceAssignedId: string;\n /** Laboratory-assigned patient ID, synthetic-AA scoped (`LAB`-prefixed). Distinct from the practice ID. */\n readonly laboratoryAssignedId: string;\n}\n\n/** A synthetic ASTM order identity: the specimen / accession id and priority. */\nexport interface AstmOrder {\n /** Specimen / accession id: synthetic-AA scoped (`ACC`-prefixed). */\n readonly specimenId: string;\n /** Priority code, emitted verbatim (`R` routine, `S` stat). */\n readonly priority: \"R\" | \"S\";\n}\n\n/** A synthetic ASTM header identity: the sender and analyzer strings for the `H` record. */\nexport interface AstmHeaderIdentity {\n /** The sending system id (clearly synthetic). */\n readonly sender: string;\n /** The analyzer / instrument string (clearly synthetic). */\n readonly analyzer: string;\n}\n\n/**\n * Mint a synthetic patient for a `P` record. Fixed draw order (name → middle → DOB → sex → practice id\n * → lab id) so the same seed yields the same patient. The two patient IDs are minted from\n * **independent** synthetic-identifier draws, so they are distinct by construction.\n *\n * @param rng - The seeded generator.\n * @returns A synthetic {@link AstmPatient}.\n * @example\n * ```ts\n * import { createRng } from \"@cosyte/synth\";\n * import { astmPatient } from \"@cosyte/synth/astm\";\n * const { person, practiceAssignedId, laboratoryAssignedId } = astmPatient(createRng(1));\n * ```\n */\nexport function astmPatient(rng: Rng): AstmPatient {\n const person = safe.name(rng);\n const middle = rng.pick(SYNTHETIC_MIDDLE_INITIALS);\n const birthDate = safe.dateYmd(rng, 1935, 2010);\n const sex = rng.pick([\"M\", \"F\"] as const);\n const practiceAssignedId = `PRA${safe.identifier(rng, \"MR\").value}`;\n const laboratoryAssignedId = `LAB${safe.identifier(rng, \"MR\").value}`;\n return { person, middle, birthDate, sex, practiceAssignedId, laboratoryAssignedId };\n}\n\n/**\n * Mint a synthetic order identity for an `O` record: a synthetic-AA-scoped accession id and a priority.\n *\n * @param rng - The seeded generator.\n * @returns A synthetic {@link AstmOrder}.\n * @example\n * ```ts\n * import { createRng } from \"@cosyte/synth\";\n * import { astmOrder } from \"@cosyte/synth/astm\";\n * const { specimenId } = astmOrder(createRng(1));\n * ```\n */\nexport function astmOrder(rng: Rng): AstmOrder {\n const specimenId = `ACC${rng.digits(8)}`;\n const priority = rng.pick([\"R\", \"S\"] as const);\n return { specimenId, priority };\n}\n\n/**\n * Mint a synthetic header identity for the `H` record: a clearly-synthetic sender and analyzer.\n *\n * @param rng - The seeded generator.\n * @returns A synthetic {@link AstmHeaderIdentity}.\n * @example\n * ```ts\n * import { createRng } from \"@cosyte/synth\";\n * import { astmHeaderIdentity } from \"@cosyte/synth/astm\";\n * const { sender } = astmHeaderIdentity(createRng(1));\n * ```\n */\nexport function astmHeaderIdentity(rng: Rng): AstmHeaderIdentity {\n const sender = rng.pick(SYNTHETIC_SENDERS);\n const analyzer = rng.pick(SYNTHETIC_ANALYZERS);\n return { sender, analyzer };\n}\n","/**\n * A small, **license-clean** pool of example ASTM laboratory tests: the analyte codes, units, and\n * plausible value ranges `synth` draws on when populating `O` (order) and `R` (result) records. The\n * codes are **facts** (a LOINC number is a public identifier, and the local analyzer codes here are\n * invented), never a bundled terminology table. Nothing clinical is asserted: a `synth` result pairs a value\n * and a code with no claim of clinical coherence: the pool exists only to make a *structurally* realistic\n * result record.\n *\n * @module\n */\n\n/** One example laboratory analyte: its codes, units, reference range, and a seeded value window. */\nexport interface AstmExampleTest {\n /** A local analyzer test code (invented, never a real vendor assay id). */\n readonly localCode: string;\n /** The public LOINC identifier for the analyte (a fact, not bundled terminology prose). */\n readonly loinc: string;\n /** The human-readable test name, emitted in the Universal Test ID name component. */\n readonly name: string;\n /** The units string, emitted verbatim in `R`-field 5 (never converted or guessed). */\n readonly units: string;\n /** The reference range text, emitted verbatim in `R`-field 6. */\n readonly referenceRange: string;\n /** Inclusive integer low bound of the seeded synthetic value (structural, not clinical). */\n readonly valueLow: number;\n /** Inclusive integer high bound of the seeded synthetic value. */\n readonly valueHigh: number;\n /** Number of decimal places to render the synthetic value with. */\n readonly decimals: number;\n}\n\n/**\n * The example test pool. A handful of common chemistry/hematology analytes, each with a public LOINC\n * code, invented local code, units, and a value window the seeded generator samples. Frozen: the pool\n * is shared, immutable data.\n *\n * @example\n * ```ts\n * import { EXAMPLE_ASTM_TESTS } from \"@cosyte/synth/astm\";\n * EXAMPLE_ASTM_TESTS[0]?.name; // \"Glucose\"\n * ```\n */\nexport const EXAMPLE_ASTM_TESTS: readonly AstmExampleTest[] = Object.freeze([\n {\n localCode: \"GLU\",\n loinc: \"2345-7\",\n name: \"Glucose\",\n units: \"mg/dL\",\n referenceRange: \"70-110\",\n valueLow: 55,\n valueHigh: 260,\n decimals: 0,\n },\n {\n localCode: \"K\",\n loinc: \"2823-3\",\n name: \"Potassium\",\n units: \"mmol/L\",\n referenceRange: \"3.5-5.1\",\n valueLow: 28,\n valueHigh: 62,\n decimals: 1,\n },\n {\n localCode: \"NA\",\n loinc: \"2951-2\",\n name: \"Sodium\",\n units: \"mmol/L\",\n referenceRange: \"136-145\",\n valueLow: 125,\n valueHigh: 155,\n decimals: 0,\n },\n {\n localCode: \"CREA\",\n loinc: \"2160-0\",\n name: \"Creatinine\",\n units: \"mg/dL\",\n referenceRange: \"0.6-1.3\",\n valueLow: 4,\n valueHigh: 32,\n decimals: 1,\n },\n {\n localCode: \"HGB\",\n loinc: \"718-7\",\n name: \"Hemoglobin\",\n units: \"g/dL\",\n referenceRange: \"12.0-17.5\",\n valueLow: 80,\n valueHigh: 190,\n decimals: 1,\n },\n {\n localCode: \"WBC\",\n loinc: \"6690-2\",\n name: \"Leukocytes\",\n units: \"10*3/uL\",\n referenceRange: \"4.5-11.0\",\n valueLow: 30,\n valueHigh: 150,\n decimals: 1,\n },\n {\n localCode: \"TSH\",\n loinc: \"3016-3\",\n name: \"Thyrotropin\",\n units: \"mIU/L\",\n referenceRange: \"0.40-4.50\",\n valueLow: 2,\n valueHigh: 90,\n decimals: 2,\n },\n {\n localCode: \"ALT\",\n loinc: \"1742-6\",\n name: \"Alanine aminotransferase\",\n units: \"U/L\",\n referenceRange: \"7-56\",\n valueLow: 5,\n valueHigh: 120,\n decimals: 0,\n },\n]);\n\n/** HL7 Table 0078 abnormal-flag codes `synth` draws from (emitted verbatim; never defaulted). */\nexport const ASTM_ABNORMAL_FLAGS: readonly string[] = Object.freeze([\"N\", \"L\", \"H\", \"A\"]);\n\n/** Result-status codes `synth` draws from (`F` final, `P` preliminary, `C` correction). */\nexport const ASTM_RESULT_STATUSES: readonly string[] = Object.freeze([\"F\", \"P\", \"C\"]);\n\n/** Free-text result comments: clearly synthetic, carry no PHI. */\nexport const ASTM_COMMENT_TEXT: readonly string[] = Object.freeze([\n \"Synthetic fixture comment - not a clinical observation.\",\n \"Sample generated by @cosyte/synth.\",\n \"Placeholder result comment for conformance testing.\",\n]);\n","/**\n * Spec-clean ASTM (E1394 / CLSI LIS02) message generation: the `H`/`P`/`O`/`R`/`C`/`L` record report,\n * built through `@cosyte/astm`'s `buildAstmMessage` so the delimiter declaration (`H|\\^&`), the record\n * type letters, the per-type sequence counters, the `L` terminator, and every escape are the parser's\n * own conservative emit. Nothing clinical is defaulted: a\n * result's status/flag/units/value are supplied from the example pool, never invented by the builder.\n *\n * A framed **E1381 / CLSI LIS01** variant is also offered ({@link generateAstmResultFramed}) via\n * `composeAstmFrames`, which frames each record into `<STX> FN text <ETB|ETX> CS <CR><LF>` with the\n * **modulo-256 checksum and the `0`–`7` frame number computed by the parser**, never faked. Both round\n * trip through `@cosyte/astm` cleanly (`parseAstmRecords` / `parseFramedAstm`: see `./round-trip`).\n *\n * Every value at a PHI-bearing locus (the `P` record's name / DOB / practice+lab IDs) is\n * drawn from the synthetic-safety providers via `./identity`, so no output can be real or plausibly-real\n * PHI. `synth` is a **format/conformance generator, not a clinical simulator**: a generated\n * result pairs a code and a value with no claim of clinical coherence.\n *\n * @module\n */\n\nimport {\n buildAstmMessage,\n composeAstmFrames,\n type AstmRecordInput,\n type MessageInput,\n} from \"@cosyte/astm\";\n\nimport { createRng, type Rng } from \"../rng/rng.js\";\nimport { astmPatient, astmOrder, astmHeaderIdentity } from \"./identity.js\";\nimport { EXAMPLE_ASTM_TESTS, ASTM_ABNORMAL_FLAGS, ASTM_COMMENT_TEXT } from \"./example-codes.js\";\n\n/** Options for the ASTM message generators. */\nexport interface GenerateAstmOptions {\n /** The seed (deterministic: same seed yields a byte-identical message). */\n readonly seed: number;\n /** How many `R` (result) records to emit. Defaults to a seeded 1–4. */\n readonly resultCount?: number;\n /** Whether to append a `C` (comment) record after the results. Defaults to `true`. */\n readonly comment?: boolean;\n}\n\n/** Render a seeded synthetic numeric result value with the analyte's decimal precision. */\nfunction resultValue(rng: Rng, low: number, high: number, decimals: number): string {\n const raw = rng.int(low, high);\n if (decimals === 0) return String(raw);\n const scale = 10 ** decimals;\n return (raw / scale).toFixed(decimals);\n}\n\n/**\n * Assemble the typed record inputs (P → O → R… → C?) for a result message from a seeded generator. The\n * header and terminator are added by {@link buildAstmMessage}; this builds the body plus the header\n * fields so both the record and framed emitters share one construction.\n */\nfunction buildResultInput(options: GenerateAstmOptions): MessageInput {\n const rng = createRng(options.seed);\n const head = astmHeaderIdentity(rng);\n const patient = astmPatient(rng);\n const order = astmOrder(rng);\n const resultCount = options.resultCount ?? rng.int(1, 4);\n\n const records: AstmRecordInput[] = [\n {\n type: \"P\",\n practiceAssignedId: patient.practiceAssignedId,\n laboratoryAssignedId: patient.laboratoryAssignedId,\n name: { last: patient.person.family, first: patient.person.given, middle: patient.middle },\n birthDate: patient.birthDate,\n sex: patient.sex,\n },\n {\n type: \"O\",\n specimenId: order.specimenId,\n universalTestId: [\"\", \"\", \"\", \"ALL\"],\n priority: order.priority,\n actionCode: \"N\",\n reportType: \"F\",\n },\n ];\n\n for (let i = 0; i < resultCount; i += 1) {\n const test = rng.pick(EXAMPLE_ASTM_TESTS);\n records.push({\n type: \"R\",\n universalTestId: [\"\", \"\", \"\", test.localCode, test.name, test.loinc],\n value: resultValue(rng, test.valueLow, test.valueHigh, test.decimals),\n units: test.units,\n referenceRange: test.referenceRange,\n abnormalFlags: rng.pick(ASTM_ABNORMAL_FLAGS),\n resultStatus: \"F\",\n });\n }\n\n if (options.comment ?? true) {\n records.push({ type: \"C\", source: \"L\", text: rng.pick(ASTM_COMMENT_TEXT), commentType: \"G\" });\n }\n\n return {\n header: { fields: [head.sender, head.analyzer] },\n records,\n terminationCode: \"N\",\n };\n}\n\n/**\n * Generate a spec-clean ASTM **result message**: an `H`/`P`/`O`/`R`…/`C`/`L` record stream, built\n * through `@cosyte/astm`'s `buildAstmMessage`. Every identity value is synthetic-by-construction; the message\n * round-trips through `parseAstmRecords` with zero warnings and re-serializes\n * byte-identically (see `./round-trip`).\n *\n * @param options - The seed, optional result count, and whether to append a comment.\n * @returns The `CR`-terminated ASTM record stream.\n * @example\n * ```ts\n * import { generateAstmResult } from \"@cosyte/synth/astm\";\n * const raw = generateAstmResult({ seed: 42 });\n * ```\n */\nexport function generateAstmResult(options: GenerateAstmOptions): string {\n return buildAstmMessage(buildResultInput(options));\n}\n\n/**\n * Generate a spec-clean ASTM **order message**: an `H`/`P`/`O`/`L` record stream with no results, for\n * the order side of the flow. Built through `buildAstmMessage`; synthetic-by-construction; round-trips\n * clean.\n *\n * @param options - The seed.\n * @returns The `CR`-terminated ASTM record stream.\n * @example\n * ```ts\n * import { generateAstmOrder } from \"@cosyte/synth/astm\";\n * const raw = generateAstmOrder({ seed: 7 });\n * ```\n */\nexport function generateAstmOrder(options: GenerateAstmOptions): string {\n return generateAstmResult({ ...options, resultCount: 0, comment: false });\n}\n\n/**\n * Generate a spec-clean **framed** ASTM result message: the same `H`/`P`/`O`/`R`…/`C`/`L` records,\n * wrapped in the **E1381 / CLSI LIS01** frame envelope (`<STX> FN text <ETB|ETX> CS <CR><LF>`) via\n * `@cosyte/astm`'s `composeAstmFrames`. The **modulo-256 checksum and the `0`–`7` frame number are\n * computed by the parser** (never hand-written), and a record over 240 bytes is split across frames,\n * so the bytes round-trip through `parseFramedAstm` with zero frame **and** record warnings (see\n * `./round-trip`). Each record is framed independently (one `ETX`-closed run per record), mirroring what\n * `decodeAstmFrames` reassembles.\n *\n * @param options - The seed, optional result count, and whether to append a comment.\n * @returns The framed byte stream.\n * @example\n * ```ts\n * import { generateAstmResultFramed } from \"@cosyte/synth/astm\";\n * const bytes = generateAstmResultFramed({ seed: 42 }); // Uint8Array, E1381 framed\n * ```\n */\nexport function generateAstmResultFramed(options: GenerateAstmOptions): Uint8Array {\n const raw = generateAstmResult(options);\n // Split the built stream into its per-record `CR`-terminated lines and frame each independently, so\n // decode reassembles exactly one record per frame run (mirrors `@cosyte/astm`'s `serializeFramedAstm`).\n const recordLines = raw\n .split(\"\\r\")\n .filter((line) => line.length > 0)\n .map((line) => `${line}\\r`);\n return composeAstmFrames(recordLines);\n}\n","/**\n * The **round-trip-through-the-parser harness** for ASTM: the headline gate for the synthetic-fixture\n * generator. A generated ASTM record stream (or framed byte stream) is \"spec-clean\" only\n * if `@cosyte/astm`, not `@cosyte/synth`'s own opinion, reads it back cleanly. Each harness parses the\n * generated wire straight back through the parser and reports what it found, so a false \"spec-clean\"\n * claim cannot hide.\n *\n * The **record** layer (E1394) and the **frame** layer (E1381) are separate concerns, so each gets its\n * own harness; both report the same {@link AstmRoundTripResult} shape (the framed one additionally folds\n * the frame-layer warnings (bad checksum, sequence gap, unterminated, oversize) into `warnings`, so a\n * framing defect is caught by the same gate).\n *\n * @module\n */\n\nimport {\n parseAstmRecords,\n serializeAstmRecords,\n parseFramedAstm,\n serializeFramedAstm,\n} from \"@cosyte/astm\";\n\n/** The verdict of one round-trip through `@cosyte/astm`. */\nexport interface AstmRoundTripResult {\n /** The serialized ASTM wire text (records: the `CR`-terminated stream; framed: the raw bytes as latin1). */\n readonly content: string;\n /** The warning codes the parser emitted on re-parse (record + frame layers). Empty ⇒ spec-clean. */\n readonly warnings: readonly string[];\n /** Whether re-serializing the re-parsed message is byte-identical to the input. */\n readonly byteStable: boolean;\n /** `true` iff the artifact is spec-clean: zero warnings **and** byte-stable. */\n readonly specClean: boolean;\n}\n\n/**\n * Round-trip a generated ASTM **record** stream through parse → serialize and report the verdict. A\n * spec-clean message re-parses with **zero warnings** and re-serializes byte-identically.\n *\n * @param raw - The ASTM record stream (typically from `generateAstmResult` / `generateAstmOrder`).\n * @returns The {@link AstmRoundTripResult}.\n * @example\n * ```ts\n * import { generateAstmResult, astmRoundTrip } from \"@cosyte/synth/astm\";\n * const { specClean } = astmRoundTrip(generateAstmResult({ seed: 1 })); // specClean === true\n * ```\n */\nexport function astmRoundTrip(raw: string): AstmRoundTripResult {\n const message = parseAstmRecords(raw);\n const warnings = message.warnings.map((w) => String(w.code));\n const byteStable = serializeAstmRecords(message) === raw;\n return { content: raw, warnings, byteStable, specClean: warnings.length === 0 && byteStable };\n}\n\n/**\n * Round-trip a generated **framed** ASTM byte stream (E1381) through decode+parse → re-frame and report\n * the verdict. A spec-clean framed message re-parses with **zero record and zero frame warnings** (every\n * modulo-256 checksum verifies, no sequence gap, no unterminated/oversize frame) and re-frames\n * byte-identically.\n *\n * @param bytes - The framed byte stream (typically from `generateAstmResultFramed`).\n * @returns The {@link AstmRoundTripResult}: `content` holds the framed bytes decoded as latin1.\n * @example\n * ```ts\n * import { generateAstmResultFramed, astmFramedRoundTrip } from \"@cosyte/synth/astm\";\n * const { specClean } = astmFramedRoundTrip(generateAstmResultFramed({ seed: 1 })); // true\n * ```\n */\nexport function astmFramedRoundTrip(bytes: Uint8Array): AstmRoundTripResult {\n const { message, frameWarnings } = parseFramedAstm(bytes);\n const warnings = [\n ...frameWarnings.map((w) => String(w.code)),\n ...message.warnings.map((w) => String(w.code)),\n ];\n const reframed = serializeFramedAstm(message);\n const byteStable = bytesEqual(reframed, bytes);\n const content = latin1(bytes);\n return { content, warnings, byteStable, specClean: warnings.length === 0 && byteStable };\n}\n\n/** Byte-for-byte equality of two frame streams. */\nfunction bytesEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i += 1) if (a[i] !== b[i]) return false;\n return true;\n}\n\n/** Decode a frame stream as latin1 for a lossless `string` view (the frame envelope is single-byte). */\nfunction latin1(bytes: Uint8Array): string {\n let out = \"\";\n for (const b of bytes) out += String.fromCharCode(b);\n return out;\n}\n","/**\n * The **selector chokepoint**. A generator's options are almost all *selectors*: a message kind, a\n * document type, a corpus mix, a claim variant, a Bundle type, a profile. Each is typed as a closed\n * union, and every one of those unions is **erased at run time**, so a JavaScript caller (or a\n * `as never` in someone's test) reaches the branch with any string at all.\n *\n * Three things went wrong when that was left unchecked, and they are all the same bug:\n *\n * 1. **The value reached a diagnostic.** An unrecognised `documentType` travelled into\n * `@cosyte/ccda`'s `buildCcda`, which is entitled to quote it back in its own `TypeError` and\n * does. This package then has a caller-supplied string on an `err.message` and an `err.stack`,\n * through its own public entry point, having taken no care of it.\n * 2. **The value reached the model.** A corpus mix entry becomes an `Artifact.kind` and a\n * `manifest.counts` key, which is precisely the structural-identifier position a downstream\n * package interpolates to describe a location.\n * 3. **The fixture was silently mislabeled.** An exhaustive `switch` over an erased union takes no\n * branch and returns `undefined`, or a trailing `else` quietly generates something else. A corpus\n * whose manifest says it holds one transaction and holds another is a golden file that lies.\n *\n * So a selector is resolved against its own set, once, before anything is generated, and an\n * unrecognised one is a fatal `SYNTH_UNSUPPORTED_KIND`. Like every fatal here it carries a code and a\n * fixed message, and quotes neither the request nor the set.\n *\n * @module\n */\n\nimport { SYNTH_FATAL_CODES, SynthError } from \"./codes.js\";\n\n/**\n * Resolve one caller-supplied selector against the closed set that governs it, or **fail closed**.\n *\n * @param allowed - Every value the selector may take.\n * @param requested - The selector the caller supplied.\n * @returns `requested`, narrowed to the union.\n * @throws SynthError `SYNTH_UNSUPPORTED_KIND` when `requested` is not in `allowed`.\n * @example\n * ```ts\n * import { resolveKind } from \"@cosyte/synth\";\n * resolveKind([\"ccd\", \"referralNote\"] as const, \"ccd\"); // \"ccd\"\n * ```\n */\nexport function resolveKind<T extends string>(allowed: readonly T[], requested: string): T {\n const match = allowed.find((value) => value === requested);\n if (match === undefined) throw new SynthError(SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_KIND);\n return match;\n}\n\n/**\n * Resolve every entry of a caller-supplied corpus mix, in order, or **fail closed** on the first\n * unrecognised one.\n *\n * It substitutes the default **only** when the caller supplied nothing, which is exactly what the\n * `??` it replaced did. An empty array is a supplied mix and is returned as one. An earlier version\n * of this function also treated `[]` as \"nothing supplied\", on the stated grounds that it matched the\n * previous behaviour; it did not: `??` fires on `undefined` and never on `[]`, and it changed the\n * result of six published entry points, turning an explicit empty selection into \"generate one of\n * everything\". A convenience that fails open is not a convenience.\n *\n * @param allowed - Every kind the corpus may generate.\n * @param requested - The mix the caller supplied, or `undefined` for the default.\n * @param fallback - The default mix, used only when `requested` is `undefined`.\n * @returns The resolved mix.\n * @throws SynthError `SYNTH_UNSUPPORTED_KIND` on the first unrecognised entry.\n * @example\n * ```ts\n * import { resolveMix } from \"@cosyte/synth\";\n * resolveMix([\"Result\", \"Order\"] as const, [\"Order\"], [\"Result\", \"Order\"]); // [\"Order\"]\n * ```\n */\nexport function resolveMix<T extends string>(\n allowed: readonly T[],\n requested: readonly string[] | undefined,\n fallback: readonly T[],\n): readonly T[] {\n if (requested === undefined) return fallback;\n return requested.map((entry) => resolveKind(allowed, entry));\n}\n","/**\n * `defineSynthProfile`: the growth-loop hook for site/vendor fixture recipes. A profile bundles the\n * value pools and the quirk recipe a fixture set should use, authored through the same public API as\n * the built-ins: a validated, frozen `SynthProfile` carrying a name, optional value overrides, and the\n * quirk names a format's quirk corpus should apply.\n *\n * @module\n */\n\nimport { SYNTH_FATAL_CODES, SynthError } from \"./codes.js\";\n\n/** The user-authored spec passed to {@link defineSynthProfile}. */\nexport interface SynthProfileSpec {\n /** A stable, human-readable profile name (e.g. `\"acme-hospital\"`). Required, non-empty. */\n readonly name: string;\n /** Optional given-name pool override (clearly-synthetic names only, see the safety invariant). */\n readonly givenNames?: readonly string[];\n /** Optional family-name pool override (clearly-synthetic names only). */\n readonly familyNames?: readonly string[];\n /**\n * The vendor quirk recipe names this profile requests. Validated against the target format's quirk\n * registry when the profile drives a quirk corpus (an unsupported quirk is a fatal\n * `SYNTH_UNSUPPORTED_QUIRK`, never a silent no-op).\n */\n readonly quirks?: readonly string[];\n}\n\n/** A frozen, validated fixture recipe produced by {@link defineSynthProfile}. */\nexport interface SynthProfile {\n /** The profile name. */\n readonly name: string;\n /** The given-name pool this profile draws from (overrides or the built-in default). */\n readonly givenNames?: readonly string[];\n /** The family-name pool this profile draws from. */\n readonly familyNames?: readonly string[];\n /** The requested quirk recipe names. */\n readonly quirks: readonly string[];\n}\n\n/**\n * Define a reusable, frozen synthetic-fixture profile.\n *\n * @param spec - The profile spec; `name` is required and non-empty.\n * @returns A deep-frozen {@link SynthProfile}.\n * @throws SynthError `SYNTH_INVALID_PROFILE` when `name` is missing or blank.\n * @example\n * ```ts\n * import { defineSynthProfile } from \"@cosyte/synth\";\n * const acme = defineSynthProfile({ name: \"acme-hospital\", quirks: [] });\n * ```\n */\nexport function defineSynthProfile(spec: SynthProfileSpec): SynthProfile {\n if (typeof spec.name !== \"string\" || spec.name.trim().length === 0) {\n throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INVALID_PROFILE);\n }\n return Object.freeze({\n name: spec.name,\n ...(spec.givenNames ? { givenNames: Object.freeze([...spec.givenNames]) } : {}),\n ...(spec.familyNames ? { familyNames: Object.freeze([...spec.familyNames]) } : {}),\n quirks: Object.freeze([...(spec.quirks ?? [])]),\n });\n}\n","/**\n * The **quirk core**. Where the spec-clean generators prove\n * *synthetic-by-construction* through each parser's own builder, the quirk layer proves the mirror\n * property: a **deliberately off-spec** fixture round-trips to **exactly the intended parser warning\n * code(s)**, no more, no fewer. The quirk vocabulary **is the parsers' own profile systems**\n * (`hl7.defineProfile`, `ccda.defineCcdaProfile`, `astm.defineAstmProfile`): a quirk exercises exactly\n * the tolerance the corresponding parser profile encodes, so a quirk fixture is never a fiction, it\n * targets a documented, coded leniency (the **intended-warning contract**).\n *\n * This module is the **format-agnostic** part: the descriptor a quirk carries, the artifact a quirk\n * generator returns, the round-trip verdict shape, and the `SYNTH_UNSUPPORTED_QUIRK` fail-closed. Each\n * format's concrete quirk recipes + transforms live behind its own subpath (`@cosyte/synth/hl7`, …).\n *\n * @module\n */\n\nimport type { SynthFormat } from \"./corpus.js\";\nimport { SYNTH_FATAL_CODES, SynthError } from \"./codes.js\";\nimport type { SynthProfile } from \"./profile.js\";\n\n/**\n * How the parser's matching profile treats a quirk once it is active: the three shapes the parsers'\n * profile systems actually exhibit (verified firsthand against each parser):\n *\n * - `\"suppressed\"`, the profile makes the warning **disappear** (HL7 v2: a `defineProfile`\n * `customSegments` claim suppresses `UNKNOWN_SEGMENT` for a declared Z-segment).\n * - `\"rebadged\"`, the profile **downgrades** the warning to the value-free `PROFILE_QUIRK_APPLIED`\n * marker with `expected: true` (C-CDA `defineCcdaProfile` / ASTM `defineAstmProfile`\n * `profileQuirkApplied`).\n * - `\"bare\"`, no shipped profile tolerates it; the quirk targets a real coded leniency a consumer can\n * tolerate via their own `defineProfile`/`defineAstmProfile`, but no built-in re-badges it.\n */\nexport type QuirkProfileDisposition = \"suppressed\" | \"rebadged\" | \"bare\";\n\n/**\n * The stable, value-free re-badge code the C-CDA and ASTM parsers emit when a profile tolerates a\n * quirk. HL7 v2 has no equivalent (it suppresses instead: see {@link QuirkProfileDisposition}).\n */\nexport const PROFILE_QUIRK_APPLIED = \"PROFILE_QUIRK_APPLIED\";\n\n/**\n * A public, grounded description of one vendor quirk: the metadata that binds a quirk recipe to a real\n * parser warning code and a **publicly-groundable** deviation (cited-public, never a private\n * vendor corpus).\n */\nexport interface QuirkDescriptor {\n /** The quirk recipe name (e.g. `\"unknown-zsegment\"`). Stable; part of the public contract. */\n readonly name: string;\n /** The format this quirk applies to. */\n readonly format: SynthFormat;\n /**\n * The **exact** parser warning code(s) a bare parse (no profile) surfaces for this quirk, the\n * intended-warning contract. A quirk that produces any other code, or none, is a generation bug.\n */\n readonly intendedWarnings: readonly string[];\n /**\n * The **public** grounding for this quirk, the spec clause or the parser's public profile that\n * documents the tolerance. Never a private vendor-attributed corpus.\n */\n readonly grounding: string;\n /** The parser profile that tolerates this quirk (when a built-in public one exists). */\n readonly toleratingProfile?: string;\n /** How {@link toleratingProfile} treats the quirk. */\n readonly disposition: QuirkProfileDisposition;\n}\n\n/** One generated quirk artifact: the off-spec wire text plus the contract it is meant to satisfy. */\nexport interface QuirkArtifact {\n /** The format this artifact belongs to. */\n readonly format: SynthFormat;\n /** The quirk recipe applied. */\n readonly quirk: string;\n /** The underlying spec-clean message kind the quirk was injected into (e.g. `\"ORU^R01\"`). */\n readonly kind: string;\n /** The **quirked** wire text (deterministic in the seed + quirk). */\n readonly content: string;\n /** The exact parser warning code(s) this artifact is meant to round-trip to. */\n readonly intendedWarnings: readonly string[];\n}\n\n/** The verdict of a bare parse under the tolerating profile, if any. */\nexport interface QuirkProfiledVerdict {\n /** The profile applied. */\n readonly profileName: string;\n /** How the profile treats the quirk. */\n readonly disposition: QuirkProfileDisposition;\n /** The warning codes the parser emitted with the profile active. */\n readonly warnings: readonly string[];\n /**\n * `true` iff the profile handled the quirk as its disposition declares: `\"suppressed\"` ⇒ the intended\n * code is gone; `\"rebadged\"` ⇒ the intended code is gone and `PROFILE_QUIRK_APPLIED` is present.\n */\n readonly tolerated: boolean;\n}\n\n/** The verdict of round-tripping a quirk artifact through its parser. */\nexport interface QuirkRoundTripResult {\n /** The quirked wire text that was parsed. */\n readonly content: string;\n /** The warning codes a **bare** parse (no profile) emitted. */\n readonly warnings: readonly string[];\n /** The exact code(s) the quirk is meant to produce. */\n readonly intendedWarnings: readonly string[];\n /**\n * `true` iff the bare parse produced **exactly** the intended code(s), the intended-warning contract.\n */\n readonly intendedWarningHeld: boolean;\n /** The verdict under the tolerating profile, when a built-in public one exists. */\n readonly withProfile?: QuirkProfiledVerdict;\n}\n\n/**\n * Exact multiset (order-independent) equality of two code lists: the intended-warning comparison.\n *\n * @param a - The first code list.\n * @param b - The second code list.\n * @returns `true` iff the two lists contain the same codes with the same multiplicities.\n * @example\n * ```ts\n * import { sameCodeSet } from \"@cosyte/synth\";\n * sameCodeSet([\"A\", \"B\"], [\"B\", \"A\"]); // true\n * ```\n */\nexport function sameCodeSet(a: readonly string[], b: readonly string[]): boolean {\n if (a.length !== b.length) return false;\n const counts = new Map<string, number>();\n for (const c of a) counts.set(c, (counts.get(c) ?? 0) + 1);\n for (const c of b) {\n const n = counts.get(c);\n if (n === undefined) return false;\n if (n === 1) counts.delete(c);\n else counts.set(c, n - 1);\n }\n return counts.size === 0;\n}\n\n/**\n * Resolve a requested quirk name against a format's registry, or **fail closed**. A quirk the format's\n * profile system does not support is a fatal `SYNTH_UNSUPPORTED_QUIRK`, never a silent no-op and never\n * a fabricated quirk with a made-up warning.\n *\n * The refusal names neither the request nor the registry. `registry`, `format` and `name` are all\n * caller-supplied, and a diagnostic that quotes its input is a diagnostic that can be made to carry\n * anything the caller was holding, which for a fixture generator wired into someone else's pipeline\n * is not a hypothetical. Branch on `err.code`; the supported set is the registry you passed\n * (`HL7_QUIRKS`, `CCDA_QUIRKS`, `ASTM_QUIRKS`), which you can enumerate directly.\n *\n * @param registry - The format's quirk descriptors, keyed by name.\n * @param format - The format being generated.\n * @param name - The requested quirk name.\n * @returns The matching {@link QuirkDescriptor}.\n * @throws SynthError with code `SYNTH_UNSUPPORTED_QUIRK` when `name` is not a supported quirk.\n * @example\n * ```ts\n * import { resolveQuirk } from \"@cosyte/synth\";\n * import { HL7_QUIRKS } from \"@cosyte/synth/hl7\";\n * resolveQuirk(HL7_QUIRKS, \"hl7v2\", \"unknown-zsegment\").intendedWarnings; // [\"UNKNOWN_SEGMENT\"]\n * ```\n */\nexport function resolveQuirk(\n registry: Readonly<Record<string, QuirkDescriptor>>,\n format: SynthFormat,\n name: string,\n): QuirkDescriptor {\n const descriptor = registry[name];\n // `format` is compared, never rendered. A descriptor found under the wrong format's registry is a\n // mislabeled fixture waiting to happen, so the mismatch fails closed on the same code.\n if (descriptor === undefined || descriptor.format !== format) {\n throw new SynthError(SYNTH_FATAL_CODES.SYNTH_UNSUPPORTED_QUIRK);\n }\n return descriptor;\n}\n\n/**\n * Evaluate whether a profiled parse tolerated a quirk as its disposition declares. Shared across the\n * formats so the \"suppressed vs re-badged\" logic lives in exactly one place.\n *\n * @param disposition - The quirk's declared profile disposition.\n * @param intendedWarnings - The bare-parse intended code(s).\n * @param warningsUnderProfile - The code(s) the parser emitted with the profile active.\n * @returns `true` iff the profile handled the quirk correctly for its disposition.\n * @example\n * ```ts\n * import { profileTolerated } from \"@cosyte/synth\";\n * profileTolerated(\"suppressed\", [\"UNKNOWN_SEGMENT\"], []); // true: the profile suppressed it\n * ```\n */\nexport function profileTolerated(\n disposition: QuirkProfileDisposition,\n intendedWarnings: readonly string[],\n warningsUnderProfile: readonly string[],\n): boolean {\n const stillHasIntended = intendedWarnings.some((c) => warningsUnderProfile.includes(c));\n switch (disposition) {\n case \"suppressed\":\n return !stillHasIntended;\n case \"rebadged\":\n return !stillHasIntended && warningsUnderProfile.includes(PROFILE_QUIRK_APPLIED);\n case \"bare\":\n return false;\n }\n}\n\n/**\n * Assert a freshly-generated quirk artifact **actually** round-trips to its intended warning(s), or\n * **fail closed**. This is the generator's self-check on the intended-warning contract: a\n * fixture whose bare parse does not produce exactly the declared code(s) is a *mislabeled* fixture, a\n * golden file that lies about the parser verdict it anchors, and must never be emitted. It is a\n * stronger guard than \"the transform changed some bytes\": a transform can mutate the wrong element (a\n * template a given document type does not key its warning on) and still change bytes while producing no\n * warning. Every format's `generate*Quirk` calls this after transforming, so the contract is enforced at\n * generation time, not merely at round-trip time.\n *\n * It no longer takes the quirk name. That parameter existed for one reason, to be interpolated into\n * the refusal, and a parameter whose only job is to reach a message is the exact shape this package\n * is removing, so it is gone rather than merely unused. The refusal names neither code list either;\n * both are caller-supplied, and the caller reads the comparison back off the arguments it holds.\n *\n * @param intendedWarnings - The declared intended code(s).\n * @param bareWarnings - The code(s) a bare parse of the generated artifact actually produced.\n * @throws SynthError `SYNTH_INTENDED_WARNING_MISMATCH` when the bare parse did not produce exactly\n * the intended code(s).\n * @example\n * ```ts\n * import { assertIntendedWarnings } from \"@cosyte/synth\";\n * assertIntendedWarnings([\"UNKNOWN_SEGMENT\"], [\"UNKNOWN_SEGMENT\"]); // ok\n * ```\n */\nexport function assertIntendedWarnings(\n intendedWarnings: readonly string[],\n bareWarnings: readonly string[],\n): void {\n if (!sameCodeSet(bareWarnings, intendedWarnings)) {\n throw new SynthError(SYNTH_FATAL_CODES.SYNTH_INTENDED_WARNING_MISMATCH);\n }\n}\n\n/**\n * Validate the quirk names carried by a {@link SynthProfile} against a format's registry, failing closed\n * on the first unsupported one. Lets a consumer author a fixture recipe with `defineSynthProfile` and\n * have its quirks checked against the *parser's* real tolerance before any fixture is generated.\n *\n * @param profile - The synth profile whose `quirks` to validate.\n * @param registry - The format's quirk descriptors.\n * @param format - The format being generated.\n * @returns The validated quirk names (the profile's, in order).\n * @throws SynthError `SYNTH_UNSUPPORTED_QUIRK` for the first unsupported quirk.\n * @example\n * ```ts\n * import { validateProfileQuirks, defineSynthProfile } from \"@cosyte/synth\";\n * import { HL7_QUIRKS } from \"@cosyte/synth/hl7\";\n * const p = defineSynthProfile({ name: \"site\", quirks: [\"unknown-zsegment\"] });\n * validateProfileQuirks(p, HL7_QUIRKS, \"hl7v2\"); // [\"unknown-zsegment\"]\n * ```\n */\nexport function validateProfileQuirks(\n profile: SynthProfile,\n registry: Readonly<Record<string, QuirkDescriptor>>,\n format: SynthFormat,\n): readonly string[] {\n for (const name of profile.quirks) resolveQuirk(registry, format, name);\n return profile.quirks;\n}\n","/**\n * ASTM E1394 **vendor-quirk generation**. A quirk deviates the\n * *structure* of an otherwise spec-clean record report (built through `@cosyte/astm`'s\n * `buildAstmMessage`) so it round-trips through `parseAstmRecords` to **exactly** one intended, stable\n * warning code: a code in the parser's `defineAstmProfile` tolerable set. Where a built-in public\n * profile tolerates the quirk, the warning is **re-badged** to the value-free `PROFILE_QUIRK_APPLIED`\n * marker (`expected: true`), exactly as the parser's `profileQuirkApplied` does.\n *\n * The deviation is applied **post-serialize** on the record stream. Two quirks ship:\n *\n * - **`unknown-escape`** → `ASTM_UNKNOWN_ESCAPE_SEQUENCE` (profile `referenceCorpus`). A non-standard\n * `&Z&` escape body is injected into a result's units field. Grounded on `@cosyte/astm`'s public\n * `referenceCorpus` profile (the redistributable kxepal/python-astm + senaite OSS corpus), which\n * re-badges it.\n * - **`unknown-record-type`** → `ASTM_RECORD_UNKNOWN_TYPE`. A record's leading type letter is changed to\n * a site-defined `Z`: a real ASTM tolerance (the parser's tolerable set includes this code), but no\n * built-in profile tolerates it, so it is a `\"bare\"` quirk (a consumer authors a `defineAstmProfile`\n * to re-badge it).\n *\n * A quirk **never** introduces a real-looking value: it changes an escape body or a record type letter,\n * never a P-record identity locus, so the synthetic-safety gate still runs and stays zero.\n *\n * @module\n */\n\nimport { parseAstmRecords, astmProfiles, type AstmProfile } from \"@cosyte/astm\";\n\nimport { createRng } from \"../rng/rng.js\";\nimport { makeCorpus, type Corpus } from \"../corpus.js\";\nimport { defineSynthProfile, type SynthProfile } from \"../profile.js\";\nimport { SYNTH_FATAL_CODES, SynthError } from \"../codes.js\";\nimport {\n resolveQuirk,\n sameCodeSet,\n profileTolerated,\n validateProfileQuirks,\n assertIntendedWarnings,\n type QuirkDescriptor,\n type QuirkArtifact,\n type QuirkRoundTripResult,\n} from \"../quirk.js\";\n\nimport { generateAstmResult } from \"./message.js\";\nimport { resolveKind } from \"../select.js\";\n\n/** Every ASTM quirk this package ships. */\nexport type AstmQuirkName = \"unknown-escape\" | \"unknown-record-type\";\n\n/**\n * Both shipped ASTM quirks are **result-report** deviations: `unknown-escape` targets an `R` record's\n * units field and `unknown-record-type` a `C` (comment) record, neither of which an *order* report\n * carries. So the quirk base is always a result report (`generateAstmResult`).\n */\nexport type AstmQuirkKind = \"Result\";\n\n/** Every value {@link AstmQuirkKind} admits. Erased at run time, so it is resolved, not trusted. */\nconst ALL_QUIRK_KINDS: readonly AstmQuirkKind[] = Object.freeze([\"Result\"]);\n\n/** The ASTM quirk registry: each recipe bound to the exact `@cosyte/astm` warning code it targets. */\nexport const ASTM_QUIRKS: Readonly<Record<AstmQuirkName, QuirkDescriptor>> = Object.freeze({\n \"unknown-escape\": Object.freeze({\n name: \"unknown-escape\",\n format: \"astm\",\n intendedWarnings: Object.freeze([\"ASTM_UNKNOWN_ESCAPE_SEQUENCE\"]),\n grounding:\n \"ASTM E1394 escape delimiter (&); a non-standard &Z& body is preserved verbatim and flagged. \" +\n \"Re-badged by @cosyte/astm's public `referenceCorpus` profile (kxepal/python-astm + senaite OSS).\",\n toleratingProfile: \"referenceCorpus\",\n disposition: \"rebadged\",\n }),\n \"unknown-record-type\": Object.freeze({\n name: \"unknown-record-type\",\n format: \"astm\",\n intendedWarnings: Object.freeze([\"ASTM_RECORD_UNKNOWN_TYPE\"]),\n grounding:\n \"ASTM E1394 permits manufacturer/site-defined record types; a Z record is surfaced as unsupported. \" +\n \"A tolerable code (in the parser's defineAstmProfile allow-list): a consumer authors a profile to \" +\n \"re-badge it; no built-in public profile does.\",\n disposition: \"bare\",\n }),\n});\n\n/** The tolerating ASTM profile object for a quirk, when a built-in public one exists. */\nfunction toleratingProfile(quirk: AstmQuirkName): AstmProfile | undefined {\n return quirk === \"unknown-escape\" ? astmProfiles.referenceCorpus : undefined;\n}\n\n/** The E1394 record separator. */\nconst CR = \"\\r\";\n\n/** The post-serialize transform for each quirk: a pure, deterministic function of the clean record stream. */\nfunction applyQuirk(quirk: AstmQuirkName, records: string): string {\n const lines = records.split(CR);\n switch (quirk) {\n case \"unknown-escape\": {\n // Inject a non-standard &Z& escape into the units field (field 5, index 4) of the first R record.\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i];\n if (line !== undefined && line.startsWith(\"R|\")) {\n const fields = line.split(\"|\");\n const units = fields[4];\n if (units !== undefined && units.length > 0) {\n fields[4] = `&Z&${units}`;\n lines[i] = fields.join(\"|\");\n return lines.join(CR);\n }\n }\n }\n return records;\n }\n case \"unknown-record-type\": {\n // Change the first comment (C) record's leading type letter to a site-defined Z.\n for (let i = 0; i < lines.length; i += 1) {\n const line = lines[i];\n if (line !== undefined && line.startsWith(\"C|\")) {\n lines[i] = `Z${line.slice(1)}`;\n return lines.join(CR);\n }\n }\n return records;\n }\n }\n}\n\n/** Options for {@link generateAstmQuirk}. */\nexport interface GenerateAstmQuirkOptions {\n /** The seed: the same seed + quirk yields a byte-identical record stream. Defaults to `0`. */\n readonly seed?: number;\n /** The quirk to inject. Required. */\n readonly quirk: AstmQuirkName;\n /** The spec-clean base report kind. Always `\"Result\"` (see {@link AstmQuirkKind}). */\n readonly kind?: AstmQuirkKind;\n}\n\n/**\n * Generate one ASTM **quirk** artifact: a spec-clean record report (built through `@cosyte/astm`) with\n * the requested vendor deviation injected post-serialize. Deterministic in `seed` + `quirk` + `kind`.\n *\n * @param options - Seed, quirk, and base kind. See {@link GenerateAstmQuirkOptions}.\n * @returns The {@link QuirkArtifact}: its `content` round-trips to `intendedWarnings` exactly.\n * @throws SynthError `SYNTH_UNSUPPORTED_QUIRK` if `quirk` is not a supported ASTM quirk.\n * @throws Error if the base report does not contain the structural anchor the quirk targets.\n * @example\n * ```ts\n * import { generateAstmQuirk, astmQuirkRoundTrip } from \"@cosyte/synth/astm\";\n * const rt = astmQuirkRoundTrip(generateAstmQuirk({ seed: 1, quirk: \"unknown-escape\" }));\n * rt.withProfile?.tolerated; // true, `referenceCorpus` re-badges ASTM_UNKNOWN_ESCAPE_SEQUENCE\n * ```\n */\nexport function generateAstmQuirk(options: GenerateAstmQuirkOptions): QuirkArtifact {\n const seed = options.seed ?? 0;\n const kind: AstmQuirkKind = resolveKind(ALL_QUIRK_KINDS, options.kind ?? \"Result\");\n const descriptor = resolveQuirk(ASTM_QUIRKS, \"astm\", options.quirk);\n const clean = generateAstmResult({ seed });\n const content = applyQuirk(options.quirk, clean);\n if (content === clean) {\n throw new SynthError(SYNTH_FATAL_CODES.SYNTH_QUIRK_ANCHOR_ABSENT);\n }\n // Self-check the intended-warning contract at generation time, never emit a mislabeled fixture.\n assertIntendedWarnings(\n descriptor.intendedWarnings,\n parseAstmRecords(content).warnings.map((w) => String(w.code)),\n );\n return Object.freeze({\n format: \"astm\" as const,\n quirk: descriptor.name,\n kind,\n content,\n intendedWarnings: descriptor.intendedWarnings,\n });\n}\n\n/**\n * Round-trip an ASTM quirk artifact through `@cosyte/astm` and report the intended-warning verdict: a bare\n * parse must produce **exactly** the intended code, and, when a built-in public\n * profile tolerates the quirk, the profiled parse must re-badge it to `PROFILE_QUIRK_APPLIED`.\n *\n * @param artifact - The quirk artifact (from {@link generateAstmQuirk}).\n * @returns The {@link QuirkRoundTripResult}.\n * @example\n * ```ts\n * import { generateAstmQuirk, astmQuirkRoundTrip } from \"@cosyte/synth/astm\";\n * astmQuirkRoundTrip(generateAstmQuirk({ seed: 1, quirk: \"unknown-escape\" })).intendedWarningHeld;\n * ```\n */\nexport function astmQuirkRoundTrip(artifact: QuirkArtifact): QuirkRoundTripResult {\n const quirk = artifact.quirk as AstmQuirkName;\n const descriptor = resolveQuirk(ASTM_QUIRKS, \"astm\", quirk);\n const bare = parseAstmRecords(artifact.content).warnings.map((w) => String(w.code));\n const profile = toleratingProfile(quirk);\n const withProfile =\n profile !== undefined && descriptor.toleratingProfile !== undefined\n ? (() => {\n const warnings = parseAstmRecords(artifact.content, { profile }).warnings.map((w) =>\n String(w.code),\n );\n return {\n profileName: descriptor.toleratingProfile,\n disposition: descriptor.disposition,\n warnings,\n tolerated: profileTolerated(\n descriptor.disposition,\n artifact.intendedWarnings,\n warnings,\n ),\n };\n })()\n : undefined;\n return {\n content: artifact.content,\n warnings: bare,\n intendedWarnings: artifact.intendedWarnings,\n intendedWarningHeld: sameCodeSet(bare, artifact.intendedWarnings),\n ...(withProfile ? { withProfile } : {}),\n };\n}\n\n/** Options for {@link astmQuirkCorpus}. */\nexport interface AstmQuirkCorpusOptions {\n /** The seed for the whole corpus (deterministic). */\n readonly seed: number;\n /** How many quirk artifacts to generate. Defaults to the number of quirks. */\n readonly count?: number;\n /** The quirk names to cycle through. Defaults to every ASTM quirk. Validated; unsupported ⇒ fatal. */\n readonly quirks?: readonly AstmQuirkName[];\n /** A {@link SynthProfile} whose `quirks` drive the corpus (validated). Takes precedence over `quirks`. */\n readonly profile?: SynthProfile;\n}\n\nconst ALL_ASTM_QUIRKS: readonly AstmQuirkName[] = Object.freeze(\n Object.keys(ASTM_QUIRKS) as AstmQuirkName[],\n);\n\n/**\n * Build a reproducible {@link Corpus} of ASTM quirk artifacts. Each artifact's `warnings` record the\n * intended code for its quirk; the manifest lists the applied quirk names.\n *\n * @param options - Seed, count, and the quirk selection. See {@link AstmQuirkCorpusOptions}.\n * @returns A deep-frozen {@link Corpus}.\n * @example\n * ```ts\n * import { astmQuirkCorpus } from \"@cosyte/synth/astm\";\n * astmQuirkCorpus({ seed: 42 }).manifest.quirks; // the applied quirk names\n * ```\n */\nexport function astmQuirkCorpus(options: AstmQuirkCorpusOptions): Corpus {\n const quirks: readonly string[] = options.profile\n ? validateProfileQuirks(options.profile, ASTM_QUIRKS, \"astm\")\n : (options.quirks ?? ALL_ASTM_QUIRKS);\n const names = quirks.length > 0 ? quirks : ALL_ASTM_QUIRKS;\n // Resolve the WHOLE list here, not lazily per generated artifact. `count` can be below\n // `names.length`, and the tail then never reaches this module's own `resolveQuirk`\n // while still landing on `manifest.quirks` verbatim. A manifest that names a quirk the\n // corpus does not contain is the same mislabeled-fixture defect the intended-warning\n // contract exists to prevent, and `manifest.quirks` is a derived identifier.\n for (const name of names) resolveQuirk(ASTM_QUIRKS, \"astm\", name);\n const count = options.count ?? names.length;\n const seedStream = createRng(options.seed);\n const artifacts = Array.from({ length: count }, (_unused, i) => {\n const quirk = names[i % names.length] as AstmQuirkName;\n const artifactSeed = seedStream.nextUint32();\n const artifact = generateAstmQuirk({ seed: artifactSeed, quirk });\n return {\n format: \"astm\" as const,\n kind: `Result~${quirk}`,\n content: artifact.content,\n warnings: artifact.intendedWarnings,\n };\n });\n return makeCorpus(options.seed, artifacts, [...new Set(names)]);\n}\n\n/** A ready-made {@link SynthProfile} requesting every built-in ASTM quirk. */\nexport const astmQuirkProfile: SynthProfile = defineSynthProfile({\n name: \"cosyte-astm-quirks\",\n quirks: [...ALL_ASTM_QUIRKS],\n});\n","/**\n * `@cosyte/synth/astm`: the ASTM generation surface, exposed as its own subpath so importing the\n * package root does **not** pull `@cosyte/astm`. This is the **lazy, per-format** boundary: a consumer\n * who only needs ASTM fixtures imports `@cosyte/synth/astm`; one who needs only the core primitives\n * never loads a parser.\n * `@cosyte/astm` is an **optional peer dependency**, present only for this subpath.\n *\n * This subpath ships spec-clean generation of the E1394 record report and its E1381 framed twin, each\n * built through `@cosyte/astm`'s own emit surface:\n *\n * - **Records (E1394):** `generateAstmResult` (`H`/`P`/`O`/`R`…/`C`/`L`) and `generateAstmOrder`\n * (`H`/`P`/`O`/`L`) via `buildAstmMessage`, each round-tripping through `parseAstmRecords` with zero\n * warnings and byte-stable, and carrying a `P` record whose name / DOB / practice+lab IDs are all\n * synthetic-by-construction. The practice- and laboratory-assigned patient IDs are\n * minted independently, so they stay **distinct**.\n * - **Framing (E1381):** `generateAstmResultFramed` via `composeAstmFrames`, the modulo-256 checksum\n * and the `0`–`7` frame number are **computed by the parser, never faked**, and the bytes round-trip\n * through `parseFramedAstm` with zero frame **and** record warnings.\n *\n * @module\n */\n\nimport { createRng } from \"../rng/rng.js\";\nimport { makeCorpus, type Corpus } from \"../corpus.js\";\n\nimport { generateAstmResult, generateAstmOrder } from \"./message.js\";\nimport { astmRoundTrip } from \"./round-trip.js\";\nimport { resolveMix } from \"../select.js\";\n\nexport {\n generateAstmResult,\n generateAstmOrder,\n generateAstmResultFramed,\n type GenerateAstmOptions,\n} from \"./message.js\";\nexport { astmRoundTrip, astmFramedRoundTrip, type AstmRoundTripResult } from \"./round-trip.js\";\nexport {\n astmPatient,\n astmOrder,\n astmHeaderIdentity,\n type AstmPatient,\n type AstmOrder,\n type AstmHeaderIdentity,\n} from \"./identity.js\";\nexport {\n EXAMPLE_ASTM_TESTS,\n ASTM_ABNORMAL_FLAGS,\n ASTM_RESULT_STATUSES,\n ASTM_COMMENT_TEXT,\n type AstmExampleTest,\n} from \"./example-codes.js\";\nexport {\n generateAstmQuirk,\n astmQuirkRoundTrip,\n astmQuirkCorpus,\n astmQuirkProfile,\n ASTM_QUIRKS,\n type AstmQuirkName,\n type AstmQuirkKind,\n type GenerateAstmQuirkOptions,\n type AstmQuirkCorpusOptions,\n} from \"./quirk.js\";\n\n/** Every ASTM message kind {@link astmCorpus} generates: the label used as the corpus `kind`. */\nexport type AstmCorpusKind = \"Result\" | \"Order\";\n\n/** Every kind {@link astmCorpus} accepts, and the default mix: a result report and an order. */\nconst ALL_KINDS: readonly AstmCorpusKind[] = Object.freeze([\"Result\", \"Order\"]);\nconst DEFAULT_MIX = ALL_KINDS;\n\n/** Generate one message of the given kind from a sub-seed, returning the round-trip verdict. */\nfunction generateKind(kind: AstmCorpusKind, seed: number): ReturnType<typeof astmRoundTrip> {\n switch (kind) {\n case \"Result\":\n return astmRoundTrip(generateAstmResult({ seed }));\n case \"Order\":\n return astmRoundTrip(generateAstmOrder({ seed }));\n }\n}\n\n/** Options for {@link astmCorpus}. */\nexport interface AstmCorpusOptions {\n /** The seed for the whole corpus (deterministic). */\n readonly seed: number;\n /** How many messages to generate. Defaults to the length of the mix. */\n readonly count?: number;\n /** The message kinds to cycle through. Defaults to one of each. */\n readonly mix?: readonly AstmCorpusKind[];\n}\n\n/**\n * Build a reproducible {@link Corpus} of spec-clean ASTM messages. Each message is generated from a\n * distinct sub-seed derived from the corpus seed (so the set is deterministic) and round-tripped through\n * `@cosyte/astm`; the per-artifact `warnings` record the parser's verdict (empty ⇒ spec-clean).\n *\n * @param options - Seed, count, and the message mix. See {@link AstmCorpusOptions}.\n * @returns A deep-frozen {@link Corpus}.\n * @example\n * ```ts\n * import { astmCorpus } from \"@cosyte/synth/astm\";\n * const corpus = astmCorpus({ seed: 42 });\n * corpus.artifacts.every((a) => a.warnings.length === 0); // true, spec-clean\n * ```\n */\nexport function astmCorpus(options: AstmCorpusOptions): Corpus {\n const { seed } = options;\n const mix = resolveMix(ALL_KINDS, options.mix, DEFAULT_MIX);\n const count = options.count ?? mix.length;\n const seedStream = createRng(seed);\n const artifacts = Array.from({ length: count }, (_unused, i) => {\n const kind = mix[i % mix.length] ?? \"Result\";\n const msgSeed = seedStream.nextUint32();\n const rt = generateKind(kind, msgSeed);\n return {\n format: \"astm\" as const,\n kind,\n content: rt.content,\n warnings: rt.warnings,\n };\n });\n return makeCorpus(seed, artifacts);\n}\n"]}