@cosyte/terminology 0.0.7 → 0.0.8

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/common/coding.ts","../src/common/diagnostics.ts","../src/common/fhir-json.ts","../src/systems/registry.ts","../src/systems/resolve.ts","../src/conceptmap/load.ts","../src/conceptmap/translate.ts","../src/codesystem/status.ts","../src/codesystem/csv.ts","../src/codesystem/fhir.ts","../src/codesystem/fixed-width.ts","../src/codesystem/rrf.ts","../src/codesystem/load.ts","../src/codesystem/lookup.ts","../src/valueset/load.ts","../src/valueset/filters.ts","../src/valueset/expand.ts","../src/valueset/validate.ts","../src/ucum/essence-data.generated.ts","../src/ucum/essence.ts","../src/ucum/parse.ts","../src/ucum/reduce.ts","../src/ucum/validate.ts","../src/crosswalk/gems.ts","../src/crosswalk/categories.ts","../src/crosswalk/complex-map.ts","../src/rxnorm/tty.ts","../src/rxnorm/load.ts","../src/rxnorm/rela.ts","../src/rxnorm/navigate.ts","../src/index.ts"],"names":["v2","coding","malformed","assignString","truncated","cached","valueSet","cannotExpand","underPath","cell"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAAA,CAAA;;;ACFxC,SAAS,IAAA,CAAK,KAAa,IAAA,EAAkC;AAC3D,EAAA,MAAM,CAAA,GAAI,IAAI,MAAA,CAAO,CAAA,GAAA,EAAM,IAAI,CAAA,UAAA,CAAY,CAAA,CAAE,KAAK,GAAG,CAAA;AACrD,EAAA,OAAO,IAAI,CAAC,CAAA;AACd;AAGA,SAAS,UAAU,KAAA,EAA6D;AAC9E,EAAA,MAAM,CAAA,GAAI,kBAAA,CAAmB,IAAA,CAAK,KAAK,CAAA;AACvC,EAAA,IAAI,CAAC,CAAA,GAAI,CAAC,CAAA,EAAG,OAAO,MAAA;AACpB,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,CAAA,CAAE,CAAC,GAAG,OAAO,CAAA;AACpC,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,CAAA,CAAE,CAAC,GAAG,MAAM,CAAA;AAClC,EAAA,IAAI,SAAA,KAAc,MAAA,IAAa,QAAA,KAAa,MAAA,EAAW,OAAO,MAAA;AAC9D,EAAA,MAAM,MAAA,GAAS,OAAO,SAAS,CAAA;AAC/B,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,GAAG,OAAO,MAAA;AACrC,EAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,QAAA,EAAS;AAClC;AAqBO,SAAS,aAAa,GAAA,EAA0B;AACrD,EAAA,MAAM,WAAyB,EAAC;AAChC,EAAA,MAAM,QAAoB,EAAC;AAE3B,EAAA,KAAA,MAAW,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,wCAAwC,CAAA,EAAG;AAEtE,IAAA,MAAM,OAAA,GAAU,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AACxB,IAAA,MAAM,IAAA,GAAO,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AACrB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,EAAS,MAAM,CAAA;AAEjC,IAAA,MAAM,QAAA,GAAW,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAA;AAC7C,IAAA,MAAM,SAAA,GAAY,QAAA,GAAW,CAAC,CAAA,KAAM,MAAA,GAAY,SAAY,IAAA,CAAK,QAAA,CAAS,CAAC,CAAA,EAAG,OAAO,CAAA;AACrF,IAAA,MAAM,MAAA,GAAS,SAAA,KAAc,MAAA,GAAY,GAAA,GAAM,OAAO,SAAS,CAAA;AAC/D,IAAA,IAAI,IAAA,KAAS,MAAA,IAAa,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,EAAG,QAAA,CAAS,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,CAAA;AAAA,EACnF;AAEA,EAAA,KAAA,MAAW,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,uBAAuB,CAAA,EAAG;AAErD,IAAA,MAAM,OAAA,GAAU,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AACxB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,EAAS,MAAM,CAAA;AACjC,IAAA,IAAI,SAAS,MAAA,EAAW;AACxB,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA;AAAA,MACA,MAAA,EAAQ,IAAA;AAAA,MACR,IAAA,EAAM,IAAA;AAAA,MACN,GAAA,EAAK,IAAA;AAAA,MACL,OAAA,EAAS,KAAA;AAAA,MACT,SAAA,EAAW;AAAA,KACZ,CAAA;AAAA,EACH;AAEA,EAAA,KAAA,MAAW,CAAA,IAAK,GAAA,CAAI,QAAA,CAAS,oCAAoC,CAAA,EAAG;AAElE,IAAA,MAAM,OAAA,GAAU,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AACxB,IAAA,MAAM,IAAA,GAAO,CAAA,CAAE,CAAC,CAAA,IAAK,EAAA;AACrB,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,EAAS,MAAM,CAAA;AACjC,IAAA,IAAI,SAAS,MAAA,EAAW;AACxB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,EAAS,WAAW,CAAA,KAAM,KAAA;AAC/C,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,OAAA,EAAS,aAAa,CAAA,KAAM,KAAA;AAEnD,IAAA,MAAM,KAAA,GAAQ,OAAA,GAAU,MAAA,GAAY,SAAA,CAAU,IAAI,CAAA;AAClD,IAAA,KAAA,CAAM,IAAA,CAAK;AAAA,MACT,IAAA;AAAA,MACA,MAAA,EAAQ,IAAA,CAAK,OAAA,EAAS,UAAU,CAAA,KAAM,KAAA;AAAA,MACtC,IAAA,EAAM,KAAA;AAAA,MACN,OAAA;AAAA,MACA,SAAA;AAAA,MACA,GAAI,KAAA,GAAQ,EAAE,KAAA,KAAU;AAAC,KAC1B,CAAA;AAAA,EACH;AAIA,EAAA,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,IAAA,CAAK,MAAA,GAAS,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA;AACrD,EAAA,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,IAAA,CAAK,MAAA,GAAS,CAAA,CAAE,IAAA,CAAK,MAAM,CAAA;AAElD,EAAA,MAAM,UAAA,GAAa,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAC,CAAC,CAAC,CAAA;AACxD,EAAA,MAAM,YAAA,GAAe,IAAI,GAAA,CAAI,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAC,CAAC,CAAC,CAAA;AAC7D,EAAA,OAAO,cAAc,EAAE,QAAA,EAAU,KAAA,EAAO,UAAA,EAAY,cAAc,CAAA;AACpE;AAGA,SAAS,gBAAA,GAA0B;AACjC,EAAA,MAAM,IAAI,UAAU,kCAAkC,CAAA;AACxD;AAaA,SAAS,WAAc,GAAA,EAA6C;AAClE,EAAA,OAAO,MAAA,CAAO,iBAAiB,GAAA,EAAK;AAAA,IAClC,GAAA,EAAK,EAAE,KAAA,EAAO,gBAAA,EAAiB;AAAA,IAC/B,MAAA,EAAQ,EAAE,KAAA,EAAO,gBAAA,EAAiB;AAAA,IAClC,KAAA,EAAO,EAAE,KAAA,EAAO,gBAAA;AAAiB,GAClC,CAAA;AACH;AA0BA,SAAS,cAAc,OAAA,EAAmC;AACxD,EAAA,KAAA,MAAW,IAAA,IAAQ,QAAQ,KAAA,EAAO;AAChC,IAAA,IAAI,IAAA,CAAK,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,KAAK,KAAK,CAAA;AACxC,IAAA,MAAA,CAAO,OAAO,IAAI,CAAA;AAAA,EACpB;AACA,EAAA,KAAA,MAAW,MAAA,IAAU,OAAA,CAAQ,QAAA,EAAU,MAAA,CAAO,OAAO,MAAM,CAAA;AAC3D,EAAA,MAAA,CAAO,MAAA,CAAO,QAAQ,KAAK,CAAA;AAC3B,EAAA,MAAA,CAAO,MAAA,CAAO,QAAQ,QAAQ,CAAA;AAC9B,EAAA,UAAA,CAAW,QAAQ,UAAmC,CAAA;AACtD,EAAA,UAAA,CAAW,QAAQ,YAAuC,CAAA;AAC1D,EAAA,OAAO,MAAA,CAAO,OAAO,OAAO,CAAA;AAC9B;AAEA,IAAI,MAAA;AAoBG,SAAS,eAAA,GAA+B;AAC7C,EAAA,MAAA,KAAW,aAAa,gBAAgB,CAAA;AACxC,EAAA,OAAO,MAAA;AACT;;;ACxKA,IAAM,WAAA,GAAc,CAAC,EAAA,KAAwB,EAAA,IAAM,MAAQ,EAAA,IAAM,EAAA;AACjE,IAAM,SAAA,GAAY,CAAC,CAAA,EAAW,CAAA,KAAuB,YAAY,CAAA,CAAE,UAAA,CAAW,CAAC,CAAC,CAAA;AAGhF,SAAS,UAAA,CAAW,GAAW,GAAA,EAAsB;AACnD,EAAA,IAAI,GAAA,IAAO,CAAA,CAAE,MAAA,EAAQ,OAAO,IAAA;AAC5B,EAAA,MAAM,CAAA,GAAI,EAAE,GAAG,CAAA;AACf,EAAA,OAAO,CAAA,KAAM,GAAA,IAAO,CAAA,KAAM,GAAA,IAAO,CAAA,KAAM,GAAA;AACzC;AAcA,SAAS,aAAA,CAAc,OAAA,EAAsB,CAAA,EAAW,GAAA,EAA4B;AAClF,EAAA,MAAM,MAAqB,EAAC;AAC5B,EAAA,KAAA,MAAW,IAAA,IAAQ,QAAQ,KAAA,EAAO;AAChC,IAAA,IAAI,CAAA,CAAE,UAAA,CAAW,IAAA,CAAK,IAAA,EAAM,GAAG,CAAA,EAAG,GAAA,CAAI,IAAA,CAAK,EAAE,IAAA,EAAM,GAAA,EAAK,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA;AAAA,EAC5E;AACA,EAAA,KAAA,MAAW,MAAA,IAAU,QAAQ,QAAA,EAAU;AACrC,IAAA,IAAI,CAAC,CAAA,CAAE,UAAA,CAAW,MAAA,CAAO,IAAA,EAAM,GAAG,CAAA,EAAG;AACrC,IAAA,MAAM,GAAA,GAAM,GAAA,GAAM,MAAA,CAAO,IAAA,CAAK,MAAA;AAC9B,IAAA,KAAA,MAAW,IAAA,IAAQ,QAAQ,KAAA,EAAO;AAChC,MAAA,IAAI,KAAK,MAAA,IAAU,CAAA,CAAE,WAAW,IAAA,CAAK,IAAA,EAAM,GAAG,CAAA,EAAG;AAC/C,QAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,IAAA,EAAM,GAAA,EAAK,MAAA,CAAO,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,MAAA,EAAQ,CAAA;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACA,EAAA,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,GAAA,GAAM,CAAA,CAAE,GAAA,IAAA,CAAQ,CAAA,CAAE,SAAS,CAAA,GAAI,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,IAAI,CAAA,CAAE,CAAA;AAC3E,EAAA,OAAO,GAAA;AACT;AAeA,IAAM,eAAA,GAAkB,GAAA;AAGxB,SAAS,cAAc,GAAA,EAAmD;AACxE,EAAA,MAAM,EAAE,GAAE,GAAI,GAAA;AACd,EAAA,IAAI,IAAI,GAAA,CAAI,GAAA;AACZ,EAAA,IAAI,IAAA,GAAO,CAAA;AACX,EAAA,IAAI,CAAA,CAAE,CAAC,CAAA,KAAM,GAAA,EAAK,CAAA,EAAA;AAAA,OAAA,IACT,CAAA,CAAE,CAAC,CAAA,KAAM,GAAA,EAAK;AACrB,IAAA,IAAA,GAAO,EAAA;AACP,IAAA,CAAA,EAAA;AAAA,EACF;AACA,EAAA,MAAM,KAAA,GAAQ,CAAA;AACd,EAAA,OAAO,IAAI,CAAA,CAAE,MAAA,IAAU,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA,EAAG,CAAA,EAAA;AACxC,EAAA,IAAI,MAAM,KAAA,EAAO,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,UAAU,KAAA,EAAM;AACpD,EAAA,GAAA,CAAI,GAAA,GAAM,CAAA;AACV,EAAA,OAAO,EAAE,KAAA,EAAO,IAAA,GAAO,MAAA,CAAO,CAAA,CAAE,KAAA,CAAM,KAAA,EAAO,CAAC,CAAC,CAAA,EAAG,QAAA,EAAU,IAAA,EAAK;AACnE;AAGA,SAAS,gBAAgB,GAAA,EAAuC;AAC9D,EAAA,MAAM,EAAE,GAAE,GAAI,GAAA;AACd,EAAA,IAAI,CAAA,GAAI,IAAI,GAAA,GAAM,CAAA;AAClB,EAAA,OAAO,CAAA,GAAI,CAAA,CAAE,MAAA,EAAQ,CAAA,EAAA,EAAK;AACxB,IAAA,MAAM,IAAA,GAAO,CAAA,CAAE,UAAA,CAAW,CAAC,CAAA;AAC3B,IAAA,IAAI,SAAS,GAAA,EAAc;AACzB,MAAA,GAAA,CAAI,MAAM,CAAA,GAAI,CAAA;AACd,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI,IAAA,GAAO,EAAA,IAAQ,IAAA,GAAO,GAAA,IAAQ,SAAS,GAAA,EAAc;AACvD,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,sDAAA,EAAuD;AAAA,IACrF;AAAA,EACF;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,mCAAA,EAAoC;AAClE;AAGA,SAAS,gBAAgB,GAAA,EAAgE;AACvF,EAAA,MAAM,aAAa,aAAA,CAAc,GAAA,CAAI,SAAS,GAAA,CAAI,CAAA,EAAG,IAAI,GAAG,CAAA;AAC5D,EAAA,KAAA,MAAW,QAAQ,UAAA,EAAY;AAC7B,IAAA,MAAM,OAAO,GAAA,CAAI,GAAA;AACjB,IAAA,GAAA,CAAI,GAAA,GAAM,OAAO,IAAA,CAAK,GAAA;AACtB,IAAA,MAAM,GAAA,GAAM,cAAc,GAAG,CAAA;AAE7B,IAAA,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,IAAA,KAAS,KAAA,IAAS,IAAA,CAAK,KAAK,IAAA,KAAS,KAAA,KAAU,CAAC,GAAA,CAAI,QAAA,EAAU;AAC3E,MAAA,GAAA,CAAI,GAAA,GAAM,IAAA;AACV,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,gBAAgB,GAAA,CAAI,GAAA;AACxB,IAAA,IAAI,IAAI,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,GAAG,MAAM,GAAA,EAAc;AAC9C,MAAA,MAAM,GAAA,GAAM,gBAAgB,GAAG,CAAA;AAC/B,MAAA,IAAI,GAAA,EAAK;AACP,QAAA,GAAA,CAAI,GAAA,GAAM,IAAA;AACV,QAAA,OAAO,GAAA;AAAA,MACT;AACA,MAAA,aAAA,GAAgB,GAAA,CAAI,GAAA;AAAA,IACtB;AACA,IAAA,IAAI,UAAA,CAAW,GAAA,CAAI,CAAA,EAAG,aAAa,CAAA,EAAG;AACpC,MAAA,MAAM,IAAA,GAAuB,IAAA,CAAK,MAAA,GAC9B,EAAE,IAAA,EAAM,UAAU,MAAA,EAAQ,IAAA,CAAK,MAAA,EAAQ,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,UAAU,GAAA,CAAI,KAAA,EAAM,GAC5E,EAAE,IAAA,EAAM,QAAA,EAAU,MAAM,IAAA,CAAK,IAAA,EAAM,QAAA,EAAU,GAAA,CAAI,KAAA,EAAM;AAC3D,MAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAK;AAAA,IAC1B;AACA,IAAA,GAAA,CAAI,GAAA,GAAM,IAAA;AAAA,EACZ;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,wBAAA,EAAyB;AACvD;AAGA,SAAS,eAAe,GAAA,EAA+D;AACrF,EAAA,MAAM,EAAE,GAAE,GAAI,GAAA;AACd,EAAA,MAAM,EAAA,GAAK,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,GAAG,CAAA;AAE/B,EAAA,IAAI,OAAO,EAAA,EAAc;AACvB,IAAA,IAAI,GAAA,CAAI,SAAS,eAAA,EAAiB;AAChC,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,+BAAA,EAAgC;AAAA,IAC9D;AACA,IAAA,GAAA,CAAI,GAAA,EAAA;AACJ,IAAA,GAAA,CAAI,KAAA,EAAA;AACJ,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,GAAA,EAAK,IAAI,CAAA;AACjC,IAAA,GAAA,CAAI,KAAA,EAAA;AACJ,IAAA,IAAI,CAAC,KAAA,CAAM,EAAA,EAAI,OAAO,KAAA;AACtB,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,EAAE,MAAM,OAAA,EAAS,IAAA,EAAM,KAAA,CAAM,IAAA,EAAK,EAAE;AAAA,EAC/D;AAEA,EAAA,IAAI,OAAO,GAAA,EAAc;AACvB,IAAA,MAAM,GAAA,GAAM,gBAAgB,GAAG,CAAA;AAC/B,IAAA,IAAI,KAAK,OAAO,GAAA;AAChB,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,MAAM,EAAE,IAAA,EAAM,cAAa,EAAE;AAAA,EAClD;AAGA,EAAA,IAAI,YAAY,EAAE,CAAA,IAAK,CAAC,CAAA,CAAE,WAAW,KAAA,EAAO,GAAA,CAAI,GAAG,CAAA,IAAK,CAAC,CAAA,CAAE,UAAA,CAAW,KAAA,EAAO,GAAA,CAAI,GAAG,CAAA,EAAG;AACrF,IAAA,MAAM,QAAQ,GAAA,CAAI,GAAA;AAClB,IAAA,OAAO,GAAA,CAAI,MAAM,CAAA,CAAE,MAAA,IAAU,UAAU,CAAA,EAAG,GAAA,CAAI,GAAG,CAAA,EAAG,GAAA,CAAI,GAAA,EAAA;AACxD,IAAA,IAAI,CAAA,CAAE,UAAA,CAAW,GAAA,CAAI,GAAG,MAAM,GAAA,EAAc;AAC1C,MAAA,MAAM,GAAA,GAAM,gBAAgB,GAAG,CAAA;AAC/B,MAAA,IAAI,KAAK,OAAO,GAAA;AAAA,IAClB;AACA,IAAA,IAAI,CAAC,UAAA,CAAW,CAAA,EAAG,GAAA,CAAI,GAAG,CAAA,EAAG;AAC3B,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,kDAAA,EAAmD;AAAA,IACjF;AACA,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,EAAE,MAAM,QAAA,EAAU,KAAA,EAAO,MAAA,CAAO,CAAA,CAAE,MAAM,KAAA,EAAO,GAAA,CAAI,GAAG,CAAC,GAAE,EAAE;AAAA,EACtF;AAEA,EAAA,OAAO,gBAAgB,GAAG,CAAA;AAC5B;AAGA,SAAS,SAAA,CAAU,KAAa,OAAA,EAA+D;AAC7F,EAAA,MAAM,UAAwD,EAAC;AAE/D,EAAA,IAAI,IAAA,GAAe,CAAA;AACnB,EAAA,IAAI,GAAA,CAAI,CAAA,CAAE,GAAA,CAAI,GAAG,MAAM,GAAA,EAAK;AAC1B,IAAA,IAAA,GAAO,EAAA;AACP,IAAA,GAAA,CAAI,GAAA,EAAA;AAAA,EACN;AACA,EAAA,MAAM,KAAA,GAAQ,eAAe,GAAG,CAAA;AAChC,EAAA,IAAI,CAAC,KAAA,CAAM,EAAA,EAAI,OAAO,KAAA;AACtB,EAAA,OAAA,CAAQ,KAAK,EAAE,IAAA,EAAM,IAAA,EAAM,KAAA,CAAM,MAAM,CAAA;AAEvC,EAAA,OAAO,GAAA,CAAI,GAAA,GAAM,GAAA,CAAI,CAAA,CAAE,MAAA,EAAQ;AAC7B,IAAA,MAAM,EAAA,GAAK,GAAA,CAAI,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA;AACxB,IAAA,IAAI,EAAA,KAAO,GAAA,IAAO,EAAA,KAAO,GAAA,EAAK;AAC9B,IAAA,GAAA,CAAI,GAAA,EAAA;AACJ,IAAA,MAAM,IAAA,GAAO,eAAe,GAAG,CAAA;AAC/B,IAAA,IAAI,CAAC,IAAA,CAAK,EAAA,EAAI,OAAO,IAAA;AACrB,IAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,IAAA,EAAM,EAAA,KAAO,GAAA,GAAM,KAAK,CAAA,EAAG,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,CAAA;AAAA,EAC7D;AAEA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,IAAI,GAAA,CAAI,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA,KAAM,GAAA,EAAK,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,mCAAA,EAA+B;AACvF,IAAA,GAAA,CAAI,GAAA,EAAA;AAAA,EACN;AACA,EAAA,OAAO,EAAE,IAAI,IAAA,EAAM,IAAA,EAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,SAAQ,EAAE;AACrD;AAeO,SAAS,UAAU,IAAA,EAA2B;AACnD,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,QAAQ,uBAAA,EAAwB;AAC3E,EAAA,MAAM,GAAA,GAAc,EAAE,CAAA,EAAG,IAAA,EAAM,GAAA,EAAK,GAAG,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,eAAA,EAAgB,EAAE;AAC5E,EAAA,MAAM,MAAA,GAAS,SAAA,CAAU,GAAA,EAAK,KAAK,CAAA;AACnC,EAAA,IAAI,CAAC,MAAA,CAAO,EAAA,EAAI,OAAO,MAAA;AACvB,EAAA,IAAI,GAAA,CAAI,GAAA,KAAQ,IAAA,CAAK,MAAA,EAAQ;AAC3B,IAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,MAAA,EAAQ,+CAAA,EAAgD;AAAA,EAC9E;AACA,EAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,IAAA,EAAM,OAAO,IAAA,EAAK;AACvC;;;AC3NA,SAAS,QAAA,CAAS,GAAoB,CAAA,EAAqC;AACzE,EAAA,MAAM,IAAA,GAA+B,EAAE,GAAG,CAAA,CAAE,IAAA,EAAK;AACjD,EAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,CAAA,CAAE,IAAI,CAAA,EAAG;AAC3C,IAAA,MAAM,IAAA,GAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,IAAK,CAAA,IAAK,CAAA;AAC9B,IAAA,IAAI,IAAA,KAAS,CAAA,EAAG,OAAO,IAAA,CAAK,CAAC,CAAA;AAAA,SACxB,IAAA,CAAK,CAAC,CAAA,GAAI,IAAA;AAAA,EACjB;AACA,EAAA,OAAO,EAAE,MAAM,QAAA,EAAU,MAAA,EAAQ,EAAE,MAAA,GAAS,CAAA,CAAE,QAAQ,IAAA,EAAK;AAC7D;AAGA,SAAS,KAAA,CAAM,GAAoB,CAAA,EAA4B;AAC7D,EAAA,IAAI,CAAA,KAAM,GAAG,OAAO,CAAA;AACpB,EAAA,MAAM,OAA+B,EAAC;AACtC,EAAA,KAAA,MAAW,CAAC,GAAG,CAAC,CAAA,IAAK,OAAO,OAAA,CAAQ,CAAA,CAAE,IAAI,CAAA,EAAG;AAC3C,IAAA,MAAM,IAAI,CAAA,GAAI,CAAA;AACd,IAAA,IAAI,CAAA,KAAM,CAAA,EAAG,IAAA,CAAK,CAAC,CAAA,GAAI,CAAA;AAAA,EACzB;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,IAAA,CAAK,IAAI,CAAA,CAAE,MAAA,EAAQ,CAAC,CAAA,EAAG,IAAA,EAAK;AAC/D;AAYA,IAAM,aAAA,GAAiC,OAAO,MAAA,CAAO;AAAA,EACnD,IAAA,EAAM,QAAA;AAAA,EACN,MAAA,EAAQ,CAAA;AAAA,EACR,IAAA,EAAM,MAAA,CAAO,MAAA,CAAO,EAAE;AACxB,CAAC,CAAA;AAmCD,IAAM,QAAA,uBAAe,OAAA,EAAmC;AACxD,IAAM,UAAA,uBAAiB,OAAA,EAAkB;AAGzC,SAAS,iBAAiB,IAAA,EAAiC;AAOzD,EAAA,IAAI,KAAK,IAAA,EAAM,OAAO,EAAE,IAAA,EAAM,UAAU,MAAA,EAAQ,CAAA,EAAG,IAAA,EAAM,EAAE,CAAC,IAAA,CAAK,GAAA,IAAO,KAAK,IAAI,GAAG,GAAE,EAAE;AAExF,EAAA,IAAI,KAAK,SAAA,EAAW,OAAO,EAAE,IAAA,EAAM,UAAU,MAAA,EAAQ,CAAA,EAAG,IAAA,EAAM,EAAE,CAAC,CAAA,IAAA,EAAO,IAAA,CAAK,IAAI,CAAA,CAAE,GAAG,GAAE,EAAE;AAE1F,EAAA,MAAMD,OAAAA,GAAS,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAChC,EAAA,IAAIA,SAAQ,OAAOA,OAAAA;AAwCnB,EAAA,IAAI,UAAA,CAAW,GAAA,CAAI,IAAI,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,MAAM,+CAA+C,CAAA;AAAA,EACjE;AACA,EAAA,IAAI,CAAC,KAAK,KAAA,EAAO;AAMf,IAAA,MAAM,IAAI,MAAM,oCAAoC,CAAA;AAAA,EACtD;AAEA,EAAA,UAAA,CAAW,IAAI,IAAI,CAAA;AACnB,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,SAAA,CAAU,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AACxC,IAAA,IAAI,CAAC,OAAO,EAAA,EAAI;AACd,MAAA,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAAA,IACzE;AACA,IAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,MAAA,CAAO,IAAI,CAAA;AAC5C,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,EAAE,IAAA,EAAM,QAAA,EAAU,MAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,EAAQ,IAAA,EAAM,EAAC,IAAK,OAAO,CAAA;AACxF,IAAA,QAAA,CAAS,GAAA,CAAI,MAAM,MAAM,CAAA;AACzB,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,SAAE;AAaA,IAAA,UAAA,CAAW,OAAO,IAAI,CAAA;AAAA,EACxB;AACF;AAGA,SAAS,mBAAmB,IAAA,EAAuC;AACjE,EAAA,MAAM,IAAA,GAAO,gBAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AACvC,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,GAClB,EAAE,MAAM,QAAA,EAAmB,MAAA,EAAQ,IAAA,CAAK,MAAA,GAAS,KAAK,MAAA,CAAO,MAAA,EAAQ,IAAA,EAAM,IAAA,CAAK,MAAK,GACrF,IAAA;AACJ,EAAA,OAAO,KAAA,CAAM,QAAA,EAAU,IAAA,CAAK,QAAQ,CAAA;AACtC;AAGA,SAAS,sBAAsB,IAAA,EAAsC;AACnE,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,QAAA;AACH,MAAA,OAAO,EAAE,MAAM,QAAA,EAAU,MAAA,EAAQ,KAAK,KAAA,EAAO,IAAA,EAAM,EAAC,EAAE;AAAA,IACxD,KAAK,YAAA;AACH,MAAA,OAAO,aAAA;AAAA,IACT,KAAK,OAAA;AACH,MAAA,OAAO,gBAAA,CAAiB,KAAK,IAAI,CAAA;AAAA,IACnC,KAAK,QAAA;AACH,MAAA,OAAO,mBAAmB,IAAI,CAAA;AAAA;AAEpC;AAGA,SAAS,iBAAiB,IAAA,EAAiC;AAEzD,EAAA,IAAI,GAAA,GAAuB,EAAE,IAAA,EAAM,QAAA,EAAU,QAAQ,CAAA,EAAG,IAAA,EAAM,EAAC,EAAE;AACjE,EAAA,KAAA,MAAW,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAK,IAAK,KAAK,OAAA,EAAS;AAC/C,IAAA,GAAA,GAAM,SAAS,GAAA,EAAK,KAAA,CAAM,sBAAsB,IAAI,CAAA,EAAG,IAAI,CAAC,CAAA;AAAA,EAC9D;AACA,EAAA,OAAO,GAAA;AACT;AAGA,SAAS,gBAAgB,IAAA,EAAyB;AAChD,EAAA,OAAO,KAAK,OAAA,CAAQ,IAAA,CAAK,CAAC,EAAE,IAAA,EAAM,MAAK,KAAM;AAC3C,IAAA,IAAI,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU,OAAO,KAAK,IAAA,CAAK,OAAA;AAC7C,IAAA,IAAI,KAAK,IAAA,KAAS,OAAA,EAAS,OAAO,eAAA,CAAgB,KAAK,IAAI,CAAA;AAC3D,IAAA,OAAO,KAAA;AAAA,EACT,CAAC,CAAA;AACH;AAGA,SAAS,iBAAiB,IAAA,EAAwB;AAChD,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,EAAa,SAAA,KAA4B;AACrD,IAAA,KAAA,MAAW,EAAE,IAAA,EAAM,IAAA,EAAM,IAAA,EAAK,IAAK,EAAE,OAAA,EAAS;AAC5C,MAAA,MAAM,IAAI,IAAA,GAAO,SAAA;AACjB,MAAA,IAAI,IAAA,CAAK,SAAS,QAAA,EAAU;AAC1B,QAAA,MAAM,GAAA,GAAM,KAAK,QAAA,GAAW,CAAA;AAC5B,QAAA,MAAA,CAAO,KAAK,CAAA,EAAG,IAAA,CAAK,MAAA,EAAQ,IAAA,IAAQ,EAAE,CAAA,EAAG,IAAA,CAAK,IAAA,CAAK,IAAI,GAAG,GAAA,KAAQ,CAAA,GAAI,KAAK,MAAA,CAAO,GAAG,CAAC,CAAA,CAAE,CAAA;AAAA,MAC1F,CAAA,MAAA,IAAW,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU;AACjC,QAAA,MAAA,CAAO,IAAA,CAAK,CAAA,CAAA,EAAI,MAAA,CAAO,IAAA,CAAK,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,KAAK,CAAA,CAAA,EAAI,MAAA,CAAO,CAAC,CAAC,EAAE,CAAA,CAAE,CAAA;AAAA,MACvE,CAAA,MAAA,IAAW,IAAA,CAAK,IAAA,KAAS,OAAA,EAAS;AAChC,QAAA,IAAA,CAAK,IAAA,CAAK,MAAM,CAAC,CAAA;AAAA,MACnB;AAAA,IAEF;AAAA,EACF,CAAA;AACA,EAAA,IAAA,CAAK,MAAM,CAAC,CAAA;AACZ,EAAA,OAAO,MAAA,CAAO,IAAA,EAAK,CAAE,IAAA,CAAK,GAAG,CAAA;AAC/B;AA+BO,SAAS,OAAO,IAAA,EAA2B;AAChD,EAAA,IAAI,eAAA,CAAgB,IAAI,CAAA,EAAG,OAAO,EAAE,MAAM,SAAA,EAAW,IAAA,EAAM,gBAAA,CAAiB,IAAI,CAAA,EAAE;AAClF,EAAA,OAAO,iBAAiB,IAAI,CAAA;AAC9B;;;AC7QA,SAAS,YAAY,CAAA,EAAmB;AACtC,EAAA,OAAO,OAAO,MAAA,CAAO,CAAA,CAAE,WAAA,CAAY,EAAE,CAAC,CAAC,CAAA;AACzC;AAGA,SAAS,YAAY,CAAA,EAAsB;AACzC,EAAA,IAAI,EAAE,IAAA,KAAS,SAAA,EAAW,OAAO,CAAA,QAAA,EAAW,EAAE,IAAI,CAAA,CAAA;AAClD,EAAA,MAAM,OAAO,MAAA,CAAO,IAAA,CAAK,CAAA,CAAE,IAAI,EAAE,IAAA,EAAK;AACtC,EAAA,MAAM,IAAA,GAAO,KAAK,MAAA,KAAW,CAAA,GAAI,MAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAG,CAAC,CAAA,EAAG,MAAA,CAAO,EAAE,IAAA,CAAK,CAAC,CAAC,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAC3F,EAAA,OAAO,GAAG,WAAA,CAAY,CAAA,CAAE,MAAM,CAAC,IAAI,IAAI,CAAA,CAAA;AACzC;AAoBO,SAAS,aAAa,IAAA,EAA8B;AACzD,EAAA,MAAM,MAAA,GAAS,UAAU,IAAI,CAAA;AAC7B,EAAA,IAAI,CAAC,MAAA,CAAO,EAAA,EAAI,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,mBAAA,EAAqB,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAO;AACxF,EAAA,OAAO,EAAE,OAAO,IAAA,EAAM,SAAA,EAAW,YAAY,MAAA,CAAO,MAAA,CAAO,IAAI,CAAC,CAAA,EAAE;AACpE;AAwBO,SAAS,SAAA,CAAU,GAAW,CAAA,EAAoB;AACvD,EAAA,MAAM,EAAA,GAAK,aAAa,CAAC,CAAA;AACzB,EAAA,MAAM,EAAA,GAAK,aAAa,CAAC,CAAA;AACzB,EAAA,OAAO,GAAG,KAAA,IAAS,EAAA,CAAG,KAAA,IAAS,EAAA,CAAG,cAAc,EAAA,CAAG,SAAA;AACrD;;;ACtCA,IAAM,KAAA,GAAQ,MAAA;AAEd,IAAM,MAAA,GAAS,OAAA;AAGf,SAAS,gBAAgB,MAAA,EAAyB;AAChD,EAAA,OAAO,MAAA,KAAW,SAAS,MAAA,KAAW,MAAA;AACxC;AAmBA,SAAS,YAAY,GAAA,EAAmC;AACtD,EAAA,IAAI,CAAC,YAAA,CAAa,IAAA,CAAK,GAAG,GAAG,OAAO,MAAA;AACpC,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,WAAA,EAAa,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA;AAAA,IACxB,KAAA,EAAO,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA;AAAA,IAClB,WAAA,EAAa,GAAA,CAAI,CAAC,CAAA,KAAM,GAAA;AAAA,IACxB,QAAA,EAAU,MAAA,CAAO,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,IACvB,UAAA,EAAY,MAAA,CAAO,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,IACzB;AAAA,GACD,CAAA;AACH;AA0BO,SAAS,SAAS,MAAA,EAA2B;AAClD,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAwB;AAC5C,EAAA,MAAM,WAA6B,EAAC;AACpC,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAM,OAAO,CAAA;AAC1C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAM,GAAA,GAAM,MAAM,CAAC,CAAA;AACnB,IAAA,IAAI,QAAQ,MAAA,EAAW;AACvB,IAAA,MAAM,OAAA,GAAU,IAAI,IAAA,EAAK;AACzB,IAAA,IAAI,YAAY,EAAA,EAAI;AACpB,IAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,KAAA,CAAM,KAAK,CAAA;AAClC,IAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,IAAA,EAAM,wBAAA;AAAA,QACN,MAAM,CAAA,GAAI,CAAA;AAAA,QACV,MAAA,EAAQ,CAAA,8CAAA,EAAiD,MAAA,CAAO,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA,OAC/E,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,MAAM,CAAC,GAAA,EAAK,GAAA,EAAK,OAAO,CAAA,GAAI,MAAA;AAC5B,IAAA,MAAM,KAAA,GAAQ,YAAY,OAAO,CAAA;AACjC,IAAA,IAAI,UAAU,MAAA,EAAW;AACvB,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,IAAA,EAAM,wBAAA;AAAA,QACN,MAAM,CAAA,GAAI,CAAA;AAAA,QACV,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,MAAM,KAAA,GAA4B,EAAE,MAAA,EAAQ,GAAA,EAAK,KAAA,EAAM;AAEvD,IAAA,IAAI,CAAC,eAAA,CAAgB,GAAG,CAAA,QAAS,MAAA,GAAS,GAAA;AAC1C,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA;AAClC,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,GAAG,CAAA;AAC5B,IAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA;AAAA,SACrB,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,CAAC,MAAM,CAAC,CAAA;AAC9B,IAAA,KAAA,EAAA;AAAA,EACF;AACA,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,WAAW,MAAA,CAAO,SAAA;AAAA,IAClB,GAAI,OAAO,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,MAAA,CAAO,OAAA,EAAQ,GAAI,EAAC;AAAA,IAClE,KAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA,EAAU,MAAA,CAAO,MAAA,CAAO,QAAQ;AAAA,GACjC,CAAA;AACH;AAGA,SAAS,kBAAkB,OAAA,EAAkE;AAC3F,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,KAAA,CAAM,WAAA,IAAe,CAAA,CAAE,MAAA,KAAW,MAAS,CAAA;AACjF,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAE/B,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,MAAM,UAAA,uBAAiB,GAAA,EAAmC;AAC1D,EAAA,KAAA,MAAW,KAAK,KAAA,EAAO;AACrB,IAAA,MAAM,CAAA,GAAI,EAAE,KAAA,CAAM,QAAA;AAClB,IAAA,IAAI,KAAA,GAAQ,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA;AAC5B,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,KAAA,uBAAY,GAAA,EAAsB;AAClC,MAAA,UAAA,CAAW,GAAA,CAAI,GAAG,KAAK,CAAA;AACvB,MAAA,YAAA,CAAa,KAAK,CAAC,CAAA;AAAA,IACrB;AACA,IAAA,MAAM,EAAA,GAAK,EAAE,KAAA,CAAM,UAAA;AACnB,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,GAAA,CAAI,EAAE,CAAA;AAC5B,IAAA,IAAI,OAAA,EAAS,OAAA,CAAQ,IAAA,CAAK,CAAA,CAAE,MAAgB,CAAA;AAAA,eACjC,GAAA,CAAI,EAAA,EAAI,CAAC,CAAA,CAAE,MAAgB,CAAC,CAAA;AAAA,EACzC;AACA,EAAA,MAAM,YAA2B,EAAC;AAClC,EAAA,KAAA,MAAW,CAAA,IAAK,aAAa,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA,EAAG;AAClD,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA;AAC9B,IAAA,MAAM,cAA+B,EAAC;AACtC,IAAA,KAAA,MAAW,EAAA,IAAM,CAAC,GAAG,KAAA,CAAM,IAAA,EAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA,EAAG;AACxD,MAAA,WAAA,CAAY,IAAA;AAAA,QACV,MAAA,CAAO,MAAA,CAAO,EAAE,UAAA,EAAY,EAAA,EAAI,OAAA,EAAS,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,GAAA,CAAI,EAAE,CAAa,GAAG;AAAA,OACrF;AAAA,IACF;AACA,IAAA,SAAA,CAAU,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,EAAE,QAAA,EAAU,CAAA,EAAG,WAAA,EAAa,MAAA,CAAO,MAAA,CAAO,WAAW,CAAA,EAAG,CAAC,CAAA;AAAA,EACxF;AACA,EAAA,OAAO,MAAA,CAAO,OAAO,SAAS,CAAA;AAChC;AAsBO,SAAS,QAAA,CAAS,KAAa,MAAA,EAAgC;AACpE,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA;AAClC,EAAA,IAAI,GAAA,KAAQ,MAAA,IAAa,GAAA,CAAI,MAAA,KAAW,CAAA,EAAG;AACzC,IAAA,MAAM,QAAA,GAA8B,OAAO,MAAA,CAAO;AAAA,MAChD,MAAA,EAAQ,KAAA;AAAA,MACR,KAAA,EAAO,KAAA;AAAA,MACP,IAAA,EAAM,yBAAA;AAAA,MACN;AAAA,KACD,CAAA;AACD,IAAA,OAAO,QAAA;AAAA,EACT;AAKA,EAAA,MAAM,cAAc,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,MAAS,CAAA;AAC5D,EAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAE5B,IAAA,MAAM,KAAA,GAAwB,OAAO,MAAA,CAAO;AAAA,MAC1C,MAAA,EAAQ,KAAA;AAAA,MACR,KAAA,EAAO,IAAA;AAAA,MACP,IAAA,EAAM,uBAAA;AAAA,MACN,MAAA;AAAA,MACA,SAAS,MAAA,CAAO,MAAA,CAAO,CAAC,GAAG,GAAG,CAAC;AAAA,KAChC,CAAA;AACD,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,YAAA,GAAe,kBAAkB,WAAW,CAAA;AAClD,EAAA,MAAM,OAAA,GAAgC;AAAA,IACpC,MAAA,EAAQ,IAAA;AAAA,IACR,MAAA;AAAA,IACA,WAAW,GAAA,CAAI,SAAA;AAAA,IACf,SAAS,MAAA,CAAO,MAAA,CAAO,CAAC,GAAG,WAAW,CAAC;AAAA,GACzC;AACA,EAAA,IAAI,YAAA,KAAiB,MAAA,EAAW,OAAA,CAAQ,YAAA,GAAe,YAAA;AACvD,EAAA,OAAO,MAAA,CAAO,OAAO,OAAO,CAAA;AAC9B;AASA,IAAM,sBAAA,uBAA0D,GAAA,CAAI;AAAA,EAClE,CAAC,WAAW,yFAAoF,CAAA;AAAA,EAChG,CAAC,WAAW,yFAAoF;AAClG,CAAC,CAAA;AAGD,IAAM,gCAAA,GACJ,qEAAA;AAqBK,SAAS,UAAU,GAAA,EAAoB;AAC5C,EAAA,MAAM,IAAI,gBAAA;AAAA,IACR,WAAA,CAAY,uBAAA;AAAA,IACZ,sBAAA,CAAuB,GAAA,CAAI,GAAA,CAAI,SAAS,CAAA,IAAK;AAAA,GAC/C;AACF;;;AC5PO,IAAM,cAAA,GAAiB;AAAA;AAAA,EAE5B,mBAAA,EAAqB,WAAA;AAAA;AAAA,EAErB,MAAA,EAAQ,WAAA;AAAA;AAAA,EAER,iBAAA,EAAmB,WAAA;AAAA;AAAA,EAEnB,SAAA,EAAW;AACb;AASO,IAAM,oCAAyC,IAAI,GAAA,CAAI,CAAC,cAAA,CAAe,MAAM,CAAC;AAO9E,IAAM,cAAA,GAAiB;AAMvB,IAAM,aAAA,GAAgB;AAMtB,IAAM,eAAA,GAAkB;;;ACvB/B,IAAM,aAAA,GAAgB,WAAA;AAEtB,IAAM,WAAA,GAAc,WAAA;AAepB,SAAS,YAAY,CAAA,EAAqC;AACxD,EAAA,MAAM,GAAA,GAAiC;AAAA,IACrC,QAAQ,CAAA,CAAE,MAAA;AAAA,IACV,OAAO,CAAA,CAAE,KAAA;AAAA,IACT,UAAU,CAAA,CAAE,QAAA;AAAA,IACZ,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,QAAQ,CAAA,CAAE;AAAA,GACZ;AACA,EAAA,IAAI,CAAA,CAAE,WAAW,MAAA,IAAa,CAAA,CAAE,WAAW,EAAA,EAAI,GAAA,CAAI,SAAS,CAAA,CAAE,MAAA;AAC9D,EAAA,IAAI,CAAA,CAAE,aAAa,MAAA,IAAa,CAAA,CAAE,aAAa,EAAA,EAAI,GAAA,CAAI,WAAW,CAAA,CAAE,QAAA;AACpE,EAAA,IAAI,CAAA,CAAE,gBAAgB,MAAA,IAAa,CAAA,CAAE,gBAAgB,EAAA,EAAI,GAAA,CAAI,cAAc,CAAA,CAAE,WAAA;AAC7E,EAAA,OAAO,MAAA,CAAO,OAAO,GAAG,CAAA;AAC1B;AAGA,SAAS,SAAS,OAAA,EAGhB;AACA,EAAA,MAAM,OAA0B,EAAC;AACjC,EAAA,MAAM,WAAoC,EAAC;AAC3C,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,OAAO,CAAA;AACnC,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,IAAK,KAAA,CAAM,CAAC,CAAA,KAAM,MAAA,IAAa,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK,KAAM,EAAA,EAAI;AAC1E,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,WAAA,CAAY,wBAAA;AAAA,MACZ;AAAA,KACF;AAAA,EACF;AACA,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,CAAC,CAAA,CAAE,KAAA,CAAM,GAAI,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,CAAA;AACvD,EAAA,MAAM,GAAA,GAAM,CAAC,IAAA,KAAyB,MAAA,CAAO,QAAQ,IAAI,CAAA;AACzD,EAAA,MAAM,OAAA,GAAU,IAAI,QAAQ,CAAA;AAC5B,EAAA,MAAM,OAAA,GAAU,IAAI,uBAAuB,CAAA;AAC3C,EAAA,MAAM,MAAA,GAAS,IAAI,UAAU,CAAA;AAC7B,EAAA,MAAM,SAAA,GAAY,IAAI,aAAa,CAAA;AACnC,EAAA,MAAM,KAAA,GAAQ,IAAI,SAAS,CAAA;AAC3B,EAAA,MAAM,OAAA,GAAU,IAAI,WAAW,CAAA;AAC/B,EAAA,MAAM,OAAA,GAAU,IAAI,WAAW,CAAA;AAC/B,EAAA,MAAM,KAAA,GAAQ,IAAI,eAAe,CAAA;AACjC,EAAA,MAAM,IAAA,GAAO,IAAI,eAAe,CAAA;AAChC,EAAA,IAAI,OAAA,GAAU,CAAA,IAAK,MAAA,GAAS,CAAA,IAAK,YAAY,CAAA,EAAG;AAC9C,IAAA,MAAM,IAAI,gBAAA;AAAA,MACR,WAAA,CAAY,wBAAA;AAAA,MACZ;AAAA,KACF;AAAA,EACF;AACA,EAAA,MAAM,EAAA,GAAK,CAAC,MAAA,EAA2B,CAAA,KACrC,CAAA,IAAK,CAAA,IAAK,CAAA,GAAI,MAAA,CAAO,MAAA,GAAU,MAAA,CAAO,CAAC,CAAA,IAAK,EAAA,GAAM,EAAA;AACpD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAM,GAAA,GAAM,MAAM,CAAC,CAAA;AACnB,IAAA,IAAI,GAAA,KAAQ,MAAA,IAAa,GAAA,KAAQ,EAAA,EAAI;AACrC,IAAA,MAAM,CAAA,GAAI,GAAA,CAAI,KAAA,CAAM,GAAI,CAAA;AAExB,IAAA,IAAI,WAAW,CAAA,IAAK,EAAA,CAAG,CAAA,EAAG,OAAO,MAAM,GAAA,EAAK;AAC5C,IAAA,MAAM,MAAA,GAAS,EAAA,CAAG,CAAA,EAAG,OAAO,CAAA;AAC5B,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,EAAA,CAAG,CAAA,EAAG,MAAM,CAAC,CAAA;AACnC,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,EAAA,CAAG,CAAA,EAAG,SAAS,CAAC,CAAA;AACzC,IAAA,IAAI,MAAA,KAAW,EAAA,IAAM,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,IAAK,CAAC,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,EAAG;AAC5E,MAAA,QAAA,CAAS,IAAA,CAAK;AAAA,QACZ,IAAA,EAAM,gCAAA;AAAA,QACN,MAAM,CAAA,GAAI,CAAA;AAAA,QACV,MAAA,EAAQ;AAAA,OACT,CAAA;AACD,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,IAAA,CAAK;AAAA,MACR,MAAA;AAAA,MACA,KAAA,EAAO,MAAA;AAAA,MACP,QAAA,EAAU,SAAA;AAAA,MACV,IAAA,EAAM,EAAA,CAAG,CAAA,EAAG,KAAK,CAAA;AAAA,MACjB,MAAA,EAAQ,EAAA,CAAG,CAAA,EAAG,OAAO,CAAA;AAAA,MACrB,MAAA,EAAQ,EAAA,CAAG,CAAA,EAAG,OAAO,CAAA;AAAA,MACrB,QAAA,EAAU,EAAA,CAAG,CAAA,EAAG,IAAI,CAAA;AAAA,MACpB,WAAA,EAAa,EAAA,CAAG,CAAA,EAAG,KAAK;AAAA,KACzB,CAAA;AAAA,EACH;AACA,EAAA,OAAO,EAAE,MAAM,QAAA,EAAS;AAC1B;AA2BO,SAAS,eAAe,KAAA,EAAoC;AACjE,EAAA,IAAI,OAAA;AACJ,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI,KAAA,CAAM,WAAW,KAAA,EAAO;AAC1B,IAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,CAAM,OAAO,CAAA;AACrC,IAAA,OAAA,GAAU,MAAA,CAAO,IAAA;AACjB,IAAA,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,QAAQ,CAAA;AAAA,EAC1C,CAAA,MAAO;AACL,IAAA,OAAA,GAAU,KAAA,CAAM,IAAA;AAChB,IAAA,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAAA,EAC7B;AAEA,EAAA,MAAM,QAAA,uBAAe,GAAA,EAA+B;AACpD,EAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,IAAA,MAAM,CAAA,GAAI,YAAY,CAAC,CAAA;AACvB,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,MAAM,CAAA;AAClC,IAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAAA,kBACP,GAAA,CAAI,CAAA,CAAE,MAAA,EAAQ,CAAC,CAAC,CAAC,CAAA;AAAA,EACjC;AAEA,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAwC;AAC5D,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,IAAI,CAAA,IAAK,QAAA,EAAU;AAClC,IAAA,MAAM,SAAS,CAAC,GAAG,IAAI,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,QAAQ,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,QAAA,GAAW,EAAE,QAAQ,CAAA;AACpF,IAAA,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,MAAA,CAAO,MAAM,CAAC,CAAA;AACtC,IAAA,KAAA,IAAS,MAAA,CAAO,MAAA;AAAA,EAClB;AAEA,EAAA,MAAM,GAAA,GAA4B;AAAA,IAChC,KAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,IAAI,KAAA,CAAM,OAAA,KAAY,MAAA,EAAW,GAAA,CAAI,UAAU,KAAA,CAAM,OAAA;AACrD,EAAA,OAAO,MAAA,CAAO,OAAO,GAAG,CAAA;AAC1B;AAUA,SAAS,gBAAA,CAAiB,QAAgB,OAAA,EAAoC;AAC5E,EAAA,MAAM,OAAA,GAAU,OAAO,IAAA,EAAK;AAC5B,EAAA,IAAI,CAAC,SAAA,CAAU,IAAA,CAAK,OAAO,GAAG,OAAO,SAAA;AAGrC,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,aAAa,CAAA,EAAG;AACnC,IAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,OAAO,SAAA;AACzC,IAAA,OAAO,OAAA,CAAQ,MAAA,KAAW,QAAA,GAAW,OAAA,GAAU,UAAA;AAAA,EACjD;AACA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,WAAW,CAAA,EAAG;AACjC,IAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,MAAA,EAAW,OAAO,SAAA;AACzC,IAAA,OAAO,OAAA,CAAQ,MAAA,KAAW,MAAA,GAAS,OAAA,GAAU,UAAA;AAAA,EAC/C;AAGA,EAAA,MAAM,QAAA,GAAW,+CAAA,CAAgD,IAAA,CAAK,OAAO,CAAA;AAC7E,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,MAAM,EAAA,GAAK,SAAS,CAAC,CAAA;AACrB,IAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,QAAA,CAAS,CAAC,CAAC,CAAA;AAChC,IAAA,IAAI,OAAA,CAAQ,aAAa,MAAA,IAAa,CAAC,OAAO,QAAA,CAAS,KAAK,GAAG,OAAO,SAAA;AACtE,IAAA,MAAM,MAAM,OAAA,CAAQ,QAAA;AACpB,IAAA,MAAM,EAAA,GACJ,OAAO,IAAA,GACH,GAAA,IAAO,QACP,EAAA,KAAO,IAAA,GACL,OAAO,KAAA,GACP,EAAA,KAAO,MACL,GAAA,GAAM,KAAA,GACN,OAAO,GAAA,GACL,GAAA,GAAM,QACN,EAAA,KAAO,GAAA,GACL,QAAQ,KAAA,GACR,MAAA;AACd,IAAA,IAAI,EAAA,KAAO,QAAW,OAAO,SAAA;AAC7B,IAAA,OAAO,KAAK,OAAA,GAAU,UAAA;AAAA,EACxB;AAEA,EAAA,OAAO,SAAA;AACT;AAgBA,SAAS,YAAA,CAAa,MAAc,OAAA,EAAoC;AACtE,EAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAE1B,EAAA,IAAI,uBAAA,CAAwB,IAAA,CAAK,OAAO,CAAA,EAAG,OAAO,OAAA;AAElD,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,KAAA,CAAM,oBAAoB,CAAA;AACpD,EAAA,IAAI,UAAA,GAAa,KAAA;AACjB,EAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,IAAA,MAAM,CAAA,GAAI,gBAAA,CAAiB,CAAA,EAAG,OAAO,CAAA;AACrC,IAAA,IAAI,CAAA,KAAM,YAAY,OAAO,UAAA;AAC7B,IAAA,IAAI,CAAA,KAAM,WAAW,UAAA,GAAa,IAAA;AAAA,EACpC;AACA,EAAA,OAAO,aAAa,SAAA,GAAY,OAAA;AAClC;AAGA,SAAS,QAAQ,CAAA,EAA6B;AAC5C,EAAA,OAAO,CAAA,CAAE,QAAA,KAAa,cAAA,CAAe,MAAA,IAAU,EAAE,MAAA,KAAW,MAAA;AAC9D;AAGA,SAAS,YAAA,CACP,KAAA,EACA,KAAA,EACA,OAAA,EACuB;AACvB,EAAA,KAAA,MAAW,SAAS,KAAA,EAAO;AACzB,IAAA,MAAM,CAAA,GAAI,YAAA,CAAa,KAAA,CAAM,IAAA,EAAM,OAAO,CAAA;AAC1C,IAAA,IAAI,MAAM,UAAA,EAAY;AACtB,IAAA,IAAI,MAAM,SAAA,EAAW;AAEnB,MAAA,OAAO,OAAO,MAAA,CAAO;AAAA,QACnB,OAAA,EAAS,kBAAA;AAAA,QACT,IAAA,EAAM,iCAAA;AAAA,QACN,KAAA;AAAA,QACA;AAAA,OACD,CAAA;AAAA,IACH;AAEA,IAAA,IAAI,OAAA,CAAQ,KAAK,CAAA,EAAG;AAClB,MAAA,MAAM,KAAA,GAAyE;AAAA,QAC7E,OAAA,EAAS,QAAA;AAAA,QACT,IAAA,EAAM,uBAAA;AAAA,QACN,KAAA;AAAA,QACA,QAAQ,KAAA,CAAM;AAAA,OAChB;AACA,MAAA,IAAI,KAAA,CAAM,QAAA,KAAa,MAAA,EAAW,KAAA,CAAM,WAAW,KAAA,CAAM,QAAA;AACzD,MAAA,OAAO,MAAA,CAAO,OAAO,KAAK,CAAA;AAAA,IAC5B;AACA,IAAA,MAAM,MAAA,GAAS,OAAO,EAAE,MAAA,EAAQ,gBAAgB,IAAA,EAAM,KAAA,CAAM,QAAkB,CAAA;AAC9E,IAAA,MAAM,QAAA,GAA8E;AAAA,MAClF,OAAA,EAAS,UAAA;AAAA,MACT,KAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,MAAM,KAAA,CAAM;AAAA,KACd;AACA,IAAA,IAAI,KAAA,CAAM,QAAA,KAAa,MAAA,EAAW,QAAA,CAAS,WAAW,KAAA,CAAM,QAAA;AAC5D,IAAA,OAAO,MAAA,CAAO,OAAO,QAAQ,CAAA;AAAA,EAC/B;AAEA,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,OAAA,EAAS,kBAAA;AAAA,IACT,IAAA,EAAM,iCAAA;AAAA,IACN,KAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH;AA+BO,SAAS,eAAA,CACd,GAAA,EACA,MAAA,EACA,OAAA,GAA0B,EAAC,EACJ;AACvB,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA;AACnC,EAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AAC3C,IAAA,MAAM,QAAA,GAA8B,OAAO,MAAA,CAAO;AAAA,MAChD,MAAA,EAAQ,KAAA;AAAA,MACR,KAAA,EAAO,KAAA;AAAA,MACP,IAAA,EAAM,yBAAA;AAAA,MACN;AAAA,KACD,CAAA;AACD,IAAA,OAAO,QAAA;AAAA,EACT;AAGA,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAA+B;AACnD,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,KAAK,CAAA;AAChC,IAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA;AAAA,SAChB;AACH,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,CAAE,KAAA,EAAO,CAAC,CAAC,CAAC,CAAA;AACxB,MAAA,YAAA,CAAa,IAAA,CAAK,EAAE,KAAK,CAAA;AAAA,IAC3B;AAAA,EACF;AAEA,EAAA,MAAM,SAAkC,EAAC;AACzC,EAAA,KAAA,MAAW,KAAK,YAAA,EAAc;AAC5B,IAAA,MAAM,QAAQ,MAAA,CAAO,MAAA,CAAO,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAsB,CAAA;AAC/D,IAAA,MAAA,CAAO,IAAA,CAAK,YAAA,CAAa,CAAA,EAAG,KAAA,EAAO,OAAO,CAAC,CAAA;AAAA,EAC7C;AAEA,EAAA,MAAM,OAAA,GAA6B,OAAO,MAAA,CAAO;AAAA,IAC/C,MAAA,EAAQ,IAAA;AAAA,IACR,MAAA;AAAA,IACA,MAAA,EAAQ,MAAA,CAAO,MAAA,CAAO,MAAM;AAAA,GAC7B,CAAA;AACD,EAAA,OAAO,OAAA;AACT;AAGO,IAAM,yBAAA,GAA4B;;;AC5WlC,IAAM,UAAA,GAAiD,OAAO,MAAA,CAAO;AAAA,EAC1E,EAAA,EAAI,YAAA;AAAA,EACJ,GAAA,EAAK,oBAAA;AAAA,EACL,GAAA,EAAK,sBAAA;AAAA,EACL,EAAA,EAAI,YAAA;AAAA,EACJ,IAAA,EAAM,kCAAA;AAAA,EACN,IAAA,EAAM,iCAAA;AAAA,EACN,IAAA,EAAM,6BAAA;AAAA,EACN,IAAA,EAAM,4BAAA;AAAA,EACN,KAAA,EAAO,qCAAA;AAAA,EACP,KAAA,EAAO,oCAAA;AAAA,EACP,GAAA,EAAK,wBAAA;AAAA,EACL,GAAA,EAAK,uBAAA;AAAA,EACL,IAAA,EAAM,8BAAA;AAAA,EACN,IAAA,EAAM,6BAAA;AAAA,EACN,KAAA,EAAO,2CAAA;AAAA,EACP,IAAA,EAAM,cAAA;AAAA,EACN,IAAA,EAAM,iBAAA;AAAA,EACN,EAAA,EAAI,WAAA;AAAA,EACJ,GAAA,EAAK,iBAAA;AAAA,EACL,GAAA,EAAK,mBAAA;AAAA,EACL,EAAA,EAAI,SAAA;AAAA,EACJ,IAAA,EAAM,4BAAA;AAAA,EACN,EAAA,EAAI;AACN,CAAC;AAGD,IAAM,QAA6B,IAAI,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,UAAU,CAAC,CAAA;AAMlE,IAAM,0BAA+B,IAAI,GAAA,CAAI,CAAC,KAAA,EAAO,IAAA,EAAM,MAAM,CAAC,CAAA;AAiB3D,SAAS,WAAW,GAAA,EAAmC;AAC5D,EAAA,OAAO,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA,GAAK,GAAA,GAAmB,MAAA;AAC9C;AAoBO,SAAS,kBAAkB,GAAA,EAAwB;AACxD,EAAA,OAAO,OAAA,CAAQ,IAAI,GAAG,CAAA;AACxB;;;AC9DA,IAAM,UAAA,GAAa,QAAA;AAEnB,IAAM,OAAA,GAAU,KAAA;AAGhB,IAAM,KAAA,GAAQ,EAAE,KAAA,EAAO,CAAA,EAAG,GAAA,EAAK,EAAA,EAAI,GAAA,EAAK,EAAA,EAAI,GAAA,EAAK,EAAA,EAAI,QAAA,EAAU,EAAA,EAAG;AAClE,IAAM,MAAM,EAAE,MAAA,EAAQ,GAAG,MAAA,EAAQ,CAAA,EAAG,MAAM,CAAA,EAAE;AAC5C,IAAM,MAAM,EAAE,KAAA,EAAO,GAAG,GAAA,EAAK,CAAA,EAAG,KAAK,EAAA,EAAG;AAkBxC,SAASI,KAAAA,CAAK,OAA0B,KAAA,EAAmC;AACzE,EAAA,MAAM,CAAA,GAAI,MAAM,KAAK,CAAA;AACrB,EAAA,OAAO,CAAA,KAAM,MAAA,GAAY,MAAA,GAAY,CAAA,CAAE,IAAA,EAAK;AAC9C;AAWA,SAAS,UAAA,CAAW,SAAiB,QAAA,EAA2D;AAC9F,EAAA,MAAM,QAAA,uBAAe,GAAA,EAA2B;AAChD,EAAA,MAAM,QAA6B,EAAC;AAEpC,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAoB;AAExC,EAAA,KAAA,MAAW,CAAC,GAAG,GAAG,CAAA,IAAK,QAAQ,KAAA,CAAM,OAAO,CAAA,CAAE,OAAA,EAAQ,EAAG;AACvD,IAAA,IAAI,QAAQ,EAAA,EAAI;AAChB,IAAA,MAAM,KAAA,GAAQ,aAAa,GAAG,CAAA;AAE9B,IAAA,IAAI,KAAA,CAAM,MAAA,IAAU,KAAA,CAAM,GAAA,EAAK;AAC7B,MAAA,KAAA,CAAM,IAAA;AAAA,QACJ,OAAO,MAAA,CAAO;AAAA,UACZ,IAAA,EAAM,2BAAA;AAAA,UACN,IAAA,EAAM,UAAA;AAAA,UACN,MAAM,CAAA,GAAI,CAAA;AAAA,UACV,MAAA,EAAQ,CAAA,QAAA,EAAW,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,wBAAA,EAA2B,MAAA,CAAO,KAAA,CAAM,GAAA,GAAM,CAAC,CAAC,CAAA;AAAA,SACxF;AAAA,OACH;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAIA,KAAAA,CAAK,KAAA,EAAO,KAAA,CAAM,GAAG,MAAM,UAAA,EAAY;AAE3C,IAAA,MAAM,KAAA,GAAQA,KAAAA,CAAK,KAAA,EAAO,KAAA,CAAM,KAAK,CAAA;AACrC,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,EAAA,EAAI;AACvC,MAAA,KAAA,CAAM,IAAA;AAAA,QACJ,OAAO,MAAA,CAAO;AAAA,UACZ,IAAA,EAAM,2BAAA;AAAA,UACN,IAAA,EAAM,UAAA;AAAA,UACN,MAAM,CAAA,GAAI,CAAA;AAAA,UACV,MAAA,EAAQ;AAAA,SACT;AAAA,OACH;AACA,MAAA;AAAA,IACF;AAKA,IAAA,MAAM,MAAM,UAAA,CAAWA,KAAAA,CAAK,OAAO,KAAA,CAAM,GAAG,KAAK,EAAE,CAAA;AACnD,IAAA,IAAI,GAAA,KAAQ,MAAA,IAAa,iBAAA,CAAkB,GAAG,CAAA,EAAG;AAC/C,MAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,KAAK,KAAK,CAAC,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG,OAAA,CAAQ,GAAA,CAAI,KAAA,EAAO,IAAI,CAAC,CAAA;AACzE,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,EAAG;AACzB,IAAA,OAAA,CAAQ,OAAO,KAAK,CAAA;AAEpB,IAAA,MAAM,IAAA,GAAOA,KAAAA,CAAK,KAAA,EAAO,KAAA,CAAM,GAAG,CAAA,IAAK,EAAA;AACvC,IAAA,MAAM,QAAA,GAAWA,KAAAA,CAAK,KAAA,EAAO,KAAA,CAAM,QAAQ,CAAA,IAAK,GAAA;AAChD,IAAA,QAAA,CAAS,GAAA;AAAA,MACP,KAAA;AAAA,MACA,MAAA,CAAO,MAAA,CAAO,EAAE,KAAA,EAAO,GAAA,EAAK,IAAA,EAAM,UAAA,EAAY,QAAA,KAAa,EAAA,IAAM,QAAA,KAAa,GAAA,EAAK;AAAA,KACrF;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,MAAA,EAAO,EAAG;AACnC,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ,OAAO,MAAA,CAAO;AAAA,QACZ,IAAA,EAAM,6BAAA;AAAA,QACN,IAAA,EAAM,UAAA;AAAA,QACN,IAAA;AAAA,QACA,MAAA,EACE;AAAA,OACH;AAAA,KACH;AAAA,EACF;AAKA,EAAA,KAAA,CAAM,KAAK,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE,IAAA,GAAO,EAAE,IAAI,CAAA;AACpC,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,EAAO,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA;AAEtC,EAAA,OAAO,QAAA;AACT;AAGA,SAAS,QAAA,CACP,SACA,QAAA,EACyD;AACzD,EAAA,MAAM,KAAA,uBAAY,GAAA,EAA0B;AAC5C,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,KAAA,MAAW,CAAC,GAAG,GAAG,CAAA,IAAK,QAAQ,KAAA,CAAM,OAAO,CAAA,CAAE,OAAA,EAAQ,EAAG;AACvD,IAAA,IAAI,QAAQ,EAAA,EAAI;AAChB,IAAA,MAAM,KAAA,GAAQ,aAAa,GAAG,CAAA;AAC9B,IAAA,IAAI,KAAA,CAAM,MAAA,IAAU,GAAA,CAAI,IAAA,EAAM;AAC5B,MAAA,QAAA,CAAS,IAAA;AAAA,QACP,OAAO,MAAA,CAAO;AAAA,UACZ,IAAA,EAAM,2BAAA;AAAA,UACN,IAAA,EAAM,QAAA;AAAA,UACN,MAAM,CAAA,GAAI,CAAA;AAAA,UACV,MAAA,EAAQ,CAAA,QAAA,EAAW,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,wBAAA,EAA2B,MAAA,CAAO,GAAA,CAAI,IAAA,GAAO,CAAC,CAAC,CAAA;AAAA,SACvF;AAAA,OACH;AACA,MAAA;AAAA,IACF;AACA,IAAA,MAAM,IAAA,GAAOA,KAAAA,CAAK,KAAA,EAAO,GAAA,CAAI,IAAI,CAAA;AACjC,IAAA,MAAM,MAAA,GAASA,KAAAA,CAAK,KAAA,EAAO,GAAA,CAAI,MAAM,CAAA;AACrC,IAAA,MAAM,MAAA,GAASA,KAAAA,CAAK,KAAA,EAAO,GAAA,CAAI,MAAM,CAAA;AAErC,IAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,EAAA,EAAI;AACvC,IAAA,IAAI,WAAW,MAAA,IAAa,MAAA,KAAW,MAAM,MAAA,KAAW,MAAA,IAAa,WAAW,EAAA,EAAI;AAIpF,IAAA,MAAM,IAAA,GAAmB,MAAA,CAAO,MAAA,CAAO,EAAE,OAAA,EAAS,QAAQ,SAAA,EAAW,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQ,CAAA;AAC3F,IAAA,MAAM,IAAA,GAAO,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA;AAC7B,IAAA,IAAI,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA;AAAA,SACnB,KAAA,CAAM,GAAA,CAAI,MAAA,EAAQ,CAAC,IAAI,CAAC,CAAA;AAC7B,IAAA,SAAA,EAAA;AAAA,EACF;AACA,EAAA,OAAO,EAAE,OAAO,SAAA,EAAU;AAC5B;AAGA,SAAS,SAAA,CACP,SACA,QAAA,EACmD;AACnD,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAkD;AACnE,EAAA,KAAA,MAAW,CAAC,GAAG,GAAG,CAAA,IAAK,QAAQ,KAAA,CAAM,OAAO,CAAA,CAAE,OAAA,EAAQ,EAAG;AACvD,IAAA,IAAI,QAAQ,EAAA,EAAI;AAChB,IAAA,MAAM,KAAA,GAAQ,aAAa,GAAG,CAAA;AAC9B,IAAA,IAAI,KAAA,CAAM,MAAA,IAAU,GAAA,CAAI,GAAA,EAAK;AAC3B,MAAA,QAAA,CAAS,IAAA;AAAA,QACP,OAAO,MAAA,CAAO;AAAA,UACZ,IAAA,EAAM,2BAAA;AAAA,UACN,IAAA,EAAM,QAAA;AAAA,UACN,MAAM,CAAA,GAAI,CAAA;AAAA,UACV,MAAA,EAAQ,CAAA,QAAA,EAAW,MAAA,CAAO,KAAA,CAAM,MAAM,CAAC,CAAA,wBAAA,EAA2B,MAAA,CAAO,GAAA,CAAI,GAAA,GAAM,CAAC,CAAC,CAAA;AAAA,SACtF;AAAA,OACH;AACA,MAAA;AAAA,IACF;AACA,IAAA,IAAIA,KAAAA,CAAK,KAAA,EAAO,GAAA,CAAI,GAAG,MAAM,OAAA,EAAS;AACtC,IAAA,MAAM,GAAA,GAAMA,KAAAA,CAAK,KAAA,EAAO,GAAA,CAAI,GAAG,CAAA;AAC/B,IAAA,MAAM,KAAA,GAAQA,KAAAA,CAAK,KAAA,EAAO,GAAA,CAAI,KAAK,CAAA;AACnC,IAAA,IAAI,QAAQ,MAAA,IAAa,GAAA,KAAQ,MAAM,KAAA,KAAU,MAAA,IAAa,UAAU,EAAA,EAAI;AAC1E,MAAA,QAAA,CAAS,IAAA;AAAA,QACP,OAAO,MAAA,CAAO;AAAA,UACZ,IAAA,EAAM,2BAAA;AAAA,UACN,IAAA,EAAM,QAAA;AAAA,UACN,MAAM,CAAA,GAAI,CAAA;AAAA,UACV,MAAA,EAAQ;AAAA,SACT;AAAA,OACH;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,IAAA,CAAK,GAAA,CAAI,GAAG,GAAG,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,MAAA,CAAO,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,QAAA,EAAU,CAAC,CAAA;AAAA,EAC9E;AACA,EAAA,OAAO,IAAA;AACT;AA6BO,SAAS,gBAAgB,MAAA,EAAwC;AACtE,EAAA,MAAM,WAAgC,EAAC;AACvC,EAAA,MAAM,QAAA,GAAW,UAAA,CAAW,MAAA,CAAO,KAAA,EAAO,QAAQ,CAAA;AAClD,EAAA,MAAM,EAAE,KAAA,EAAO,SAAA,KAAc,QAAA,CAAS,MAAA,CAAO,KAAK,QAAQ,CAAA;AAC1D,EAAA,MAAM,IAAA,GACJ,MAAA,CAAO,GAAA,KAAQ,MAAA,GAAY,SAAA,CAAU,OAAO,GAAA,EAAK,QAAQ,CAAA,mBAAI,IAAI,GAAA,EAAmB;AAGtF,EAAA,KAAA,MAAW,QAAQ,KAAA,CAAM,MAAA,EAAO,EAAG,MAAA,CAAO,OAAO,IAAI,CAAA;AAErD,EAAA,MAAM,GAAA,GAA6B;AAAA,IACjC,QAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,cAAc,QAAA,CAAS,IAAA;AAAA,IACvB,SAAA;AAAA,IACA,QAAA,EAAU,MAAA,CAAO,MAAA,CAAO,QAAQ;AAAA,GAClC;AACA,EAAA,IAAI,MAAA,CAAO,OAAA,KAAY,MAAA,EAAW,GAAA,CAAI,UAAU,MAAA,CAAO,OAAA;AACvD,EAAA,OAAO,MAAA,CAAO,OAAO,GAAG,CAAA;AAC1B;;;ACzPO,IAAM,IAAA,GAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMlB,cAAA,EAAgB,gBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMhB,aAAA,EAAe,eAAA;AAAA;AAAA,EAEf,sBAAA,EAAwB,wBAAA;AAAA;AAAA,EAExB,qBAAA,EAAuB,uBAAA;AAAA;AAAA,EAEvB,YAAA,EAAc,cAAA;AAAA;AAAA,EAEd,aAAA,EAAe,eAAA;AAAA;AAAA,EAEf,aAAA,EAAe,eAAA;AAAA;AAAA,EAEf,YAAA,EAAc,cAAA;AAAA;AAAA,EAEd,mBAAA,EAAqB,mBAAA;AAAA;AAAA,EAErB,kBAAA,EAAoB,kBAAA;AAAA;AAAA,EAEpB,WAAA,EAAa,aAAA;AAAA;AAAA,EAEb,WAAA,EAAa,aAAA;AAAA;AAAA,EAEb,QAAA,EAAU,UAAA;AAAA;AAAA,EAEV,YAAA,EAAc,cAAA;AAAA;AAAA,EAEd,mBAAA,EAAqB,qBAAA;AAAA;AAAA,EAErB,kBAAA,EAAoB,oBAAA;AAAA;AAAA,EAEpB,GAAA,EAAK,KAAA;AAAA;AAAA,EAEL,WAAA,EAAa;AACf;AAkBO,IAAM,YAAA,GAAiD,OAAO,MAAA,CAAO;AAAA,EAC1E,CAAC,IAAA,CAAK,cAAc,GAAG,IAAA,CAAK,aAAA;AAAA,EAC5B,CAAC,IAAA,CAAK,aAAa,GAAG,IAAA,CAAK,cAAA;AAAA,EAC3B,CAAC,IAAA,CAAK,sBAAsB,GAAG,IAAA,CAAK,qBAAA;AAAA,EACpC,CAAC,IAAA,CAAK,qBAAqB,GAAG,IAAA,CAAK,sBAAA;AAAA,EACnC,CAAC,IAAA,CAAK,YAAY,GAAG,IAAA,CAAK,aAAA;AAAA,EAC1B,CAAC,IAAA,CAAK,aAAa,GAAG,IAAA,CAAK,YAAA;AAAA,EAC3B,CAAC,IAAA,CAAK,aAAa,GAAG,IAAA,CAAK,YAAA;AAAA,EAC3B,CAAC,IAAA,CAAK,YAAY,GAAG,IAAA,CAAK,aAAA;AAAA,EAC1B,CAAC,IAAA,CAAK,mBAAmB,GAAG,IAAA,CAAK,kBAAA;AAAA,EACjC,CAAC,IAAA,CAAK,kBAAkB,GAAG,IAAA,CAAK,mBAAA;AAAA,EAChC,CAAC,IAAA,CAAK,WAAW,GAAG,IAAA,CAAK,WAAA;AAAA,EACzB,CAAC,IAAA,CAAK,WAAW,GAAG,IAAA,CAAK,WAAA;AAAA,EACzB,CAAC,IAAA,CAAK,QAAQ,GAAG,IAAA,CAAK,YAAA;AAAA,EACtB,CAAC,IAAA,CAAK,YAAY,GAAG,IAAA,CAAK,QAAA;AAAA,EAC1B,CAAC,IAAA,CAAK,mBAAmB,GAAG,IAAA,CAAK,kBAAA;AAAA,EACjC,CAAC,IAAA,CAAK,kBAAkB,GAAG,IAAA,CAAK,mBAAA;AAAA,EAChC,CAAC,IAAA,CAAK,GAAG,GAAG,IAAA,CAAK,WAAA;AAAA,EACjB,CAAC,IAAA,CAAK,WAAW,GAAG,IAAA,CAAK;AAC3B,CAAC;AAGM,IAAM,aAAA,GAAgB;;;AC1FtB,SAAS,UAAA,CAAW,OAAoB,KAAA,EAA0C;AACvF,EAAA,OAAO,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;AACjC;AAGA,SAAS,MAAA,CACP,KAAA,EACA,KAAA,EACA,UAAA,EACiB;AACjB,EAAA,IAAI,CAAC,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9B,IAAA,OAAO,MAAA,CAAO,OAAO,EAAE,KAAA,EAAO,OAAO,IAAA,EAAM,2BAAA,EAA6B,OAAO,CAAA;AAAA,EACjF;AACA,EAAA,MAAM,MAAuB,EAAC;AAC9B,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,QAAQ,KAAA,CAAM,KAAA,CAAM,IAAI,KAAK,CAAA,IAAK,EAAC,EAAG;AAC/C,IAAA,IAAI,CAAC,UAAA,CAAW,GAAA,CAAI,IAAA,CAAK,SAAS,CAAA,EAAG;AACrC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,EAAG;AAC3B,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,KAAK,MAAM,CAAA;AAG7C,IAAA,IAAI,WAAW,MAAA,EAAW;AACxB,MAAA,GAAA,CAAI,KAAK,MAAM,CAAA;AACf,MAAA,IAAA,CAAK,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,IACtB;AAAA,EACF;AACA,EAAA,OAAO,OAAO,MAAA,CAAO;AAAA,IACnB,KAAA,EAAO,IAAA;AAAA,IACP,KAAA;AAAA,IACA,YAAY,MAAA,CAAO,MAAA,CAAO,CAAC,GAAG,UAAU,CAAC,CAAA;AAAA,IACzC,OAAA,EAAS,MAAA,CAAO,MAAA,CAAO,GAAG;AAAA,GAC3B,CAAA;AACH;AAuBO,SAAS,aAAA,CACd,KAAA,EACA,KAAA,EACA,SAAA,EACiB;AACjB,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAO,cAAc,QAAA,GAAW,CAAC,SAAS,CAAA,GAAI,SAAS,CAAA;AAC3E,EAAA,OAAO,MAAA,CAAO,KAAA,EAAO,KAAA,EAAO,GAAG,CAAA;AACjC;AAmDO,SAAS,aAAA,CAAc,OAAoB,KAAA,EAAgC;AAChF,EAAA,OAAO,MAAA,CAAO,KAAA,EAAO,KAAA,kBAAO,IAAI,GAAA,CAAI,CAAC,IAAA,CAAK,cAAA,EAAgB,IAAA,CAAK,sBAAsB,CAAC,CAAC,CAAA;AACzF;AAqBO,SAAS,UAAA,CAAW,OAAoB,KAAA,EAAgC;AAC7E,EAAA,OAAO,MAAA,CAAO,OAAO,KAAA,kBAAO,IAAI,IAAI,CAAC,IAAA,CAAK,YAAY,CAAC,CAAC,CAAA;AAC1D;AAoBO,SAAS,SAAA,CAAU,OAAoB,KAAA,EAAgC;AAC5E,EAAA,OAAO,MAAA,CAAO,OAAO,KAAA,kBAAO,IAAI,IAAI,CAAC,IAAA,CAAK,aAAa,CAAC,CAAC,CAAA;AAC3D;AAmBO,SAAS,WAAA,CAAY,OAAoB,KAAA,EAAgC;AAC9E,EAAA,OAAO,MAAA,CAAO,KAAA,EAAO,KAAA,kBAAO,IAAI,GAAA,CAAI,CAAC,IAAA,CAAK,aAAA,EAAe,IAAA,CAAK,mBAAmB,CAAC,CAAC,CAAA;AACrF;AAmBO,SAAS,UAAA,CAAW,OAAoB,KAAA,EAAgC;AAC7E,EAAA,OAAO,MAAA,CAAO,OAAO,KAAA,kBAAO,IAAI,IAAI,CAAC,IAAA,CAAK,WAAW,CAAC,CAAC,CAAA;AACzD;AAyBO,SAAS,UAAA,CAAW,OAAoB,GAAA,EAAwB;AACrE,EAAA,MAAM,GAAA,GAAM,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA;AAC9B,EAAA,IAAI,QAAQ,MAAA,EAAW;AACrB,IAAA,OAAO,MAAA,CAAO,OAAO,EAAE,QAAA,EAAU,OAAO,IAAA,EAAM,0BAAA,EAA4B,KAAK,CAAA;AAAA,EACjF;AACA,EAAA,MAAM,GAAA,GAAM;AAAA,IACV,QAAA,EAAU,IAAA;AAAA,IACV,GAAA;AAAA,IACA,OAAO,GAAA,CAAI,KAAA;AAAA,IACX,QAAQ,GAAA,CAAI,MAAA;AAAA,IACZ,GAAI,MAAM,OAAA,KAAY,MAAA,GAAY,EAAE,IAAA,EAAM,KAAA,CAAM,OAAA,EAAQ,GAAI;AAAC,GAC/D;AACA,EAAA,OAAO,MAAA,CAAO,OAAO,GAAG,CAAA;AAC1B;AAGA,SAAS,SAAS,IAAA,EAA2B;AAC3C,EAAA,OAAO,IAAI,GAAA;AAAA,IACT,IAAA,CACG,WAAA,EAAY,CACZ,KAAA,CAAM,YAAY,EAClB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,KAAM,EAAE;AAAA,GAC3B;AACF;AAGA,SAAS,OAAA,CAAQ,GAAwB,CAAA,EAAgC;AACvE,EAAA,IAAI,EAAE,IAAA,KAAS,CAAA,IAAK,CAAA,CAAE,IAAA,KAAS,GAAG,OAAO,CAAA;AACzC,EAAA,IAAI,KAAA,GAAQ,CAAA;AACZ,EAAA,KAAA,MAAW,KAAK,CAAA,EAAG,IAAI,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,EAAG,KAAA,EAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,IAAA,GAAO,CAAA,CAAE,IAAA,GAAO,KAAA;AAChC,EAAA,OAAO,KAAA,KAAU,CAAA,GAAI,CAAA,GAAI,KAAA,GAAQ,KAAA;AACnC;AAmCO,SAAS,gBAAA,CACd,KAAA,EACA,KAAA,EACA,OAAA,GAAmC,EAAC,EACD;AACnC,EAAA,MAAM,QAAA,GAAW,QAAQ,QAAA,IAAY,IAAA;AACrC,EAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,EAAA;AAC/B,EAAA,MAAM,CAAA,GAAI,SAAS,KAAK,CAAA;AACxB,EAAA,IAAI,EAAE,IAAA,KAAS,CAAA,SAAU,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA;AAEzC,EAAA,MAAM,SAAmC,EAAC;AAC1C,EAAA,KAAA,MAAW,OAAA,IAAW,KAAA,CAAM,QAAA,CAAS,MAAA,EAAO,EAAG;AAC7C,IAAA,MAAM,QAAQ,OAAA,CAAQ,CAAA,EAAG,QAAA,CAAS,OAAA,CAAQ,IAAI,CAAC,CAAA;AAC/C,IAAA,IAAI,KAAA,IAAS,QAAA,EAAU,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,EAAE,WAAA,EAAa,IAAA,EAAM,OAAA,EAAS,KAAA,EAAO,CAAC,CAAA;AAAA,EACzF;AAEA,EAAA,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,KAAA,GAAQ,CAAA,CAAE,KAAA,IAAS,CAAA,CAAE,QAAQ,KAAA,CAAM,aAAA,CAAc,CAAA,CAAE,OAAA,CAAQ,KAAK,CAAC,CAAA;AACzF,EAAA,OAAO,OAAO,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,KAAK,CAAC,CAAA;AAC7C;;;ACjOO,IAAM,OAAA,GAAkB","file":"index.mjs","sourcesContent":["/**\n * The immutable FHIR value types the engine operates over: {@link Coding} and\n * {@link CodeableConcept}.\n *\n * These mirror the FHIR R4 datatypes of the same names (the interchange lingua franca the whole\n * ecosystem speaks), reduced to the fields the terminology operations need. Every instance the\n * engine hands back is deep-frozen, so a translated result is safe to share across a pipeline\n * without defensive copying — the immutability discipline the parsers follow.\n *\n * @packageDocumentation\n */\n\n/**\n * A single coded value — a `code` drawn from a code `system`, optionally versioned and displayed.\n *\n * Models FHIR R4 `Coding`. `system` is the code system's **canonical URI** (e.g.\n * `http://loinc.org`), not a mnemonic or OID — use {@link ../systems/resolve.resolveSystem} to\n * canonicalize before constructing one. `system` is optional because a raw wire code sometimes\n * arrives without one; the engine surfaces that rather than inventing a system.\n *\n * @example\n * ```ts\n * import { coding } from \"@cosyte/terminology\";\n *\n * const c = coding({ system: \"http://loinc.org\", code: \"2160-0\", display: \"Creatinine\" });\n * c.code; // => \"2160-0\"\n * ```\n */\nexport interface Coding {\n /** The code system's canonical URI (e.g. `http://snomed.info/sct`). Optional when unknown. */\n readonly system?: string;\n /** The symbol in the code system's syntax. Required — a coding without a code is meaningless. */\n readonly code: string;\n /** The code system version this code is drawn from, when known (mappings are release-scoped). */\n readonly version?: string;\n /** The human-readable label. Carried verbatim from the source; never fabricated by the engine. */\n readonly display?: string;\n}\n\n/**\n * A concept described by one or more {@link Coding}s plus optional free text — FHIR R4\n * `CodeableConcept`. Included so the value layer is complete for downstream consumers even though\n * {@link ../conceptmap/translate.translate} operates on a single {@link Coding}.\n *\n * @example\n * ```ts\n * import { codeableConcept } from \"@cosyte/terminology\";\n *\n * const cc = codeableConcept({\n * coding: [{ system: \"http://loinc.org\", code: \"2160-0\" }],\n * text: \"Serum creatinine\",\n * });\n * cc.coding[0].code; // => \"2160-0\"\n * ```\n */\nexport interface CodeableConcept {\n /** The codings for this concept, in order of preference. Frozen and never empty-by-fabrication. */\n readonly coding: readonly Coding[];\n /** Plain-text representation of the concept, when supplied. */\n readonly text?: string;\n}\n\n/**\n * Construct a deep-frozen {@link Coding}.\n *\n * The returned object is `Object.freeze`d so it cannot be mutated in place — parsed/translated\n * values are immutable by default. Optional fields are only present when supplied (no `undefined`\n * keys), so structural equality checks stay clean.\n *\n * @param init - The coding fields; `code` is required.\n * @returns A frozen {@link Coding}.\n * @example\n * ```ts\n * import { coding } from \"@cosyte/terminology\";\n *\n * const frozen = coding({ system: \"http://loinc.org\", code: \"2160-0\" });\n * Object.isFrozen(frozen); // => true\n * ```\n */\nexport function coding(init: Coding): Coding {\n const out: { -readonly [K in keyof Coding]: Coding[K] } = { code: init.code };\n if (init.system !== undefined) out.system = init.system;\n if (init.version !== undefined) out.version = init.version;\n if (init.display !== undefined) out.display = init.display;\n return Object.freeze(out);\n}\n\n/**\n * Construct a deep-frozen {@link CodeableConcept} (its `coding` array and every member frozen).\n *\n * @param init - The concept fields; `coding` is required (may be empty).\n * @returns A frozen {@link CodeableConcept}.\n * @example\n * ```ts\n * import { codeableConcept } from \"@cosyte/terminology\";\n *\n * const cc = codeableConcept({ coding: [{ code: \"2160-0\" }] });\n * Object.isFrozen(cc.coding); // => true\n * ```\n */\nexport function codeableConcept(init: CodeableConcept): CodeableConcept {\n const frozenCodings = Object.freeze(init.coding.map((c) => coding(c)));\n const out: { -readonly [K in keyof CodeableConcept]: CodeableConcept[K] } = {\n coding: frozenCodings,\n };\n if (init.text !== undefined) out.text = init.text;\n return Object.freeze(out);\n}\n","/**\n * The engine's **stable diagnostic + fatal code registries** and its typed error.\n *\n * `@cosyte/terminology` is an engine, not a lenient wire-format parser, so its stable codes are\n * **diagnostics** (typed, surfaced outcomes a consumer branches on) and **fatals** (thrown on\n * structurally unusable input), rather than the parsers' \"Tier-2 tolerance warnings\". The\n * discipline is identical: the code strings are part of the public contract — consumers narrow on\n * them, so renaming or removing one is a **breaking change**, and the full set is snapshotted via\n * `sortedCodeSet` (`@cosyte/test-utils`) as a reviewable tripwire.\n *\n * **Value-free by construction**, and the property is stated as what it actually is: every string a\n * diagnostic or fatal message is assembled from is **owned by the engine**. Three kinds, and no\n * fourth: a string literal; an entry in a frozen table keyed on the engine's own vocabulary; and a\n * **locus this package built** — a 1-based `line`, a column count, or an index path over the\n * caller's own resource made of integers and FHIR field names (`ConceptMap group[0].element[0].target[0]`,\n * `compose.include[2]`). Nothing a caller configured and nothing their release or resource contained\n * is ever one of them, so no such string reaches a `message`, a `stack`, or a `detail`, at any\n * length.\n *\n * Read that as the rule, and note what it does **not** say. It does not say no factory takes a\n * `string` parameter. Several do: `malformed(path, fault)` in `conceptmap/load.ts` and\n * `valueset/load.ts`, and `cannotExpand(detail, path)`, `truncated(detail, path)` and\n * `underPath(d, prefix)` in `valueset/` — where `expand.ts` and `validate.ts` each carry their own\n * copy. It says every **argument** reaching them is engine-owned: each `fault` and `detail` is a\n * literal at the call site, each `path` and `prefix` is built from indices by the loader that\n * raises it. That distinction is the thing to preserve — an absolute \"no factory takes a value\n * parameter\" reads as a stronger guarantee than the one the code makes, and those factories are the\n * counter-example to it. Do not write the count down; derive it.\n *\n * Positional context is value-free the same way: a `line` integer, an `ExpansionDiagnostic.path`\n * index path into the caller's own resource (`compose.include[2]`), or a closed-set token\n * (`RXNCONSO` / `RXNREL` / `RXNSAT`) — never a URI, a column name, or a field the file supplied.\n * This matters because a code *in patient context* can be PHI, and a thrown error is the one surface\n * that reaches a log or an error reporter without the consumer choosing to put it there.\n *\n * **▶ THE CLAIM IS ABOUT THE MESSAGE FIELDS, NOT ABOUT THE OBJECTS. DO NOT SHORTEN IT TO \"A\n * DIAGNOSTIC IS SAFE TO LOG\".** The safe strings are the *message* fields:\n * `TerminologyError.message` / `.stack`, `LoadWarning.detail`, `GemLoadWarning.detail`,\n * `ComplexMapLoadWarning.detail`, `RxNormLoadWarning.detail`, `ExpansionDiagnostic.detail`,\n * `ParseFailure.reason` and `UcumValidation.reason`, plus the loci beside them.\n *\n * The **objects** these codes appear on are a different matter, and they carry verbatim text from\n * two *different* provenances, which decide differently:\n *\n * - **Your query, echoed back** — `LookupUnknown.input`, `LookupResult.code`, `UnknownSystem.input`,\n * `TranslateUnmapped.source`, `CrosswalkUnmapped.source`, `CrosswalkNoMap.source`,\n * `RxNormUnknown.rxcui`, `RxNormRelated.predicates`, `NdcUnmapped.ndc`,\n * `ValueSetMembership.coding`, and **`MapProvenance.sourceSystem`** — which is the `system` off\n * the `Coding` you passed to `translate`, verbatim and unbounded, whenever that coding\n * carries one; the map's own `group.source` is only the fallback for a coding that does not. The\n * query is the one genuinely **patient-derived** input this engine takes (a code off a parsed\n * message, a unit off an observation, an NDC off a prescription), so this is the class that\n * decides a PHI question.\n * - **Your loaded artifact, carried through** — `ComplexMapContextRequired.rules` (the map\n * document's own `rule` / `advice` text) and `MapProvenance.targetSystem` / `.conceptMapUrl` /\n * `.conceptMapVersion`, which are read off the loaded map (`group.target`, `map.url`,\n * `map.version`). These are *reference data*, bounded by the map or release you loaded, not by\n * anything a patient supplied. **`MapProvenance` straddles the two lists** — do not read the whole\n * record as reference data on the strength of the fields that are.\n *\n * Read both lists as illustrative, not closed: **assume any result field may hold what you passed\n * in.** So `JSON.stringify(lookupResult)` into a log is a PHI decision, and `String(err)` is not.\n * Log the `code` and the locus; log a value only if you would log the code you passed in.\n *\n * Those echoes are deliberate and are not going away: they are how a never-fabricate outcome says\n * *which* thing it refused to guess, they are the caller's own data returned to the caller, and\n * bounding them would mean fabricating a miss.\n *\n * @packageDocumentation\n */\n\n/**\n * Stable **diagnostic codes** — typed, surfaced, non-throwing outcomes.\n *\n * These are not errors: they are first-class results a caller inspects (an unmapped translation,\n * an unrecognized code system). `key === value` so `Object.values(...)` yields the snapshot set.\n *\n * @example\n * ```ts\n * import { DIAGNOSTIC_CODES } from \"@cosyte/terminology\";\n *\n * DIAGNOSTIC_CODES.TERM_TRANSLATE_UNMAPPED; // => \"TERM_TRANSLATE_UNMAPPED\"\n * ```\n */\nexport const DIAGNOSTIC_CODES = {\n /**\n * A `$translate` found no target for the source code. A **first-class outcome, never an error** —\n * the source is surfaced as `unmapped`, never replaced with a guessed target (the never-fabricate\n * invariant).\n */\n TERM_TRANSLATE_UNMAPPED: \"TERM_TRANSLATE_UNMAPPED\",\n /**\n * A code-system identifier (URI, OID, or mnemonic) was not recognized by the identity resolver.\n * Surfaced as a typed `unknown`, never coerced to a guessed canonical URI.\n */\n TERM_SYSTEM_UNRECOGNIZED: \"TERM_SYSTEM_UNRECOGNIZED\",\n /**\n * An RRF (pipe-delimited RxNorm/UMLS release) row was structurally unusable — too few columns to\n * reach a configured field, or a missing code. The row is **skipped and surfaced** as a load\n * warning (liberal on load), never kept as a partially-parsed concept.\n */\n TERM_RRF_MALFORMED_ROW: \"TERM_RRF_MALFORMED_ROW\",\n /**\n * A CSV (RFC-4180, e.g. LOINC `Loinc.csv`) row was structurally unusable — too few fields to reach\n * a configured column. The row is **skipped and surfaced** as a load warning, never partial.\n */\n TERM_CSV_MALFORMED: \"TERM_CSV_MALFORMED\",\n /**\n * A fixed-width (e.g. ICD-10-CM order file) row was structurally unusable — too short to contain\n * the configured code field, or a missing code. Skipped and surfaced, never partial.\n */\n TERM_FIXED_WIDTH_MALFORMED: \"TERM_FIXED_WIDTH_MALFORMED\",\n /**\n * A concept inside a FHIR `CodeSystem` resource was unusable — not an object, or missing its\n * required `code`. Skipped and surfaced (the whole resource still loads); `line` is `0` since a\n * JSON concept is not line-addressable.\n */\n TERM_FHIR_CONCEPT_MALFORMED: \"TERM_FHIR_CONCEPT_MALFORMED\",\n /**\n * A `$lookup`/`$validate-code` found no concept for the code in the loaded release. A **first-class\n * typed outcome, never a guess** — the engine returns `unknown`/`valid: false`, never a fabricated\n * display or a coerced `valid: true` (the never-fabricate invariant, applied to code identity).\n */\n TERM_CODE_UNKNOWN: \"TERM_CODE_UNKNOWN\",\n /**\n * A resolved concept is **deprecated / no longer current** (e.g. LOINC `STATUS = DEPRECATED`, or a\n * FHIR concept flagged `inactive`). Surfaced on the concept's status so a caller never presents a\n * non-current code as clean; the concept is still *found* (a lookup succeeds), it is just flagged.\n */\n TERM_CONCEPT_DEPRECATED: \"TERM_CONCEPT_DEPRECATED\",\n /**\n * A resolved concept is a **classification header, not a billable/valid leaf** (e.g. an ICD-10-CM\n * order-file row with the position-15 flag `0`). Surfaced on the concept's status: a header code is\n * found but is **not valid for claim submission**, and must never be presented as billable.\n */\n TERM_CONCEPT_HEADER_NOT_BILLABLE: \"TERM_CONCEPT_HEADER_NOT_BILLABLE\",\n /**\n * A ValueSet `compose` part could **not be expanded** — an intensional `include`/`exclude` whose\n * code system was not supplied, an unresolvable referenced value set, or a `filter` operator the\n * engine does not implement. Surfaced as a typed outcome that marks the expansion **incomplete**;\n * the engine **never** fabricates a member and **never** returns a silently-empty \"no members\"\n * answer for a part it could not compute (a false \"not a member\" is a clinical error).\n */\n TERM_VALUESET_CANNOT_EXPAND: \"TERM_VALUESET_CANNOT_EXPAND\",\n /**\n * A **pre-computed** `ValueSet.expansion` is **incomplete** — its `total` exceeds the number of\n * `contains` entries, or it is flagged too-costly (the VSAC `$expand` >1200-code truncation\n * hazard). The engine **never treats a truncated expansion as complete membership**: a code\n * absent from a truncated expansion is `undetermined`, never a confident \"not a member\".\n */\n TERM_VALUESET_EXPANSION_TRUNCATED: \"TERM_VALUESET_EXPANSION_TRUNCATED\",\n /**\n * A UCUM unit expression is **not valid** — it does not parse against the UCUM grammar, or it\n * names an atom absent from the vendored UCUM table. A **first-class typed outcome, never an\n * error and never a guess**: {@link validateUcum} returns `{ valid: false, reason }`, never a\n * coerced or \"nearest\" unit (the never-fabricate invariant, applied to units). The\n * `reason` is value-free (a grammar fault or an unknown-atom shape), never PHI.\n */\n TERM_UCUM_INVALID: \"TERM_UCUM_INVALID\",\n /**\n * A crosswalk source code has an **authored No-Map** — the steward declares it has no valid target\n * in the other classification (a GEM `NoDx`/`NoPCS` sentinel, or a SNOMED complex-map `447638001`\n * \"cannot be classified\" category). A **first-class typed outcome, never an error and never a\n * guess** (the never-fabricate invariant, applied to crosswalks). Distinct from\n * {@link TERM_CROSSWALK_UNMAPPED}: the source *is* in the map, and the map says \"no target\".\n */\n TERM_CROSSWALK_NO_MAP: \"TERM_CROSSWALK_NO_MAP\",\n /**\n * A crosswalk source code is **absent from the map entirely** — not an authored No-Map, simply not\n * present. Surfaced as a typed outcome (never a fabricated target, never a silent success), and\n * kept distinct from {@link TERM_CROSSWALK_NO_MAP} so a caller can tell \"the steward said no target\"\n * from \"this code was not in the file\".\n */\n TERM_CROSSWALK_UNMAPPED: \"TERM_CROSSWALK_UNMAPPED\",\n /**\n * A SNOMED→ICD-10-CM complex-map group's decision needs **patient context** (an `IFA` age band or\n * gender) the caller did not supply. The engine surfaces the candidate rules + advice and **refuses\n * to pick a branch** it lacks the data for — never a silently-chosen target.\n */\n TERM_CROSSWALK_CONTEXT_REQUIRED: \"TERM_CROSSWALK_CONTEXT_REQUIRED\",\n /**\n * A GEM file line was structurally unusable — not three whitespace-delimited fields, or a flag\n * field that is not a 5-digit code. The row is **skipped and surfaced** as a load warning (liberal\n * on load), never kept as a partially-parsed entry.\n */\n TERM_GEM_MALFORMED_ROW: \"TERM_GEM_MALFORMED_ROW\",\n /**\n * A SNOMED complex-map RF2 refset row was structurally unusable — missing its\n * `referencedComponentId`/`mapGroup`/`mapPriority`. Skipped and surfaced, never partial.\n */\n TERM_COMPLEX_MAP_MALFORMED_ROW: \"TERM_COMPLEX_MAP_MALFORMED_ROW\",\n /**\n * A RxNorm RRF row (`RXNCONSO` / `RXNREL` / `RXNSAT`) was structurally unusable — too few columns to\n * reach a required field, or a missing `RXCUI`/NDC value. The row is **skipped and surfaced** as a\n * load warning (liberal on load), never kept as a partial concept/edge. Rows that are simply *not of\n * interest* (a non-`RXNORM` atom, an atom-level relationship, a non-`NDC` attribute) are skipped\n * **silently** — they are expected, not faults.\n */\n TERM_RXNORM_MALFORMED_ROW: \"TERM_RXNORM_MALFORMED_ROW\",\n /**\n * An `RXCUI` appeared in the release's `SAB=RXNORM` atoms but **none of them could establish its\n * term type**, so it is **not** in the graph. Either every atom carried a synonym-class `TTY`\n * (`PSN`/`SY`/`TMSY`, which Appendix 5 defines as a \"synonym of another TTY\" and which therefore\n * types a *name* rather than a concept) or every atom carried a `TTY` this engine does not model.\n * The concept is skipped rather than typed from a synonym atom: an absent concept is already a\n * first-class typed answer (`TERM_RXNORM_UNKNOWN_RXCUI`), while a concept whose term type reads\n * `TMSY` is a fabricated claim about what a drug *is* that a caller cannot detect.\n */\n TERM_RXNORM_UNTYPED_CONCEPT: \"TERM_RXNORM_UNTYPED_CONCEPT\",\n /**\n * A RxNorm graph navigation was asked about an `RXCUI` **absent from the loaded release** — a\n * first-class typed outcome, never a fabricated concept and never an empty \"success\" (the\n * never-fabricate invariant, applied to the drug graph). Distinct from a *present*\n * concept that simply has no edge of the requested relationship (that is a found result with empty\n * targets).\n */\n TERM_RXNORM_UNKNOWN_RXCUI: \"TERM_RXNORM_UNKNOWN_RXCUI\",\n /**\n * An NDC could **not be resolved** to any `RXCUI` in the loaded RxNorm release — a typed, surfaced\n * absence, never a guessed `RXCUI`. NDC↔RXCUI is many:1 and temporal, so a resolution\n * is always release-scoped; an NDC not present in the loaded release is this diagnostic.\n */\n TERM_RXNORM_NDC_UNMAPPED: \"TERM_RXNORM_NDC_UNMAPPED\",\n} as const;\n\n/**\n * A value from {@link DIAGNOSTIC_CODES} — the type consumers narrow a diagnostic's `code` against.\n */\nexport type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];\n\n/**\n * Stable **fatal codes** — thrown (as a {@link TerminologyError}) when input cannot be loaded into\n * a usable model at all. Always thrown, never swallowed. `key === value`, part of the contract.\n *\n * @example\n * ```ts\n * import { FATAL_CODES } from \"@cosyte/terminology\";\n *\n * FATAL_CODES.TERM_CONCEPTMAP_MALFORMED; // => \"TERM_CONCEPTMAP_MALFORMED\"\n * ```\n */\nexport const FATAL_CODES = {\n /**\n * A `ConceptMap` resource was structurally unusable — wrong `resourceType`, or a group/element\n * missing a required field. Thrown rather than silently loading a partial, misleading map.\n */\n TERM_CONCEPTMAP_MALFORMED: \"TERM_CONCEPTMAP_MALFORMED\",\n /**\n * A CodeSystem *source* was structurally unusable — a FHIR resource with the wrong `resourceType`,\n * or a delimited source whose configured code/display column is absent from the header. Thrown\n * rather than silently loading an empty or mis-keyed release. (Malformed individual **rows** are\n * skipped-and-surfaced load warnings, not fatals — only an unusable *source* is fatal.)\n */\n TERM_CODESYSTEM_MALFORMED: \"TERM_CODESYSTEM_MALFORMED\",\n /**\n * A `ValueSet` resource was structurally unusable — wrong `resourceType`, or a `compose`/`expansion`\n * whose required shape (an `include` that is not an object, a `contains` entry missing its `code`)\n * is corrupt. Thrown rather than silently loading a partial value set that would bind *some* codes\n * and quietly drop others. (A `filter` operator the engine does not implement is **not** fatal — it\n * is the surfaced `TERM_VALUESET_CANNOT_EXPAND` diagnostic at expansion time.)\n */\n TERM_VALUESET_MALFORMED: \"TERM_VALUESET_MALFORMED\",\n /**\n * A crosswalk map *source* was structurally unusable — e.g. a SNOMED complex-map RF2 refset with\n * empty content or a header missing a required column. Thrown rather than silently loading an empty\n * or mis-keyed map. (Malformed individual **rows** are skipped-and-surfaced warnings, not fatals.)\n */\n TERM_CROSSWALK_MALFORMED: \"TERM_CROSSWALK_MALFORMED\",\n /**\n * An **inversion** of a directional crosswalk was requested — a forbidden operation. The GEMs and\n * the SNOMED→ICD-10-CM map are authoritative in **one direction only**; a forward map is not the\n * inverse of the backward map. Thrown by {@link ../crosswalk/gems.invertGem} so the\n * never-invert refusal is a first-class, discoverable contract rather than a silent absence.\n */\n TERM_MAP_NOT_INVERTIBLE: \"TERM_MAP_NOT_INVERTIBLE\",\n} as const;\n\n/**\n * A value from {@link FATAL_CODES} — the type carried by a thrown {@link TerminologyError}.\n */\nexport type FatalCode = (typeof FATAL_CODES)[keyof typeof FATAL_CODES];\n\n/**\n * The engine's typed error. Carries a stable {@link FatalCode} so callers branch on `err.code`\n * without string-matching the message. Thrown only for {@link FATAL_CODES} conditions.\n *\n * The `message` is **value-free**: it names the structural fault (a resource path, a missing field,\n * the *role* of a configured column) and never echoes an input value — so it is safe to log, and\n * safe in an `err.stack` that reaches an error reporter. The rule the strings are built by is in\n * this module's docblock above.\n *\n * @example\n * ```ts\n * import { loadConceptMap, TerminologyError, FATAL_CODES } from \"@cosyte/terminology\";\n *\n * try {\n * loadConceptMap({ resourceType: \"Patient\" });\n * } catch (err) {\n * (err as TerminologyError).code === FATAL_CODES.TERM_CONCEPTMAP_MALFORMED; // => true\n * }\n * ```\n */\nexport class TerminologyError extends Error {\n /** The stable fatal code. Branch on this, not on {@link message}. */\n public readonly code: FatalCode;\n\n /**\n * @param code - The stable {@link FatalCode} describing the fault.\n * @param message - A **value-free** structural description (path + fault; never an input value).\n * Every piece of it must be engine-owned — a literal, a frozen-table entry, or a locus this\n * package built. This string reaches `err.stack`, so interpolating a caller-supplied or\n * document-derived value into it is how a diagnostic becomes a leak.\n */\n public constructor(code: FatalCode, message: string) {\n super(message);\n this.name = \"TerminologyError\";\n this.code = code;\n // Restore the prototype chain for reliable `instanceof` across the ESM/CJS build boundary.\n Object.setPrototypeOf(this, TerminologyError.prototype);\n }\n}\n","/**\n * Minimal, zero-dependency navigation helpers for **untrusted FHIR JSON** (`unknown` inputs\n * decoded from a consumer-supplied `ConceptMap`/`CodeSystem`/`ValueSet`).\n *\n * The engine never trusts the shape of its inputs: every accessor here narrows an `unknown`\n * to a concrete type or returns `undefined`, so a malformed resource degrades to a typed\n * diagnostic (see {@link ../conceptmap/load}) rather than a `TypeError` deep in a getter. This\n * is the terminology-engine analogue of a parser's lenient tokenizer — liberal on load.\n *\n * These helpers are **value-free**: they read structure, never log or echo field *values*, so a\n * code-in-context (which can be PHI) never flows into a message.\n *\n * @packageDocumentation\n */\n\n/**\n * Narrow an `unknown` to a plain JSON object (a non-null, non-array `object`).\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a non-null, non-array object.\n * @example\n * ```ts\n * import { isJsonObject } from \"@cosyte/terminology\";\n *\n * isJsonObject({ resourceType: \"ConceptMap\" }); // => true\n * ```\n */\nexport function isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Read a **string** property from an untrusted object, or `undefined` if absent/not a string.\n *\n * @param obj - The source object (may be any `unknown`).\n * @param key - The property name to read.\n * @returns The string value, or `undefined` when the key is missing or not a string.\n * @example\n * ```ts\n * import { getString } from \"@cosyte/terminology\";\n *\n * getString({ url: \"http://loinc.org\" }, \"url\"); // => \"http://loinc.org\"\n * ```\n */\nexport function getString(obj: unknown, key: string): string | undefined {\n if (!isJsonObject(obj)) return undefined;\n const v = obj[key];\n return typeof v === \"string\" ? v : undefined;\n}\n\n/**\n * Read an **array** property from an untrusted object as a `readonly unknown[]`, or `undefined`.\n *\n * The elements are left as `unknown` — callers narrow each one. A non-array (including a missing\n * key) yields `undefined`, which callers treat as \"no entries\" rather than an error.\n *\n * @param obj - The source object (may be any `unknown`).\n * @param key - The property name to read.\n * @returns The array (elements untyped), or `undefined` when the key is missing or not an array.\n * @example\n * ```ts\n * import { getArray } from \"@cosyte/terminology\";\n *\n * getArray({ group: [{ source: \"a\" }] }, \"group\")?.length; // => 1\n * ```\n */\nexport function getArray(obj: unknown, key: string): readonly unknown[] | undefined {\n if (!isJsonObject(obj)) return undefined;\n const v = obj[key];\n return Array.isArray(v) ? v : undefined;\n}\n\n/**\n * Read a **boolean** property from an untrusted object, or `undefined` if absent/not a boolean.\n *\n * A non-boolean (including a missing key, or the strings `\"true\"`/`\"false\"`) yields `undefined` —\n * the accessor never coerces, so a caller can distinguish \"explicitly `false`\" from \"absent\".\n *\n * @param obj - The source object (may be any `unknown`).\n * @param key - The property name to read.\n * @returns The boolean value, or `undefined` when the key is missing or not a boolean.\n * @example\n * ```ts\n * import { getBoolean } from \"@cosyte/terminology\";\n *\n * getBoolean({ inactive: true }, \"inactive\"); // => true\n * ```\n */\nexport function getBoolean(obj: unknown, key: string): boolean | undefined {\n if (!isJsonObject(obj)) return undefined;\n const v = obj[key];\n return typeof v === \"boolean\" ? v : undefined;\n}\n\n/**\n * Read a **number** property from an untrusted object, or `undefined` if absent/not a finite number.\n *\n * @param obj - The source object (may be any `unknown`).\n * @param key - The property name to read.\n * @returns The number value, or `undefined` when the key is missing or not a finite number.\n * @example\n * ```ts\n * import { getNumber } from \"@cosyte/terminology\";\n *\n * getNumber({ valueInteger: 3 }, \"valueInteger\"); // => 3\n * ```\n */\nexport function getNumber(obj: unknown, key: string): number | undefined {\n if (!isJsonObject(obj)) return undefined;\n const v = obj[key];\n return typeof v === \"number\" && Number.isFinite(v) ? v : undefined;\n}\n","/**\n * The **code-system identity registry** — the grounded OID ↔ canonical-URI ↔ mnemonic facts the\n * ecosystem uses.\n *\n * A code-system *identity* (the triple of canonical URI, OID, and HL7 v2 mnemonic that all name\n * the same terminology) is a **published identifier** for the system, not the system's code list — so\n * it is encoded here, cited firsthand. That is where the line falls: identities are encoded; the code\n * *lists themselves* (SNOMED CT / CPT / LOINC content) are BYO and never bundled.\n *\n * **Every identity below is grounded firsthand against a primary source** (verified 2026-07-21):\n *\n * - The FHIR R4 terminology-systems registry — `https://hl7.org/fhir/R4/terminologies-systems.html`\n * — for LOINC, SNOMED CT, RxNorm, UCUM, CPT, NDC, CVX (canonical URI + OID), and for the HL7 v2\n * table URI/OID patterns (`http://terminology.hl7.org/CodeSystem/v2-[X]` ↔\n * `2.16.840.1.113883.12.[X]`).\n * - The FHIR R4 ICD page — `https://hl7.org/fhir/R4/icd.html` — for ICD-10-CM\n * (`http://hl7.org/fhir/sid/icd-10-cm` ↔ `2.16.840.1.113883.6.90`).\n * - HL7 Table 0396 (coding-system mnemonics) — the THO `v2-0396` code system — for the mnemonics\n * (`LN`, `SCT`, `I10C`, `RXNORM`, `UCUM`, `C4`, `NDC`, `CVX`).\n *\n * Identities that could not be pinned to a primary source firsthand are **omitted**, not\n * guessed — notably ICD-9-CM and ICD-10-PCS, whose OID\n * assignments were ambiguous across sources.\n *\n * @packageDocumentation\n */\n\n/**\n * A resolved code-system identity — the canonical URI plus the alternate identifiers that name the\n * same system.\n */\nexport interface SystemIdentity {\n /** The canonical URI — the single value the engine treats as the system's identity. */\n readonly url: string;\n /** The registered OID (bare, no `urn:oid:` prefix), when the system has one. */\n readonly oid?: string;\n /** A short human-readable name for diagnostics/logs (value-free — a system name, never a value). */\n readonly name: string;\n /** HL7 v2 Table 0396 mnemonic(s) and other accepted short aliases for this system. */\n readonly mnemonics: readonly string[];\n}\n\n/**\n * The seed identity table. Order is irrelevant; lookup indexes are built from it in\n * {@link ../systems/resolve}. Each entry is one firsthand-grounded system (see the module doc).\n */\nexport const SYSTEM_IDENTITIES: readonly SystemIdentity[] = Object.freeze(\n [\n {\n url: \"http://loinc.org\",\n oid: \"2.16.840.1.113883.6.1\",\n name: \"LOINC\",\n mnemonics: [\"LN\", \"LOINC\"],\n },\n {\n url: \"http://snomed.info/sct\",\n oid: \"2.16.840.1.113883.6.96\",\n name: \"SNOMED CT\",\n mnemonics: [\"SCT\", \"SNOMEDCT\", \"SNOMED\"],\n },\n {\n url: \"http://hl7.org/fhir/sid/icd-10-cm\",\n oid: \"2.16.840.1.113883.6.90\",\n name: \"ICD-10-CM\",\n mnemonics: [\"I10C\", \"ICD10CM\"],\n },\n {\n url: \"http://www.nlm.nih.gov/research/umls/rxnorm\",\n oid: \"2.16.840.1.113883.6.88\",\n name: \"RxNorm\",\n mnemonics: [\"RXNORM\"],\n },\n {\n url: \"http://unitsofmeasure.org\",\n oid: \"2.16.840.1.113883.6.8\",\n name: \"UCUM\",\n mnemonics: [\"UCUM\"],\n },\n {\n url: \"http://www.ama-assn.org/go/cpt\",\n oid: \"2.16.840.1.113883.6.12\",\n name: \"CPT\",\n mnemonics: [\"C4\", \"CPT\"],\n },\n {\n url: \"http://hl7.org/fhir/sid/ndc\",\n oid: \"2.16.840.1.113883.6.69\",\n name: \"NDC\",\n mnemonics: [\"NDC\"],\n },\n {\n url: \"http://hl7.org/fhir/sid/cvx\",\n oid: \"2.16.840.1.113883.12.292\",\n name: \"CVX (CDC Vaccine Codes)\",\n mnemonics: [\"CVX\"],\n },\n ].map((e) => Object.freeze({ ...e, mnemonics: Object.freeze([...e.mnemonics]) })),\n);\n\n/**\n * The OID root under which every HL7 v2 table code system is registered:\n * `2.16.840.1.113883.12.[table]` — grounded against the FHIR R4 terminology-systems registry.\n * The table number is appended with no leading zeros (e.g. table 0203 → `…12.203`).\n */\nexport const HL7_V2_OID_ROOT = \"2.16.840.1.113883.12\";\n\n/**\n * The canonical URI prefix for HL7 v2 table code systems in HL7 Terminology (THO):\n * `http://terminology.hl7.org/CodeSystem/v2-[XXXX]`, where `[XXXX]` is the zero-padded 4-digit\n * table id — grounded against the FHIR R4 terminology-systems registry.\n */\nexport const HL7_V2_URL_PREFIX = \"http://terminology.hl7.org/CodeSystem/v2-\";\n","/**\n * The **code-system identity / canonical-URI resolver** — `resolveSystem`.\n *\n * Given a code system named any of the ways the ecosystem names it — a canonical URI, an OID (bare\n * or `urn:oid:`-prefixed), or an HL7 v2 mnemonic (`LN`, `SCT`, …) — it returns the one canonical\n * {@link SystemIdentity}. This is the piece `@cosyte/transform` pins so a `Coding` off any parser\n * (HL7 v2 CE/CWE, C-CDA, FHIR) can be canonicalized to a single system URI before translation.\n *\n * **Never guesses.** An identifier that matches nothing known returns a typed\n * `{ unknown: true, input }` — never a fabricated URI (the never-fabricate invariant, applied to\n * system identity).\n *\n * @packageDocumentation\n */\n\nimport {\n HL7_V2_OID_ROOT,\n HL7_V2_URL_PREFIX,\n SYSTEM_IDENTITIES,\n type SystemIdentity,\n} from \"./registry.js\";\n\n/** The typed \"not recognized\" outcome from {@link resolveSystem} — surfaced, never a guess. */\nexport interface UnknownSystem {\n /** Discriminant: the identifier was not recognized. */\n readonly unknown: true;\n /** The identifier as supplied, echoed back so the caller can surface/log it. */\n readonly input: string;\n}\n\n/** The result of {@link resolveSystem}: a resolved {@link SystemIdentity} or a typed unknown. */\nexport type ResolveSystemResult = SystemIdentity | UnknownSystem;\n\n// Lookup indexes, built once from the frozen seed table. Keys are lowercased for URI/mnemonic\n// case-insensitivity; OIDs are matched exactly (digits/dots only).\nconst byUrl = new Map<string, SystemIdentity>();\nconst byOid = new Map<string, SystemIdentity>();\nconst byMnemonic = new Map<string, SystemIdentity>();\n\nfor (const id of SYSTEM_IDENTITIES) {\n byUrl.set(id.url.toLowerCase(), id);\n if (id.oid !== undefined) byOid.set(id.oid, id);\n for (const m of id.mnemonics) byMnemonic.set(m.toLowerCase(), id);\n}\n\nconst OID_RE = /^[0-2](?:\\.(?:0|[1-9]\\d*))+$/;\n\n/** Strip a `urn:oid:` prefix if present, returning the bare OID (or the input unchanged). */\nfunction stripOidPrefix(input: string): string {\n const lower = input.toLowerCase();\n return lower.startsWith(\"urn:oid:\") ? input.slice(\"urn:oid:\".length) : input;\n}\n\n/**\n * Recognize an HL7 v2 table code system by URI or OID and build its identity structurally.\n *\n * The v2 table family is huge and open-ended, so it is resolved by **pattern**, not enumerated:\n * `http://terminology.hl7.org/CodeSystem/v2-[XXXX]` ↔ `2.16.840.1.113883.12.[table]`. Both\n * patterns are grounded firsthand (see {@link ../systems/registry}). Returns `undefined` when the\n * input is not a v2 table identifier.\n */\nfunction resolveV2Table(rawInput: string, bareOid: string): SystemIdentity | undefined {\n // OID form: <v2 root>.<table>, table a 1-4 digit integer with no leading zeros. Capped at 4\n // digits to stay symmetric with the URI form (HL7 v2 table ids are 4-digit).\n if (bareOid.startsWith(`${HL7_V2_OID_ROOT}.`)) {\n const tail = bareOid.slice(HL7_V2_OID_ROOT.length + 1);\n if (/^(?:0|[1-9]\\d{0,3})$/.test(tail)) {\n const padded = tail.padStart(4, \"0\");\n return Object.freeze({\n url: `${HL7_V2_URL_PREFIX}${padded}`,\n oid: bareOid,\n name: `HL7 v2 table ${padded}`,\n mnemonics: Object.freeze([`v2-${padded}`]),\n });\n }\n }\n // URI form: <prefix><4-digit table>. Accept case-insensitively on the prefix.\n const lower = rawInput.toLowerCase();\n if (lower.startsWith(HL7_V2_URL_PREFIX.toLowerCase())) {\n const tail = rawInput.slice(HL7_V2_URL_PREFIX.length);\n if (/^\\d{1,4}$/.test(tail)) {\n const padded = tail.padStart(4, \"0\");\n const table = String(Number(tail));\n return Object.freeze({\n url: `${HL7_V2_URL_PREFIX}${padded}`,\n oid: `${HL7_V2_OID_ROOT}.${table}`,\n name: `HL7 v2 table ${padded}`,\n mnemonics: Object.freeze([`v2-${padded}`]),\n });\n }\n }\n return undefined;\n}\n\n/**\n * Resolve a code-system identifier to its canonical {@link SystemIdentity}.\n *\n * Accepts, in order of attempt: a canonical URI (case-insensitive), a `v2-XXXX` mnemonic or a\n * v2 table URI/OID (resolved structurally), a bare or `urn:oid:`-prefixed OID, or an HL7 v2\n * Table 0396 mnemonic. Whitespace is trimmed. An empty or unrecognized identifier yields a typed\n * {@link UnknownSystem} — the resolver **never** invents a URI.\n *\n * @param id - The identifier (canonical URI, OID, `urn:oid:` OID, or mnemonic).\n * @returns The resolved {@link SystemIdentity}, or `{ unknown: true, input }`.\n * @example\n * ```ts\n * import { resolveSystem } from \"@cosyte/terminology\";\n *\n * resolveSystem(\"2.16.840.1.113883.6.1\"); // => { url: \"http://loinc.org\", … }\n * resolveSystem(\"SCT\"); // => { url: \"http://snomed.info/sct\", … }\n * resolveSystem(\"http://example.com/nope\"); // => { unknown: true, input: \"http://example.com/nope\" }\n * ```\n */\nexport function resolveSystem(id: string): ResolveSystemResult {\n // Defensive against JS callers that ignore the `string` type.\n if (typeof id !== \"string\") return { unknown: true, input: \"\" };\n const input = id.trim();\n if (input === \"\") return { unknown: true, input: id };\n\n // 1. Exact canonical URI (case-insensitive).\n const urlHit = byUrl.get(input.toLowerCase());\n if (urlHit) return urlHit;\n\n // 2. HL7 v2 mnemonic (case-insensitive), e.g. LN / SCT / RXNORM.\n const mnemonicHit = byMnemonic.get(input.toLowerCase());\n if (mnemonicHit) return mnemonicHit;\n\n // 3. OID (bare or urn:oid:-prefixed).\n const bareOid = stripOidPrefix(input);\n if (OID_RE.test(bareOid)) {\n const oidHit = byOid.get(bareOid);\n if (oidHit) return oidHit;\n const v2 = resolveV2Table(input, bareOid);\n if (v2) return v2;\n return { unknown: true, input };\n }\n\n // 4. HL7 v2 table by URI/`v2-XXXX` form.\n const v2 = resolveV2Table(input, bareOid);\n if (v2) return v2;\n\n return { unknown: true, input };\n}\n\n/**\n * Type guard: did {@link resolveSystem} fail to recognize the identifier?\n *\n * @param result - A {@link resolveSystem} result.\n * @returns `true` when the result is a typed {@link UnknownSystem}.\n * @example\n * ```ts\n * import { resolveSystem, isUnknownSystem } from \"@cosyte/terminology\";\n *\n * isUnknownSystem(resolveSystem(\"nope\")); // => true\n * ```\n */\nexport function isUnknownSystem(result: ResolveSystemResult): result is UnknownSystem {\n return \"unknown\" in result;\n}\n","/**\n * {@link loadConceptMap} — validate and normalize an untrusted FHIR R4 `ConceptMap` JSON resource\n * into the immutable {@link ConceptMap} model the `$translate` engine runs over.\n *\n * **Conservative on load** (unlike a wire parser's lenient posture): a ConceptMap drives a clinical\n * translation, so a structurally unusable map is a typed **fatal**\n * ({@link FATAL_CODES.TERM_CONCEPTMAP_MALFORMED}), never a silently partial map that would translate\n * *some* codes and quietly drop others. Fault messages are **value-free** — they name the resource\n * *path* and the fault, never echo a code or display *value*.\n *\n * @packageDocumentation\n */\n\nimport { TerminologyError, FATAL_CODES } from \"../common/diagnostics.js\";\nimport { getArray, getString, isJsonObject } from \"../common/fhir-json.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport type {\n ConceptMap,\n ConceptMapElement,\n ConceptMapGroup,\n ConceptMapTarget,\n ConceptMapUnmapped,\n R4Equivalence,\n UnmappedMode,\n} from \"./types.js\";\n\nconst R4_EQUIVALENCES: ReadonlySet<string> = new Set<R4Equivalence>([\n \"relatedto\",\n \"equivalent\",\n \"equal\",\n \"wider\",\n \"subsumes\",\n \"narrower\",\n \"specializes\",\n \"inexact\",\n \"unmatched\",\n \"disjoint\",\n]);\n\nconst INPUT_UNMAPPED_MODES: ReadonlySet<string> = new Set<UnmappedMode>([\n \"provided\",\n \"fixed\",\n \"other-map\",\n]);\n\n/** Throw a value-free {@link TerminologyError} for a malformed ConceptMap at `path`. */\nfunction malformed(path: string, fault: string): never {\n throw new TerminologyError(FATAL_CODES.TERM_CONCEPTMAP_MALFORMED, `ConceptMap ${path}: ${fault}`);\n}\n\n/** Copy an optional string property onto `out[key]` only when present (no `undefined` keys). */\nfunction assignString<T extends Record<string, unknown>>(out: T, src: unknown, key: string): void {\n const v = getString(src, key);\n if (v !== undefined) (out as Record<string, unknown>)[key] = v;\n}\n\nfunction loadTarget(raw: unknown, path: string): ConceptMapTarget {\n if (!isJsonObject(raw)) malformed(path, \"target is not an object\");\n const equivalence = getString(raw, \"equivalence\");\n if (equivalence === undefined) {\n malformed(path, \"target is missing the required 'equivalence' field\");\n }\n if (!R4_EQUIVALENCES.has(equivalence)) {\n malformed(path, \"target has an unrecognized 'equivalence' value\");\n }\n const out: Writable<ConceptMapTarget> = { equivalence: equivalence as R4Equivalence };\n assignString(out, raw, \"code\");\n assignString(out, raw, \"display\");\n assignString(out, raw, \"comment\");\n return Object.freeze(out);\n}\n\nfunction loadElement(raw: unknown, path: string): ConceptMapElement {\n if (!isJsonObject(raw)) malformed(path, \"element is not an object\");\n const rawTargets = getArray(raw, \"target\") ?? [];\n const target = Object.freeze(\n rawTargets.map((t, i) => loadTarget(t, `${path}.target[${String(i)}]`)),\n );\n const out: Writable<ConceptMapElement> = { target };\n assignString(out, raw, \"code\");\n assignString(out, raw, \"display\");\n return Object.freeze(out);\n}\n\nfunction loadUnmapped(raw: unknown, path: string): ConceptMapUnmapped {\n if (!isJsonObject(raw)) malformed(path, \"unmapped is not an object\");\n const mode = getString(raw, \"mode\");\n if (mode === undefined || !INPUT_UNMAPPED_MODES.has(mode)) {\n malformed(path, \"unmapped has a missing or unrecognized 'mode'\");\n }\n const out: Writable<ConceptMapUnmapped> = { mode: mode as UnmappedMode };\n assignString(out, raw, \"code\");\n assignString(out, raw, \"display\");\n assignString(out, raw, \"url\");\n return Object.freeze(out);\n}\n\nfunction loadGroup(raw: unknown, path: string): ConceptMapGroup {\n if (!isJsonObject(raw)) malformed(path, \"group is not an object\");\n const rawElements = getArray(raw, \"element\") ?? [];\n const element = Object.freeze(\n rawElements.map((e, i) => loadElement(e, `${path}.element[${String(i)}]`)),\n );\n const out: Writable<ConceptMapGroup> = { element };\n assignString(out, raw, \"source\");\n assignString(out, raw, \"sourceVersion\");\n assignString(out, raw, \"target\");\n assignString(out, raw, \"targetVersion\");\n if (isJsonObject(raw) && raw[\"unmapped\"] !== undefined) {\n out.unmapped = loadUnmapped(raw[\"unmapped\"], `${path}.unmapped`);\n }\n return Object.freeze(out);\n}\n\n/**\n * Load an untrusted FHIR R4 `ConceptMap` JSON value into an immutable {@link ConceptMap}.\n *\n * Accepts the standard resource shape: a top-level object with `resourceType: \"ConceptMap\"` and an\n * optional `group[]`. `source[x]`/`target[x]` scopes are read from either the `Uri` or `Canonical`\n * variant. The result is deep-frozen. Anything structurally unusable throws a\n * {@link TerminologyError} carrying {@link FATAL_CODES.TERM_CONCEPTMAP_MALFORMED}.\n *\n * @param json - The untrusted resource (typically `JSON.parse` output — hence `unknown`).\n * @returns The immutable, validated {@link ConceptMap}.\n * @throws {TerminologyError} `TERM_CONCEPTMAP_MALFORMED` when the resource is not a usable ConceptMap.\n * @example\n * ```ts\n * import { loadConceptMap } from \"@cosyte/terminology\";\n *\n * const map = loadConceptMap({\n * resourceType: \"ConceptMap\",\n * url: \"http://example.org/cm/gender\",\n * group: [\n * {\n * source: \"http://hl7.org/fhir/administrative-gender\",\n * target: \"http://terminology.hl7.org/CodeSystem/v2-0001\",\n * element: [{ code: \"male\", target: [{ code: \"M\", equivalence: \"equivalent\" }] }],\n * },\n * ],\n * });\n * map.group.length; // => 1\n * ```\n */\nexport function loadConceptMap(json: unknown): ConceptMap {\n if (!isJsonObject(json)) malformed(\"\", \"resource is not a JSON object\");\n const resourceType = getString(json, \"resourceType\");\n if (resourceType !== \"ConceptMap\") {\n malformed(\"\", \"resource is not a ConceptMap (wrong or missing resourceType)\");\n }\n const rawGroups = getArray(json, \"group\") ?? [];\n const group = Object.freeze(rawGroups.map((g, i) => loadGroup(g, `group[${String(i)}]`)));\n const out: Writable<ConceptMap> = { group };\n assignString(out, json, \"url\");\n assignString(out, json, \"version\");\n // R4 source[x]/target[x] — accept either the Uri or Canonical form.\n const sourceScope = getString(json, \"sourceUri\") ?? getString(json, \"sourceCanonical\");\n const targetScope = getString(json, \"targetUri\") ?? getString(json, \"targetCanonical\");\n if (sourceScope !== undefined) out.sourceScope = sourceScope;\n if (targetScope !== undefined) out.targetScope = targetScope;\n return Object.freeze(out);\n}\n","/**\n * {@link translate} — the ConceptMap `$translate` engine, modeled on the FHIR\n * `ConceptMap/$translate` operation.\n *\n * Given a source {@link Coding} and a loaded {@link ConceptMap}, it returns the declared target\n * code(s) with their FHIR relationship and the map's provenance — or, when the source does not map,\n * a **typed {@link TranslateUnmapped}**. Two invariants govern it:\n *\n * 1. **Never fabricate.** An unmapped source yields a surfaced `unmapped` result — never a guessed\n * target. Every target returned is drawn verbatim from the map; the engine invents nothing.\n * 2. **Never invert.** Translation reads the map in its authored direction only: a source coding is\n * matched against `group.element.code` (the source side) and **never** against target codes. A\n * directional map therefore cannot be run backwards — reverse translation requires an explicit\n * inverse map; it is never synthesized here.\n *\n * @packageDocumentation\n */\n\nimport { coding, type Coding } from \"../common/coding.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport type {\n ConceptMap,\n ConceptMapGroup,\n MapProvenance,\n R4Equivalence,\n Relationship,\n TranslateMatch,\n TranslateResult,\n TranslateUnmapped,\n UnmappedMode,\n} from \"./types.js\";\n\n/**\n * Map a verbatim FHIR R4 `equivalence` token to the normalized, version-neutral\n * {@link Relationship} (the R5 vocabulary). The full R4 enum folds in; this is total.\n */\nfunction equivalenceToRelationship(equivalence: R4Equivalence): Relationship {\n switch (equivalence) {\n case \"equivalent\":\n case \"equal\":\n return \"equivalent\";\n case \"wider\":\n case \"subsumes\":\n // The source concept is-a the target ⇒ the source is narrower than the target.\n return \"source-is-narrower-than-target\";\n case \"narrower\":\n case \"specializes\":\n // The target concept is-a the source ⇒ the source is broader than the target.\n return \"source-is-broader-than-target\";\n case \"relatedto\":\n case \"inexact\":\n return \"related-to\";\n case \"disjoint\":\n case \"unmatched\":\n return \"not-related-to\";\n }\n}\n\n/** Does this group apply to a source coding in `system`? A group with no declared source is a\n * single-system wildcard; a coding with no system cannot be discriminated, so all groups apply. */\nfunction groupApplies(group: ConceptMapGroup, system: string | undefined): boolean {\n if (system === undefined) return true;\n return group.source === undefined || group.source === system;\n}\n\n/** Build the provenance record for a translation attempt against `map`, optionally within `group`. */\nfunction provenanceOf(\n map: ConceptMap,\n group: ConceptMapGroup | undefined,\n sourceSystem: string | undefined,\n): MapProvenance {\n const out: { -readonly [K in keyof MapProvenance]: MapProvenance[K] } = {};\n if (map.url !== undefined) out.conceptMapUrl = map.url;\n if (map.version !== undefined) out.conceptMapVersion = map.version;\n const src = sourceSystem ?? group?.source;\n if (src !== undefined) out.sourceSystem = src;\n if (group?.target !== undefined) out.targetSystem = group.target;\n return Object.freeze(out);\n}\n\n/** Assemble the typed unmapped result, reporting (never applying) any declared fallback. */\nfunction unmappedResult(\n source: Coding,\n mode: UnmappedMode,\n provenance: MapProvenance,\n fixedTarget: Coding | undefined,\n otherMapUrl: string | undefined,\n): TranslateResult {\n const out: Writable<TranslateUnmapped> = {\n unmapped: true,\n code: \"TERM_TRANSLATE_UNMAPPED\",\n mode,\n source,\n provenance,\n };\n if (fixedTarget !== undefined) out.fixedTarget = fixedTarget;\n if (otherMapUrl !== undefined) out.otherMapUrl = otherMapUrl;\n return Object.freeze(out);\n}\n\n/**\n * Translate a source {@link Coding} through a loaded {@link ConceptMap}.\n *\n * Matches the coding's `code` against each applicable group's `element.code` (the **source** side —\n * never targets, so the map is never inverted) and returns every declared target for it. A target\n * with an `unmatched` equivalence, or with no `code`, is treated as \"no target\" — the FHIR way of\n * asserting a non-mapping — and does not count as a match. When nothing matches, the map author's\n * `group.unmapped` directive (if any) is *reported* via the result's {@link UnmappedMode} but never\n * silently applied.\n *\n * @param sourceCoding - The source concept to translate.\n * @param map - A {@link ConceptMap} from {@link loadConceptMap}.\n * @returns A {@link TranslateResult} — matched targets, or a typed unmapped outcome.\n * @example\n * ```ts\n * import { loadConceptMap, translate } from \"@cosyte/terminology\";\n *\n * const map = loadConceptMap({\n * resourceType: \"ConceptMap\",\n * group: [\n * {\n * source: \"http://hl7.org/fhir/administrative-gender\",\n * target: \"http://terminology.hl7.org/CodeSystem/v2-0001\",\n * element: [{ code: \"male\", target: [{ code: \"M\", equivalence: \"equivalent\" }] }],\n * },\n * ],\n * });\n * const r = translate(\n * { system: \"http://hl7.org/fhir/administrative-gender\", code: \"male\" },\n * map,\n * );\n * r.unmapped; // => false\n * ```\n */\nexport function translate(sourceCoding: Coding, map: ConceptMap): TranslateResult {\n const source = coding(sourceCoding);\n const system = source.system;\n\n const matches: TranslateMatch[] = [];\n let firstMatchGroup: ConceptMapGroup | undefined;\n let sourceCodePresent = false;\n let fallbackGroup: ConceptMapGroup | undefined;\n\n for (const group of map.group) {\n if (!groupApplies(group, system)) continue;\n if (fallbackGroup === undefined && group.unmapped !== undefined) fallbackGroup = group;\n\n for (const element of group.element) {\n if (element.code !== source.code) continue;\n sourceCodePresent = true;\n for (const t of element.target) {\n // A target without a code, or an explicit `unmatched`, asserts \"no target\" — not a match.\n if (t.code === undefined || t.equivalence === \"unmatched\") continue;\n const targetCoding = coding({\n ...(group.target !== undefined ? { system: group.target } : {}),\n code: t.code,\n ...(t.display !== undefined ? { display: t.display } : {}),\n ...(group.targetVersion !== undefined ? { version: group.targetVersion } : {}),\n });\n const match: {\n -readonly [K in keyof TranslateMatch]: TranslateMatch[K];\n } = {\n target: targetCoding,\n relationship: equivalenceToRelationship(t.equivalence),\n equivalence: t.equivalence,\n };\n if (t.comment !== undefined) match.comment = t.comment;\n matches.push(Object.freeze(match));\n if (firstMatchGroup === undefined) firstMatchGroup = group;\n }\n }\n }\n\n if (matches.length > 0) {\n return Object.freeze({\n unmapped: false,\n matches: Object.freeze(matches),\n provenance: provenanceOf(map, firstMatchGroup, system),\n });\n }\n\n // No usable target. If the source code appeared but every target was a non-mapping, this is an\n // authored \"no map\" (mode 'none'). Otherwise consult a declared group.unmapped fallback.\n if (!sourceCodePresent && fallbackGroup?.unmapped !== undefined) {\n const um = fallbackGroup.unmapped;\n const provenance = provenanceOf(map, fallbackGroup, system);\n if (um.mode === \"fixed\" && um.code !== undefined) {\n const fixed = coding({\n ...(fallbackGroup.target !== undefined ? { system: fallbackGroup.target } : {}),\n code: um.code,\n ...(um.display !== undefined ? { display: um.display } : {}),\n });\n return unmappedResult(source, \"fixed\", provenance, fixed, undefined);\n }\n if (um.mode === \"other-map\") {\n return unmappedResult(source, \"other-map\", provenance, undefined, um.url);\n }\n if (um.mode === \"provided\") {\n return unmappedResult(source, \"provided\", provenance, undefined, undefined);\n }\n }\n\n return unmappedResult(\n source,\n \"none\",\n provenanceOf(map, firstMatchGroup, system),\n undefined,\n undefined,\n );\n}\n","/**\n * Status interpretation shared by the loaders — the {@link defaultStatusMapper} that turns a raw\n * steward status token into a normalized {@link ConceptActivity}, and {@link makeStatus} which\n * assembles the frozen {@link ConceptStatus} (attaching the stable diagnostic code for the two\n * concerns it distinguishes: deprecated and header-not-billable).\n *\n * The mapper is deliberately **conservative**: it recognizes only the tokens grounded in the format\n * docs (LOINC `STATUS` lifecycle values and RxNorm/UMLS `SUPPRESS` values), and maps\n * everything else to `unknown` — a non-active state carrying the raw token, **never** a guessed\n * clean-active. Every loader lets the consumer override it for a release with bespoke semantics.\n *\n * @packageDocumentation\n */\n\nimport { DIAGNOSTIC_CODES } from \"../common/diagnostics.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport type { ConceptActivity, ConceptStatus, StatusMapper } from \"./types.js\";\n\n/**\n * The default raw-token → {@link ConceptActivity} mapping, case-insensitive.\n *\n * Recognized (grounded in the format docs): `\"\"`/`N`/`ACTIVE` → active; `DEPRECATED` → deprecated;\n * `DISCOURAGED`; `TRIAL`; `O`/`OBSOLETE` → obsolete; `Y`/`E`/`SUPPRESSED` → suppressed. Anything else\n * → `unknown` (surfaced with its raw token, never coerced to active).\n *\n * @param raw - The steward's raw status token.\n * @returns The normalized activity.\n * @example\n * ```ts\n * import { defaultStatusMapper } from \"@cosyte/terminology\";\n *\n * defaultStatusMapper(\"DEPRECATED\"); // => \"deprecated\"\n * defaultStatusMapper(\"N\"); // => \"active\"\n * ```\n */\nexport const defaultStatusMapper: StatusMapper = (raw: string): ConceptActivity => {\n switch (raw.trim().toUpperCase()) {\n case \"\":\n case \"N\":\n case \"ACTIVE\":\n return \"active\";\n case \"DEPRECATED\":\n return \"deprecated\";\n case \"DISCOURAGED\":\n return \"discouraged\";\n case \"TRIAL\":\n return \"trial\";\n case \"O\":\n case \"OBSOLETE\":\n return \"obsolete\";\n case \"Y\":\n case \"E\":\n case \"SUPPRESSED\":\n return \"suppressed\";\n default:\n return \"unknown\";\n }\n};\n\n/**\n * Assemble a frozen {@link ConceptStatus} from a normalized activity, carrying the raw token and (for\n * classification systems) the billable flag, and attaching the stable diagnostic code for the two\n * concerns it distinguishes — `TERM_CONCEPT_DEPRECATED` and `TERM_CONCEPT_HEADER_NOT_BILLABLE`.\n *\n * @param activity - The normalized activity.\n * @param raw - The verbatim steward token, if any (omitted from the result when empty).\n * @param billable - The billable flag for a classification system, if applicable.\n * @returns A frozen {@link ConceptStatus}.\n * @example\n * ```ts\n * import { makeStatus } from \"@cosyte/terminology\";\n *\n * makeStatus(\"deprecated\", \"DEPRECATED\").code; // => \"TERM_CONCEPT_DEPRECATED\"\n * ```\n */\nexport function makeStatus(\n activity: ConceptActivity,\n raw?: string,\n billable?: boolean,\n): ConceptStatus {\n const out: Writable<ConceptStatus> = { activity, active: activity === \"active\" };\n if (raw !== undefined && raw !== \"\") out.raw = raw;\n if (billable !== undefined) out.billable = billable;\n if (activity === \"deprecated\") out.code = DIAGNOSTIC_CODES.TERM_CONCEPT_DEPRECATED;\n else if (activity === \"header\") out.code = DIAGNOSTIC_CODES.TERM_CONCEPT_HEADER_NOT_BILLABLE;\n return Object.freeze(out);\n}\n","/**\n * The **RFC-4180 CSV** reader — the one release format that needs real quote handling (LOINC's\n * `Loinc.csv`). Fields may be quoted with `\"`; inside a quoted field a literal quote is escaped as\n * `\"\"`, and commas and newlines are data. Hand-rolled, zero-dep (the CSV surface is small and\n * well-specified enough to hand-roll rather than pull a dependency).\n *\n * **Liberal on load:** a data row with too few fields to reach a configured column is **skipped and\n * surfaced** as a `TERM_CSV_MALFORMED` warning; an unterminated final quote is surfaced too — never a\n * crash. A configured code/display header that is **absent from the header row** is a *fatal*\n * (`TERM_CODESYSTEM_MALFORMED`): the source config does not match the file, so nothing loads cleanly.\n * That fatal names the missing column's **role** (`code`, `display`, `status`, a property column)\n * from a frozen table, never the column name you configured — the message reaches `err.stack`, and a\n * column name is consumer-supplied text of unbounded length.\n *\n * @packageDocumentation\n */\n\nimport { DIAGNOSTIC_CODES, FATAL_CODES, TerminologyError } from \"../common/diagnostics.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { defaultStatusMapper, makeStatus } from \"./status.js\";\nimport type { Concept, CsvSource, LoadWarning, Property } from \"./types.js\";\n\n/** The lenient RFC-4180 parse result: the rows, plus whether a quoted field was left unterminated. */\ninterface CsvParse {\n /** The parsed rows, each an array of field strings (untrimmed — CSV whitespace can be significant). */\n readonly rows: string[][];\n /** True when a quoted field opened but never closed before end-of-input (a malformed final field). */\n readonly unterminatedQuote: boolean;\n}\n\n/**\n * Parse RFC-4180 CSV content into rows and fields, **lenient** in the one place a strict RFC-4180\n * parser is dangerous: a `\"` is a field-quote **only at the start of a field**. A stray/unescaped\n * quote in the *middle* of an otherwise-unquoted field (e.g. an inch mark, `12\" fitting`) is a\n * **literal character**, not a quote-open — so it can never flip quote-mode and silently swallow the\n * rest of the file into one garbled field. Inside a quoted field, `\"\"` is an escaped quote and commas\n * and newlines are literal data. An opened quote that never closes before EOF is reported via\n * {@link CsvParse.unterminatedQuote} (surfaced by {@link parseCsvSource}), never swallowed.\n *\n * @param content - The raw CSV text.\n * @returns The parsed {@link CsvParse}.\n */\nfunction parseCsvRows(content: string): CsvParse {\n const rows: string[][] = [];\n let row: string[] = [];\n let field = \"\";\n let inQuotes = false;\n let fieldStart = true; // are we at the first char of the current field?\n let sawAny = false; // any content on the current (possibly-empty) logical row\n const n = content.length;\n\n for (let i = 0; i < n; i++) {\n const ch = content.charAt(i);\n if (inQuotes) {\n if (ch === '\"') {\n if (content.charAt(i + 1) === '\"') {\n field += '\"';\n i++;\n } else {\n inQuotes = false; // close the quoted field; stay in the same (non-start) field\n }\n } else {\n field += ch;\n }\n continue;\n }\n if (ch === '\"' && fieldStart) {\n inQuotes = true;\n fieldStart = false;\n sawAny = true;\n } else if (ch === \",\") {\n row.push(field);\n field = \"\";\n fieldStart = true;\n sawAny = true;\n } else if (ch === \"\\n\") {\n row.push(field);\n rows.push(row);\n row = [];\n field = \"\";\n fieldStart = true;\n sawAny = false;\n } else if (ch === \"\\r\") {\n // CRLF: ignore the CR; the LF ends the row.\n } else {\n // Any other char (including a `\"` that is NOT at field start) is literal.\n field += ch;\n fieldStart = false;\n sawAny = true;\n }\n }\n // Flush a trailing row that did not end with a newline.\n if (sawAny || field !== \"\" || row.length > 0) {\n row.push(field);\n rows.push(row);\n }\n return { rows, unterminatedQuote: inQuotes };\n}\n\n/**\n * Parse RFC-4180 CSV content into rows of fields (the `.rows` of {@link parseCsvRows}). Lenient: a\n * stray mid-field quote is literal, so a malformed quote never silently swallows subsequent rows.\n *\n * @param content - The raw CSV text.\n * @returns The rows, each an array of field strings (untrimmed).\n * @example\n * ```ts\n * import { parseCsv } from \"@cosyte/terminology\";\n *\n * parseCsv('a,b\\n\"x,y\",\"z\"\"q\"'); // => [[\"a\", \"b\"], [\"x,y\", 'z\"q']]\n * ```\n */\nexport function parseCsv(content: string): string[][] {\n return parseCsvRows(content).rows;\n}\n\n/**\n * The **role** a configured CSV column plays. A closed set: it is the engine's own vocabulary, never\n * a string that came from the caller or the file.\n */\ntype CsvColumnRole = \"code\" | \"display\" | \"status\" | \"property\";\n\n/**\n * The frozen fatal message per {@link CsvColumnRole}. A **table lookup, not an interpolation** — the\n * factory below takes no value parameter, so no caller-supplied or document-derived string can reach\n * `TerminologyError.message` (and from there `err.stack`, and from there an error reporter) however\n * long or however hostile it is.\n *\n * The role is the useful half anyway: a caller who configured `columns.code = \"LOINC_NUM\"` already\n * holds that string, and what they need from the engine is *which* configured column their file does\n * not have. Naming a property column's own string would echo an unbounded value to say something the\n * caller can recover in one line from their own `columns.properties` and the file's header row.\n */\nconst MISSING_COLUMN_MESSAGE: Readonly<Record<CsvColumnRole, string>> = Object.freeze({\n code: \"CSV source: the configured 'code' column is not present in the header row\",\n display: \"CSV source: the configured 'display' column is not present in the header row\",\n status: \"CSV source: the configured 'status' column is not present in the header row\",\n property: \"CSV source: a configured property column is not present in the header row\",\n});\n\n/** Resolve a header name to its column index, or throw a value-free fatal naming only its role. */\nfunction requireHeader(header: readonly string[], name: string, role: CsvColumnRole): number {\n const idx = header.indexOf(name);\n if (idx < 0) {\n throw new TerminologyError(FATAL_CODES.TERM_CODESYSTEM_MALFORMED, MISSING_COLUMN_MESSAGE[role]);\n }\n return idx;\n}\n\n/**\n * Parse a {@link CsvSource} into concepts and skipped-row warnings.\n *\n * @param source - The CSV source.\n * @returns The parsed concepts (by code) and the load warnings.\n * @throws {TerminologyError} `TERM_CODESYSTEM_MALFORMED` when the file has no header row, or a\n * configured `code`/`display`/`status`/property column is absent from the header. The message\n * names the missing column's **role**, never the name you configured.\n * @example\n * ```ts\n * import { parseCsvSource } from \"@cosyte/terminology\";\n *\n * const { concepts } = parseCsvSource({\n * format: \"csv\",\n * content: \"CODE,NAME\\n2160-0,Creatinine\",\n * columns: { code: \"CODE\", display: \"NAME\" },\n * });\n * concepts.get(\"2160-0\")?.display; // => \"Creatinine\"\n * ```\n */\nexport function parseCsvSource(source: CsvSource): {\n concepts: Map<string, Concept>;\n warnings: LoadWarning[];\n} {\n const statusMap = source.statusMap ?? defaultStatusMapper;\n const { rows, unterminatedQuote } = parseCsvRows(source.content);\n const header = rows[0];\n if (header === undefined) {\n throw new TerminologyError(\n FATAL_CODES.TERM_CODESYSTEM_MALFORMED,\n \"CSV source: the file has no header row\",\n );\n }\n const warnings: LoadWarning[] = [];\n if (unterminatedQuote) {\n // A quoted field opened but never closed before EOF — the final logical row is malformed. Surface\n // it (never silently keep a garbled field), pointing at the last parsed row.\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_CSV_MALFORMED,\n line: rows.length,\n detail: \"an opened quoted field was not terminated before end-of-input\",\n }),\n );\n }\n\n const codeIdx = requireHeader(header, source.columns.code, \"code\");\n const displayIdx = requireHeader(header, source.columns.display, \"display\");\n const statusIdx =\n source.columns.status !== undefined\n ? requireHeader(header, source.columns.status, \"status\")\n : undefined;\n const propIdx: { name: string; index: number }[] = (source.columns.properties ?? []).map((n) => ({\n name: n,\n index: requireHeader(header, n, \"property\"),\n }));\n const needCols =\n Math.max(codeIdx, displayIdx, statusIdx ?? 0, ...propIdx.map((p) => p.index)) + 1;\n\n const concepts = new Map<string, Concept>();\n\n for (let r = 1; r < rows.length; r++) {\n const cells = rows[r] ?? [];\n const lineNo = r + 1;\n if (cells.length < needCols) {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_CSV_MALFORMED,\n line: lineNo,\n detail: `row has ${String(cells.length)} fields, need ${String(needCols)}`,\n }),\n );\n continue;\n }\n const code = (cells[codeIdx] ?? \"\").trim();\n if (code === \"\") {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_CSV_MALFORMED,\n line: lineNo,\n detail: \"row is missing its code\",\n }),\n );\n continue;\n }\n if (concepts.has(code)) continue; // first row per code wins\n\n const out: Writable<Concept> = { code, properties: [] };\n const display = (cells[displayIdx] ?? \"\").trim();\n if (display !== \"\") out.display = display;\n if (statusIdx !== undefined) {\n const rawStatus = (cells[statusIdx] ?? \"\").trim();\n out.status = makeStatus(statusMap(rawStatus), rawStatus);\n }\n const props: Property[] = [];\n for (const p of propIdx) {\n const value = (cells[p.index] ?? \"\").trim();\n if (value !== \"\") props.push(Object.freeze({ code: p.name, value }));\n }\n out.properties = Object.freeze(props);\n concepts.set(code, Object.freeze(out));\n }\n\n return { concepts, warnings };\n}\n","/**\n * The **FHIR R4 `CodeSystem`** JSON loader — the native, consumer-supplied model. Reads the untrusted\n * resource into the engine's {@link Concept} map, flattening nested `concept` hierarchies and mapping\n * the standard concept properties to {@link ConceptStatus}.\n *\n * Grounded firsthand on FHIR R4 (`https://hl7.org/fhir/R4/codesystem.html` and the concept-properties\n * code system, `https://hl7.org/fhir/R4/codesystem-concept-properties.html`): a concept has\n * `code`/`display`/`definition`/`designation`/`property`/nested `concept`; the base property\n * **`inactive`** (boolean) is *\"True if the concept is not considered active — e.g. not a valid\n * concept any more\"*, **`deprecated`** (dateTime) marks a deprecation, and a `status` string property\n * is common in real systems.\n *\n * **Conservative on load:** the wrong `resourceType` is a *fatal* (`TERM_CODESYSTEM_MALFORMED`); a\n * concept missing its required `code` is skipped and surfaced (a malformed row, not a whole-file\n * fatal).\n *\n * @packageDocumentation\n */\n\nimport { DIAGNOSTIC_CODES, FATAL_CODES, TerminologyError } from \"../common/diagnostics.js\";\nimport { getArray, getBoolean, getNumber, getString, isJsonObject } from \"../common/fhir-json.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { makeStatus } from \"./status.js\";\nimport type {\n Concept,\n ConceptStatus,\n FhirCodeSystemSource,\n LoadWarning,\n Property,\n} from \"./types.js\";\n\n/** Read a FHIR `property.value[x]` into a primitive Property value, or `undefined` if none present. */\nfunction readPropertyValue(raw: Record<string, unknown>): string | boolean | number | undefined {\n const s =\n getString(raw, \"valueString\") ?? getString(raw, \"valueCode\") ?? getString(raw, \"valueDateTime\");\n if (s !== undefined) return s;\n const b = getBoolean(raw, \"valueBoolean\");\n if (b !== undefined) return b;\n const num = getNumber(raw, \"valueInteger\") ?? getNumber(raw, \"valueDecimal\");\n if (num !== undefined) return num;\n // valueCoding: surface its code (the identity that matters), when present.\n const coding = raw[\"valueCoding\"];\n const codingCode = getString(coding, \"code\");\n if (codingCode !== undefined) return codingCode;\n return undefined;\n}\n\n/** Derive a {@link ConceptStatus} from a concept's raw properties, or `undefined` when none signal it. */\nfunction deriveStatus(props: readonly Property[]): ConceptStatus | undefined {\n const statusProp = props.find((p) => p.code === \"status\");\n if (statusProp !== undefined && typeof statusProp.value === \"string\") {\n // A `status` string is release-specific; carry it verbatim as an `unknown`-unless-active signal.\n const raw = statusProp.value;\n const activity = raw.trim().toLowerCase() === \"active\" ? \"active\" : \"deprecated\";\n return makeStatus(activity, raw);\n }\n const inactive = props.find((p) => p.code === \"inactive\");\n const deprecated = props.find((p) => p.code === \"deprecated\");\n if (inactive?.value === true || deprecated !== undefined) {\n // FHIR `inactive: true` / a `deprecated` date ⇒ not current. Flagged, never presented clean.\n return makeStatus(\"deprecated\");\n }\n return undefined;\n}\n\n/**\n * Recursively collect concepts from a `concept[]` array into `into`, surfacing skipped rows.\n *\n * `parentCode` is the code of the enclosing concept when this array is a nested `concept` list. FHIR\n * `CodeSystem` nesting is the default **is-a** hierarchy (`hierarchyMeaning` defaults to `is-a`), so a\n * nested child gains a synthesized standard **`parent`** concept-property\n * (`http://hl7.org/fhir/concept-properties#parent`) pointing at its enclosing code — the subsumption\n * signal the ValueSet `is-a`/`descendent-of` filter reads. A `parent` property already declared\n * verbatim for the same value is never duplicated; the flattened concept map is otherwise unchanged.\n */\nfunction collectConcepts(\n rawConcepts: readonly unknown[],\n into: Map<string, Concept>,\n warnings: LoadWarning[],\n parentCode?: string,\n): void {\n for (const raw of rawConcepts) {\n if (!isJsonObject(raw)) {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_FHIR_CONCEPT_MALFORMED,\n line: 0,\n detail: \"concept is not an object\",\n }),\n );\n continue;\n }\n const code = getString(raw, \"code\");\n if (code !== undefined && code !== \"\" && !into.has(code)) {\n const props: Property[] = [];\n for (const p of getArray(raw, \"property\") ?? []) {\n const pcode = getString(p, \"code\");\n if (pcode === undefined) continue;\n const value = isJsonObject(p) ? readPropertyValue(p) : undefined;\n if (value !== undefined) props.push(Object.freeze({ code: pcode, value }));\n }\n // Synthesize the nesting-derived `parent` edge (unless the release already declared it), so a\n // nested hierarchy is queryable by `is-a`/`descendent-of` exactly like an explicit `parent`.\n if (\n parentCode !== undefined &&\n !props.some((p) => p.code === \"parent\" && p.value === parentCode)\n ) {\n props.push(Object.freeze({ code: \"parent\", value: parentCode }));\n }\n const out: Writable<Concept> = { code, properties: Object.freeze(props) };\n const display = getString(raw, \"display\");\n if (display !== undefined) out.display = display;\n const definition = getString(raw, \"definition\");\n if (definition !== undefined) out.definition = definition;\n const status = deriveStatus(props);\n if (status !== undefined) out.status = status;\n into.set(code, Object.freeze(out));\n } else if (code === undefined || code === \"\") {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_FHIR_CONCEPT_MALFORMED,\n line: 0,\n detail: \"concept is missing its required code\",\n }),\n );\n }\n // Recurse into nested children regardless (a header concept still has valid leaf children). The\n // enclosing concept's code becomes the child's synthesized `parent` (when the child has a code).\n const children = getArray(raw, \"concept\");\n if (children !== undefined) {\n collectConcepts(children, into, warnings, code !== \"\" ? code : undefined);\n }\n }\n}\n\n/**\n * Parse a {@link FhirCodeSystemSource} into concepts, a resolved url/version/name, and warnings.\n *\n * @param source - The FHIR CodeSystem source.\n * @returns The parsed concepts (by code), the load warnings, and the resource metadata.\n * @throws {TerminologyError} `TERM_CODESYSTEM_MALFORMED` when the resource is not a FHIR `CodeSystem`.\n * @example\n * ```ts\n * import { parseFhirCodeSystem } from \"@cosyte/terminology\";\n *\n * const { concepts } = parseFhirCodeSystem({\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"A\", display: \"Alpha\" }] },\n * format: \"fhir\",\n * });\n * concepts.get(\"A\")?.display; // => \"Alpha\"\n * ```\n */\nexport function parseFhirCodeSystem(source: FhirCodeSystemSource): {\n concepts: Map<string, Concept>;\n warnings: LoadWarning[];\n url?: string;\n version?: string;\n name?: string;\n} {\n const resource = source.resource;\n if (!isJsonObject(resource) || getString(resource, \"resourceType\") !== \"CodeSystem\") {\n throw new TerminologyError(\n FATAL_CODES.TERM_CODESYSTEM_MALFORMED,\n \"FHIR source: resource is not a CodeSystem (wrong or missing resourceType)\",\n );\n }\n const concepts = new Map<string, Concept>();\n const warnings: LoadWarning[] = [];\n collectConcepts(getArray(resource, \"concept\") ?? [], concepts, warnings);\n\n const out: { concepts: Map<string, Concept>; warnings: LoadWarning[] } & {\n url?: string;\n version?: string;\n name?: string;\n } = { concepts, warnings };\n const url = getString(resource, \"url\");\n if (url !== undefined) out.url = url;\n const version = getString(resource, \"version\");\n if (version !== undefined) out.version = version;\n const name = getString(resource, \"name\");\n if (name !== undefined) out.name = name;\n return out;\n}\n","/**\n * The **fixed-width** reader — slice a line by column, for order-file layouts like the ICD-10-CM\n * order file (`icd10cm_order_YYYY.txt`). Fully parameterized: the consumer supplies the field slices,\n * so the *engine* is content-agnostic and the byte offsets live in the caller's config, not baked in.\n *\n * The documented ICD-10-CM preset is {@link ICD10CM_ORDER_FILE_FIELDS} — the position-15 flag\n * (0-based char index 14) is `1` for a **billable/valid** code and `0` for a **header** (grounded on\n * the CMS/CDC order-file layout). Confirm the exact offsets against your release's README before\n * relying on the preset — which is exactly why the reader takes the slices as a parameter.\n *\n * **Liberal on load:** a line too short to contain the code slice, or with an empty code, is skipped\n * and surfaced as a `TERM_FIXED_WIDTH_MALFORMED` warning.\n *\n * @packageDocumentation\n */\n\nimport { DIAGNOSTIC_CODES } from \"../common/diagnostics.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { defaultStatusMapper, makeStatus } from \"./status.js\";\nimport type {\n Concept,\n ConceptActivity,\n FieldSlice,\n FixedWidthFieldMap,\n FixedWidthSource,\n LoadWarning,\n Property,\n} from \"./types.js\";\n\n/**\n * Extract and trim a {@link FieldSlice} from a line (`end` omitted slices to end of line).\n *\n * @param line - The source line.\n * @param slice - The half-open `[start, end)` slice.\n * @returns The trimmed field text (empty when the slice is entirely past the line's end).\n * @example\n * ```ts\n * import { sliceField } from \"@cosyte/terminology\";\n *\n * sliceField(\"00001 A00 1 Cholera\", { start: 6, end: 13 }); // => \"A00\"\n * ```\n */\nexport function sliceField(line: string, slice: FieldSlice): string {\n const raw =\n slice.end === undefined ? line.slice(slice.start) : line.slice(slice.start, slice.end);\n return raw.trim();\n}\n\n/**\n * The documented **ICD-10-CM order file** field layout (0-based char indices).\n *\n * - `code` — the ICD-10-CM code (no decimal point).\n * - `billable` — position-15 flag at index 14: `\"1\"` = billable/valid leaf, `\"0\"` = header.\n * - `display` — the long description (to end of line).\n * - property `shortDescription` — the 60-char short description.\n *\n * Grounded on the CMS/CDC order-file layout; **verify against your release's README** before relying\n * on the exact offsets, which are not confirmed against an authoritative machine-readable source.\n * The reader takes the layout as a parameter precisely so this preset is a starting point, not a\n * hardcoded assumption.\n */\nexport const ICD10CM_ORDER_FILE_FIELDS: FixedWidthFieldMap = Object.freeze({\n code: Object.freeze({ start: 6, end: 13 }),\n display: Object.freeze({ start: 77 }),\n billable: Object.freeze({ at: 14, billableValue: \"1\" }),\n properties: Object.freeze([\n Object.freeze({ name: \"shortDescription\", slice: Object.freeze({ start: 16, end: 76 }) }),\n ]),\n});\n\n/**\n * Parse a {@link FixedWidthSource} into concepts and skipped-row warnings.\n *\n * @param source - The fixed-width source.\n * @returns The parsed concepts (by code) and the load warnings.\n * @example\n * ```ts\n * import { parseFixedWidth } from \"@cosyte/terminology\";\n *\n * const { concepts } = parseFixedWidth({\n * format: \"fixed-width\",\n * content: \"A00 1 Cholera\",\n * fields: { code: { start: 0, end: 3 }, display: { start: 6 } },\n * });\n * concepts.get(\"A00\")?.display; // => \"Cholera\"\n * ```\n */\nexport function parseFixedWidth(source: FixedWidthSource): {\n concepts: Map<string, Concept>;\n warnings: LoadWarning[];\n} {\n const statusMap = source.statusMap ?? defaultStatusMapper;\n const fields: FixedWidthFieldMap = source.fields;\n const concepts = new Map<string, Concept>();\n const warnings: LoadWarning[] = [];\n\n const lines = source.content.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (line.trim() === \"\") continue;\n const lineNo = i + 1;\n if (line.length <= fields.code.start) {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_FIXED_WIDTH_MALFORMED,\n line: lineNo,\n detail: `line length ${String(line.length)} does not reach the code field`,\n }),\n );\n continue;\n }\n const code = sliceField(line, fields.code);\n if (code === \"\") {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_FIXED_WIDTH_MALFORMED,\n line: lineNo,\n detail: \"row is missing its code\",\n }),\n );\n continue;\n }\n if (concepts.has(code)) continue;\n\n const out: Writable<Concept> = { code, properties: [] };\n const display = sliceField(line, fields.display);\n if (display !== \"\") out.display = display;\n\n // Status: a billable flag takes precedence (header vs leaf); otherwise a status slice, if any.\n if (fields.billable !== undefined) {\n const flag = line.charAt(fields.billable.at);\n const billable = flag === fields.billable.billableValue;\n const activity: ConceptActivity = billable ? \"active\" : \"header\";\n out.status = makeStatus(activity, flag, billable);\n } else if (fields.status !== undefined) {\n const rawStatus = sliceField(line, fields.status);\n out.status = makeStatus(statusMap(rawStatus), rawStatus);\n }\n\n const props: Property[] = [];\n for (const p of fields.properties ?? []) {\n const value = sliceField(line, p.slice);\n if (value !== \"\") props.push(Object.freeze({ code: p.name, value }));\n }\n out.properties = Object.freeze(props);\n concepts.set(code, Object.freeze(out));\n }\n\n return { concepts, warnings };\n}\n","/**\n * The **RRF** (Rich Release Format) reader — the pipe-delimited layer shared by RxNorm (`RXNCONSO`/\n * `RXNSAT`) and UMLS (`MRCONSO`/`MRSAT`). One parameterized reader serves both: they share the RRF\n * shape — fields separated by `|`, with **one trailing pipe per line** (grounded firsthand on the\n * UMLS Reference Manual, `https://www.ncbi.nlm.nih.gov/books/NBK9685/`: *\"values … are separated by\n * vertical bars (|)\"* and each row ends with *\"a vertical bar and line termination\"*).\n *\n * **Liberal on load**: a row too short to reach a configured column, or with an empty\n * code, is **skipped and surfaced** as a `TERM_RRF_MALFORMED_ROW` warning — never kept as a partial\n * concept, never a crash. RRF reserves `|` as the delimiter (fields never contain a literal pipe), so\n * a plain split is exact.\n *\n * @packageDocumentation\n */\n\nimport { DIAGNOSTIC_CODES } from \"../common/diagnostics.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { defaultStatusMapper, makeStatus } from \"./status.js\";\nimport type { Concept, LoadWarning, Property, RrfSource } from \"./types.js\";\n\n/**\n * Split one RRF line into its fields, dropping the single reserved trailing pipe.\n *\n * @param line - One RRF line (no line terminator).\n * @returns The fields, in column order.\n * @example\n * ```ts\n * import { parseRrfLine } from \"@cosyte/terminology\";\n *\n * parseRrfLine(\"316151|ENG|lisinopril 10 MG|\"); // => [\"316151\", \"ENG\", \"lisinopril 10 MG\"]\n * ```\n */\nexport function parseRrfLine(line: string): readonly string[] {\n const cells = line.split(\"|\");\n // RRF terminates each row with a reserved trailing '|', yielding one trailing empty cell — drop it.\n if (cells.length > 0 && cells[cells.length - 1] === \"\") cells.pop();\n return cells;\n}\n\n/** The highest column index the mapping references — a row must have at least this many cells. */\nfunction maxColumn(source: RrfSource): number {\n const { code, display, status, properties } = source.columns;\n let max = Math.max(code, display, status ?? 0);\n for (const p of properties ?? []) max = Math.max(max, p.column);\n return max;\n}\n\n/** Read a cell by index, trimmed; `undefined` when the index is out of range. */\nfunction cell(cells: readonly string[], index: number): string | undefined {\n const v = cells[index];\n return v === undefined ? undefined : v.trim();\n}\n\n/**\n * Parse an {@link RrfSource} into concepts (first row per code wins) and skipped-row warnings.\n *\n * A code that recurs across rows (RRF repeats a code once per atom/attribute) keeps its **first**\n * occurrence — a documented v1 limitation: preferred-atom selection (`TS`/`STT`/`ISPREF`) and\n * attribute merging are later work. The result is data only; {@link loadCodeSystem} freezes it.\n *\n * @param source - The RRF source.\n * @returns The parsed concepts (by code) and the load warnings.\n * @example\n * ```ts\n * import { parseRrf } from \"@cosyte/terminology\";\n *\n * const { concepts } = parseRrf({\n * format: \"rrf\",\n * content: \"1|Aspirin|\",\n * columns: { code: 0, display: 1 },\n * });\n * concepts.get(\"1\")?.display; // => \"Aspirin\"\n * ```\n */\nexport function parseRrf(source: RrfSource): {\n concepts: Map<string, Concept>;\n warnings: LoadWarning[];\n} {\n const statusMap = source.statusMap ?? defaultStatusMapper;\n const needCols = maxColumn(source) + 1;\n const concepts = new Map<string, Concept>();\n const warnings: LoadWarning[] = [];\n\n const lines = source.content.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i] ?? \"\";\n if (raw === \"\") continue; // blank line (e.g. trailing newline) — not a row\n const lineNo = i + 1;\n const cells = parseRrfLine(raw);\n if (cells.length < needCols) {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_RRF_MALFORMED_ROW,\n line: lineNo,\n detail: `row has ${String(cells.length)} columns, need ${String(needCols)}`,\n }),\n );\n continue;\n }\n const code = cell(cells, source.columns.code);\n if (code === undefined || code === \"\") {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_RRF_MALFORMED_ROW,\n line: lineNo,\n detail: \"row is missing its code\",\n }),\n );\n continue;\n }\n if (concepts.has(code)) continue; // first row per code wins\n\n const out: Writable<Concept> = { code, properties: [] };\n const display = cell(cells, source.columns.display);\n if (display !== undefined && display !== \"\") out.display = display;\n if (source.columns.status !== undefined) {\n const rawStatus = cell(cells, source.columns.status) ?? \"\";\n out.status = makeStatus(statusMap(rawStatus), rawStatus);\n }\n const props: Property[] = [];\n for (const p of source.columns.properties ?? []) {\n const value = cell(cells, p.column);\n if (value !== undefined && value !== \"\") {\n props.push(Object.freeze({ code: p.name, value }));\n }\n }\n out.properties = Object.freeze(props);\n concepts.set(code, Object.freeze(out));\n }\n\n return { concepts, warnings };\n}\n","/**\n * {@link loadCodeSystem} — the single entry point that dispatches a {@link CodeSystemSource} to the\n * right reader (RRF / CSV / fixed-width / FHIR) and assembles the immutable {@link CodeSystem}.\n *\n * The engine is **content-agnostic**: it loads a *consumer-supplied* release and ships\n * **no code-system release** of its own. The loaded model is deep-frozen and keyed by code\n * for O(1) {@link lookup}/{@link validateCode}.\n *\n * @packageDocumentation\n */\n\nimport type { Writable } from \"../common/writable.js\";\nimport { parseCsvSource } from \"./csv.js\";\nimport { parseFhirCodeSystem } from \"./fhir.js\";\nimport { parseFixedWidth } from \"./fixed-width.js\";\nimport { parseRrf } from \"./rrf.js\";\nimport type { CodeSystem, CodeSystemSource, Concept, LoadWarning } from \"./types.js\";\n\n/**\n * Seal a built concept map so the returned release is genuinely immutable — `Object.freeze` does not\n * stop `Map.set`/`delete`/`clear`, and a mutated map would let a caller inject a **fabricated**\n * concept past the never-fabricate invariant (and desync `count`). The mutators are replaced with a\n * throwing guard, mirroring how `Object.freeze` rejects writes in strict mode. Read/iteration are\n * untouched; the type is already `ReadonlyMap`.\n */\nfunction sealConceptMap(map: Map<string, Concept>): ReadonlyMap<string, Concept> {\n const guard = (): never => {\n throw new TypeError(\"Cannot mutate a loaded CodeSystem's concepts map (it is immutable)\");\n };\n for (const method of [\"set\", \"delete\", \"clear\"] as const) {\n Object.defineProperty(map, method, { value: guard, writable: false, configurable: false });\n }\n return map;\n}\n\n/**\n * Load a consumer-supplied code-system release into an immutable, queryable {@link CodeSystem}.\n *\n * Dispatches on `source.format`:\n * - `\"rrf\"` — pipe-delimited RxNorm/UMLS release (one parameterized reader for both).\n * - `\"csv\"` — RFC-4180 CSV (e.g. LOINC `Loinc.csv`), with real quote handling.\n * - `\"fixed-width\"` — slice-by-column order files (e.g. ICD-10-CM; see `ICD10CM_ORDER_FILE_FIELDS`).\n * - `\"fhir\"` — a native FHIR R4 `CodeSystem` JSON resource.\n *\n * **Liberal on load:** a malformed *row* is skipped and surfaced in `warnings` (never a crash, never a\n * partial concept). **Conservative on structure:** an unusable *source* (wrong FHIR `resourceType`, or\n * a CSV whose configured columns are absent from the header) throws a typed `TerminologyError`\n * carrying `TERM_CODESYSTEM_MALFORMED`.\n *\n * @param source - The release descriptor (a discriminated {@link CodeSystemSource}).\n * @returns The immutable, deep-frozen {@link CodeSystem}.\n * @throws {TerminologyError} `TERM_CODESYSTEM_MALFORMED` when the source is structurally unusable.\n * @example\n * ```ts\n * import { loadCodeSystem } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: {\n * resourceType: \"CodeSystem\",\n * url: \"http://example.org/cs\",\n * concept: [{ code: \"A\", display: \"Alpha\" }],\n * },\n * });\n * cs.count; // => 1\n * ```\n */\nexport function loadCodeSystem(source: CodeSystemSource): CodeSystem {\n let concepts: Map<string, Concept>;\n let warnings: LoadWarning[];\n const out: Writable<CodeSystem> = { count: 0, concepts: new Map(), warnings: [] };\n\n switch (source.format) {\n case \"rrf\": {\n ({ concepts, warnings } = parseRrf(source));\n if (source.url !== undefined) out.url = source.url;\n if (source.version !== undefined) out.version = source.version;\n if (source.name !== undefined) out.name = source.name;\n break;\n }\n case \"csv\": {\n ({ concepts, warnings } = parseCsvSource(source));\n if (source.url !== undefined) out.url = source.url;\n if (source.version !== undefined) out.version = source.version;\n if (source.name !== undefined) out.name = source.name;\n break;\n }\n case \"fixed-width\": {\n ({ concepts, warnings } = parseFixedWidth(source));\n if (source.url !== undefined) out.url = source.url;\n if (source.version !== undefined) out.version = source.version;\n if (source.name !== undefined) out.name = source.name;\n break;\n }\n case \"fhir\": {\n const parsed = parseFhirCodeSystem(source);\n concepts = parsed.concepts;\n warnings = parsed.warnings;\n if (parsed.url !== undefined) out.url = parsed.url;\n if (parsed.version !== undefined) out.version = parsed.version;\n if (parsed.name !== undefined) out.name = parsed.name;\n break;\n }\n }\n\n out.count = concepts.size;\n out.concepts = sealConceptMap(concepts);\n out.warnings = Object.freeze(warnings);\n return Object.freeze(out);\n}\n","/**\n * {@link lookup} and {@link validateCode} — the FHIR R4 CodeSystem `$lookup` and `$validate-code`\n * operations over a loaded {@link CodeSystem}.\n *\n * Grounded firsthand on FHIR R4 (`https://hl7.org/fhir/R4/codesystem-operation-lookup.html`,\n * `https://hl7.org/fhir/R4/codesystem-operation-validate-code.html`):\n *\n * - `$lookup` returns the concept's `display` (*\"The preferred display for this concept\"*) and its\n * `property` values (*\"additional information about the code, including status\"*).\n * - `$validate-code` returns `result` (*\"True if the concept details supplied are valid\"*).\n *\n * Both honor the **never-fabricate invariant**, applied here to code identity: an\n * unknown code yields a typed `unknown` / `valid: false` — **never** a fabricated display and\n * **never** a guessed `valid: true`. A found-but-non-current concept (deprecated, or an ICD-10-CM\n * header) validates as present **but carries its status flag**, so a caller never treats it as clean.\n *\n * @packageDocumentation\n */\n\nimport type { Writable } from \"../common/writable.js\";\nimport type {\n CodeSystem,\n LookupOutcome,\n LookupResult,\n LookupUnknown,\n ValidateCodeResult,\n} from \"./types.js\";\n\n/**\n * `$lookup`: resolve a code to its display, definition, status, and properties in a loaded release.\n *\n * @param cs - The loaded {@link CodeSystem}.\n * @param code - The code to look up.\n * @returns A {@link LookupResult} when found, or a typed {@link LookupUnknown} — never a guess.\n * @example\n * ```ts\n * import { loadCodeSystem, lookup } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"A\", display: \"Alpha\" }] },\n * });\n * const r = lookup(cs, \"A\");\n * r.found === true && r.display; // => \"Alpha\"\n * ```\n */\nexport function lookup(cs: CodeSystem, code: string): LookupOutcome {\n const concept = cs.concepts.get(code);\n if (concept === undefined) {\n const unknown: LookupUnknown = { found: false, code: \"TERM_CODE_UNKNOWN\", input: code };\n return Object.freeze(unknown);\n }\n const out: Writable<LookupResult> = {\n found: true,\n code: concept.code,\n properties: concept.properties,\n };\n if (concept.display !== undefined) out.display = concept.display;\n if (concept.definition !== undefined) out.definition = concept.definition;\n if (concept.status !== undefined) out.status = concept.status;\n if (cs.url !== undefined) out.system = cs.url;\n if (cs.version !== undefined) out.version = cs.version;\n return Object.freeze(out);\n}\n\n/**\n * `$validate-code`: is `code` a valid member of the loaded code system?\n *\n * A found code is `valid: true`, **carrying its status** (a deprecated or header code is present but\n * flagged — never silently clean). An absent code is `valid: false` with `TERM_CODE_UNKNOWN`, never a\n * guessed `true`.\n *\n * @param cs - The loaded {@link CodeSystem}.\n * @param code - The code to validate.\n * @returns A {@link ValidateCodeResult}.\n * @example\n * ```ts\n * import { loadCodeSystem, validateCode } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"A\", display: \"Alpha\" }] },\n * });\n * validateCode(cs, \"A\").valid; // => true\n * validateCode(cs, \"ZZZ\").valid; // => false\n * ```\n */\nexport function validateCode(cs: CodeSystem, code: string): ValidateCodeResult {\n const concept = cs.concepts.get(code);\n if (concept === undefined) {\n return Object.freeze({ valid: false, code: \"TERM_CODE_UNKNOWN\" });\n }\n const out: Writable<ValidateCodeResult> = { valid: true };\n if (concept.status !== undefined) out.status = concept.status;\n return Object.freeze(out);\n}\n","/**\n * {@link loadValueSet} — validate and normalize an untrusted FHIR R4 `ValueSet` JSON resource into\n * the immutable {@link ValueSet} model the `$expand` / `$validate-code` binding operations run over.\n *\n * **Conservative on load** (like {@link ../conceptmap/load.loadConceptMap}, unlike a lenient wire\n * parser): a value set *binds* whether a code is allowed in a clinical slot, so a structurally\n * unusable resource is a typed **fatal** ({@link FATAL_CODES.TERM_VALUESET_MALFORMED}) rather than a\n * silently partial value set that would admit *some* codes and quietly drop others. A `filter`\n * operator the engine does not implement is **not** fatal — the value set loads, and the gap surfaces\n * at expansion time as a {@link DIAGNOSTIC_CODES.TERM_VALUESET_CANNOT_EXPAND} diagnostic. Fault\n * messages are **value-free**: they name the resource *path* and the fault, never echo a code value.\n *\n * @packageDocumentation\n */\n\nimport { FATAL_CODES, TerminologyError } from \"../common/diagnostics.js\";\nimport { getArray, getBoolean, getNumber, getString, isJsonObject } from \"../common/fhir-json.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport type {\n ConceptRef,\n ConceptSetComponent,\n ConceptSetFilter,\n ExpansionContains,\n FilterOperator,\n ValueSet,\n ValueSetCompose,\n ValueSetExpansion,\n} from \"./types.js\";\n\n/** The FHIR `valueset-toocostly` extension URL — flags a pre-computed expansion as incomplete. */\nconst TOO_COSTLY_EXTENSION = \"http://hl7.org/fhir/StructureDefinition/valueset-toocostly\";\n\n/** Throw a value-free {@link TerminologyError} for a malformed ValueSet at `path`. */\nfunction malformed(path: string, fault: string): never {\n throw new TerminologyError(FATAL_CODES.TERM_VALUESET_MALFORMED, `ValueSet ${path}: ${fault}`);\n}\n\n/** Copy an optional string property onto `out[key]` only when present (no `undefined` keys). */\nfunction assignString<T extends Record<string, unknown>>(out: T, src: unknown, key: string): void {\n const v = getString(src, key);\n if (v !== undefined) (out as Record<string, unknown>)[key] = v;\n}\n\nfunction loadFilter(raw: unknown, path: string): ConceptSetFilter {\n if (!isJsonObject(raw)) malformed(path, \"filter is not an object\");\n const property = getString(raw, \"property\");\n const op = getString(raw, \"op\");\n const value = getString(raw, \"value\");\n if (property === undefined || op === undefined || value === undefined) {\n malformed(path, \"filter is missing a required 'property', 'op', or 'value'\");\n }\n // `op` is carried verbatim — an operator the engine does not implement is surfaced at expansion\n // time as TERM_VALUESET_CANNOT_EXPAND, not rejected here (a value set may still be usable via its\n // other components). The cast is safe: unknown strings widen to the not-implemented arm.\n return Object.freeze({ property, op: op as FilterOperator, value });\n}\n\nfunction loadConcept(raw: unknown, path: string): ConceptRef {\n if (!isJsonObject(raw)) malformed(path, \"concept is not an object\");\n const code = getString(raw, \"code\");\n if (code === undefined) malformed(path, \"concept is missing its required 'code'\");\n const out: Writable<ConceptRef> = { code };\n assignString(out, raw, \"display\");\n return Object.freeze(out);\n}\n\nfunction loadComponent(raw: unknown, path: string): ConceptSetComponent {\n if (!isJsonObject(raw)) malformed(path, \"component is not an object\");\n const out: Writable<ConceptSetComponent> = {};\n assignString(out, raw, \"system\");\n assignString(out, raw, \"version\");\n const rawConcepts = getArray(raw, \"concept\");\n if (rawConcepts !== undefined) {\n out.concept = Object.freeze(\n rawConcepts.map((c, i) => loadConcept(c, `${path}.concept[${String(i)}]`)),\n );\n }\n const rawFilters = getArray(raw, \"filter\");\n if (rawFilters !== undefined) {\n out.filter = Object.freeze(\n rawFilters.map((f, i) => loadFilter(f, `${path}.filter[${String(i)}]`)),\n );\n }\n const rawValueSets = getArray(raw, \"valueSet\");\n if (rawValueSets !== undefined) {\n const urls: string[] = [];\n for (const [i, vsRef] of rawValueSets.entries()) {\n if (typeof vsRef !== \"string\") {\n malformed(\n `${path}.valueSet[${String(i)}]`,\n \"value set reference is not a canonical URL string\",\n );\n }\n urls.push(vsRef);\n }\n out.valueSet = Object.freeze(urls);\n }\n // FHIR R4 ValueSet.compose invariants: a `concept`/`filter` selection SHALL name a `system`, and a\n // component SHALL have a `system` or a `valueSet`. A constraint-less component (`{}`) is refused\n // here — never loaded as a silently \"matches everything\" set that binding would then admit blindly.\n const hasSystem = out.system !== undefined;\n const hasValueSet = out.valueSet !== undefined;\n if ((out.concept !== undefined || out.filter !== undefined) && !hasSystem) {\n malformed(path, \"a component with 'concept' or 'filter' must name a 'system'\");\n }\n if (!hasSystem && !hasValueSet) {\n malformed(path, \"a component must have a 'system' or a 'valueSet'\");\n }\n return Object.freeze(out);\n}\n\nfunction loadCompose(raw: unknown, path: string): ValueSetCompose {\n if (!isJsonObject(raw)) malformed(path, \"compose is not an object\");\n const include = Object.freeze(\n (getArray(raw, \"include\") ?? []).map((c, i) =>\n loadComponent(c, `${path}.include[${String(i)}]`),\n ),\n );\n const exclude = Object.freeze(\n (getArray(raw, \"exclude\") ?? []).map((c, i) =>\n loadComponent(c, `${path}.exclude[${String(i)}]`),\n ),\n );\n return Object.freeze({ include, exclude });\n}\n\nfunction loadContains(raw: unknown, path: string): ExpansionContains {\n if (!isJsonObject(raw)) malformed(path, \"contains entry is not an object\");\n const code = getString(raw, \"code\");\n if (code === undefined) malformed(path, \"contains entry is missing its required 'code'\");\n const out: Writable<ExpansionContains> = { code };\n assignString(out, raw, \"system\");\n assignString(out, raw, \"display\");\n assignString(out, raw, \"version\");\n return Object.freeze(out);\n}\n\n/** True when the `expansion.extension` array flags a `valueset-toocostly: true`. */\nfunction isTooCostly(raw: Record<string, unknown>): boolean {\n for (const ext of getArray(raw, \"extension\") ?? []) {\n if (\n getString(ext, \"url\") === TOO_COSTLY_EXTENSION &&\n getBoolean(ext, \"valueBoolean\") === true\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction loadExpansion(raw: unknown, path: string): ValueSetExpansion {\n if (!isJsonObject(raw)) malformed(path, \"expansion is not an object\");\n const contains = Object.freeze(\n (getArray(raw, \"contains\") ?? []).map((c, i) =>\n loadContains(c, `${path}.contains[${String(i)}]`),\n ),\n );\n const total = getNumber(raw, \"total\");\n // Truncated when the server-reported total exceeds what it actually returned, or it flagged the\n // expansion too-costly. Either way the snapshot is a lower bound, never complete membership.\n const truncated = (total !== undefined && total > contains.length) || isTooCostly(raw);\n const out: Writable<ValueSetExpansion> = { contains, truncated };\n if (total !== undefined) out.total = total;\n return Object.freeze(out);\n}\n\n/**\n * Load an untrusted FHIR R4 `ValueSet` JSON value into an immutable {@link ValueSet}.\n *\n * Accepts the standard resource shape: `resourceType: \"ValueSet\"` with an optional intensional\n * `compose` (`include`/`exclude` of `system`/`concept`/`filter`/`valueSet`) and/or a **pre-computed**\n * `expansion` (`contains`, with `total` and the `valueset-toocostly` extension read into a derived\n * `truncated` flag). The result is deep-frozen. Anything structurally unusable throws a\n * {@link TerminologyError} carrying {@link FATAL_CODES.TERM_VALUESET_MALFORMED}.\n *\n * @param json - The untrusted resource (typically `JSON.parse` output — hence `unknown`).\n * @returns The immutable, validated {@link ValueSet}.\n * @throws {TerminologyError} `TERM_VALUESET_MALFORMED` when the resource is not a usable ValueSet.\n * @example\n * ```ts\n * import { loadValueSet } from \"@cosyte/terminology\";\n *\n * const vs = loadValueSet({\n * resourceType: \"ValueSet\",\n * url: \"http://example.org/vs/colors\",\n * compose: {\n * include: [{ system: \"http://example.org/cs\", concept: [{ code: \"red\" }, { code: \"green\" }] }],\n * },\n * });\n * vs.compose?.include.length; // => 1\n * ```\n */\nexport function loadValueSet(json: unknown): ValueSet {\n if (!isJsonObject(json)) malformed(\"\", \"resource is not a JSON object\");\n if (getString(json, \"resourceType\") !== \"ValueSet\") {\n malformed(\"\", \"resource is not a ValueSet (wrong or missing resourceType)\");\n }\n const out: Writable<ValueSet> = {};\n assignString(out, json, \"url\");\n assignString(out, json, \"version\");\n assignString(out, json, \"name\");\n if (json[\"compose\"] !== undefined) out.compose = loadCompose(json[\"compose\"], \"compose\");\n if (json[\"expansion\"] !== undefined)\n out.expansion = loadExpansion(json[\"expansion\"], \"expansion\");\n return Object.freeze(out);\n}\n","/**\n * Subsumption + `compose.include.filter` evaluation — the shared machinery {@link ./expand.expand}\n * and {@link ./validate.validateCodeInValueSet} both draw on.\n *\n * **Subsumption** is read from the loaded {@link CodeSystem}'s **`parent`** concept-properties\n * (`http://hl7.org/fhir/concept-properties#parent`) — which the FHIR loader synthesizes from a nested\n * `concept` hierarchy and carries verbatim from an explicit `parent` property. This is deliberately\n * the release's **own** hierarchy: subsumption across two separate releases is not computed, and a\n * code system that encodes no parent edges has no descendants beyond identity, which is treated as\n * complete — not guessed deeper.\n *\n * **Filter support is explicit.** `is-a` / `descendent-of` / `is-not-a` / `=` / `in` / `not-in` /\n * `exists` are implemented; `regex` / `generalizes` / anything unrecognized report `supported: false`\n * so the caller surfaces a typed {@link DIAGNOSTIC_CODES.TERM_VALUESET_CANNOT_EXPAND} rather than\n * silently mis-including or dropping codes.\n *\n * @packageDocumentation\n */\n\nimport type { CodeSystem, Concept } from \"../codesystem/types.js\";\nimport type { ConceptSetFilter, FilterOperator } from \"./types.js\";\n\n/** The `filter` operators the engine implements; anything else surfaces as cannot-expand. */\nconst SUPPORTED_OPS: ReadonlySet<FilterOperator> = new Set<FilterOperator>([\n \"=\",\n \"is-a\",\n \"descendent-of\",\n \"is-not-a\",\n \"in\",\n \"not-in\",\n \"exists\",\n]);\n\n/**\n * The filters whose operator the engine does **not** implement (`regex` / `generalizes` / unknown) —\n * a non-empty result means the caller must surface a typed cannot-expand, never mis-expand.\n *\n * @param filters - The component's filters.\n * @returns The subset with an unimplemented operator (empty when all are supported).\n * @example\n * ```ts\n * import { unsupportedOps } from \"@cosyte/terminology\";\n *\n * unsupportedOps([{ property: \"concept\", op: \"is-a\", value: \"x\" }]).length; // => 0\n * ```\n */\nexport function unsupportedOps(filters: readonly ConceptSetFilter[]): readonly ConceptSetFilter[] {\n return filters.filter((f) => !SUPPORTED_OPS.has(f.op));\n}\n\n/** An immutable ancestor index over a {@link CodeSystem}'s `parent` edges. */\nexport interface Subsumption {\n /** All (transitive) ancestor codes of `code`, cycle-safe. Excludes `code` itself. */\n ancestorsOf(code: string): ReadonlySet<string>;\n}\n\n/** Read the direct `parent` codes a concept declares (synthesized-from-nesting or verbatim). */\nfunction directParents(concept: Concept): string[] {\n const parents: string[] = [];\n for (const p of concept.properties) {\n if (p.code === \"parent\" && typeof p.value === \"string\") parents.push(p.value);\n }\n return parents;\n}\n\n/**\n * Build a cycle-safe ancestor index from a loaded {@link CodeSystem}'s `parent` concept-properties.\n *\n * @param cs - The loaded code system.\n * @returns A {@link Subsumption} answering transitive-ancestor queries.\n * @example\n * ```ts\n * import { loadCodeSystem, buildSubsumption } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"p\", concept: [{ code: \"c\" }] }] },\n * });\n * buildSubsumption(cs).ancestorsOf(\"c\").has(\"p\"); // => true\n * ```\n */\nexport function buildSubsumption(cs: CodeSystem): Subsumption {\n const parentsOf = new Map<string, readonly string[]>();\n for (const concept of cs.concepts.values()) {\n const parents = directParents(concept);\n if (parents.length > 0) parentsOf.set(concept.code, parents);\n }\n const cache = new Map<string, ReadonlySet<string>>();\n const ancestorsOf = (code: string): ReadonlySet<string> => {\n const cached = cache.get(code);\n if (cached !== undefined) return cached;\n const acc = new Set<string>();\n const stack = [...(parentsOf.get(code) ?? [])];\n while (stack.length > 0) {\n const next = stack.pop();\n if (next === undefined || acc.has(next) || next === code) continue;\n acc.add(next);\n for (const p of parentsOf.get(next) ?? []) stack.push(p);\n }\n cache.set(code, acc);\n return acc;\n };\n return { ancestorsOf };\n}\n\n/**\n * True when `code` is-a `anchor` — the same code, or a (transitive) descendant of it.\n *\n * @param sub - The subsumption index (from {@link buildSubsumption}).\n * @param code - The candidate code.\n * @param anchor - The ancestor code to test against.\n * @returns Whether `code` is `anchor` or a descendant of it.\n * @example\n * ```ts\n * import { loadCodeSystem, buildSubsumption, isA } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"p\", concept: [{ code: \"c\" }] }] },\n * });\n * isA(buildSubsumption(cs), \"c\", \"p\"); // => true\n * ```\n */\nexport function isA(sub: Subsumption, code: string, anchor: string): boolean {\n return code === anchor || sub.ancestorsOf(code).has(anchor);\n}\n\n/** Split a `,`-separated filter value (`in`/`not-in`) into a trimmed, non-empty token set. */\nfunction valueSet(value: string): ReadonlySet<string> {\n return new Set(\n value\n .split(\",\")\n .map((v) => v.trim())\n .filter((v) => v.length > 0),\n );\n}\n\n/** Read a concept's first property value for `property`, as a string, or `undefined`. */\nfunction propertyValue(concept: Concept, property: string): string | undefined {\n for (const p of concept.properties) {\n if (p.code === property) return typeof p.value === \"string\" ? p.value : String(p.value);\n }\n return undefined;\n}\n\n/** The outcome of evaluating a single filter against a single concept. */\nexport interface FilterMatch {\n /** Whether the concept satisfies the filter (meaningful only when {@link supported}). */\n readonly matched: boolean;\n /** Whether the engine implements this filter operator; `false` ⇒ the caller must surface it. */\n readonly supported: boolean;\n}\n\nconst UNSUPPORTED: FilterMatch = Object.freeze({ matched: false, supported: false });\n\n/**\n * Evaluate one {@link ConceptSetFilter} against one {@link Concept}, using the release's hierarchy.\n *\n * The `concept` filter property (and the hierarchy operators regardless of property) reads the code\n * itself / its subsumption; other properties read the concept's `property` values. An unimplemented\n * operator returns `{ supported: false }` — never a coerced `matched`.\n *\n * @param concept - The concept under test.\n * @param filter - The filter predicate.\n * @param sub - The subsumption index for the concept's code system.\n * @returns A {@link FilterMatch}.\n * @example\n * ```ts\n * import { loadCodeSystem, buildSubsumption, matchesFilter } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"p\", concept: [{ code: \"c\" }] }] },\n * });\n * const dog = cs.concepts.get(\"c\");\n * dog && matchesFilter(dog, { property: \"concept\", op: \"is-a\", value: \"p\" }, buildSubsumption(cs)).matched; // => true\n * ```\n */\nexport function matchesFilter(\n concept: Concept,\n filter: ConceptSetFilter,\n sub: Subsumption,\n): FilterMatch {\n const onCode = filter.property === \"concept\";\n switch (filter.op) {\n case \"is-a\":\n return { matched: isA(sub, concept.code, filter.value), supported: true };\n case \"descendent-of\":\n // Strict: descendants only, excluding the anchor itself.\n return {\n matched: concept.code !== filter.value && sub.ancestorsOf(concept.code).has(filter.value),\n supported: true,\n };\n case \"is-not-a\":\n return { matched: !isA(sub, concept.code, filter.value), supported: true };\n case \"=\": {\n const actual = onCode ? concept.code : propertyValue(concept, filter.property);\n return { matched: actual === filter.value, supported: true };\n }\n case \"in\": {\n const set = valueSet(filter.value);\n const actual = onCode ? concept.code : propertyValue(concept, filter.property);\n return { matched: actual !== undefined && set.has(actual), supported: true };\n }\n case \"not-in\": {\n const set = valueSet(filter.value);\n const actual = onCode ? concept.code : propertyValue(concept, filter.property);\n // A concept the property is absent on is not \"in\" the set, hence \"not-in\" is true.\n return { matched: actual === undefined || !set.has(actual), supported: true };\n }\n case \"exists\": {\n const present = onCode ? true : propertyValue(concept, filter.property) !== undefined;\n const wantPresent = filter.value.trim().toLowerCase() === \"true\";\n return { matched: present === wantPresent, supported: true };\n }\n case \"regex\":\n case \"generalizes\":\n default:\n // Not implemented (or an unrecognized runtime operator) — surfaced, never mis-expanded.\n return UNSUPPORTED;\n }\n}\n\n/**\n * Evaluate every filter in a component against one concept: does it satisfy **all** of them, and were\n * they **all** supported? An unsupported operator short-circuits `supported: false`.\n *\n * @param concept - The concept under test.\n * @param filters - The component's filters (ANDed).\n * @param sub - The subsumption index.\n * @returns A {@link FilterMatch} over the conjunction.\n * @example\n * ```ts\n * import { loadCodeSystem, buildSubsumption, matchesAllFilters } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"c\" }] },\n * });\n * const c = cs.concepts.get(\"c\");\n * c && matchesAllFilters(c, [{ property: \"concept\", op: \"=\", value: \"c\" }], buildSubsumption(cs)).matched; // => true\n * ```\n */\nexport function matchesAllFilters(\n concept: Concept,\n filters: readonly ConceptSetFilter[],\n sub: Subsumption,\n): FilterMatch {\n let matched = true;\n for (const f of filters) {\n const r = matchesFilter(concept, f, sub);\n if (!r.supported) return UNSUPPORTED;\n if (!r.matched) matched = false;\n }\n return { matched, supported: true };\n}\n","/**\n * {@link expand} — the FHIR R4 ValueSet `$expand` operation over a loaded {@link ValueSet}.\n *\n * Grounded firsthand on FHIR R4 (`https://hl7.org/fhir/R4/valueset-operation-expand.html`,\n * `https://hl7.org/fhir/R4/valueset.html#compose`):\n *\n * - A **pre-computed** `expansion` is used as-is (extensional), and its completeness is checked — a\n * truncated snapshot is flagged, never treated as full membership.\n * - An intensional `compose` is expanded over **consumer-supplied** {@link ../codesystem/types.CodeSystem}\n * releases: the union of `include` components minus the union of `exclude` components. Each component\n * selects by explicit `concept`, by `filter` (subsumption + property predicates), by the whole\n * `system`, and/or by intersecting referenced value sets.\n *\n * **Never fabricate.** A part that cannot be computed — a missing code system, an unresolved\n * referenced value set, an unimplemented `filter` operator — yields a typed\n * {@link ../common/diagnostics.DIAGNOSTIC_CODES.TERM_VALUESET_CANNOT_EXPAND} and marks the result\n * `complete: false`, so the `contains` set is an explicit **lower bound**, never a silently-empty or\n * fabricated membership.\n *\n * @packageDocumentation\n */\n\nimport { coding, type Coding } from \"../common/coding.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { buildSubsumption, matchesAllFilters, unsupportedOps } from \"./filters.js\";\nimport type {\n ConceptSetComponent,\n ExpandResult,\n ExpansionContext,\n ExpansionDiagnostic,\n ValueSet,\n} from \"./types.js\";\n\n/** The stable identity of a coding for set operations — `system` + `code` (version is a refinement). */\nfunction codingKey(system: string | undefined, code: string): string {\n return `${system ?? \"\"}\\u001f${code}`;\n}\n\n/** Build a frozen {@link Coding} from a value set's parts, dropping absent optionals. */\nfunction makeCoding(\n system: string | undefined,\n code: string,\n display?: string,\n version?: string,\n): Coding {\n const init: Writable<Coding> = { code };\n if (system !== undefined) init.system = system;\n if (version !== undefined) init.version = version;\n if (display !== undefined) init.display = display;\n return coding(init);\n}\n\nfunction cannotExpand(detail: string, path?: string): ExpansionDiagnostic {\n const d: Writable<ExpansionDiagnostic> = { code: \"TERM_VALUESET_CANNOT_EXPAND\", detail };\n if (path !== undefined) d.path = path;\n return Object.freeze(d);\n}\n\nfunction truncated(detail: string, path?: string): ExpansionDiagnostic {\n const d: Writable<ExpansionDiagnostic> = { code: \"TERM_VALUESET_EXPANSION_TRUNCATED\", detail };\n if (path !== undefined) d.path = path;\n return Object.freeze(d);\n}\n\n/**\n * Re-root a diagnostic raised inside a *referenced* value set onto the reference that reached it, so\n * a nested `compose.include[3]` is still navigable from the caller's own resource. Value-free: both\n * halves are index paths this module built.\n */\nfunction underPath(d: ExpansionDiagnostic, prefix: string): ExpansionDiagnostic {\n const out: Writable<ExpansionDiagnostic> = { code: d.code, detail: d.detail };\n out.path = d.path === undefined ? prefix : `${prefix}/${d.path}`;\n return Object.freeze(out);\n}\n\n/** The internal result of expanding a single `include`/`exclude` component: a keyed member map. */\ninterface ComponentExpansion {\n readonly members: Map<string, Coding>;\n readonly complete: boolean;\n readonly diagnostics: readonly ExpansionDiagnostic[];\n}\n\n/** Intersect `into` down to the keys also present in `other` (mutates and returns `into`). */\nfunction intersectInto(into: Map<string, Coding>, other: Map<string, Coding>): Map<string, Coding> {\n for (const k of into.keys()) if (!other.has(k)) into.delete(k);\n return into;\n}\n\n/** Expand every referenced value set and intersect their memberships (a code must be in all). */\nfunction expandReferencedValueSets(\n urls: readonly string[],\n ctx: ExpansionContext,\n visited: ReadonlySet<string>,\n path: string,\n): ComponentExpansion {\n const diagnostics: ExpansionDiagnostic[] = [];\n let complete = true;\n let acc: Map<string, Coding> | null = null;\n for (const [i, url] of urls.entries()) {\n const refPath = `${path}.valueSet[${String(i)}]`;\n if (visited.has(url)) {\n diagnostics.push(cannotExpand(\"cyclic value set reference\", refPath));\n complete = false;\n acc = new Map();\n continue;\n }\n const vs = ctx.valueSets?.get(url);\n if (vs === undefined) {\n diagnostics.push(cannotExpand(\"referenced value set not supplied\", refPath));\n complete = false;\n acc = new Map();\n continue;\n }\n const exp = expandInternal(vs, ctx, new Set([...visited, url]));\n if (!exp.complete) complete = false;\n for (const d of exp.diagnostics) diagnostics.push(underPath(d, refPath));\n const members = new Map<string, Coding>();\n for (const c of exp.contains) members.set(codingKey(c.system, c.code), c);\n acc = acc === null ? members : intersectInto(acc, members);\n }\n return { members: acc ?? new Map<string, Coding>(), complete, diagnostics };\n}\n\n/** Expand one `include`/`exclude` component into a keyed member map. */\nfunction expandComponent(\n component: ConceptSetComponent,\n ctx: ExpansionContext,\n visited: ReadonlySet<string>,\n path: string,\n): ComponentExpansion {\n const diagnostics: ExpansionDiagnostic[] = [];\n let complete = true;\n const { system, version, concept, filter, valueSet } = component;\n // A present `concept` (even empty) is an **enumeration** — never re-read as a whole-system include;\n // \"all of system\" is only the concept-absent, filter-absent case (FHIR ValueSet.compose semantics).\n const hasConcept = concept !== undefined;\n const hasFilter = filter !== undefined && filter.length > 0;\n const hasVs = valueSet !== undefined && valueSet.length > 0;\n\n let base: Map<string, Coding> | null = null;\n\n if (hasConcept) {\n // Extensional: enumerated codes are always fully computable.\n base = new Map();\n for (const c of concept) {\n base.set(codingKey(system, c.code), makeCoding(system, c.code, c.display, version));\n }\n } else if (hasFilter || (system !== undefined && !hasVs)) {\n // Intensional filter, or a whole-system include — both need the loaded code system.\n if (system === undefined) {\n diagnostics.push(cannotExpand(\"intensional filter without a code system 'system'\", path));\n return { members: new Map(), complete: false, diagnostics };\n }\n const cs = ctx.codeSystems?.get(system);\n if (cs === undefined) {\n diagnostics.push(cannotExpand(\"code system not supplied for intensional include\", path));\n return { members: new Map(), complete: false, diagnostics };\n }\n if (hasFilter) {\n const unsupported = unsupportedOps(filter);\n if (unsupported.length > 0) {\n diagnostics.push(cannotExpand(\"unsupported filter operator\", path));\n return { members: new Map(), complete: false, diagnostics };\n }\n const sub = buildSubsumption(cs);\n base = new Map();\n for (const concpt of cs.concepts.values()) {\n if (matchesAllFilters(concpt, filter, sub).matched) {\n base.set(\n codingKey(system, concpt.code),\n makeCoding(system, concpt.code, concpt.display, version),\n );\n }\n }\n } else {\n base = new Map();\n for (const concpt of cs.concepts.values()) {\n base.set(\n codingKey(system, concpt.code),\n makeCoding(system, concpt.code, concpt.display, version),\n );\n }\n }\n }\n\n if (hasVs) {\n const refs = expandReferencedValueSets(valueSet, ctx, visited, path);\n for (const d of refs.diagnostics) diagnostics.push(d);\n if (!refs.complete) complete = false;\n base = base === null ? refs.members : intersectInto(base, refs.members);\n // A component that names a `system` alongside a `valueSet` (with no `concept`/`filter` base) is\n // an **intersection**: keep only referenced-value-set members drawn from that system. Without this\n // the system scope is silently dropped and a cross-system code is fabricated into membership\n // (FHIR R4 ValueSet.compose.include combines system + valueSet by intersection). For the\n // concept/filter/whole-system branches every member already carries `system`, so this is a no-op.\n if (system !== undefined) {\n for (const [k, c] of [...base]) if (c.system !== system) base.delete(k);\n }\n }\n\n // A component that selects nothing (no system, concept, filter, or valueSet) adds no members.\n return { members: base ?? new Map<string, Coding>(), complete, diagnostics };\n}\n\n/** Expand a compose, or pass through a pre-computed expansion, with a cycle-visited set. */\nfunction expandInternal(\n vs: ValueSet,\n ctx: ExpansionContext,\n visited: ReadonlySet<string>,\n): ExpandResult {\n if (vs.expansion !== undefined) {\n const seen = new Set<string>();\n const contains: Coding[] = [];\n for (const c of vs.expansion.contains) {\n const key = codingKey(c.system, c.code);\n if (seen.has(key)) continue;\n seen.add(key);\n contains.push(makeCoding(c.system, c.code, c.display, c.version));\n }\n const diagnostics: ExpansionDiagnostic[] = [];\n let complete = true;\n if (vs.expansion.truncated) {\n complete = false;\n diagnostics.push(\n truncated(\"pre-computed expansion is incomplete (truncated or too-costly)\", \"expansion\"),\n );\n }\n const out: Writable<ExpandResult> = {\n complete,\n contains: Object.freeze(contains),\n diagnostics: Object.freeze(diagnostics),\n };\n if (vs.expansion.total !== undefined) out.total = vs.expansion.total;\n return Object.freeze(out);\n }\n\n if (vs.compose !== undefined) {\n const included = new Map<string, Coding>();\n const diagnostics: ExpansionDiagnostic[] = [];\n let complete = true;\n for (const [i, inc] of vs.compose.include.entries()) {\n const r = expandComponent(inc, ctx, visited, `compose.include[${String(i)}]`);\n if (!r.complete) complete = false;\n for (const d of r.diagnostics) diagnostics.push(d);\n for (const [k, c] of r.members) if (!included.has(k)) included.set(k, c);\n }\n for (const [i, exc] of vs.compose.exclude.entries()) {\n const r = expandComponent(exc, ctx, visited, `compose.exclude[${String(i)}]`);\n for (const d of r.diagnostics) diagnostics.push(d);\n // Remove the members we could prove are excluded.\n for (const k of r.members.keys()) included.delete(k);\n if (!r.complete) {\n complete = false;\n // An exclude we could not fully compute may exclude MORE than we proved. To keep `contains` a\n // true LOWER bound (never retain a possible non-member), drop every remaining member the\n // exclude could still match — a member in the exclude's system (or all members when the\n // exclude names no system). A dropped genuine member is fine for a lower bound; a retained\n // excluded one would be a fabricated membership (the never-fabricate contract).\n for (const [k, c] of [...included]) {\n if (exc.system === undefined || c.system === exc.system) included.delete(k);\n }\n }\n }\n return Object.freeze({\n complete,\n contains: Object.freeze([...included.values()]),\n diagnostics: Object.freeze(diagnostics),\n });\n }\n\n // A value set with neither compose nor expansion has an empty, complete membership.\n return Object.freeze({\n complete: true,\n contains: Object.freeze([]),\n diagnostics: Object.freeze([]),\n });\n}\n\n/**\n * `$expand`: compute the flattened membership of a {@link ValueSet} over the supplied code systems.\n *\n * @param vs - The loaded value set.\n * @param ctx - The loaded code systems / referenced value sets the intensional parts resolve against.\n * @returns An {@link ExpandResult} — the `contains` members plus an honest `complete` flag. When\n * `complete` is `false`, `contains` is a lower bound (never treat it as exhaustive membership).\n * @example\n * ```ts\n * import { loadValueSet, loadCodeSystem, expand } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: {\n * resourceType: \"CodeSystem\",\n * url: \"http://example.org/cs\",\n * concept: [{ code: \"a\" }, { code: \"b\" }, { code: \"c\" }],\n * },\n * });\n * const vs = loadValueSet({\n * resourceType: \"ValueSet\",\n * compose: { include: [{ system: \"http://example.org/cs\", concept: [{ code: \"a\" }, { code: \"b\" }] }] },\n * });\n * const result = expand(vs, { codeSystems: new Map([[\"http://example.org/cs\", cs]]) });\n * result.complete; // => true\n * result.contains.length; // => 2\n * ```\n */\nexport function expand(vs: ValueSet, ctx: ExpansionContext = {}): ExpandResult {\n return expandInternal(vs, ctx, new Set(vs.url !== undefined ? [vs.url] : []));\n}\n","/**\n * {@link validateCodeInValueSet} — the FHIR R4 ValueSet `$validate-code` operation (value-set\n * binding): is a {@link Coding} a member of a {@link ValueSet}?\n *\n * Grounded firsthand on FHIR R4 (`https://hl7.org/fhir/R4/valueset-operation-validate-code.html`): a\n * binding decides whether a code is *allowed* in a slot. The engine returns a **decided** membership\n * (`result: true`/`false`) **only when it can prove it** — a code found in a computable `include` and\n * not removed by any computable `exclude` is a definite member; a code absent from a fully-evaluated\n * value set is a definite non-member. When any relevant part cannot be evaluated (a missing code\n * system, a truncated pre-computed expansion, an unimplemented `filter`), the answer is a typed\n * {@link ValueSetMemberUndetermined} — **never** a fabricated `false` (a false \"not a member\" is a\n * clinical error).\n *\n * @packageDocumentation\n */\n\nimport type { Coding } from \"../common/coding.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { buildSubsumption, matchesAllFilters, unsupportedOps } from \"./filters.js\";\nimport type {\n ConceptSetComponent,\n ExpansionContext,\n ExpansionDiagnostic,\n ValueSet,\n ValueSetMembership,\n} from \"./types.js\";\n\nfunction cannotExpand(detail: string, path?: string): ExpansionDiagnostic {\n const d: Writable<ExpansionDiagnostic> = { code: \"TERM_VALUESET_CANNOT_EXPAND\", detail };\n if (path !== undefined) d.path = path;\n return Object.freeze(d);\n}\n\n/**\n * Re-root a diagnostic raised inside a *referenced* value set onto the reference that reached it.\n *\n * The **path format and its construction** are shared with `expand` (index paths over `compose`,\n * `/`-joined across a reference). The **sets of diagnostics are not**, and must not be read as\n * identical: membership short-circuits where expansion cannot. A component whose target system\n * differs is a definite non-match here before any diagnostic is raised, an unresolvable `exclude`\n * that cannot change a decided verdict yields nothing here while expansion still reports it, and\n * expansion returns early from a component that names both an unusable `system` and a `valueSet`\n * where membership goes on to evaluate the reference. Same vocabulary, different question.\n */\nfunction underPath(d: ExpansionDiagnostic, prefix: string): ExpansionDiagnostic {\n const out: Writable<ExpansionDiagnostic> = { code: d.code, detail: d.detail };\n out.path = d.path === undefined ? prefix : `${prefix}/${d.path}`;\n return Object.freeze(out);\n}\n\n/** Whether a single `include`/`exclude` component matches `target`, and whether that is decidable. */\ninterface ComponentMatch {\n /** The match verdict — meaningful only when {@link complete}. */\n readonly matched: boolean;\n /** Whether the verdict is trustworthy (both a match and a non-match were fully evaluated). */\n readonly complete: boolean;\n readonly diagnostics: readonly ExpansionDiagnostic[];\n}\n\nfunction matchComponent(\n target: Coding,\n component: ConceptSetComponent,\n ctx: ExpansionContext,\n visited: ReadonlySet<string>,\n path: string,\n): ComponentMatch {\n const diagnostics: ExpansionDiagnostic[] = [];\n const { system, concept, filter, valueSet } = component;\n // A present `concept` (even empty) is an enumeration; \"all of system\" is the concept/filter-absent\n // case only — mirrors expandComponent so membership and expansion agree.\n const hasConcept = concept !== undefined;\n const hasFilter = filter !== undefined && filter.length > 0;\n const hasVs = valueSet !== undefined && valueSet.length > 0;\n\n // ── base (concept / filter / whole-system) ──\n let baseMatched: boolean | null = null; // null ⇒ no base constraint\n let baseComplete = true;\n\n if (system !== undefined && target.system !== undefined && system !== target.system) {\n // The component's concept/filter selection is scoped to `system`; a different target system is a\n // definite non-match on the base.\n baseMatched = false;\n } else if (hasConcept) {\n baseMatched = concept.some((c) => c.code === target.code);\n } else if (hasFilter || (system !== undefined && !hasVs)) {\n if (system === undefined) {\n diagnostics.push(cannotExpand(\"intensional filter without a code system 'system'\", path));\n baseMatched = false;\n baseComplete = false;\n } else {\n const cs = ctx.codeSystems?.get(system);\n if (cs === undefined) {\n diagnostics.push(cannotExpand(\"code system not supplied for intensional include\", path));\n baseMatched = false;\n baseComplete = false;\n } else if (hasFilter) {\n if (unsupportedOps(filter).length > 0) {\n diagnostics.push(cannotExpand(\"unsupported filter operator\", path));\n baseMatched = false;\n baseComplete = false;\n } else {\n const concpt = cs.concepts.get(target.code);\n // A code absent from the system is a definite non-member of any filter over it.\n baseMatched =\n concpt !== undefined && matchesAllFilters(concpt, filter, buildSubsumption(cs)).matched;\n }\n } else {\n baseMatched = cs.concepts.get(target.code) !== undefined;\n }\n }\n }\n\n // ── referenced value sets (intersection: member of every one) ──\n let refDefiniteFalse = false;\n let refUndetermined = false;\n if (hasVs) {\n for (const [i, url] of valueSet.entries()) {\n const refPath = `${path}.valueSet[${String(i)}]`;\n if (visited.has(url)) {\n diagnostics.push(cannotExpand(\"cyclic value set reference\", refPath));\n refUndetermined = true;\n continue;\n }\n const vs = ctx.valueSets?.get(url);\n if (vs === undefined) {\n diagnostics.push(cannotExpand(\"referenced value set not supplied\", refPath));\n refUndetermined = true;\n continue;\n }\n const m = validateInternal(target, vs, ctx, new Set([...visited, url]));\n if (m.undetermined) {\n for (const d of m.diagnostics) diagnostics.push(underPath(d, refPath));\n refUndetermined = true;\n } else if (!m.result) {\n refDefiniteFalse = true;\n }\n }\n }\n\n // ── combine base ∩ refs ──\n const baseDefiniteFalse = baseMatched === false && baseComplete;\n const baseDefiniteTrue = baseMatched === null || (baseMatched === true && baseComplete);\n const refDefiniteTrue = !hasVs || (!refDefiniteFalse && !refUndetermined);\n\n if (baseDefiniteFalse || refDefiniteFalse) {\n return { matched: false, complete: true, diagnostics };\n }\n if (baseDefiniteTrue && refDefiniteTrue) {\n return { matched: true, complete: true, diagnostics };\n }\n return { matched: false, complete: false, diagnostics };\n}\n\nfunction decided(result: boolean, coding: Coding): ValueSetMembership {\n return Object.freeze({ undetermined: false, result, coding });\n}\n\nfunction undetermined(\n coding: Coding,\n diagnostics: readonly ExpansionDiagnostic[],\n): ValueSetMembership {\n return Object.freeze({\n undetermined: true,\n code: \"TERM_VALUESET_CANNOT_EXPAND\",\n coding,\n diagnostics: Object.freeze([...diagnostics]),\n });\n}\n\nfunction validateInternal(\n target: Coding,\n vs: ValueSet,\n ctx: ExpansionContext,\n visited: ReadonlySet<string>,\n): ValueSetMembership {\n if (vs.expansion !== undefined) {\n const found = vs.expansion.contains.some(\n (c) =>\n c.code === target.code &&\n (c.system === undefined || target.system === undefined || c.system === target.system),\n );\n if (found) return decided(true, target);\n if (vs.expansion.truncated) {\n return undetermined(target, [\n cannotExpand(\"pre-computed expansion is incomplete (truncated or too-costly)\", \"expansion\"),\n ]);\n }\n return decided(false, target);\n }\n\n if (vs.compose !== undefined) {\n const diagnostics: ExpansionDiagnostic[] = [];\n let includedDefinite = false;\n let anyIncludeUndetermined = false;\n for (const [i, inc] of vs.compose.include.entries()) {\n const m = matchComponent(target, inc, ctx, visited, `compose.include[${String(i)}]`);\n for (const d of m.diagnostics) diagnostics.push(d);\n if (m.complete && m.matched) includedDefinite = true;\n if (!m.complete) anyIncludeUndetermined = true;\n }\n let excludedDefinite = false;\n let anyExcludeUndetermined = false;\n for (const [i, exc] of vs.compose.exclude.entries()) {\n const m = matchComponent(target, exc, ctx, visited, `compose.exclude[${String(i)}]`);\n for (const d of m.diagnostics) diagnostics.push(d);\n if (m.complete && m.matched) excludedDefinite = true;\n if (!m.complete) anyExcludeUndetermined = true;\n }\n\n if (excludedDefinite) return decided(false, target);\n if (includedDefinite && !anyExcludeUndetermined) return decided(true, target);\n if (!includedDefinite && !anyIncludeUndetermined && !anyExcludeUndetermined) {\n return decided(false, target);\n }\n return undetermined(target, diagnostics);\n }\n\n // Neither compose nor expansion ⇒ an empty value set ⇒ nothing is a member (definite).\n return decided(false, target);\n}\n\n/**\n * `$validate-code` (ValueSet): is `coding` a member of `valueSet`?\n *\n * @param coding - The code to test (system + code).\n * @param valueSet - The loaded value set.\n * @param ctx - The loaded code systems / referenced value sets the intensional parts resolve against.\n * @returns A decided {@link ValueSetMembership} (`result: true`/`false`), or a typed\n * {@link ValueSetMemberUndetermined} when membership could not be proven — never a fabricated `false`.\n * @example\n * ```ts\n * import { loadValueSet, validateCodeInValueSet } from \"@cosyte/terminology\";\n *\n * const vs = loadValueSet({\n * resourceType: \"ValueSet\",\n * compose: { include: [{ system: \"http://example.org/cs\", concept: [{ code: \"a\" }, { code: \"b\" }] }] },\n * });\n * const r = validateCodeInValueSet({ system: \"http://example.org/cs\", code: \"a\" }, vs);\n * r.undetermined === false && r.result; // => true\n * ```\n */\nexport function validateCodeInValueSet(\n coding: Coding,\n valueSet: ValueSet,\n ctx: ExpansionContext = {},\n): ValueSetMembership {\n return validateInternal(\n coding,\n valueSet,\n ctx,\n new Set(valueSet.url !== undefined ? [valueSet.url] : []),\n );\n}\n","/**\n * The **verbatim, unmodified** UCUM unit table (`ucum-essence.xml`), embedded as a string.\n *\n * GENERATED by `scripts/generate-ucum-essence-data.ts` from `vendor/ucum/ucum-essence.xml` —\n * **do not edit by hand**. The content is UCUM's, reproduced byte-for-byte; only the string wrapper\n * is added. Regenerate with `pnpm gen:ucum`.\n *\n * The Unified Code for Units of Measure (UCUM) is copyright ©1999–2024, Regenstrief Institute, Inc.\n * All rights reserved. Reproduced under the UCUM Copyright Notice and License\n * (https://ucum.org/license); this copy is unmodified. Provided \"as is\" without warranty of any\n * kind. See `vendor/ucum/NOTICE.md`.\n *\n * @packageDocumentation\n */\n\n// prettier-ignore\n/**\n * The verbatim UCUM `ucum-essence.xml` v2.2 (revision-date 2024-06-17). Parsed lazily by\n * {@link ../ucum/essence.loadUcumEssence} into the engine's in-memory unit table.\n */\nexport const UCUM_ESSENCE_XML: string = `<?xml version=\"1.0\" encoding=\"ascii\"?>\n<root xmlns=\"http://unitsofmeasure.org/ucum-essence\" version=\"2.2\" revision=\"N/A\"\n revision-date=\"2024-06-17\">\n <prefix Code=\"Y\" CODE=\"YA\">\n <name>yotta</name>\n <printSymbol>Y</printSymbol>\n <value value=\"1e24\">1 &#215; 10<sup>24</sup>\n </value>\n </prefix>\n <prefix Code=\"Z\" CODE=\"ZA\">\n <name>zetta</name>\n <printSymbol>Z</printSymbol>\n <value value=\"1e21\">1 &#215; 10<sup>21</sup>\n </value>\n </prefix>\n <prefix Code=\"E\" CODE=\"EX\">\n <name>exa</name>\n <printSymbol>E</printSymbol>\n <value value=\"1e18\">1 &#215; 10<sup>18</sup>\n </value>\n </prefix>\n <prefix Code=\"P\" CODE=\"PT\">\n <name>peta</name>\n <printSymbol>P</printSymbol>\n <value value=\"1e15\">1 &#215; 10<sup>15</sup>\n </value>\n </prefix>\n <prefix Code=\"T\" CODE=\"TR\">\n <name>tera</name>\n <printSymbol>T</printSymbol>\n <value value=\"1e12\">1 &#215; 10<sup>12</sup>\n </value>\n </prefix>\n <prefix Code=\"G\" CODE=\"GA\">\n <name>giga</name>\n <printSymbol>G</printSymbol>\n <value value=\"1e9\">1 &#215; 10<sup>9</sup>\n </value>\n </prefix>\n <prefix Code=\"M\" CODE=\"MA\">\n <name>mega</name>\n <printSymbol>M</printSymbol>\n <value value=\"1e6\">1 &#215; 10<sup>6</sup>\n </value>\n </prefix>\n <prefix Code=\"k\" CODE=\"K\">\n <name>kilo</name>\n <printSymbol>k</printSymbol>\n <value value=\"1e3\">1 &#215; 10<sup>3</sup>\n </value>\n </prefix>\n <prefix Code=\"h\" CODE=\"H\">\n <name>hecto</name>\n <printSymbol>h</printSymbol>\n <value value=\"1e2\">1 &#215; 10<sup>2</sup>\n </value>\n </prefix>\n <prefix Code=\"da\" CODE=\"DA\">\n <name>deka</name>\n <printSymbol>da</printSymbol>\n <value value=\"1e1\">1 &#215; 10<sup>1</sup>\n </value>\n </prefix>\n <prefix Code=\"d\" CODE=\"D\">\n <name>deci</name>\n <printSymbol>d</printSymbol>\n <value value=\"1e-1\">1 &#215; 10<sup>-1</sup>\n </value>\n </prefix>\n <prefix Code=\"c\" CODE=\"C\">\n <name>centi</name>\n <printSymbol>c</printSymbol>\n <value value=\"1e-2\">1 &#215; 10<sup>-2</sup>\n </value>\n </prefix>\n <prefix Code=\"m\" CODE=\"M\">\n <name>milli</name>\n <printSymbol>m</printSymbol>\n <value value=\"1e-3\">1 &#215; 10<sup>-3</sup>\n </value>\n </prefix>\n <prefix Code=\"u\" CODE=\"U\">\n <name>micro</name>\n <printSymbol>&#956;</printSymbol>\n <value value=\"1e-6\">1 &#215; 10<sup>-6</sup>\n </value>\n </prefix>\n <prefix Code=\"n\" CODE=\"N\">\n <name>nano</name>\n <printSymbol>n</printSymbol>\n <value value=\"1e-9\">1 &#215; 10<sup>-9</sup>\n </value>\n </prefix>\n <prefix Code=\"p\" CODE=\"P\">\n <name>pico</name>\n <printSymbol>p</printSymbol>\n <value value=\"1e-12\">1 &#215; 10<sup>-12</sup>\n </value>\n </prefix>\n <prefix Code=\"f\" CODE=\"F\">\n <name>femto</name>\n <printSymbol>f</printSymbol>\n <value value=\"1e-15\">1 &#215; 10<sup>-15</sup>\n </value>\n </prefix>\n <prefix Code=\"a\" CODE=\"A\">\n <name>atto</name>\n <printSymbol>a</printSymbol>\n <value value=\"1e-18\">1 &#215; 10<sup>-18</sup>\n </value>\n </prefix>\n <prefix Code=\"z\" CODE=\"ZO\">\n <name>zepto</name>\n <printSymbol>z</printSymbol>\n <value value=\"1e-21\">1 &#215; 10<sup>-21</sup>\n </value>\n </prefix>\n <prefix Code=\"y\" CODE=\"YO\">\n <name>yocto</name>\n <printSymbol>y</printSymbol>\n <value value=\"1e-24\">1 &#215; 10<sup>-24</sup>\n </value>\n </prefix>\n <base-unit Code=\"m\" CODE=\"M\" dim=\"L\">\n <name>meter</name>\n <printSymbol>m</printSymbol>\n <property>length</property>\n </base-unit>\n <base-unit Code=\"s\" CODE=\"S\" dim=\"T\">\n <name>second</name>\n <printSymbol>s</printSymbol>\n <property>time</property>\n </base-unit>\n <base-unit Code=\"g\" CODE=\"G\" dim=\"M\">\n <name>gram</name>\n <printSymbol>g</printSymbol>\n <property>mass</property>\n </base-unit>\n <base-unit Code=\"rad\" CODE=\"RAD\" dim=\"A\">\n <name>radian</name>\n <printSymbol>rad</printSymbol>\n <property>plane angle</property>\n </base-unit>\n <base-unit Code=\"K\" CODE=\"K\" dim=\"C\">\n <name>kelvin</name>\n <printSymbol>K</printSymbol>\n <property>temperature</property>\n </base-unit>\n <base-unit Code=\"C\" CODE=\"C\" dim=\"Q\">\n <name>coulomb</name>\n <printSymbol>C</printSymbol>\n <property>electric charge</property>\n </base-unit>\n <base-unit Code=\"cd\" CODE=\"CD\" dim=\"F\">\n <name>candela</name>\n <printSymbol>cd</printSymbol>\n <property>luminous intensity</property>\n </base-unit>\n <unit Code=\"10*\" CODE=\"10*\" isMetric=\"no\" class=\"dimless\">\n <name>the number ten for arbitrary powers</name>\n <printSymbol>10</printSymbol>\n <property>number</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"10\">10</value>\n </unit>\n <unit Code=\"10^\" CODE=\"10^\" isMetric=\"no\" class=\"dimless\">\n <name>the number ten for arbitrary powers</name>\n <printSymbol>10</printSymbol>\n <property>number</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"10\">10</value>\n </unit>\n <unit Code=\"[pi]\" CODE=\"[PI]\" isMetric=\"no\" class=\"dimless\">\n <name>the number pi</name>\n <printSymbol>&#960;</printSymbol>\n <property>number</property>\n <value Unit=\"1\" UNIT=\"1\"\n value=\"3.1415926535897932384626433832795028841971693993751058209749445923\">&#960;</value>\n </unit>\n <unit Code=\"%\" CODE=\"%\" isMetric=\"no\" class=\"dimless\">\n <name>percent</name>\n <printSymbol>%</printSymbol>\n <property>fraction</property>\n <value Unit=\"10*-2\" UNIT=\"10*-2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ppth]\" CODE=\"[PPTH]\" isMetric=\"no\" class=\"dimless\">\n <name>parts per thousand</name>\n <printSymbol>ppth</printSymbol>\n <property>fraction</property>\n <value Unit=\"10*-3\" UNIT=\"10*-3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ppm]\" CODE=\"[PPM]\" isMetric=\"no\" class=\"dimless\">\n <name>parts per million</name>\n <printSymbol>ppm</printSymbol>\n <property>fraction</property>\n <value Unit=\"10*-6\" UNIT=\"10*-6\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ppb]\" CODE=\"[PPB]\" isMetric=\"no\" class=\"dimless\">\n <name>parts per billion</name>\n <printSymbol>ppb</printSymbol>\n <property>fraction</property>\n <value Unit=\"10*-9\" UNIT=\"10*-9\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pptr]\" CODE=\"[PPTR]\" isMetric=\"no\" class=\"dimless\">\n <name>parts per trillion</name>\n <printSymbol>pptr</printSymbol>\n <property>fraction</property>\n <value Unit=\"10*-12\" UNIT=\"10*-12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"mol\" CODE=\"MOL\" isMetric=\"yes\" class=\"si\">\n <name>mole</name>\n <printSymbol>mol</printSymbol>\n <property>amount of substance</property>\n <value Unit=\"10*23\" UNIT=\"10*23\" value=\"6.02214076\">6.02214076</value>\n </unit>\n <unit Code=\"sr\" CODE=\"SR\" isMetric=\"yes\" class=\"si\">\n <name>steradian</name>\n <printSymbol>sr</printSymbol>\n <property>solid angle</property>\n <value Unit=\"rad2\" UNIT=\"RAD2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Hz\" CODE=\"HZ\" isMetric=\"yes\" class=\"si\">\n <name>hertz</name>\n <printSymbol>Hz</printSymbol>\n <property>frequency</property>\n <value Unit=\"s-1\" UNIT=\"S-1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"N\" CODE=\"N\" isMetric=\"yes\" class=\"si\">\n <name>newton</name>\n <printSymbol>N</printSymbol>\n <property>force</property>\n <value Unit=\"kg.m/s2\" UNIT=\"KG.M/S2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Pa\" CODE=\"PAL\" isMetric=\"yes\" class=\"si\">\n <name>pascal</name>\n <printSymbol>Pa</printSymbol>\n <property>pressure</property>\n <value Unit=\"N/m2\" UNIT=\"N/M2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"J\" CODE=\"J\" isMetric=\"yes\" class=\"si\">\n <name>joule</name>\n <printSymbol>J</printSymbol>\n <property>energy</property>\n <value Unit=\"N.m\" UNIT=\"N.M\" value=\"1\">1</value>\n </unit>\n <unit Code=\"W\" CODE=\"W\" isMetric=\"yes\" class=\"si\">\n <name>watt</name>\n <printSymbol>W</printSymbol>\n <property>power</property>\n <value Unit=\"J/s\" UNIT=\"J/S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"A\" CODE=\"A\" isMetric=\"yes\" class=\"si\">\n <name>amp&#232;re</name>\n <printSymbol>A</printSymbol>\n <property>electric current</property>\n <value Unit=\"C/s\" UNIT=\"C/S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"V\" CODE=\"V\" isMetric=\"yes\" class=\"si\">\n <name>volt</name>\n <printSymbol>V</printSymbol>\n <property>electric potential</property>\n <value Unit=\"J/C\" UNIT=\"J/C\" value=\"1\">1</value>\n </unit>\n <unit Code=\"F\" CODE=\"F\" isMetric=\"yes\" class=\"si\">\n <name>farad</name>\n <printSymbol>F</printSymbol>\n <property>electric capacitance</property>\n <value Unit=\"C/V\" UNIT=\"C/V\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Ohm\" CODE=\"OHM\" isMetric=\"yes\" class=\"si\">\n <name>ohm</name>\n <printSymbol>&#937;</printSymbol>\n <property>electric resistance</property>\n <value Unit=\"V/A\" UNIT=\"V/A\" value=\"1\">1</value>\n </unit>\n <unit Code=\"S\" CODE=\"SIE\" isMetric=\"yes\" class=\"si\">\n <name>siemens</name>\n <printSymbol>S</printSymbol>\n <property>electric conductance</property>\n <value Unit=\"Ohm-1\" UNIT=\"OHM-1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Wb\" CODE=\"WB\" isMetric=\"yes\" class=\"si\">\n <name>weber</name>\n <printSymbol>Wb</printSymbol>\n <property>magnetic flux</property>\n <value Unit=\"V.s\" UNIT=\"V.S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Cel\" CODE=\"CEL\" isMetric=\"yes\" isSpecial=\"yes\" class=\"si\">\n <name>degree Celsius</name>\n <printSymbol>&#176;C</printSymbol>\n <property>temperature</property>\n <value Unit=\"cel(1 K)\" UNIT=\"CEL(1 K)\">\n <function name=\"Cel\" value=\"1\" Unit=\"K\"/>\n </value>\n </unit>\n <unit Code=\"T\" CODE=\"T\" isMetric=\"yes\" class=\"si\">\n <name>tesla</name>\n <printSymbol>T</printSymbol>\n <property>magnetic flux density</property>\n <value Unit=\"Wb/m2\" UNIT=\"WB/M2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"H\" CODE=\"H\" isMetric=\"yes\" class=\"si\">\n <name>henry</name>\n <printSymbol>H</printSymbol>\n <property>inductance</property>\n <value Unit=\"Wb/A\" UNIT=\"WB/A\" value=\"1\">1</value>\n </unit>\n <unit Code=\"lm\" CODE=\"LM\" isMetric=\"yes\" class=\"si\">\n <name>lumen</name>\n <printSymbol>lm</printSymbol>\n <property>luminous flux</property>\n <value Unit=\"cd.sr\" UNIT=\"CD.SR\" value=\"1\">1</value>\n </unit>\n <unit Code=\"lx\" CODE=\"LX\" isMetric=\"yes\" class=\"si\">\n <name>lux</name>\n <printSymbol>lx</printSymbol>\n <property>illuminance</property>\n <value Unit=\"lm/m2\" UNIT=\"LM/M2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Bq\" CODE=\"BQ\" isMetric=\"yes\" class=\"si\">\n <name>becquerel</name>\n <printSymbol>Bq</printSymbol>\n <property>radioactivity</property>\n <value Unit=\"s-1\" UNIT=\"S-1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Gy\" CODE=\"GY\" isMetric=\"yes\" class=\"si\">\n <name>gray</name>\n <printSymbol>Gy</printSymbol>\n <property>energy dose</property>\n <value Unit=\"J/kg\" UNIT=\"J/KG\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Sv\" CODE=\"SV\" isMetric=\"yes\" class=\"si\">\n <name>sievert</name>\n <printSymbol>Sv</printSymbol>\n <property>dose equivalent</property>\n <value Unit=\"J/kg\" UNIT=\"J/KG\" value=\"1\">1</value>\n </unit>\n <unit Code=\"gon\" CODE=\"GON\" isMetric=\"no\" class=\"iso1000\">\n <name>gon</name>\n <name>grade</name>\n <printSymbol>\n <sup>g</sup>\n </printSymbol>\n <property>plane angle</property>\n <value Unit=\"deg\" UNIT=\"DEG\" value=\"0.9\">0.9</value>\n </unit>\n <unit Code=\"deg\" CODE=\"DEG\" isMetric=\"no\" class=\"iso1000\">\n <name>degree</name>\n <printSymbol>&#176;</printSymbol>\n <property>plane angle</property>\n <value Unit=\"[pi].rad/360\" UNIT=\"[PI].RAD/360\" value=\"2\">2</value>\n </unit>\n <unit Code=\"'\" CODE=\"'\" isMetric=\"no\" class=\"iso1000\">\n <name>minute</name>\n <printSymbol>'</printSymbol>\n <property>plane angle</property>\n <value Unit=\"deg/60\" UNIT=\"DEG/60\" value=\"1\">1</value>\n </unit>\n <unit Code=\"''\" CODE=\"''\" isMetric=\"no\" class=\"iso1000\">\n <name>second</name>\n <printSymbol>''</printSymbol>\n <property>plane angle</property>\n <value Unit=\"'/60\" UNIT=\"'/60\" value=\"1\">1</value>\n </unit>\n <unit Code=\"l\" CODE=\"L\" isMetric=\"yes\" class=\"iso1000\">\n <name>liter</name>\n <printSymbol>l</printSymbol>\n <property>volume</property>\n <value Unit=\"dm3\" UNIT=\"DM3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"L\" CODE=\"L\" isMetric=\"yes\" class=\"iso1000\">\n <name>liter</name>\n <printSymbol>L</printSymbol>\n <property>volume</property>\n <value Unit=\"l\" UNIT=\"L\" value=\"1\">1</value>\n </unit>\n <unit Code=\"ar\" CODE=\"AR\" isMetric=\"yes\" class=\"iso1000\">\n <name>are</name>\n <printSymbol>a</printSymbol>\n <property>area</property>\n <value Unit=\"m2\" UNIT=\"M2\" value=\"100\">100</value>\n </unit>\n <unit Code=\"min\" CODE=\"MIN\" isMetric=\"no\" class=\"iso1000\">\n <name>minute</name>\n <printSymbol>min</printSymbol>\n <property>time</property>\n <value Unit=\"s\" UNIT=\"S\" value=\"60\">60</value>\n </unit>\n <unit Code=\"h\" CODE=\"HR\" isMetric=\"no\" class=\"iso1000\">\n <name>hour</name>\n <printSymbol>h</printSymbol>\n <property>time</property>\n <value Unit=\"min\" UNIT=\"MIN\" value=\"60\">60</value>\n </unit>\n <unit Code=\"d\" CODE=\"D\" isMetric=\"no\" class=\"iso1000\">\n <name>day</name>\n <printSymbol>d</printSymbol>\n <property>time</property>\n <value Unit=\"h\" UNIT=\"HR\" value=\"24\">24</value>\n </unit>\n <unit Code=\"a_t\" CODE=\"ANN_T\" isMetric=\"no\" class=\"iso1000\">\n <name>tropical year</name>\n <printSymbol>a<sub>t</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"d\" UNIT=\"D\" value=\"365.24219\">365.24219</value>\n </unit>\n <unit Code=\"a_j\" CODE=\"ANN_J\" isMetric=\"no\" class=\"iso1000\">\n <name>mean Julian year</name>\n <printSymbol>a<sub>j</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"d\" UNIT=\"D\" value=\"365.25\">365.25</value>\n </unit>\n <unit Code=\"a_g\" CODE=\"ANN_G\" isMetric=\"no\" class=\"iso1000\">\n <name>mean Gregorian year</name>\n <printSymbol>a<sub>g</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"d\" UNIT=\"D\" value=\"365.2425\">365.2425</value>\n </unit>\n <unit Code=\"a\" CODE=\"ANN\" isMetric=\"no\" class=\"iso1000\">\n <name>year</name>\n <printSymbol>a</printSymbol>\n <property>time</property>\n <value Unit=\"a_j\" UNIT=\"ANN_J\" value=\"1\">1</value>\n </unit>\n <unit Code=\"wk\" CODE=\"WK\" isMetric=\"no\" class=\"iso1000\">\n <name>week</name>\n <printSymbol>wk</printSymbol>\n <property>time</property>\n <value Unit=\"d\" UNIT=\"D\" value=\"7\">7</value>\n </unit>\n <unit Code=\"mo_s\" CODE=\"MO_S\" isMetric=\"no\" class=\"iso1000\">\n <name>synodal month</name>\n <printSymbol>mo<sub>s</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"d\" UNIT=\"D\" value=\"29.53059\">29.53059</value>\n </unit>\n <unit Code=\"mo_j\" CODE=\"MO_J\" isMetric=\"no\" class=\"iso1000\">\n <name>mean Julian month</name>\n <printSymbol>mo<sub>j</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"a_j/12\" UNIT=\"ANN_J/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"mo_g\" CODE=\"MO_G\" isMetric=\"no\" class=\"iso1000\">\n <name>mean Gregorian month</name>\n <printSymbol>mo<sub>g</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"a_g/12\" UNIT=\"ANN_G/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"mo\" CODE=\"MO\" isMetric=\"no\" class=\"iso1000\">\n <name>month</name>\n <printSymbol>mo</printSymbol>\n <property>time</property>\n <value Unit=\"mo_j\" UNIT=\"MO_J\" value=\"1\">1</value>\n </unit>\n <unit Code=\"t\" CODE=\"TNE\" isMetric=\"yes\" class=\"iso1000\">\n <name>tonne</name>\n <printSymbol>t</printSymbol>\n <property>mass</property>\n <value Unit=\"kg\" UNIT=\"KG\" value=\"1e3\">1 &#215; 10<sup>3</sup>\n </value>\n </unit>\n <unit Code=\"bar\" CODE=\"BAR\" isMetric=\"yes\" class=\"iso1000\">\n <name>bar</name>\n <printSymbol>bar</printSymbol>\n <property>pressure</property>\n <value Unit=\"Pa\" UNIT=\"PAL\" value=\"1e5\">1 &#215; 10<sup>5</sup>\n </value>\n </unit>\n <unit Code=\"u\" CODE=\"AMU\" isMetric=\"yes\" class=\"iso1000\">\n <name>unified atomic mass unit</name>\n <printSymbol>u</printSymbol>\n <property>mass</property>\n <value Unit=\"g\" UNIT=\"G\" value=\"1.66053906660e-24\">1.66053906660 &#215; 10<sup>-24</sup>\n </value>\n </unit>\n <unit Code=\"eV\" CODE=\"EV\" isMetric=\"yes\" class=\"iso1000\">\n <name>electronvolt</name>\n <printSymbol>eV</printSymbol>\n <property>energy</property>\n <value Unit=\"[e].V\" UNIT=\"[E].V\" value=\"1\">1</value>\n </unit>\n <unit Code=\"AU\" CODE=\"ASU\" isMetric=\"no\" class=\"iso1000\">\n <name>astronomic unit</name>\n <printSymbol>AU</printSymbol>\n <property>length</property>\n <value Unit=\"Mm\" UNIT=\"MAM\" value=\"149597.870691\">149597.870691</value>\n </unit>\n <unit Code=\"pc\" CODE=\"PRS\" isMetric=\"yes\" class=\"iso1000\">\n <name>parsec</name>\n <printSymbol>pc</printSymbol>\n <property>length</property>\n <value Unit=\"m\" UNIT=\"M\" value=\"3.085678e16\">3.085678 &#215; 10<sup>16</sup>\n </value>\n </unit>\n <unit Code=\"[c]\" CODE=\"[C]\" isMetric=\"yes\" class=\"const\">\n <name>velocity of light</name>\n <printSymbol>\n <i>c</i>\n </printSymbol>\n <property>velocity</property>\n <value Unit=\"m/s\" UNIT=\"M/S\" value=\"299792458\">299792458</value>\n </unit>\n <unit Code=\"[h]\" CODE=\"[H]\" isMetric=\"yes\" class=\"const\">\n <name>Planck constant</name>\n <printSymbol>\n <i>h</i>\n </printSymbol>\n <property>action</property>\n <value Unit=\"J.s\" UNIT=\"J.S\" value=\"6.62607015e-34\">6.62607015 &#215; 10<sup>-34</sup>\n </value>\n </unit>\n <unit Code=\"[k]\" CODE=\"[K]\" isMetric=\"yes\" class=\"const\">\n <name>Boltzmann constant</name>\n <printSymbol>\n <i>k</i>\n </printSymbol>\n <property>(unclassified)</property>\n <value Unit=\"J/K\" UNIT=\"J/K\" value=\"1.380649e-23\">1.380649 &#215; 10<sup>-23</sup>\n </value>\n </unit>\n <unit Code=\"[eps_0]\" CODE=\"[EPS_0]\" isMetric=\"yes\" class=\"const\">\n <name>permittivity of vacuum</name>\n <printSymbol>\n <i>&#949;<sub>\n <r>0</r>\n </sub>\n </i>\n </printSymbol>\n <property>electric permittivity</property>\n <value Unit=\"F/m\" UNIT=\"F/M\" value=\"8.854187817e-12\">8.854187817 &#215; 10<sup>-12</sup>\n </value>\n </unit>\n <unit Code=\"[mu_0]\" CODE=\"[MU_0]\" isMetric=\"yes\" class=\"const\">\n <name>permeability of vacuum</name>\n <printSymbol>\n <i>&#956;<sub>\n <r>0</r>\n </sub>\n </i>\n </printSymbol>\n <property>magnetic permeability</property>\n <value Unit=\"4.[pi].10*-7.N/A2\" UNIT=\"4.[PI].10*-7.N/A2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[e]\" CODE=\"[E]\" isMetric=\"yes\" class=\"const\">\n <name>elementary charge</name>\n <printSymbol>\n <i>e</i>\n </printSymbol>\n <property>electric charge</property>\n <value Unit=\"C\" UNIT=\"C\" value=\"1.602176634e-19\">1.602176634 &#215; 10<sup>-19</sup>\n </value>\n </unit>\n <unit Code=\"[m_e]\" CODE=\"[M_E]\" isMetric=\"yes\" class=\"const\">\n <name>electron mass</name>\n <printSymbol>\n <i>m<sub>\n <r>e</r>\n </sub>\n </i>\n </printSymbol>\n <property>mass</property>\n <value Unit=\"kg\" UNIT=\"kg\" value=\"9.1093837139e-31\">9.1093837139 &#215; 10<sup>-31</sup>\n </value>\n </unit>\n <unit Code=\"[m_p]\" CODE=\"[M_P]\" isMetric=\"yes\" class=\"const\">\n <name>proton mass</name>\n <printSymbol>\n <i>m<sub>\n <r>p</r>\n </sub>\n </i>\n </printSymbol>\n <property>mass</property>\n <value Unit=\"kg\" UNIT=\"kg\" value=\"1.67262192595e-27\">1.67262192595 &#215; 10<sup>-27</sup>\n </value>\n </unit>\n <unit Code=\"[G]\" CODE=\"[GC]\" isMetric=\"yes\" class=\"const\">\n <name>Newtonian constant of gravitation</name>\n <printSymbol>\n <i>G</i>\n </printSymbol>\n <property>(unclassified)</property>\n <value Unit=\"m3.kg-1.s-2\" UNIT=\"M3.KG-1.S-2\" value=\"6.67430e-11\">6.67430 &#215; 10<sup>-11</sup>\n </value>\n </unit>\n <unit Code=\"[g]\" CODE=\"[G]\" isMetric=\"yes\" class=\"const\">\n <name>standard acceleration of free fall</name>\n <printSymbol>\n <i>g<sub>n</sub>\n </i>\n </printSymbol>\n <property>acceleration</property>\n <value Unit=\"m/s2\" UNIT=\"M/S2\" value=\"980665e-5\">9.80665</value>\n </unit>\n <unit Code=\"atm\" CODE=\"ATM\" isMetric=\"no\" class=\"const\">\n <name>standard atmosphere</name>\n <printSymbol>atm</printSymbol>\n <property>pressure</property>\n <value Unit=\"Pa\" UNIT=\"PAL\" value=\"101325\">101325</value>\n </unit>\n <unit Code=\"[ly]\" CODE=\"[LY]\" isMetric=\"yes\" class=\"const\">\n <name>light-year</name>\n <printSymbol>l.y.</printSymbol>\n <property>length</property>\n <value Unit=\"[c].a_j\" UNIT=\"[C].ANN_J\" value=\"1\">1</value>\n </unit>\n <unit Code=\"gf\" CODE=\"GF\" isMetric=\"yes\" class=\"const\">\n <name>gram-force</name>\n <printSymbol>gf</printSymbol>\n <property>force</property>\n <value Unit=\"g.[g]\" UNIT=\"G.[G]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[lbf_av]\" CODE=\"[LBF_AV]\" isMetric=\"no\" class=\"const\">\n <name>pound force</name>\n <printSymbol>lbf</printSymbol>\n <property>force</property>\n <value Unit=\"[lb_av].[g]\" UNIT=\"[LB_AV].[G]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Ky\" CODE=\"KY\" isMetric=\"yes\" class=\"cgs\">\n <name>Kayser</name>\n <printSymbol>K</printSymbol>\n <property>lineic number</property>\n <value Unit=\"cm-1\" UNIT=\"CM-1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Gal\" CODE=\"GL\" isMetric=\"yes\" class=\"cgs\">\n <name>Gal</name>\n <printSymbol>Gal</printSymbol>\n <property>acceleration</property>\n <value Unit=\"cm/s2\" UNIT=\"CM/S2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"dyn\" CODE=\"DYN\" isMetric=\"yes\" class=\"cgs\">\n <name>dyne</name>\n <printSymbol>dyn</printSymbol>\n <property>force</property>\n <value Unit=\"g.cm/s2\" UNIT=\"G.CM/S2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"erg\" CODE=\"ERG\" isMetric=\"yes\" class=\"cgs\">\n <name>erg</name>\n <printSymbol>erg</printSymbol>\n <property>energy</property>\n <value Unit=\"dyn.cm\" UNIT=\"DYN.CM\" value=\"1\">1</value>\n </unit>\n <unit Code=\"P\" CODE=\"P\" isMetric=\"yes\" class=\"cgs\">\n <name>Poise</name>\n <printSymbol>P</printSymbol>\n <property>dynamic viscosity</property>\n <value Unit=\"dyn.s/cm2\" UNIT=\"DYN.S/CM2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Bi\" CODE=\"BI\" isMetric=\"yes\" class=\"cgs\">\n <name>Biot</name>\n <printSymbol>Bi</printSymbol>\n <property>electric current</property>\n <value Unit=\"A\" UNIT=\"A\" value=\"10\">10</value>\n </unit>\n <unit Code=\"St\" CODE=\"ST\" isMetric=\"yes\" class=\"cgs\">\n <name>Stokes</name>\n <printSymbol>St</printSymbol>\n <property>kinematic viscosity</property>\n <value Unit=\"cm2/s\" UNIT=\"CM2/S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Mx\" CODE=\"MX\" isMetric=\"yes\" class=\"cgs\">\n <name>Maxwell</name>\n <printSymbol>Mx</printSymbol>\n <property>flux of magnetic induction</property>\n <value Unit=\"Wb\" UNIT=\"WB\" value=\"1e-8\">1 &#215; 10<sup>-8</sup>\n </value>\n </unit>\n <unit Code=\"G\" CODE=\"GS\" isMetric=\"yes\" class=\"cgs\">\n <name>Gauss</name>\n <printSymbol>Gs</printSymbol>\n <property>magnetic flux density</property>\n <value Unit=\"T\" UNIT=\"T\" value=\"1e-4\">1 &#215; 10<sup>-4</sup>\n </value>\n </unit>\n <unit Code=\"Oe\" CODE=\"OE\" isMetric=\"yes\" class=\"cgs\">\n <name>Oersted</name>\n <printSymbol>Oe</printSymbol>\n <property>magnetic field intensity</property>\n <value Unit=\"/[pi].A/m\" UNIT=\"/[PI].A/M\" value=\"250\">250</value>\n </unit>\n <unit Code=\"Gb\" CODE=\"GB\" isMetric=\"yes\" class=\"cgs\">\n <name>Gilbert</name>\n <printSymbol>Gb</printSymbol>\n <property>magnetic tension</property>\n <value Unit=\"Oe.cm\" UNIT=\"OE.CM\" value=\"1\">1</value>\n </unit>\n <unit Code=\"sb\" CODE=\"SB\" isMetric=\"yes\" class=\"cgs\">\n <name>stilb</name>\n <printSymbol>sb</printSymbol>\n <property>lum. intensity density</property>\n <value Unit=\"cd/cm2\" UNIT=\"CD/CM2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Lmb\" CODE=\"LMB\" isMetric=\"yes\" class=\"cgs\">\n <name>Lambert</name>\n <printSymbol>L</printSymbol>\n <property>brightness</property>\n <value Unit=\"cd/cm2/[pi]\" UNIT=\"CD/CM2/[PI]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"ph\" CODE=\"PHT\" isMetric=\"yes\" class=\"cgs\">\n <name>phot</name>\n <printSymbol>ph</printSymbol>\n <property>illuminance</property>\n <value Unit=\"lx\" UNIT=\"LX\" value=\"1e-4\">1 &#215; 10<sup>-4</sup>\n </value>\n </unit>\n <unit Code=\"Ci\" CODE=\"CI\" isMetric=\"yes\" class=\"cgs\">\n <name>Curie</name>\n <printSymbol>Ci</printSymbol>\n <property>radioactivity</property>\n <value Unit=\"Bq\" UNIT=\"BQ\" value=\"37e9\">3.7 &#215; 10<sup>10</sup>\n </value>\n </unit>\n <unit Code=\"R\" CODE=\"ROE\" isMetric=\"yes\" class=\"cgs\">\n <name>Roentgen</name>\n <printSymbol>R</printSymbol>\n <property>ion dose</property>\n <value Unit=\"C/kg\" UNIT=\"C/KG\" value=\"2.58e-4\">2.58 &#215; 10<sup>-4</sup>\n </value>\n </unit>\n <unit Code=\"RAD\" CODE=\"[RAD]\" isMetric=\"yes\" class=\"cgs\">\n <name>radiation absorbed dose</name>\n <printSymbol>RAD</printSymbol>\n <property>energy dose</property>\n <value Unit=\"erg/g\" UNIT=\"ERG/G\" value=\"100\">100</value>\n </unit>\n <unit Code=\"REM\" CODE=\"[REM]\" isMetric=\"yes\" class=\"cgs\">\n <name>radiation equivalent man</name>\n <printSymbol>REM</printSymbol>\n <property>dose equivalent</property>\n <value Unit=\"RAD\" UNIT=\"[RAD]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[in_i]\" CODE=\"[IN_I]\" isMetric=\"no\" class=\"intcust\">\n <name>inch</name>\n <printSymbol>in</printSymbol>\n <property>length</property>\n <value Unit=\"cm\" UNIT=\"CM\" value=\"254e-2\">2.54</value>\n </unit>\n <unit Code=\"[ft_i]\" CODE=\"[FT_I]\" isMetric=\"no\" class=\"intcust\">\n <name>foot</name>\n <printSymbol>ft</printSymbol>\n <property>length</property>\n <value Unit=\"[in_i]\" UNIT=\"[IN_I]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[yd_i]\" CODE=\"[YD_I]\" isMetric=\"no\" class=\"intcust\">\n <name>yard</name>\n <printSymbol>yd</printSymbol>\n <property>length</property>\n <value Unit=\"[ft_i]\" UNIT=\"[FT_I]\" value=\"3\">3</value>\n </unit>\n <unit Code=\"[mi_i]\" CODE=\"[MI_I]\" isMetric=\"no\" class=\"intcust\">\n <name>mile</name>\n <printSymbol>mi</printSymbol>\n <property>length</property>\n <value Unit=\"[ft_i]\" UNIT=\"[FT_I]\" value=\"5280\">5280</value>\n </unit>\n <unit Code=\"[fth_i]\" CODE=\"[FTH_I]\" isMetric=\"no\" class=\"intcust\">\n <name>fathom</name>\n <printSymbol>fth</printSymbol>\n <property>depth of water</property>\n <value Unit=\"[ft_i]\" UNIT=\"[FT_I]\" value=\"6\">6</value>\n </unit>\n <unit Code=\"[nmi_i]\" CODE=\"[NMI_I]\" isMetric=\"no\" class=\"intcust\">\n <name>nautical mile</name>\n <printSymbol>n.mi</printSymbol>\n <property>length</property>\n <value Unit=\"m\" UNIT=\"M\" value=\"1852\">1852</value>\n </unit>\n <unit Code=\"[kn_i]\" CODE=\"[KN_I]\" isMetric=\"no\" class=\"intcust\">\n <name>knot</name>\n <printSymbol>knot</printSymbol>\n <property>velocity</property>\n <value Unit=\"[nmi_i]/h\" UNIT=\"[NMI_I]/H\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[sin_i]\" CODE=\"[SIN_I]\" isMetric=\"no\" class=\"intcust\">\n <name>square inch</name>\n <property>area</property>\n <value Unit=\"[in_i]2\" UNIT=\"[IN_I]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[sft_i]\" CODE=\"[SFT_I]\" isMetric=\"no\" class=\"intcust\">\n <name>square foot</name>\n <property>area</property>\n <value Unit=\"[ft_i]2\" UNIT=\"[FT_I]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[syd_i]\" CODE=\"[SYD_I]\" isMetric=\"no\" class=\"intcust\">\n <name>square yard</name>\n <property>area</property>\n <value Unit=\"[yd_i]2\" UNIT=\"[YD_I]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[cin_i]\" CODE=\"[CIN_I]\" isMetric=\"no\" class=\"intcust\">\n <name>cubic inch</name>\n <property>volume</property>\n <value Unit=\"[in_i]3\" UNIT=\"[IN_I]3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[cft_i]\" CODE=\"[CFT_I]\" isMetric=\"no\" class=\"intcust\">\n <name>cubic foot</name>\n <property>volume</property>\n <value Unit=\"[ft_i]3\" UNIT=\"[FT_I]3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[cyd_i]\" CODE=\"[CYD_I]\" isMetric=\"no\" class=\"intcust\">\n <name>cubic yard</name>\n <printSymbol>cu.yd</printSymbol>\n <property>volume</property>\n <value Unit=\"[yd_i]3\" UNIT=\"[YD_I]3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[bf_i]\" CODE=\"[BF_I]\" isMetric=\"no\" class=\"intcust\">\n <name>board foot</name>\n <property>volume</property>\n <value Unit=\"[in_i]3\" UNIT=\"[IN_I]3\" value=\"144\">144</value>\n </unit>\n <unit Code=\"[cr_i]\" CODE=\"[CR_I]\" isMetric=\"no\" class=\"intcust\">\n <name>cord</name>\n <property>volume</property>\n <value Unit=\"[ft_i]3\" UNIT=\"[FT_I]3\" value=\"128\">128</value>\n </unit>\n <unit Code=\"[mil_i]\" CODE=\"[MIL_I]\" isMetric=\"no\" class=\"intcust\">\n <name>mil</name>\n <printSymbol>mil</printSymbol>\n <property>length</property>\n <value Unit=\"[in_i]\" UNIT=\"[IN_I]\" value=\"1e-3\">1 &#215; 10<sup>-3</sup>\n </value>\n </unit>\n <unit Code=\"[cml_i]\" CODE=\"[CML_I]\" isMetric=\"no\" class=\"intcust\">\n <name>circular mil</name>\n <printSymbol>circ.mil</printSymbol>\n <property>area</property>\n <value Unit=\"[pi]/4.[mil_i]2\" UNIT=\"[PI]/4.[MIL_I]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[hd_i]\" CODE=\"[HD_I]\" isMetric=\"no\" class=\"intcust\">\n <name>hand</name>\n <printSymbol>hd</printSymbol>\n <property>height of horses</property>\n <value Unit=\"[in_i]\" UNIT=\"[IN_I]\" value=\"4\">4</value>\n </unit>\n <unit Code=\"[ft_us]\" CODE=\"[FT_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>foot</name>\n <printSymbol>ft<sub>us</sub>\n </printSymbol>\n <property>length</property>\n <value Unit=\"m/3937\" UNIT=\"M/3937\" value=\"1200\">1200</value>\n </unit>\n <unit Code=\"[yd_us]\" CODE=\"[YD_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>yard</name>\n <property>length</property>\n <value Unit=\"[ft_us]\" UNIT=\"[FT_US]\" value=\"3\">3</value>\n </unit>\n <unit Code=\"[in_us]\" CODE=\"[IN_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>inch</name>\n <property>length</property>\n <value Unit=\"[ft_us]/12\" UNIT=\"[FT_US]/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[rd_us]\" CODE=\"[RD_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>rod</name>\n <property>length</property>\n <value Unit=\"[ft_us]\" UNIT=\"[FT_US]\" value=\"16.5\">16.5</value>\n </unit>\n <unit Code=\"[ch_us]\" CODE=\"[CH_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>Gunter's chain</name>\n <name>Surveyor's chain</name>\n <property>length</property>\n <value Unit=\"[rd_us]\" UNIT=\"[RD_US]\" value=\"4\">4</value>\n </unit>\n <unit Code=\"[lk_us]\" CODE=\"[LK_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>link for Gunter's chain</name>\n <property>length</property>\n <value Unit=\"[ch_us]/100\" UNIT=\"[CH_US]/100\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[rch_us]\" CODE=\"[RCH_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>Ramden's chain</name>\n <name>Engineer's chain</name>\n <property>length</property>\n <value Unit=\"[ft_us]\" UNIT=\"[FT_US]\" value=\"100\">100</value>\n </unit>\n <unit Code=\"[rlk_us]\" CODE=\"[RLK_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>link for Ramden's chain</name>\n <property>length</property>\n <value Unit=\"[rch_us]/100\" UNIT=\"[RCH_US]/100\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[fth_us]\" CODE=\"[FTH_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>fathom</name>\n <property>length</property>\n <value Unit=\"[ft_us]\" UNIT=\"[FT_US]\" value=\"6\">6</value>\n </unit>\n <unit Code=\"[fur_us]\" CODE=\"[FUR_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>furlong</name>\n <property>length</property>\n <value Unit=\"[rd_us]\" UNIT=\"[RD_US]\" value=\"40\">40</value>\n </unit>\n <unit Code=\"[mi_us]\" CODE=\"[MI_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>mile</name>\n <property>length</property>\n <value Unit=\"[fur_us]\" UNIT=\"[FUR_US]\" value=\"8\">8</value>\n </unit>\n <unit Code=\"[acr_us]\" CODE=\"[ACR_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>acre</name>\n <property>area</property>\n <value Unit=\"[rd_us]2\" UNIT=\"[RD_US]2\" value=\"160\">160</value>\n </unit>\n <unit Code=\"[srd_us]\" CODE=\"[SRD_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>square rod</name>\n <property>area</property>\n <value Unit=\"[rd_us]2\" UNIT=\"[RD_US]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[smi_us]\" CODE=\"[SMI_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>square mile</name>\n <property>area</property>\n <value Unit=\"[mi_us]2\" UNIT=\"[MI_US]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[sct]\" CODE=\"[SCT]\" isMetric=\"no\" class=\"us-lengths\">\n <name>section</name>\n <property>area</property>\n <value Unit=\"[mi_us]2\" UNIT=\"[MI_US]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[twp]\" CODE=\"[TWP]\" isMetric=\"no\" class=\"us-lengths\">\n <name>township</name>\n <property>area</property>\n <value Unit=\"[sct]\" UNIT=\"[SCT]\" value=\"36\">36</value>\n </unit>\n <unit Code=\"[mil_us]\" CODE=\"[MIL_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>mil</name>\n <property>length</property>\n <value Unit=\"[in_us]\" UNIT=\"[IN_US]\" value=\"1e-3\">1 &#215; 10<sup>-3</sup>\n </value>\n </unit>\n <unit Code=\"[in_br]\" CODE=\"[IN_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>inch</name>\n <property>length</property>\n <value Unit=\"cm\" UNIT=\"CM\" value=\"2.539998\">2.539998</value>\n </unit>\n <unit Code=\"[ft_br]\" CODE=\"[FT_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>foot</name>\n <property>length</property>\n <value Unit=\"[in_br]\" UNIT=\"[IN_BR]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[rd_br]\" CODE=\"[RD_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>rod</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"16.5\">16.5</value>\n </unit>\n <unit Code=\"[ch_br]\" CODE=\"[CH_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>Gunter's chain</name>\n <property>length</property>\n <value Unit=\"[rd_br]\" UNIT=\"[RD_BR]\" value=\"4\">4</value>\n </unit>\n <unit Code=\"[lk_br]\" CODE=\"[LK_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>link for Gunter's chain</name>\n <property>length</property>\n <value Unit=\"[ch_br]/100\" UNIT=\"[CH_BR]/100\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[fth_br]\" CODE=\"[FTH_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>fathom</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"6\">6</value>\n </unit>\n <unit Code=\"[pc_br]\" CODE=\"[PC_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>pace</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"2.5\">2.5</value>\n </unit>\n <unit Code=\"[yd_br]\" CODE=\"[YD_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>yard</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"3\">3</value>\n </unit>\n <unit Code=\"[mi_br]\" CODE=\"[MI_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>mile</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"5280\">5280</value>\n </unit>\n <unit Code=\"[nmi_br]\" CODE=\"[NMI_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>nautical mile</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"6080\">6080</value>\n </unit>\n <unit Code=\"[kn_br]\" CODE=\"[KN_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>knot</name>\n <property>velocity</property>\n <value Unit=\"[nmi_br]/h\" UNIT=\"[NMI_BR]/H\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[acr_br]\" CODE=\"[ACR_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>acre</name>\n <property>area</property>\n <value Unit=\"[yd_br]2\" UNIT=\"[YD_BR]2\" value=\"4840\">4840</value>\n </unit>\n <unit Code=\"[gal_us]\" CODE=\"[GAL_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>Queen&#160;Anne's wine gallon</name>\n <property>fluid volume</property>\n <value Unit=\"[in_i]3\" UNIT=\"[IN_I]3\" value=\"231\">231</value>\n </unit>\n <unit Code=\"[bbl_us]\" CODE=\"[BBL_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>barrel</name>\n <property>fluid volume</property>\n <value Unit=\"[gal_us]\" UNIT=\"[GAL_US]\" value=\"42\">42</value>\n </unit>\n <unit Code=\"[qt_us]\" CODE=\"[QT_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>quart</name>\n <property>fluid volume</property>\n <value Unit=\"[gal_us]/4\" UNIT=\"[GAL_US]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pt_us]\" CODE=\"[PT_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>pint</name>\n <property>fluid volume</property>\n <value Unit=\"[qt_us]/2\" UNIT=\"[QT_US]/2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[gil_us]\" CODE=\"[GIL_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>gill</name>\n <property>fluid volume</property>\n <value Unit=\"[pt_us]/4\" UNIT=\"[PT_US]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[foz_us]\" CODE=\"[FOZ_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>fluid ounce</name>\n <printSymbol>oz fl</printSymbol>\n <property>fluid volume</property>\n <value Unit=\"[gil_us]/4\" UNIT=\"[GIL_US]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[fdr_us]\" CODE=\"[FDR_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>fluid dram</name>\n <property>fluid volume</property>\n <value Unit=\"[foz_us]/8\" UNIT=\"[FOZ_US]/8\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[min_us]\" CODE=\"[MIN_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>minim</name>\n <property>fluid volume</property>\n <value Unit=\"[fdr_us]/60\" UNIT=\"[FDR_US]/60\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[crd_us]\" CODE=\"[CRD_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>cord</name>\n <property>fluid volume</property>\n <value Unit=\"[ft_i]3\" UNIT=\"[FT_I]3\" value=\"128\">128</value>\n </unit>\n <unit Code=\"[bu_us]\" CODE=\"[BU_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>bushel</name>\n <property>dry volume</property>\n <value Unit=\"[in_i]3\" UNIT=\"[IN_I]3\" value=\"2150.42\">2150.42</value>\n </unit>\n <unit Code=\"[gal_wi]\" CODE=\"[GAL_WI]\" isMetric=\"no\" class=\"us-volumes\">\n <name>historical winchester gallon</name>\n <property>dry volume</property>\n <value Unit=\"[bu_us]/8\" UNIT=\"[BU_US]/8\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pk_us]\" CODE=\"[PK_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>peck</name>\n <property>dry volume</property>\n <value Unit=\"[bu_us]/4\" UNIT=\"[BU_US]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[dqt_us]\" CODE=\"[DQT_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>dry quart</name>\n <property>dry volume</property>\n <value Unit=\"[pk_us]/8\" UNIT=\"[PK_US]/8\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[dpt_us]\" CODE=\"[DPT_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>dry pint</name>\n <property>dry volume</property>\n <value Unit=\"[dqt_us]/2\" UNIT=\"[DQT_US]/2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[tbs_us]\" CODE=\"[TBS_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>tablespoon</name>\n <property>volume</property>\n <value Unit=\"[foz_us]/2\" UNIT=\"[FOZ_US]/2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[tsp_us]\" CODE=\"[TSP_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>teaspoon</name>\n <property>volume</property>\n <value Unit=\"[tbs_us]/3\" UNIT=\"[TBS_US]/3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[cup_us]\" CODE=\"[CUP_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>cup</name>\n <property>volume</property>\n <value Unit=\"[tbs_us]\" UNIT=\"[TBS_US]\" value=\"16\">16</value>\n </unit>\n <unit Code=\"[foz_m]\" CODE=\"[FOZ_M]\" isMetric=\"no\" class=\"us-volumes\">\n <name>metric fluid ounce</name>\n <printSymbol>oz fl</printSymbol>\n <property>fluid volume</property>\n <value Unit=\"mL\" UNIT=\"ML\" value=\"30\">30</value>\n </unit>\n <unit Code=\"[cup_m]\" CODE=\"[CUP_M]\" isMetric=\"no\" class=\"us-volumes\">\n <name>metric cup</name>\n <property>volume</property>\n <value Unit=\"mL\" UNIT=\"ML\" value=\"240\">240</value>\n </unit>\n <unit Code=\"[tsp_m]\" CODE=\"[TSP_M]\" isMetric=\"no\" class=\"us-volumes\">\n <name>metric teaspoon</name>\n <property>volume</property>\n <value Unit=\"mL\" UNIT=\"mL\" value=\"5\">5</value>\n </unit>\n <unit Code=\"[tbs_m]\" CODE=\"[TBS_M]\" isMetric=\"no\" class=\"us-volumes\">\n <name>metric tablespoon</name>\n <property>volume</property>\n <value Unit=\"mL\" UNIT=\"mL\" value=\"15\">15</value>\n </unit>\n <unit Code=\"[gal_br]\" CODE=\"[GAL_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>gallon</name>\n <property>volume</property>\n <value Unit=\"l\" UNIT=\"L\" value=\"4.54609\">4.54609</value>\n </unit>\n <unit Code=\"[pk_br]\" CODE=\"[PK_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>peck</name>\n <property>volume</property>\n <value Unit=\"[gal_br]\" UNIT=\"[GAL_BR]\" value=\"2\">2</value>\n </unit>\n <unit Code=\"[bu_br]\" CODE=\"[BU_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>bushel</name>\n <property>volume</property>\n <value Unit=\"[pk_br]\" UNIT=\"[PK_BR]\" value=\"4\">4</value>\n </unit>\n <unit Code=\"[qt_br]\" CODE=\"[QT_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>quart</name>\n <property>volume</property>\n <value Unit=\"[gal_br]/4\" UNIT=\"[GAL_BR]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pt_br]\" CODE=\"[PT_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>pint</name>\n <property>volume</property>\n <value Unit=\"[qt_br]/2\" UNIT=\"[QT_BR]/2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[gil_br]\" CODE=\"[GIL_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>gill</name>\n <property>volume</property>\n <value Unit=\"[pt_br]/4\" UNIT=\"[PT_BR]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[foz_br]\" CODE=\"[FOZ_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>fluid ounce</name>\n <property>volume</property>\n <value Unit=\"[gil_br]/5\" UNIT=\"[GIL_BR]/5\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[fdr_br]\" CODE=\"[FDR_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>fluid dram</name>\n <property>volume</property>\n <value Unit=\"[foz_br]/8\" UNIT=\"[FOZ_BR]/8\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[min_br]\" CODE=\"[MIN_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>minim</name>\n <property>volume</property>\n <value Unit=\"[fdr_br]/60\" UNIT=\"[FDR_BR]/60\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[gr]\" CODE=\"[GR]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>grain</name>\n <property>mass</property>\n <value Unit=\"mg\" UNIT=\"MG\" value=\"64.79891\">64.79891</value>\n </unit>\n <unit Code=\"[lb_av]\" CODE=\"[LB_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>pound</name>\n <printSymbol>lb</printSymbol>\n <property>mass</property>\n <value Unit=\"[gr]\" UNIT=\"[GR]\" value=\"7000\">7000</value>\n </unit>\n <unit Code=\"[oz_av]\" CODE=\"[OZ_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>ounce</name>\n <printSymbol>oz</printSymbol>\n <property>mass</property>\n <value Unit=\"[lb_av]/16\" UNIT=\"[LB_AV]/16\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[dr_av]\" CODE=\"[DR_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>dram</name>\n <property>mass</property>\n <value Unit=\"[oz_av]/16\" UNIT=\"[OZ_AV]/16\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[scwt_av]\" CODE=\"[SCWT_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>short hundredweight</name>\n <name>U.S. hundredweight</name>\n <property>mass</property>\n <value Unit=\"[lb_av]\" UNIT=\"[LB_AV]\" value=\"100\">100</value>\n </unit>\n <unit Code=\"[lcwt_av]\" CODE=\"[LCWT_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>long hundredweight</name>\n <name>British hundredweight</name>\n <property>mass</property>\n <value Unit=\"[lb_av]\" UNIT=\"[LB_AV]\" value=\"112\">112</value>\n </unit>\n <unit Code=\"[ston_av]\" CODE=\"[STON_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>short ton</name>\n <name>U.S. ton</name>\n <property>mass</property>\n <value Unit=\"[scwt_av]\" UNIT=\"[SCWT_AV]\" value=\"20\">20</value>\n </unit>\n <unit Code=\"[lton_av]\" CODE=\"[LTON_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>long ton</name>\n <name>British ton</name>\n <property>mass</property>\n <value Unit=\"[lcwt_av]\" UNIT=\"[LCWT_AV]\" value=\"20\">20</value>\n </unit>\n <unit Code=\"[stone_av]\" CODE=\"[STONE_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>stone</name>\n <name>British stone</name>\n <property>mass</property>\n <value Unit=\"[lb_av]\" UNIT=\"[LB_AV]\" value=\"14\">14</value>\n </unit>\n <unit Code=\"[pwt_tr]\" CODE=\"[PWT_TR]\" isMetric=\"no\" class=\"troy\">\n <name>pennyweight</name>\n <property>mass</property>\n <value Unit=\"[gr]\" UNIT=\"[GR]\" value=\"24\">24</value>\n </unit>\n <unit Code=\"[oz_tr]\" CODE=\"[OZ_TR]\" isMetric=\"no\" class=\"troy\">\n <name>ounce</name>\n <property>mass</property>\n <value Unit=\"[pwt_tr]\" UNIT=\"[PWT_TR]\" value=\"20\">20</value>\n </unit>\n <unit Code=\"[lb_tr]\" CODE=\"[LB_TR]\" isMetric=\"no\" class=\"troy\">\n <name>pound</name>\n <property>mass</property>\n <value Unit=\"[oz_tr]\" UNIT=\"[OZ_TR]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[sc_ap]\" CODE=\"[SC_AP]\" isMetric=\"no\" class=\"apoth\">\n <name>scruple</name>\n <property>mass</property>\n <value Unit=\"[gr]\" UNIT=\"[GR]\" value=\"20\">20</value>\n </unit>\n <unit Code=\"[dr_ap]\" CODE=\"[DR_AP]\" isMetric=\"no\" class=\"apoth\">\n <name>dram</name>\n <name>drachm</name>\n <property>mass</property>\n <value Unit=\"[sc_ap]\" UNIT=\"[SC_AP]\" value=\"3\">3</value>\n </unit>\n <unit Code=\"[oz_ap]\" CODE=\"[OZ_AP]\" isMetric=\"no\" class=\"apoth\">\n <name>ounce</name>\n <property>mass</property>\n <value Unit=\"[dr_ap]\" UNIT=\"[DR_AP]\" value=\"8\">8</value>\n </unit>\n <unit Code=\"[lb_ap]\" CODE=\"[LB_AP]\" isMetric=\"no\" class=\"apoth\">\n <name>pound</name>\n <property>mass</property>\n <value Unit=\"[oz_ap]\" UNIT=\"[OZ_AP]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[oz_m]\" CODE=\"[OZ_M]\" isMetric=\"no\" class=\"apoth\">\n <name>metric ounce</name>\n <property>mass</property>\n <value Unit=\"g\" UNIT=\"g\" value=\"28\">28</value>\n </unit>\n <unit Code=\"[lne]\" CODE=\"[LNE]\" isMetric=\"no\" class=\"typeset\">\n <name>line</name>\n <property>length</property>\n <value Unit=\"[in_i]/12\" UNIT=\"[IN_I]/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pnt]\" CODE=\"[PNT]\" isMetric=\"no\" class=\"typeset\">\n <name>point</name>\n <property>length</property>\n <value Unit=\"[lne]/6\" UNIT=\"[LNE]/6\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pca]\" CODE=\"[PCA]\" isMetric=\"no\" class=\"typeset\">\n <name>pica</name>\n <property>length</property>\n <value Unit=\"[pnt]\" UNIT=\"[PNT]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[pnt_pr]\" CODE=\"[PNT_PR]\" isMetric=\"no\" class=\"typeset\">\n <name>Printer's point</name>\n <property>length</property>\n <value Unit=\"[in_i]\" UNIT=\"[IN_I]\" value=\"0.013837\">0.013837</value>\n </unit>\n <unit Code=\"[pca_pr]\" CODE=\"[PCA_PR]\" isMetric=\"no\" class=\"typeset\">\n <name>Printer's pica</name>\n <property>length</property>\n <value Unit=\"[pnt_pr]\" UNIT=\"[PNT_PR]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[pied]\" CODE=\"[PIED]\" isMetric=\"no\" class=\"typeset\">\n <name>pied</name>\n <name>French foot</name>\n <property>length</property>\n <value Unit=\"cm\" UNIT=\"CM\" value=\"32.48\">32.48</value>\n </unit>\n <unit Code=\"[pouce]\" CODE=\"[POUCE]\" isMetric=\"no\" class=\"typeset\">\n <name>pouce</name>\n <name>French inch</name>\n <property>length</property>\n <value Unit=\"[pied]/12\" UNIT=\"[PIED]/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ligne]\" CODE=\"[LIGNE]\" isMetric=\"no\" class=\"typeset\">\n <name>ligne</name>\n <name>French line</name>\n <property>length</property>\n <value Unit=\"[pouce]/12\" UNIT=\"[POUCE]/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[didot]\" CODE=\"[DIDOT]\" isMetric=\"no\" class=\"typeset\">\n <name>didot</name>\n <name>Didot's point</name>\n <property>length</property>\n <value Unit=\"[ligne]/6\" UNIT=\"[LIGNE]/6\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[cicero]\" CODE=\"[CICERO]\" isMetric=\"no\" class=\"typeset\">\n <name>cicero</name>\n <name>Didot's pica</name>\n <property>length</property>\n <value Unit=\"[didot]\" UNIT=\"[DIDOT]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[degF]\" CODE=\"[DEGF]\" isMetric=\"no\" isSpecial=\"yes\" class=\"heat\">\n <name>degree Fahrenheit</name>\n <printSymbol>&#176;F</printSymbol>\n <property>temperature</property>\n <value Unit=\"degf(5 K/9)\" UNIT=\"DEGF(5 K/9)\">\n <function name=\"degF\" value=\"5\" Unit=\"K/9\"/>\n </value>\n </unit>\n <unit Code=\"[degR]\" CODE=\"[degR]\" isMetric=\"no\" class=\"heat\">\n <name>degree Rankine</name>\n <printSymbol>&#176;R</printSymbol>\n <property>temperature</property>\n <value value=\"5\" Unit=\"K/9\" UNIT=\"K/9\">5</value>\n </unit>\n <unit Code=\"[degRe]\" CODE=\"[degRe]\" isMetric=\"no\" isSpecial=\"yes\" class=\"heat\">\n <name>degree R&#233;aumur</name>\n <printSymbol>&#176;R&#233;</printSymbol>\n <property>temperature</property>\n <value Unit=\"degre(5 K/4)\" UNIT=\"DEGRE(5 K/4)\">\n <function name=\"degRe\" value=\"5\" Unit=\"K/4\"/>\n </value>\n </unit>\n <unit Code=\"cal_[15]\" CODE=\"CAL_[15]\" isMetric=\"yes\" class=\"heat\">\n <name>calorie at 15&#160;&#176;C</name>\n <printSymbol>cal<sub>15&#176;C</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"J\" UNIT=\"J\" value=\"4.18580\">4.18580</value>\n </unit>\n <unit Code=\"cal_[20]\" CODE=\"CAL_[20]\" isMetric=\"yes\" class=\"heat\">\n <name>calorie at 20&#160;&#176;C</name>\n <printSymbol>cal<sub>20&#176;C</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"J\" UNIT=\"J\" value=\"4.18190\">4.18190</value>\n </unit>\n <unit Code=\"cal_m\" CODE=\"CAL_M\" isMetric=\"yes\" class=\"heat\">\n <name>mean calorie</name>\n <printSymbol>cal<sub>m</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"J\" UNIT=\"J\" value=\"4.19002\">4.19002</value>\n </unit>\n <unit Code=\"cal_IT\" CODE=\"CAL_IT\" isMetric=\"yes\" class=\"heat\">\n <name>international table calorie</name>\n <printSymbol>cal<sub>IT</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"J\" UNIT=\"J\" value=\"4.1868\">4.1868</value>\n </unit>\n <unit Code=\"cal_th\" CODE=\"CAL_TH\" isMetric=\"yes\" class=\"heat\">\n <name>thermochemical calorie</name>\n <printSymbol>cal<sub>th</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"J\" UNIT=\"J\" value=\"4.184\">4.184</value>\n </unit>\n <unit Code=\"cal\" CODE=\"CAL\" isMetric=\"yes\" class=\"heat\">\n <name>calorie</name>\n <printSymbol>cal</printSymbol>\n <property>energy</property>\n <value Unit=\"cal_th\" UNIT=\"CAL_TH\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[Cal]\" CODE=\"[CAL]\" isMetric=\"no\" class=\"heat\">\n <name>nutrition label Calories</name>\n <printSymbol>Cal</printSymbol>\n <property>energy</property>\n <value Unit=\"kcal_th\" UNIT=\"KCAL_TH\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[Btu_39]\" CODE=\"[BTU_39]\" isMetric=\"no\" class=\"heat\">\n <name>British thermal unit at 39&#160;&#176;F</name>\n <printSymbol>Btu<sub>39&#176;F</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.05967\">1.05967</value>\n </unit>\n <unit Code=\"[Btu_59]\" CODE=\"[BTU_59]\" isMetric=\"no\" class=\"heat\">\n <name>British thermal unit at 59&#160;&#176;F</name>\n <printSymbol>Btu<sub>59&#176;F</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.05480\">1.05480</value>\n </unit>\n <unit Code=\"[Btu_60]\" CODE=\"[BTU_60]\" isMetric=\"no\" class=\"heat\">\n <name>British thermal unit at 60&#160;&#176;F</name>\n <printSymbol>Btu<sub>60&#176;F</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.05468\">1.05468</value>\n </unit>\n <unit Code=\"[Btu_m]\" CODE=\"[BTU_M]\" isMetric=\"no\" class=\"heat\">\n <name>mean British thermal unit</name>\n <printSymbol>Btu<sub>m</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.05587\">1.05587</value>\n </unit>\n <unit Code=\"[Btu_IT]\" CODE=\"[BTU_IT]\" isMetric=\"no\" class=\"heat\">\n <name>international table British thermal unit</name>\n <printSymbol>Btu<sub>IT</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.05505585262\">1.05505585262</value>\n </unit>\n <unit Code=\"[Btu_th]\" CODE=\"[BTU_TH]\" isMetric=\"no\" class=\"heat\">\n <name>thermochemical British thermal unit</name>\n <printSymbol>Btu<sub>th</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.054350\">1.054350</value>\n </unit>\n <unit Code=\"[Btu]\" CODE=\"[BTU]\" isMetric=\"no\" class=\"heat\">\n <name>British thermal unit</name>\n <printSymbol>btu</printSymbol>\n <property>energy</property>\n <value Unit=\"[Btu_th]\" UNIT=\"[BTU_TH]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[HP]\" CODE=\"[HP]\" isMetric=\"no\" class=\"heat\">\n <name>horsepower</name>\n <property>power</property>\n <value Unit=\"[ft_i].[lbf_av]/s\" UNIT=\"[FT_I].[LBF_AV]/S\" value=\"550\">550</value>\n </unit>\n <unit Code=\"tex\" CODE=\"TEX\" isMetric=\"yes\" class=\"heat\">\n <name>tex</name>\n <printSymbol>tex</printSymbol>\n <property>linear mass density (of textile thread)</property>\n <value value=\"1\" Unit=\"g/km\" UNIT=\"G/KM\">1</value>\n </unit>\n <unit Code=\"[den]\" CODE=\"[DEN]\" isMetric=\"no\" class=\"heat\">\n <name>Denier</name>\n <printSymbol>den</printSymbol>\n <property>linear mass density (of textile thread)</property>\n <value value=\"1\" Unit=\"g/9/km\" UNIT=\"G/9/KM\">1</value>\n </unit>\n <unit Code=\"m[H2O]\" CODE=\"M[H2O]\" isMetric=\"yes\" class=\"clinical\">\n <name>meter of water column</name>\n <printSymbol>m&#160;H<sub>\n <r>2</r>\n </sub>O</printSymbol>\n <property>pressure</property>\n <value Unit=\"kPa\" UNIT=\"KPAL\" value=\"980665e-5\">9.80665</value>\n </unit>\n <unit Code=\"m[Hg]\" CODE=\"M[HG]\" isMetric=\"yes\" class=\"clinical\">\n <name>meter of mercury column</name>\n <printSymbol>m&#160;Hg</printSymbol>\n <property>pressure</property>\n <value Unit=\"kPa\" UNIT=\"KPAL\" value=\"133.3220\">133.3220</value>\n </unit>\n <unit Code=\"[in_i'H2O]\" CODE=\"[IN_I'H2O]\" isMetric=\"no\" class=\"clinical\">\n <name>inch of water column</name>\n <printSymbol>in&#160;H<sub>\n <r>2</r>\n </sub>O</printSymbol>\n <property>pressure</property>\n <value Unit=\"m[H2O].[in_i]/m\" UNIT=\"M[H2O].[IN_I]/M\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[in_i'Hg]\" CODE=\"[IN_I'HG]\" isMetric=\"no\" class=\"clinical\">\n <name>inch of mercury column</name>\n <printSymbol>in&#160;Hg</printSymbol>\n <property>pressure</property>\n <value Unit=\"m[Hg].[in_i]/m\" UNIT=\"M[HG].[IN_I]/M\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[PRU]\" CODE=\"[PRU]\" isMetric=\"no\" class=\"clinical\">\n <name>peripheral vascular resistance unit</name>\n <printSymbol>P.R.U.</printSymbol>\n <property>fluid resistance</property>\n <value Unit=\"mm[Hg].s/ml\" UNIT=\"MM[HG].S/ML\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[wood'U]\" CODE=\"[WOOD'U]\" isMetric=\"no\" class=\"clinical\">\n <name>Wood unit</name>\n <printSymbol>Wood U.</printSymbol>\n <property>fluid resistance</property>\n <value Unit=\"mm[Hg].min/L\" UNIT=\"MM[HG].MIN/L\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[diop]\" CODE=\"[DIOP]\" isMetric=\"no\" class=\"clinical\">\n <name>diopter</name>\n <printSymbol>dpt</printSymbol>\n <property>refraction of a lens</property>\n <value Unit=\"/m\" UNIT=\"/M\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[p'diop]\" CODE=\"[P'DIOP]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>prism diopter</name>\n <printSymbol>PD</printSymbol>\n <property>refraction of a prism</property>\n <value Unit=\"100tan(1 rad)\" UNIT=\"100TAN(1 RAD)\">\n <function name=\"tanTimes100\" value=\"1\" Unit=\"rad\"/>\n </value>\n </unit>\n <unit Code=\"%[slope]\" CODE=\"%[SLOPE]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>percent of slope</name>\n <printSymbol>%</printSymbol>\n <property>slope</property>\n <value Unit=\"100tan(1 rad)\" UNIT=\"100TAN(1 RAD)\">\n <function name=\"100tan\" value=\"1\" Unit=\"deg\"/>\n </value>\n </unit>\n <unit Code=\"[mesh_i]\" CODE=\"[MESH_I]\" isMetric=\"no\" class=\"clinical\">\n <name>mesh</name>\n <property>lineic number</property>\n <value Unit=\"/[in_i]\" UNIT=\"/[IN_I]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[Ch]\" CODE=\"[CH]\" isMetric=\"no\" class=\"clinical\">\n <name>Charri&#232;re</name>\n <name>french</name>\n <printSymbol>Ch</printSymbol>\n <property>gauge of catheters</property>\n <value Unit=\"mm/3\" UNIT=\"MM/3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[drp]\" CODE=\"[DRP]\" isMetric=\"no\" class=\"clinical\">\n <name>drop</name>\n <printSymbol>drp</printSymbol>\n <property>volume</property>\n <value Unit=\"ml/20\" UNIT=\"ML/20\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[hnsf'U]\" CODE=\"[HNSF'U]\" isMetric=\"no\" class=\"clinical\">\n <name>Hounsfield unit</name>\n <printSymbol>HF</printSymbol>\n <property>x-ray attenuation</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[MET]\" CODE=\"[MET]\" isMetric=\"no\" class=\"clinical\">\n <name>metabolic equivalent</name>\n <printSymbol>MET</printSymbol>\n <property>metabolic cost of physical activity</property>\n <value Unit=\"mL/min/kg\" UNIT=\"ML/MIN/KG\" value=\"3.5\">3.5</value>\n </unit>\n <unit Code=\"[hp'_X]\" CODE=\"[HP'_X]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>homeopathic potency of decimal series (retired)</name>\n <printSymbol>X</printSymbol>\n <property>homeopathic potency (retired)</property>\n <value Unit=\"hpX(1 1)\" UNIT=\"HPX(1 1)\">\n <function name=\"hpX\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"[hp'_C]\" CODE=\"[HP'_C]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>homeopathic potency of centesimal series (retired)</name>\n <printSymbol>C</printSymbol>\n <property>homeopathic potency (retired)</property>\n <value Unit=\"hpC(1 1)\" UNIT=\"HPC(1 1)\">\n <function name=\"hpC\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"[hp'_M]\" CODE=\"[HP'_M]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>homeopathic potency of millesimal series (retired)</name>\n <printSymbol>M</printSymbol>\n <property>homeopathic potency (retired)</property>\n <value Unit=\"hpM(1 1)\" UNIT=\"HPM(1 1)\">\n <function name=\"hpM\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"[hp'_Q]\" CODE=\"[HP'_Q]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>homeopathic potency of quintamillesimal series (retired)</name>\n <printSymbol>Q</printSymbol>\n <property>homeopathic potency (retired)</property>\n <value Unit=\"hpQ(1 1)\" UNIT=\"HPQ(1 1)\">\n <function name=\"hpQ\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"[hp_X]\" CODE=\"[HP_X]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of decimal hahnemannian series</name>\n <printSymbol>X</printSymbol>\n <property>homeopathic potency (Hahnemann)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[hp_C]\" CODE=\"[HP_C]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of centesimal hahnemannian series</name>\n <printSymbol>C</printSymbol>\n <property>homeopathic potency (Hahnemann)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[hp_M]\" CODE=\"[HP_M]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of millesimal hahnemannian series</name>\n <printSymbol>M</printSymbol>\n <property>homeopathic potency (Hahnemann)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[hp_Q]\" CODE=\"[HP_Q]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of quintamillesimal hahnemannian series</name>\n <printSymbol>Q</printSymbol>\n <property>homeopathic potency (Hahnemann)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[kp_X]\" CODE=\"[KP_X]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of decimal korsakovian series</name>\n <printSymbol>X</printSymbol>\n <property>homeopathic potency (Korsakov)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[kp_C]\" CODE=\"[KP_C]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of centesimal korsakovian series</name>\n <printSymbol>C</printSymbol>\n <property>homeopathic potency (Korsakov)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[kp_M]\" CODE=\"[KP_M]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of millesimal korsakovian series</name>\n <printSymbol>M</printSymbol>\n <property>homeopathic potency (Korsakov)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[kp_Q]\" CODE=\"[KP_Q]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of quintamillesimal korsakovian series</name>\n <printSymbol>Q</printSymbol>\n <property>homeopathic potency (Korsakov)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"eq\" CODE=\"EQ\" isMetric=\"yes\" class=\"chemical\">\n <name>equivalents</name>\n <printSymbol>eq</printSymbol>\n <property>amount of substance</property>\n <value Unit=\"mol\" UNIT=\"MOL\" value=\"1\">1</value>\n </unit>\n <unit Code=\"osm\" CODE=\"OSM\" isMetric=\"yes\" class=\"chemical\">\n <name>osmole</name>\n <printSymbol>osm</printSymbol>\n <property>amount of substance (dissolved particles)</property>\n <value Unit=\"mol\" UNIT=\"MOL\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pH]\" CODE=\"[PH]\" isMetric=\"no\" isSpecial=\"yes\" class=\"chemical\">\n <name>pH</name>\n <printSymbol>pH</printSymbol>\n <property>acidity</property>\n <value Unit=\"pH(1 mol/l)\" UNIT=\"PH(1 MOL/L)\">\n <function name=\"pH\" value=\"1\" Unit=\"mol/l\"/>\n </value>\n </unit>\n <unit Code=\"g%\" CODE=\"G%\" isMetric=\"yes\" class=\"chemical\">\n <name>gram percent</name>\n <printSymbol>g%</printSymbol>\n <property>mass concentration</property>\n <value Unit=\"g/dl\" UNIT=\"G/DL\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[S]\" CODE=\"[S]\" isMetric=\"no\" class=\"chemical\">\n <name>Svedberg unit</name>\n <printSymbol>S</printSymbol>\n <property>sedimentation coefficient</property>\n <value Unit=\"10*-13.s\" UNIT=\"10*-13.S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[HPF]\" CODE=\"[HPF]\" isMetric=\"no\" class=\"chemical\">\n <name>high power field</name>\n <printSymbol>HPF</printSymbol>\n <property>view area in microscope</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[LPF]\" CODE=\"[LPF]\" isMetric=\"no\" class=\"chemical\">\n <name>low power field</name>\n <printSymbol>LPF</printSymbol>\n <property>view area in microscope</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"100\">100</value>\n </unit>\n <unit Code=\"kat\" CODE=\"KAT\" isMetric=\"yes\" class=\"chemical\">\n <name>katal</name>\n <printSymbol>kat</printSymbol>\n <property>catalytic activity</property>\n <value Unit=\"mol/s\" UNIT=\"MOL/S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"U\" CODE=\"U\" isMetric=\"yes\" class=\"chemical\">\n <name>Unit</name>\n <printSymbol>U</printSymbol>\n <property>catalytic activity</property>\n <value Unit=\"umol/min\" UNIT=\"UMOL/MIN\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[iU]\" CODE=\"[IU]\" isMetric=\"yes\" isArbitrary=\"yes\" class=\"chemical\">\n <name>international unit</name>\n <printSymbol>IU</printSymbol>\n <property>arbitrary</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[IU]\" CODE=\"[IU]\" isMetric=\"yes\" isArbitrary=\"yes\" class=\"chemical\">\n <name>international unit</name>\n <printSymbol>i.U.</printSymbol>\n <property>arbitrary</property>\n <value Unit=\"[iU]\" UNIT=\"[IU]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[arb'U]\" CODE=\"[ARB'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>arbitrary unit</name>\n <printSymbol>arb. U</printSymbol>\n <property>arbitrary</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[USP'U]\" CODE=\"[USP'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>United States Pharmacopeia unit</name>\n <printSymbol>U.S.P.</printSymbol>\n <property>arbitrary</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[GPL'U]\" CODE=\"[GPL'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>GPL unit</name>\n <property>biologic activity of anticardiolipin IgG</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[MPL'U]\" CODE=\"[MPL'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>MPL unit</name>\n <property>biologic activity of anticardiolipin IgM</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[APL'U]\" CODE=\"[APL'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>APL unit</name>\n <property>biologic activity of anticardiolipin IgA</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[beth'U]\" CODE=\"[BETH'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>Bethesda unit</name>\n <property>biologic activity of factor VIII inhibitor</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[anti'Xa'U]\" CODE=\"[ANTI'XA'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>anti factor Xa unit</name>\n <property>biologic activity of factor Xa inhibitor (heparin)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[todd'U]\" CODE=\"[TODD'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>Todd unit</name>\n <property>biologic activity antistreptolysin O</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[dye'U]\" CODE=\"[DYE'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>Dye unit</name>\n <property>biologic activity of amylase</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[smgy'U]\" CODE=\"[SMGY'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>Somogyi unit</name>\n <property>biologic activity of amylase</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[bdsk'U]\" CODE=\"[BDSK'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>Bodansky unit</name>\n <property>biologic activity of phosphatase</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ka'U]\" CODE=\"[KA'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>King-Armstrong unit</name>\n <property>biologic activity of phosphatase</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[knk'U]\" CODE=\"[KNK'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>Kunkel unit</name>\n <property>arbitrary biologic activity</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[mclg'U]\" CODE=\"[MCLG'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>Mac Lagan unit</name>\n <property>arbitrary biologic activity</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[tb'U]\" CODE=\"[TB'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>tuberculin unit</name>\n <property>biologic activity of tuberculin</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[CCID_50]\" CODE=\"[CCID_50]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>50% cell culture infectious dose</name>\n <printSymbol>CCID<sub>50</sub>\n </printSymbol>\n <property>biologic activity (infectivity) of an infectious agent preparation</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[TCID_50]\" CODE=\"[TCID_50]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>50% tissue culture infectious dose</name>\n <printSymbol>TCID<sub>50</sub>\n </printSymbol>\n <property>biologic activity (infectivity) of an infectious agent preparation</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[EID_50]\" CODE=\"[EID_50]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>50% embryo infectious dose</name>\n <printSymbol>EID<sub>50</sub>\n </printSymbol>\n <property>biologic activity (infectivity) of an infectious agent preparation</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[PFU]\" CODE=\"[PFU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>plaque forming units</name>\n <printSymbol>PFU</printSymbol>\n <property>amount of an infectious agent</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[FFU]\" CODE=\"[FFU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>focus forming units</name>\n <printSymbol>FFU</printSymbol>\n <property>amount of an infectious agent</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[CFU]\" CODE=\"[CFU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>colony forming units</name>\n <printSymbol>CFU</printSymbol>\n <property>amount of a proliferating organism</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[IR]\" CODE=\"[IR]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>index of reactivity</name>\n <printSymbol>IR</printSymbol>\n <property>amount of an allergen calibrated through in-vivo testing using the Stallergenes&#174; method</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[BAU]\" CODE=\"[BAU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>bioequivalent allergen unit</name>\n <printSymbol>BAU</printSymbol>\n <property>amount of an allergen calibrated through in-vivo testing based on the ID50EAL method of (intradermal dilution for 50mm sum of erythema diameters</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[AU]\" CODE=\"[AU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>allergen unit</name>\n <printSymbol>AU</printSymbol>\n <property>procedure defined amount of an allergen using some reference standard</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[Amb'a'1'U]\" CODE=\"[AMB'A'1'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>allergen unit for Ambrosia artemisiifolia</name>\n <printSymbol>Amb a 1 U</printSymbol>\n <property>procedure defined amount of the major allergen of ragweed</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[PNU]\" CODE=\"[PNU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>protein nitrogen unit</name>\n <printSymbol>PNU</printSymbol>\n <property>procedure defined amount of a protein substance</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[Lf]\" CODE=\"[LF]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>Limit of flocculation</name>\n <printSymbol>Lf</printSymbol>\n <property>procedure defined amount of an antigen substance</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[D'ag'U]\" CODE=\"[D'AG'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>D-antigen unit</name>\n <printSymbol/>\n <property>procedure defined amount of a poliomyelitis d-antigen substance</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[FEU]\" CODE=\"[FEU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>fibrinogen equivalent unit</name>\n <printSymbol/>\n <property>amount of fibrinogen broken down into the measured d-dimers</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ELU]\" CODE=\"[ELU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>ELISA unit</name>\n <printSymbol/>\n <property>arbitrary ELISA unit</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[EU]\" CODE=\"[EU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>Ehrlich unit</name>\n <printSymbol/>\n <property>Ehrlich unit</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Np\" CODE=\"NEP\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>neper</name>\n <printSymbol>Np</printSymbol>\n <property>level</property>\n <value Unit=\"ln(1 1)\" UNIT=\"LN(1 1)\">\n <function name=\"ln\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"B\" CODE=\"B\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel</name>\n <printSymbol>B</printSymbol>\n <property>level</property>\n <value Unit=\"lg(1 1)\" UNIT=\"LG(1 1)\">\n <function name=\"lg\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"B[SPL]\" CODE=\"B[SPL]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel sound pressure</name>\n <printSymbol>B(SPL)</printSymbol>\n <property>pressure level</property>\n <value Unit=\"2lg(2 10*-5.Pa)\" UNIT=\"2LG(2 10*-5.PAL)\">\n <function name=\"lgTimes2\" value=\"2\" Unit=\"10*-5.Pa\"/>\n </value>\n </unit>\n <unit Code=\"B[V]\" CODE=\"B[V]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel volt</name>\n <printSymbol>B(V)</printSymbol>\n <property>electric potential level</property>\n <value Unit=\"2lg(1 V)\" UNIT=\"2LG(1 V)\">\n <function name=\"lgTimes2\" value=\"1\" Unit=\"V\"/>\n </value>\n </unit>\n <unit Code=\"B[mV]\" CODE=\"B[MV]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel millivolt</name>\n <printSymbol>B(mV)</printSymbol>\n <property>electric potential level</property>\n <value Unit=\"2lg(1 mV)\" UNIT=\"2LG(1 MV)\">\n <function name=\"lgTimes2\" value=\"1\" Unit=\"mV\"/>\n </value>\n </unit>\n <unit Code=\"B[uV]\" CODE=\"B[UV]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel microvolt</name>\n <printSymbol>B(&#956;V)</printSymbol>\n <property>electric potential level</property>\n <value Unit=\"2lg(1 uV)\" UNIT=\"2LG(1 UV)\">\n <function name=\"lgTimes2\" value=\"1\" Unit=\"uV\"/>\n </value>\n </unit>\n <unit Code=\"B[10.nV]\" CODE=\"B[10.NV]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel 10 nanovolt</name>\n <printSymbol>B(10 nV)</printSymbol>\n <property>electric potential level</property>\n <value Unit=\"2lg(10 nV)\" UNIT=\"2LG(10 NV)\">\n <function name=\"lgTimes2\" value=\"10\" Unit=\"nV\"/>\n </value>\n </unit>\n <unit Code=\"B[W]\" CODE=\"B[W]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel watt</name>\n <printSymbol>B(W)</printSymbol>\n <property>power level</property>\n <value Unit=\"lg(1 W)\" UNIT=\"LG(1 W)\">\n <function name=\"lg\" value=\"1\" Unit=\"W\"/>\n </value>\n </unit>\n <unit Code=\"B[kW]\" CODE=\"B[KW]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel kilowatt</name>\n <printSymbol>B(kW)</printSymbol>\n <property>power level</property>\n <value Unit=\"lg(1 kW)\" UNIT=\"LG(1 KW)\">\n <function name=\"lg\" value=\"1\" Unit=\"kW\"/>\n </value>\n </unit>\n <unit Code=\"st\" CODE=\"STR\" isMetric=\"yes\" class=\"misc\">\n <name>stere</name>\n <printSymbol>st</printSymbol>\n <property>volume</property>\n <value Unit=\"m3\" UNIT=\"M3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Ao\" CODE=\"AO\" isMetric=\"no\" class=\"misc\">\n <name>&#197;ngstr&#246;m</name>\n <printSymbol>&#197;</printSymbol>\n <property>length</property>\n <value Unit=\"nm\" UNIT=\"NM\" value=\"0.1\">0.1</value>\n </unit>\n <unit Code=\"b\" CODE=\"BRN\" isMetric=\"no\" class=\"misc\">\n <name>barn</name>\n <printSymbol>b</printSymbol>\n <property>action area</property>\n <value Unit=\"fm2\" UNIT=\"FM2\" value=\"100\">100</value>\n </unit>\n <unit Code=\"att\" CODE=\"ATT\" isMetric=\"no\" class=\"misc\">\n <name>technical atmosphere</name>\n <printSymbol>at</printSymbol>\n <property>pressure</property>\n <value Unit=\"kgf/cm2\" UNIT=\"KGF/CM2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"mho\" CODE=\"MHO\" isMetric=\"yes\" class=\"misc\">\n <name>mho</name>\n <printSymbol>mho</printSymbol>\n <property>electric conductance</property>\n <value Unit=\"S\" UNIT=\"S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[psi]\" CODE=\"[PSI]\" isMetric=\"no\" class=\"misc\">\n <name>pound per square inch</name>\n <printSymbol>psi</printSymbol>\n <property>pressure</property>\n <value Unit=\"[lbf_av]/[in_i]2\" UNIT=\"[LBF_AV]/[IN_I]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"circ\" CODE=\"CIRC\" isMetric=\"no\" class=\"misc\">\n <name>circle</name>\n <printSymbol>circ</printSymbol>\n <property>plane angle</property>\n <value Unit=\"[pi].rad\" UNIT=\"[PI].RAD\" value=\"2\">2</value>\n </unit>\n <unit Code=\"sph\" CODE=\"SPH\" isMetric=\"no\" class=\"misc\">\n <name>sphere</name>\n <printSymbol>sph</printSymbol>\n <property>solid angle</property>\n <value Unit=\"[pi].sr\" UNIT=\"[PI].SR\" value=\"4\">4</value>\n </unit>\n <unit Code=\"[car_m]\" CODE=\"[CAR_M]\" isMetric=\"no\" class=\"misc\">\n <name>metric carat</name>\n <printSymbol>ct<sub>m</sub>\n </printSymbol>\n <property>mass</property>\n <value Unit=\"g\" UNIT=\"G\" value=\"2e-1\">0.2</value>\n </unit>\n <unit Code=\"[car_Au]\" CODE=\"[CAR_AU]\" isMetric=\"no\" class=\"misc\">\n <name>carat of gold alloys</name>\n <printSymbol>ct<sub>\n <r>Au</r>\n </sub>\n </printSymbol>\n <property>mass fraction</property>\n <value Unit=\"/24\" UNIT=\"/24\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[smoot]\" CODE=\"[SMOOT]\" isMetric=\"no\" class=\"misc\">\n <name>Smoot</name>\n <printSymbol/>\n <property>length</property>\n <value Unit=\"[in_i]\" UNIT=\"[IN_I]\" value=\"67\">67</value>\n </unit>\n <unit Code=\"[m/s2/Hz^(1/2)]\" CODE=\"[M/S2/HZ^(1/2)]\" isMetric=\"no\" isSpecial=\"yes\"\n class=\"misc\">\n <name>meter per square seconds per square root of hertz</name>\n <printSymbol/>\n <property>amplitude spectral density</property>\n <value Unit=\"sqrt(1 m2/s4/Hz)\" UNIT=\"SQRT(1 M2/S4/HZ)\">\n <function name=\"sqrt\" value=\"1\" Unit=\"m2/s4/Hz\"/>\n </value>\n </unit>\n <unit Code=\"[NTU]\" CODE=\"[NTU]\" isMetric=\"no\" class=\"misc\">\n <name>Nephelometric Turbidity Unit</name>\n <printSymbol/>\n <property>turbidity</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[FNU]\" CODE=\"[FNU]\" isMetric=\"no\" class=\"misc\">\n <name>Formazin Nephelometric Unit</name>\n <printSymbol/>\n <property>turbidity</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"bit_s\" CODE=\"BIT_S\" isMetric=\"no\" isSpecial=\"yes\" class=\"infotech\">\n <name>bit</name>\n <printSymbol>bit<sub>s</sub>\n </printSymbol>\n <property>amount of information</property>\n <value Unit=\"ld(1 1)\" UNIT=\"ld(1 1)\">\n <function name=\"ld\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"bit\" CODE=\"BIT\" isMetric=\"yes\" class=\"infotech\">\n <name>bit</name>\n <printSymbol>bit</printSymbol>\n <property>amount of information</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"By\" CODE=\"BY\" isMetric=\"yes\" class=\"infotech\">\n <name>byte</name>\n <printSymbol>B</printSymbol>\n <property>amount of information</property>\n <value Unit=\"bit\" UNIT=\"bit\" value=\"8\">8</value>\n </unit>\n <unit Code=\"Bd\" CODE=\"BD\" isMetric=\"yes\" class=\"infotech\">\n <name>baud</name>\n <printSymbol>Bd</printSymbol>\n <property>signal transmission rate</property>\n <value Unit=\"/s\" UNIT=\"/s\" value=\"1\">1</value>\n </unit>\n <prefix Code=\"Ki\" CODE=\"KIB\">\n <name>kibi</name>\n <printSymbol>Ki</printSymbol>\n <value value=\"1024\">1024</value>\n </prefix>\n <prefix Code=\"Mi\" CODE=\"MIB\">\n <name>mebi</name>\n <printSymbol>Mi</printSymbol>\n <value value=\"1048576\">1048576</value>\n </prefix>\n <prefix Code=\"Gi\" CODE=\"GIB\">\n <name>gibi</name>\n <printSymbol>Gi</printSymbol>\n <value value=\"1073741824\">1073741824</value>\n </prefix>\n <prefix Code=\"Ti\" CODE=\"TIB\">\n <name>tebi</name>\n <printSymbol>Ti</printSymbol>\n <value value=\"1099511627776\">1099511627776</value>\n </prefix>\n</root>`;\n","/**\n * Parse the vendored, verbatim UCUM `ucum-essence.xml` (embedded as {@link UCUM_ESSENCE_XML}) into\n * the engine's in-memory unit model — the {@link UcumEssence} table of prefixes and atoms.\n *\n * Hand-rolled, **zero-dependency** scanning of a known-well-formed document (not a general XML\n * parser): the essence file is a flat, regular list of `<prefix>` / `<base-unit>` / `<unit>`\n * elements. Parsed **once**, lazily, and cached — the engine reads no file at runtime; the table is\n * a pure in-process transform of the embedded verbatim content, never serialized or distributed. The\n * UCUM table is copyright © Regenstrief Institute, Inc. and is bundled verbatim — see\n * `vendor/ucum/NOTICE.md`, which ships with this package.\n *\n * @packageDocumentation\n */\n\nimport { UCUM_ESSENCE_XML } from \"./essence-data.generated.js\";\nimport type { UcumAtom, UcumEssence, UcumPrefix } from \"./types.js\";\n\n/** Read an XML attribute value (`name=\"value\"`) from an element's opening tag. */\nfunction attr(tag: string, name: string): string | undefined {\n const m = new RegExp(`\\\\b${name}=\"([^\"]*)\"`).exec(tag);\n return m?.[1];\n}\n\n/** The nested `<value ... value=\"…\" Unit=\"…\">` of a `<unit>` element, when present. */\nfunction readValue(block: string): { factor: number; unit: string } | undefined {\n const m = /<value\\b([^>]*)>/.exec(block);\n if (!m?.[1]) return undefined;\n const valueAttr = attr(m[1], \"value\");\n const unitAttr = attr(m[1], \"Unit\");\n if (valueAttr === undefined || unitAttr === undefined) return undefined;\n const factor = Number(valueAttr);\n if (!Number.isFinite(factor)) return undefined;\n return { factor, unit: unitAttr };\n}\n\n/**\n * Parse a UCUM essence XML document into the prefix + atom tables. Exported for the drift/robustness\n * tests (feeding it malformed rows); production code calls {@link loadUcumEssence}, which caches.\n *\n * The table it returns is **deeply frozen** — every atom, every atom's definition, every prefix and\n * both arrays — so the `readonly` on those is enforced when the code runs and not only when it\n * compiles. The two lookup maps refuse `set` / `delete` / `clear`; a `Map` cannot be made immutable\n * in place, so that is the direct route and not every route (see {@link sealLookup}).\n *\n * @param xml - The essence XML (the vendored verbatim document, or a test fragment).\n * @returns The parsed {@link UcumEssence} model, frozen.\n * @example\n * ```ts\n * import { parseEssence } from \"@cosyte/terminology/ucum/essence\";\n *\n * const table = parseEssence('<root><base-unit Code=\"m\" dim=\"L\"><name>m</name></base-unit></root>');\n * table.atomByCode.get(\"m\")?.base; // => true\n * ```\n */\nexport function parseEssence(xml: string): UcumEssence {\n const prefixes: UcumPrefix[] = [];\n const atoms: UcumAtom[] = [];\n\n for (const m of xml.matchAll(/<prefix\\b([^>]*)>([\\s\\S]*?)<\\/prefix>/g)) {\n /* v8 ignore next 2 -- matchAll always yields both capture groups; the `?? \"\"` is a type fallback */\n const openTag = m[1] ?? \"\";\n const body = m[2] ?? \"\";\n const code = attr(openTag, \"Code\");\n // A prefix's `<value>` carries only a `value` attribute (no `Unit`) — read it directly.\n const valueTag = /<value\\b([^>]*)>/.exec(body);\n const valueAttr = valueTag?.[1] === undefined ? undefined : attr(valueTag[1], \"value\");\n const factor = valueAttr === undefined ? NaN : Number(valueAttr);\n if (code !== undefined && Number.isFinite(factor)) prefixes.push({ code, factor });\n }\n\n for (const m of xml.matchAll(/<base-unit\\b([^>]*)>/g)) {\n /* v8 ignore next -- matchAll always yields the capture group; the `?? \"\"` is a type fallback */\n const openTag = m[1] ?? \"\";\n const code = attr(openTag, \"Code\");\n if (code === undefined) continue;\n atoms.push({\n code,\n metric: true,\n base: true,\n dim: code,\n special: false,\n arbitrary: false,\n });\n }\n\n for (const m of xml.matchAll(/<unit\\b([^>]*)>([\\s\\S]*?)<\\/unit>/g)) {\n /* v8 ignore next 2 -- matchAll always yields both capture groups; the `?? \"\"` is a type fallback */\n const openTag = m[1] ?? \"\";\n const body = m[2] ?? \"\";\n const code = attr(openTag, \"Code\");\n if (code === undefined) continue;\n const special = attr(openTag, \"isSpecial\") === \"yes\";\n const arbitrary = attr(openTag, \"isArbitrary\") === \"yes\";\n // Special units are non-linear (a `<function>`, not a scalar) — never carry a linear value.\n const value = special ? undefined : readValue(body);\n atoms.push({\n code,\n metric: attr(openTag, \"isMetric\") === \"yes\",\n base: false,\n special,\n arbitrary,\n ...(value ? { value } : {}),\n });\n }\n\n // Longest symbols first so greedy matching resolves e.g. `min` (minute) before `m` (metre) and\n // `da` (deca) before the 1-char prefixes.\n prefixes.sort((a, b) => b.code.length - a.code.length);\n atoms.sort((a, b) => b.code.length - a.code.length);\n\n const atomByCode = new Map(atoms.map((a) => [a.code, a]));\n const prefixByCode = new Map(prefixes.map((p) => [p.code, p]));\n return freezeEssence({ prefixes, atoms, atomByCode, prefixByCode });\n}\n\n/** Refuse a write to the shared unit table. Named so the throw site reads as the table's own rule. */\nfunction refuseTableWrite(): never {\n throw new TypeError(\"the UCUM unit table is immutable\");\n}\n\n/**\n * Refuse `set` / `delete` / `clear` on a lookup map, which `Object.freeze` cannot: a `Map` keeps its\n * entries in internal slots, so freezing the object leaves the prototype's mutators working.\n *\n * **This closes the direct route and not every route, and the difference is measured rather than\n * assumed.** `Map.prototype.set.call(table.atomByCode, …)` still inserts. What that reaches is\n * bounded by where the maps are read: {@link parseUcum} resolves an atom by scanning `atoms`, never\n * through `atomByCode`, so an entry forced in this way changes **no** reduction and no `ucumEqual`\n * answer — only what the caller's own `atomByCode.get` hands back. Both halves are pinned in\n * `test/ucum/essence-immutable.test.ts`.\n */\nfunction sealLookup<V>(map: Map<string, V>): ReadonlyMap<string, V> {\n return Object.defineProperties(map, {\n set: { value: refuseTableWrite },\n delete: { value: refuseTableWrite },\n clear: { value: refuseTableWrite },\n });\n}\n\n/**\n * Make the parsed table immutable **at run time**, not only to the type checker.\n *\n * Every field of {@link UcumEssence} and {@link UcumAtom} is `readonly`, which TypeScript erases:\n * until this change nothing here froze anything, so a consumer holding the table\n * {@link loadUcumEssence} handed it could write an atom's definition in place. That is not a\n * cosmetic hole. `reduce` memoizes each atom's reduction against the atom **object**, so corrupting\n * a loaded atom **before its first reduction** writes the memo, and the reading survives putting the\n * table back exactly as shipped. Measured on `bf153cb` with the litre defined as `1`:\n * `ucumEqual(\"L\", \"1\")` and `ucumEqual(\"mg/L\", \"mg\")` both answered `true` where the uncorrupted\n * control answered `false`, and `mmol/L` fell from `6.0221407599999985e+23 × m-3` to a dimensionless\n * `6.02214076e+20` — a concentration reading equal to a mass, out of an engine whose stated\n * invariant is that it never fabricates.\n *\n * **The freeze has to be deep, and a shallow one is worth nothing here**: freezing the atom alone\n * leaves `atom.value.unit = \"1\"`, which reproduces the same three readings. The `atoms` array is\n * frozen too, because that is the one {@link parseUcum} scans — replacing an element there hands the\n * parser a forged atom directly, with the same result and without touching the memo at all.\n *\n * Note that `Object.freeze` refuses a write by **throwing in strict mode and silently ignoring it in\n * sloppy mode**. The invariant this function provides is therefore *the table does not change*,\n * which holds in both; the `TypeError` a strict-mode caller sees is how that is observed, not what\n * is promised.\n */\nfunction freezeEssence(essence: UcumEssence): UcumEssence {\n for (const atom of essence.atoms) {\n if (atom.value) Object.freeze(atom.value);\n Object.freeze(atom);\n }\n for (const prefix of essence.prefixes) Object.freeze(prefix);\n Object.freeze(essence.atoms);\n Object.freeze(essence.prefixes);\n sealLookup(essence.atomByCode as Map<string, UcumAtom>);\n sealLookup(essence.prefixByCode as Map<string, UcumPrefix>);\n return Object.freeze(essence);\n}\n\nlet cached: UcumEssence | undefined;\n\n/**\n * Load the UCUM essence table, parsing the embedded verbatim XML on first call and caching it.\n *\n * One table is shared by every caller and by the engine itself, so it is handed out **frozen**: an\n * atom's definition cannot be rewritten in place, and neither can the `atoms` array the parser\n * scans. It used to be, and doing so before that atom's first reduction poisoned the\n * reduction memo for the life of the process — a fabricated unit equivalence that survived putting\n * the table back. A write is refused, which in strict mode means a `TypeError`.\n *\n * @returns The shared, frozen in-memory {@link UcumEssence} model.\n * @example\n * ```ts\n * import { loadUcumEssence } from \"@cosyte/terminology\";\n *\n * const essence = loadUcumEssence();\n * essence.atomByCode.has(\"m\"); // => true\n * ```\n */\nexport function loadUcumEssence(): UcumEssence {\n cached ??= parseEssence(UCUM_ESSENCE_XML);\n return cached;\n}\n","/**\n * The **UCUM grammar parser**: a hand-rolled, zero-dependency recursive-descent\n * parser from a unit expression string to a {@link UnitNode} AST, grounded firsthand on the UCUM\n * specification's syntax (base units, metric prefixes attached with no delimiter and resolved by\n * longest-match, `.` multiply / `/` divide, signed integer exponents, `{…}` inert annotations, and\n * the `10*` / `10^` powers-of-ten). Validation **is** parsing: an expression is valid iff it parses\n * completely over **known** atoms — an unknown atom yields no match and fails, never a guessed unit.\n *\n * @packageDocumentation\n */\n\nimport { loadUcumEssence } from \"./essence.js\";\nimport type {\n ComponentNode,\n SimpleUnitNode,\n UcumAtom,\n UcumEssence,\n UcumPrefix,\n UnitNode,\n} from \"./types.js\";\n\n/** A successful parse (the AST) or a value-free failure reason. */\nexport type ParseResult = { readonly ok: true; readonly node: UnitNode } | ParseFailure;\n\n/** A parse failure carrying a value-free structural reason. */\nexport interface ParseFailure {\n readonly ok: false;\n /** A structural description of the fault (never echoes an input *value* beyond the offending token shape). */\n readonly reason: string;\n}\n\nconst isDigitCode = (cc: number): boolean => cc >= 0x30 && cc <= 0x39;\nconst isDigitAt = (s: string, i: number): boolean => isDigitCode(s.charCodeAt(i));\n\n/** A component followed by anything but end / `.` / `/` / `)` is a juxtaposition error. */\nfunction atBoundary(s: string, pos: number): boolean {\n if (pos >= s.length) return true;\n const c = s[pos];\n return c === \".\" || c === \"/\" || c === \")\";\n}\n\n/** One candidate interpretation of a simple unit at a position: a prefix?+atom consuming `len` chars. */\ninterface SimpleMatch {\n readonly prefix?: UcumPrefix;\n readonly atom: UcumAtom;\n readonly len: number;\n}\n\n/**\n * All plausible (prefix?+atom) interpretations at `pos`, ordered by preference: longer total match\n * first, and a bare atom before a prefixed one on a tie (so `Pa` is pascal, not peta-are). The\n * caller commits to the first whose continuation lands on a component boundary.\n */\nfunction simpleMatches(essence: UcumEssence, s: string, pos: number): SimpleMatch[] {\n const out: SimpleMatch[] = [];\n for (const atom of essence.atoms) {\n if (s.startsWith(atom.code, pos)) out.push({ atom, len: atom.code.length });\n }\n for (const prefix of essence.prefixes) {\n if (!s.startsWith(prefix.code, pos)) continue;\n const rem = pos + prefix.code.length;\n for (const atom of essence.atoms) {\n if (atom.metric && s.startsWith(atom.code, rem)) {\n out.push({ prefix, atom, len: prefix.code.length + atom.code.length });\n }\n }\n }\n out.sort((a, b) => b.len - a.len || (a.prefix ? 1 : 0) - (b.prefix ? 1 : 0));\n return out;\n}\n\ninterface Cursor {\n readonly s: string;\n pos: number;\n /** Current parenthesis-nesting depth — capped to keep hostile input from overflowing the stack. */\n depth: number;\n readonly essence: UcumEssence;\n}\n\n/**\n * Maximum parenthesis nesting. Real UCUM units nest a handful of levels at most; a cap keeps a\n * hostile input (e.g. thousands of `(`) from overflowing the recursive-descent stack — it degrades\n * to a typed invalid, never a crash: the parser does not crash on hostile input.\n */\nconst MAX_PAREN_DEPTH = 100;\n\n/** Parse an optional signed-integer exponent at the cursor. Returns the value (default 1). */\nfunction parseExponent(cur: Cursor): { value: number; consumed: boolean } {\n const { s } = cur;\n let i = cur.pos;\n let sign = 1;\n if (s[i] === \"+\") i++;\n else if (s[i] === \"-\") {\n sign = -1;\n i++;\n }\n const start = i;\n while (i < s.length && isDigitAt(s, i)) i++;\n if (i === start) return { value: 1, consumed: false }; // no digits — no exponent\n cur.pos = i;\n return { value: sign * Number(s.slice(start, i)), consumed: true };\n}\n\n/** Parse and validate a `{…}` annotation, advancing past the closing brace. */\nfunction parseAnnotation(cur: Cursor): ParseFailure | undefined {\n const { s } = cur;\n let i = cur.pos + 1; // skip '{'\n for (; i < s.length; i++) {\n const code = s.charCodeAt(i);\n if (code === 0x7d /* } */) {\n cur.pos = i + 1;\n return undefined;\n }\n // Annotation text is printable ASCII (0x20–0x7E) except the curly braces — no Unicode.\n if (code < 0x20 || code > 0x7e || code === 0x7b /* { */) {\n return { ok: false, reason: \"annotation contains a non-ASCII or illegal character\" };\n }\n }\n return { ok: false, reason: \"annotation is not closed with '}'\" };\n}\n\n/** Parse a simple unit (prefix?+atom) + optional exponent, committing to the first valid boundary. */\nfunction parseSimpleUnit(cur: Cursor): { ok: true; node: SimpleUnitNode } | ParseFailure {\n const candidates = simpleMatches(cur.essence, cur.s, cur.pos);\n for (const cand of candidates) {\n const save = cur.pos;\n cur.pos = save + cand.len;\n const exp = parseExponent(cur);\n // `10*` / `10^` are the powers-of-ten — they require an explicit exponent.\n if ((cand.atom.code === \"10*\" || cand.atom.code === \"10^\") && !exp.consumed) {\n cur.pos = save;\n continue;\n }\n // An annotation may ride on the simple unit; the boundary is checked after it.\n let annotationEnd = cur.pos;\n if (cur.s.charCodeAt(cur.pos) === 0x7b /* { */) {\n const err = parseAnnotation(cur);\n if (err) {\n cur.pos = save;\n return err;\n }\n annotationEnd = cur.pos;\n }\n if (atBoundary(cur.s, annotationEnd)) {\n const node: SimpleUnitNode = cand.prefix\n ? { kind: \"simple\", prefix: cand.prefix, atom: cand.atom, exponent: exp.value }\n : { kind: \"simple\", atom: cand.atom, exponent: exp.value };\n return { ok: true, node };\n }\n cur.pos = save; // this interpretation doesn't reach a boundary — try the next\n }\n return { ok: false, reason: \"unrecognized unit atom\" };\n}\n\n/** Parse a single component: a group `( … )`, an annotation-only term, a factor, or a simple unit. */\nfunction parseComponent(cur: Cursor): { ok: true; node: ComponentNode } | ParseFailure {\n const { s } = cur;\n const cc = s.charCodeAt(cur.pos); // NaN at end-of-input — falls through to the atom parser\n\n if (cc === 0x28 /* ( */) {\n if (cur.depth >= MAX_PAREN_DEPTH) {\n return { ok: false, reason: \"parentheses nested too deeply\" };\n }\n cur.pos++;\n cur.depth++;\n const inner = parseTerm(cur, true);\n cur.depth--;\n if (!inner.ok) return inner;\n return { ok: true, node: { kind: \"group\", term: inner.node } };\n }\n\n if (cc === 0x7b /* { */) {\n const err = parseAnnotation(cur);\n if (err) return err;\n return { ok: true, node: { kind: \"annotation\" } };\n }\n\n // A bare integer factor (e.g. the `4` in `4.[pi]`) — but `10*n` / `10^n` are simple units, not factors.\n if (isDigitCode(cc) && !s.startsWith(\"10*\", cur.pos) && !s.startsWith(\"10^\", cur.pos)) {\n const start = cur.pos;\n while (cur.pos < s.length && isDigitAt(s, cur.pos)) cur.pos++;\n if (s.charCodeAt(cur.pos) === 0x7b /* { */) {\n const err = parseAnnotation(cur);\n if (err) return err;\n }\n if (!atBoundary(s, cur.pos)) {\n return { ok: false, reason: \"a numeric factor must be followed by an operator\" };\n }\n return { ok: true, node: { kind: \"factor\", value: Number(s.slice(start, cur.pos)) } };\n }\n\n return parseSimpleUnit(cur);\n}\n\n/** Parse a term: components joined by `.` / `/`, with a leading `/` meaning `1/…`. */\nfunction parseTerm(cur: Cursor, inParen: boolean): { ok: true; node: UnitNode } | ParseFailure {\n const factors: Array<{ sign: 1 | -1; node: ComponentNode }> = [];\n\n let sign: 1 | -1 = 1;\n if (cur.s[cur.pos] === \"/\") {\n sign = -1;\n cur.pos++;\n }\n const first = parseComponent(cur);\n if (!first.ok) return first;\n factors.push({ sign, node: first.node });\n\n while (cur.pos < cur.s.length) {\n const op = cur.s[cur.pos];\n if (op !== \".\" && op !== \"/\") break;\n cur.pos++;\n const comp = parseComponent(cur);\n if (!comp.ok) return comp;\n factors.push({ sign: op === \"/\" ? -1 : 1, node: comp.node });\n }\n\n if (inParen) {\n if (cur.s[cur.pos] !== \")\") return { ok: false, reason: \"unbalanced '(' — missing ')'\" };\n cur.pos++;\n }\n return { ok: true, node: { kind: \"term\", factors } };\n}\n\n/**\n * Parse a UCUM unit expression into an AST.\n *\n * @param unit - The unit expression (e.g. `\"mmol/L\"`, `\"kg.m/s2\"`, `\"10*3/ul\"`).\n * @returns The parsed {@link UnitNode}, or a typed {@link ParseFailure} with a value-free reason.\n * @example\n * ```ts\n * import { parseUcum } from \"@cosyte/terminology\";\n *\n * parseUcum(\"mmol/L\").ok; // => true\n * parseUcum(\"m/\").ok; // => false\n * ```\n */\nexport function parseUcum(unit: string): ParseResult {\n if (unit.length === 0) return { ok: false, reason: \"empty unit expression\" };\n const cur: Cursor = { s: unit, pos: 0, depth: 0, essence: loadUcumEssence() };\n const result = parseTerm(cur, false);\n if (!result.ok) return result;\n if (cur.pos !== unit.length) {\n return { ok: false, reason: \"unexpected trailing input (missing operator?)\" };\n }\n return { ok: true, node: result.node };\n}\n","/**\n * **Dimensional reduction** of a parsed UCUM unit: reduce an expression to its\n * canonical base-unit form — a scalar factor times a map of the seven UCUM base dimensions\n * (`m s g rad K C cd`), recursively substituting each atom's essence definition down to base units.\n *\n * This is **representation** canonicalization, not magnitude *conversion*: it answers \"are these two\n * expressions the same unit\" (`N` ≡ `kg.m/s2`, `mmol/L` ≡ `mmol.L-1`), never \"what is 5 mg/dL in\n * mmol/L\" (that needs an analyte's molar mass, which the engine refuses). **Special** units (`Cel`,\n * `B`, `[pH]`) are non-linear and carry no factor/dimension — they reduce to an opaque normalized\n * form and are never equated with a linear unit. **Arbitrary** units (`[IU]`, `[arb'U]`) are modeled\n * as their own dimension axis, so they cancel with themselves but convert to nothing else.\n *\n * @packageDocumentation\n */\n\nimport { parseUcum } from \"./parse.js\";\nimport type {\n ComponentNode,\n LinearReduction,\n Reduction,\n SimpleUnitNode,\n UcumAtom,\n UnitNode,\n} from \"./types.js\";\n\n/** Multiply two linear reductions (add dimension exponents, multiply factors). */\nfunction multiply(a: LinearReduction, b: LinearReduction): LinearReduction {\n const dims: Record<string, number> = { ...a.dims };\n for (const [k, v] of Object.entries(b.dims)) {\n const next = (dims[k] ?? 0) + v;\n if (next === 0) delete dims[k];\n else dims[k] = next;\n }\n return { kind: \"linear\", factor: a.factor * b.factor, dims };\n}\n\n/** Raise a linear reduction to an integer power (factor exponentiated, exponents scaled). */\nfunction power(r: LinearReduction, p: number): LinearReduction {\n if (p === 1) return r;\n const dims: Record<string, number> = {};\n for (const [k, v] of Object.entries(r.dims)) {\n const e = v * p;\n if (e !== 0) dims[k] = e;\n }\n return { kind: \"linear\", factor: Math.pow(r.factor, p), dims };\n}\n\n/**\n * The dimensionless reduction, used as an internal building block. **Frozen, and never handed to a\n * caller**: it is module-global, so a consumer able to mutate the object it received would be\n * mutating the engine. On `0.0.5` it was neither — `reduce` returned it for a term with no factors,\n * and setting `dims.m = 1` and `factor = 999` on that result made every later reduction in the\n * process start from those, so `kg.m/s2` came back as `999000 × m2.g.s-2` and\n * `ucumEqual(\"N\", \"kg.m/s2\")` answered `false`. {@link linearReduceTerm} now accumulates from a\n * fresh object, so the reductions callers receive are per-call and mutable as before, and the freeze\n * keeps a later path that returns this one from re-opening the same hole silently.\n */\nconst DIMENSIONLESS: LinearReduction = Object.freeze({\n kind: \"linear\",\n factor: 1,\n dims: Object.freeze({}),\n});\n\n/**\n * The per-atom memo of a completed reduction, and the guard against an atom whose definition leads\n * back to itself. **Both are keyed on the atom OBJECT, never on `atom.code`.**\n *\n * Keying on the code string made these tables a channel between atoms that merely share a code.\n * `reduce` is exported and takes a caller-built `UnitNode`, and nothing checks that an atom on it\n * came from the vendored table, so a forged atom wrote under a shipped atom's key and every later\n * reduction of the shipped atom in that process read what the forged one left. Measured on `0.0.5`,\n * forging `{ code: \"L\" }` with no `value` as the first touch of `L`: `ucumEqual(\"L\", \"1\")` and\n * `ucumEqual(\"mg/L\", \"mg\")` both answered `true` (control: `false`), and `mmol/L` reduced without\n * its `m-3` — a concentration reading equal to a mass, out of a never-fabricate engine.\n *\n * Identity keying makes an entry describe the atom it was computed from, and it does not cost the\n * hot path: the atoms `parseUcum` resolves are the singletons `loadUcumEssence` caches, so a parsed\n * expression still finds one entry per atom, and the lookup is a reference compare rather than a\n * string hash. Benchmarked warm against the string-keyed original two ways — separate processes,\n * and both trees alternating inside one process, best-of-n over hundreds of thousands of `reduce`\n * calls — the difference did **not** reproduce in either direction: over twelve alternating trials\n * the head/base ratio landed above 1 four times and below it eight, spread far wider than any\n * difference between the two. So the claim here is\n * only that identity keying has **no measured cost on the hot path**, and no figures are quoted,\n * because three drafts quoted three pairs and none of them was reproducible. Do not add one back.\n * An atom a caller\n * built gets its own entry, collected with it — the containers hold their keys weakly, so forged\n * atoms cannot accumulate either.\n *\n * **Identity keying closes the forged-atom route and does not reach the mutation one, so the other\n * half of the answer lives in `essence.ts`.** An entry describing the atom it was computed from is\n * still a lie if that atom was rewritten before it was computed: until this change the shared table\n * was `readonly` to TypeScript only, and defining the loaded litre as `1` before the litre's first\n * reduction made `ucumEqual(\"L\", \"1\")` answer `true` for the life of the process, even after the\n * table was put back. The table is frozen now. Neither half substitutes for the other.\n */\nconst atomMemo = new WeakMap<UcumAtom, LinearReduction>();\nconst inProgress = new WeakSet<UcumAtom>();\n\n/** Reduce a single (non-special) atom to base units, memoized per atom. */\nfunction reduceAtomLinear(atom: UcumAtom): LinearReduction {\n // Every base atom in the bundled table carries its `dim`, but this function is reachable with an\n // atom a caller assembled, so `?? atom.code` is a real arm rather than a type-narrowing fallback\n // and is covered as one. It used to sit under a `/* v8 ignore next */` asserting the table's\n // property as if it were the exported surface's — the same over-scoped claim that hid a leak one\n // function over. Answering a forged base atom on its own code changes nothing for the table's\n // atoms: it is keyed by identity like every other memo entry.\n if (atom.base) return { kind: \"linear\", factor: 1, dims: { [atom.dim ?? atom.code]: 1 } };\n // Arbitrary units are not commensurable with anything else: give each its own dimension axis.\n if (atom.arbitrary) return { kind: \"linear\", factor: 1, dims: { [`arb:${atom.code}`]: 1 } };\n\n const cached = atomMemo.get(atom);\n if (cached) return cached;\n\n // The three guards below. No expression `parseUcum` accepts reaches any of them, but **that is a\n // property of `reduce`'s own control flow, not of the unit table** — an earlier wording of this\n // comment said the table's atoms all carry a resolvable definition and that was false. Measured on\n // the bundled v2.2 table: of its 312 atoms, 28 carry no `value` at all — the 7 base units and the\n // 21 special ones (`Cel`, `[pH]`, `B`, `Np`, `[degF]`, …), 0 arbitrary. What keeps them out of\n // here is that `reduce` short-circuits a special-containing expression to the opaque `special`\n // form before any linear reduction, and base and arbitrary atoms are answered above. Of the 291\n // non-special atoms — the 7 base units, answered above, plus the 284 that carry a `value` — every\n // one reduces fully: no definition chain in the table reaches a value-less atom, an unparseable\n // definition, or a cycle. **284 is the count that carries a `value`, not the count of non-special\n // atoms**, and a draft of this comment attached it to the wrong noun; both are asserted in\n // `test/ucum/reduce-memo.test.ts` so neither can drift from the table. That file's last case is\n // the sweep this comment rests on.\n //\n // Reachability differs per guard, and this is deliberate. A caller-assembled atom reaches the two\n // below it: nothing checks an atom's provenance, and an atom **defined in terms of a special unit**\n // (`{ value: { unit: \"Cel\" } }`) lands on the table's own `Cel` in the no-linear-definition guard.\n // The cyclic guard is reached differently again, and this took three wrong descriptions to get\n // right — do not re-derive it from the shape of the code, because the shape is misleading. Naming\n // is not enough: a definition is resolved by `parseUcum` against the loaded table, so an assembled\n // atom, or one off a second table built with `parseEssence`, can name a table atom but never be\n // one; a self-referential `Pa` taken off a table copy resolves to the shipped pascal and answers\n // 1000 g.m-1.s-2. Corrupting a *loaded* atom in place used to reach it and no longer does, because\n // the table is frozen. **What reaches it is an ACCESSOR**: `UcumAtom.value` is `readonly` to\n // TypeScript only, which a getter satisfies, and `atom.value.unit` is read *below*, after\n // `inProgress.add(atom)` — so a caller's getter runs inside the recursion and can re-enter\n // `reduce` with this very atom. No mutation, no table, no cast. That is a supported public call\n // and it is pinned in `test/ucum/reduce.test.ts`, under a 100,000-byte atom code, so this guard\n // is covered rather than excluded. A definition cycle in the vendored table would reach it too,\n // and the whole-table sweep in `reduce-memo.test.ts` asserts there is not one today.\n //\n // Every message here is a literal. A caller-assembled `atom.code` is unbounded: interpolating one\n // produced a 1,000,042-byte `Error.message`, with those same bytes in `err.stack`, on `0.0.5`.\n // Do not put an atom back into a message, and do not memoize an answer for an atom none of these\n // let through. All three are pinned in `test/ucum/reduce.test.ts` by whole-message equality, a\n // length bound, and `err.stack` under a 100,000-byte caller-supplied code. Equality is the\n // load-bearing part — `toThrowError(string)` is a substring match, and a draft that used only that\n // stayed green with the atom interpolated back in.\n if (inProgress.has(atom)) {\n throw new Error(\"cyclic UCUM atom definition in the unit table\");\n }\n if (!atom.value) {\n // This atom carries no linear definition and is neither a base nor an arbitrary unit, so there\n // is nothing to reduce. Answering \"dimensionless\" here is what let a value-less assembled `L`\n // equal `1`. The message says \"no linear definition\" rather than blaming the table, because both\n // its reachable cases are real: an atom that was never in the table, and a shipped **special**\n // atom, which is in the table and legitimately has no linear form.\n throw new Error(\"UCUM atom has no linear definition\");\n }\n\n inProgress.add(atom);\n try {\n const parsed = parseUcum(atom.value.unit);\n if (!parsed.ok) {\n throw new Error(\"unparseable UCUM essence definition in the unit table\");\n }\n const reduced = linearReduceTerm(parsed.node);\n const result = multiply({ kind: \"linear\", factor: atom.value.factor, dims: {} }, reduced);\n atomMemo.set(atom, result);\n return result;\n } finally {\n // `finally`, because `linearReduceTerm` can throw while this atom is marked in progress — an\n // atom defined in terms of a special unit reaches the no-linear-definition guard from inside the\n // recursion, and one whose definition does not parse reaches the guard just above. The delete\n // used to sit on the success path only, so the entry stayed behind and every later reduction\n // touching that atom hit the cyclic guard for the rest of the process. Measured on published\n // `0.0.5`, where a forged atom coded `N` and defined as `N` did re-enter the cyclic guard,\n // because the keys were code strings: after one such call every `ucumEqual(\"N\", \"kg.m/s2\")`\n // threw. **That route is closed here** — identity keys mean an assembled atom is never the table\n // atom its definition names, and the same call now reduces cleanly. The `finally` is still\n // load-bearing, for the two throws named above rather than for that one. Do not read the message\n // literals in this file back onto `0.0.5`: it threw `cyclic UCUM atom definition for 'N'`, still\n // interpolating the atom. These literals are newer than that build.\n inProgress.delete(atom);\n }\n}\n\n/** Reduce a simple unit (prefix?+atom+exponent), assuming it is not special. */\nfunction reduceSimpleLinear(node: SimpleUnitNode): LinearReduction {\n const base = reduceAtomLinear(node.atom);\n const prefixed = node.prefix\n ? { kind: \"linear\" as const, factor: base.factor * node.prefix.factor, dims: base.dims }\n : base;\n return power(prefixed, node.exponent);\n}\n\n/** Reduce one component to a linear form (specials handled separately by the caller). */\nfunction linearReduceComponent(comp: ComponentNode): LinearReduction {\n switch (comp.kind) {\n case \"factor\":\n return { kind: \"linear\", factor: comp.value, dims: {} };\n case \"annotation\":\n return DIMENSIONLESS;\n case \"group\":\n return linearReduceTerm(comp.term);\n case \"simple\":\n return reduceSimpleLinear(comp);\n }\n}\n\n/** Reduce a whole term to a linear form (assumes no special units in the tree). */\nfunction linearReduceTerm(node: UnitNode): LinearReduction {\n // A fresh accumulator, not the shared `DIMENSIONLESS`: this value can be what `reduce` returns.\n let acc: LinearReduction = { kind: \"linear\", factor: 1, dims: {} };\n for (const { sign, node: comp } of node.factors) {\n acc = multiply(acc, power(linearReduceComponent(comp), sign));\n }\n return acc;\n}\n\n/** Whether any simple unit anywhere in the tree is a special (non-linear) unit. */\nfunction containsSpecial(node: UnitNode): boolean {\n return node.factors.some(({ node: comp }) => {\n if (comp.kind === \"simple\") return comp.atom.special;\n if (comp.kind === \"group\") return containsSpecial(comp.term);\n return false;\n });\n}\n\n/** A normalized, order-independent token string for a special-containing expression. */\nfunction serializeSpecial(node: UnitNode): string {\n const tokens: string[] = [];\n const walk = (t: UnitNode, outerSign: number): void => {\n for (const { sign, node: comp } of t.factors) {\n const s = sign * outerSign;\n if (comp.kind === \"simple\") {\n const net = comp.exponent * s;\n tokens.push(`${comp.prefix?.code ?? \"\"}${comp.atom.code}${net === 1 ? \"\" : String(net)}`);\n } else if (comp.kind === \"factor\") {\n tokens.push(`#${String(comp.value)}${s === 1 ? \"\" : `^${String(s)}`}`);\n } else if (comp.kind === \"group\") {\n walk(comp.term, s);\n }\n // annotations are inert — dropped\n }\n };\n walk(node, 1);\n return tokens.sort().join(\".\");\n}\n\n/**\n * Reduce a parsed UCUM unit to its canonical {@link Reduction} — a linear scalar×dimension form, or\n * an opaque `special` form for expressions involving a non-linear special unit.\n *\n * The reduction of one atom is cached against **that atom object**, so a `UnitNode` you assembled\n * yourself is answered from its own atoms and cannot change how a unit off {@link parseUcum} reduces,\n * in this call or any later one.\n *\n * @param node - The AST from {@link parseUcum}.\n * @returns The reduced form.\n * @throws {Error} If reducing `node` reaches an atom with no linear definition, or one whose\n * definition does not parse. **No expression {@link parseUcum} accepts reaches either**; a node\n * you assemble yourself can, including by defining an atom in terms of a special unit such as\n * `Cel`, which lands on the table's own `Cel`. A third guard catches a definition that leads back\n * to itself. Naming a table atom does not reach it — a definition is resolved against the loaded\n * table, so your atom can name one but never be one — and neither does the table itself, which is\n * frozen; what reaches it is a `value` accessor that re-enters `reduce` for the same atom while\n * that atom is still being reduced. The message names the fault, never the atom.\n * @example\n * ```ts\n * import { parseUcum, reduce } from \"@cosyte/terminology\";\n *\n * const parsed = parseUcum(\"N\");\n * if (parsed.ok) {\n * const r = reduce(parsed.node);\n * r.kind; // => \"linear\" (1000 × g·m·s⁻²)\n * }\n * ```\n */\nexport function reduce(node: UnitNode): Reduction {\n if (containsSpecial(node)) return { kind: \"special\", form: serializeSpecial(node) };\n return linearReduceTerm(node);\n}\n","/**\n * The public **UCUM** surface: {@link validateUcum} (recognition + a canonical\n * descriptor) and {@link ucumEqual} (are two expressions the *same unit*).\n *\n * Both are **recognition / validation / representation-canonicalization only** — never magnitude\n * conversion. The never-fabricate posture holds: an unparseable or unknown unit is\n * a typed {@link TERM_UCUM_INVALID} outcome carrying a value-free reason, **never** a guessed\n * \"nearest\" unit; and a special (non-linear) unit is never claimed equal to a linear one.\n *\n * @packageDocumentation\n */\n\nimport { parseUcum } from \"./parse.js\";\nimport { reduce } from \"./reduce.js\";\nimport type { Reduction, UcumValidation } from \"./types.js\";\n\n/** Round a scalar to 12 significant figures so float noise never splits two equal units. */\nfunction roundFactor(x: number): string {\n return String(Number(x.toPrecision(12)));\n}\n\n/** Serialize a reduction to a stable, comparison-ready canonical descriptor string. */\nfunction canonicalOf(r: Reduction): string {\n if (r.kind === \"special\") return `special:${r.form}`;\n const keys = Object.keys(r.dims).sort();\n const dims = keys.length === 0 ? \"1\" : keys.map((k) => `${k}${String(r.dims[k])}`).join(\".\");\n return `${roundFactor(r.factor)} ${dims}`;\n}\n\n/**\n * Validate a UCUM unit expression and, when valid, return its canonical descriptor.\n *\n * Validation **is** parsing against the UCUM grammar over the known atom table: an expression is\n * valid iff it parses completely. An invalid expression returns a typed {@link TERM_UCUM_INVALID}\n * with a value-free reason — never a coerced or guessed unit.\n *\n * @param unit - The UCUM unit expression (e.g. `\"mmol/L\"`, `\"kg.m/s2\"`, `\"Cel\"`).\n * @returns `{ valid: true, canonical }` or `{ valid: false, code: \"TERM_UCUM_INVALID\", reason }`.\n * @example\n * ```ts\n * import { validateUcum } from \"@cosyte/terminology\";\n *\n * validateUcum(\"mmol/L\").valid; // => true\n * const bad = validateUcum(\"mg/dl/\"); // trailing operator\n * bad.valid; // => false\n * ```\n */\nexport function validateUcum(unit: string): UcumValidation {\n const parsed = parseUcum(unit);\n if (!parsed.ok) return { valid: false, code: \"TERM_UCUM_INVALID\", reason: parsed.reason };\n return { valid: true, canonical: canonicalOf(reduce(parsed.node)) };\n}\n\n/**\n * Whether two UCUM expressions denote the **same unit** — i.e. they reduce to the same canonical\n * form (equal base dimensions *and* equal scale). This recognizes representational equivalences\n * (`N` ≡ `kg.m/s2`, `mmol/L` ≡ `mmol.L-1`, annotations inert) but is **not** magnitude conversion:\n * `mg` and `g` are different units and compare unequal.\n *\n * A unit is never equal to an invalid expression, and a special (non-linear) unit (`Cel`, `[pH]`) is\n * equal only to a structurally identical special unit — never to a linear unit (the never-fabricate\n * posture: the engine will not assert an equivalence it cannot prove).\n *\n * @param a - The first UCUM unit expression.\n * @param b - The second UCUM unit expression.\n * @returns `true` iff both are valid and denote the same unit.\n * @example\n * ```ts\n * import { ucumEqual } from \"@cosyte/terminology\";\n *\n * ucumEqual(\"N\", \"kg.m/s2\"); // => true\n * ucumEqual(\"mmol/L\", \"mmol.L-1\"); // => true\n * ucumEqual(\"mg\", \"g\"); // => false\n * ```\n */\nexport function ucumEqual(a: string, b: string): boolean {\n const va = validateUcum(a);\n const vb = validateUcum(b);\n return va.valid && vb.valid && va.canonical === vb.canonical;\n}\n","/**\n * The CMS **ICD-9 ↔ ICD-10 GEMs** (General Equivalence Mappings) loader + applier.\n *\n * The GEMs are **CMS/NCHS public-domain** (US-government work) reference mappings between the ICD-9-CM\n * and ICD-10-CM diagnosis classifications. CMS is emphatic about what they are — *\"GEMs are not\n * crosswalks. They are reference mappings… the raw material from which providers… derive specific\n * applied mappings\"* — so this resolver treats a GEM hit as a **candidate**, never an equivalence:\n *\n * - **Approximate by default.** Position-1 flag: most entries are approximate (source and target are\n * not identical in meaning). The flag rides through; the engine asserts nothing beyond it.\n * - **No-Map is first-class.** A source with no valid target carries the `NoDx` sentinel (and the\n * position-2 flag); {@link applyGem} returns a typed {@link CrosswalkNoMap}, never a guessed code.\n * - **1:many, never collapsed.** A source with several targets returns the **whole** candidate set.\n * - **Combination clusters.** A combination source (position-3 flag) maps to a *combination* of\n * targets grouped by scenario (position 4) and choice list (position 5); the result surfaces that\n * structure so a caller can build valid clusters, never a single fabricated target.\n * - **Directional, never inverted.** The forward (9→10) and backward (10→9) files are **separate,\n * non-inverse** artifacts; {@link invertGem} refuses to synthesize one from the other.\n *\n * The engine ships **no GEM content**: the caller supplies the public-domain GEM file (BYO).\n *\n * @packageDocumentation\n */\n\nimport { TerminologyError, FATAL_CODES } from \"../common/diagnostics.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport type {\n CrosswalkNoMap,\n CrosswalkUnmapped,\n GemApplyResult,\n GemChoiceList,\n GemDirection,\n GemEntry,\n GemFlags,\n GemLoadWarning,\n GemMap,\n GemMatched,\n GemScenario,\n} from \"./types.js\";\n\n/** The diagnosis GEM No-Map target sentinel — the source has no valid ICD equivalent. */\nconst NO_DX = \"NoDx\";\n/** The procedure GEM No-Map target sentinel (accepted so the reader also serves the PCS GEMs). */\nconst NO_PCS = \"NoPCS\";\n\n/** Is a target field the CMS No-Map sentinel (`NoDx` / `NoPCS`)? */\nfunction isNoMapSentinel(target: string): boolean {\n return target === NO_DX || target === NO_PCS;\n}\n\n/**\n * A raw GEM source file, plus the direction it maps and its release version. BYO — the caller\n * supplies the public-domain CMS GEM file content.\n */\nexport interface GemSource {\n /** The raw GEM file content (whitespace-delimited: `source target flags`, one entry per line). */\n readonly content: string;\n /** Which direction this file maps (`\"9-to-10\"` for `…_I9gem.txt`, `\"10-to-9\"` for `…_I10gem.txt`). */\n readonly direction: GemDirection;\n /** The GEM release/version (e.g. `\"2018\"`), when known — mappings are release-scoped. */\n readonly version?: string;\n}\n\n/**\n * Decode a GEM 5-position flag field into typed {@link GemFlags}. The layout (CMS Dx GEM User's\n * Guide) is `approximate | no-map | combination | scenario | choice-list`, one digit each.\n */\nfunction decodeFlags(raw: string): GemFlags | undefined {\n if (!/^[0-9]{5}$/.test(raw)) return undefined;\n return Object.freeze({\n approximate: raw[0] === \"1\",\n noMap: raw[1] === \"1\",\n combination: raw[2] === \"1\",\n scenario: Number(raw[3]),\n choiceList: Number(raw[4]),\n raw,\n });\n}\n\n/**\n * Load a CMS GEM file into an immutable {@link GemMap}, keyed by source code.\n *\n * Liberal on load: a structurally unusable *line* (not three whitespace-delimited fields, or a\n * malformed 5-digit flag) is **skipped and surfaced** as a {@link GemLoadWarning}, never a\n * partially-parsed entry. An unusable *source* is not possible here (an all-malformed file loads to an\n * empty map with warnings) — there is no fatal for GEM load. Ships **no** GEM content: the entries are\n * the caller's public-domain file.\n *\n * @param source - The {@link GemSource} (raw content + direction + version).\n * @returns The immutable {@link GemMap}.\n * @example\n * ```ts\n * import { loadGems, applyGem } from \"@cosyte/terminology\";\n *\n * // Synthetic rows in the CMS GEM format (source target flags): an exact map and a No-Map.\n * const gems = loadGems({\n * direction: \"9-to-10\",\n * version: \"2018\",\n * content: \"0010 A000 00000\\nV290 NoDx 11000\\n\",\n * });\n * applyGem(gems, \"0010\").mapped; // => true\n * ```\n */\nexport function loadGems(source: GemSource): GemMap {\n const entries = new Map<string, GemEntry[]>();\n const warnings: GemLoadWarning[] = [];\n let count = 0;\n const lines = source.content.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n if (raw === undefined) continue;\n const trimmed = raw.trim();\n if (trimmed === \"\") continue;\n const fields = trimmed.split(/\\s+/);\n if (fields.length !== 3) {\n warnings.push({\n code: \"TERM_GEM_MALFORMED_ROW\",\n line: i + 1,\n detail: `expected 3 whitespace-delimited fields, found ${String(fields.length)}`,\n });\n continue;\n }\n const [src, tgt, flagStr] = fields as [string, string, string];\n const flags = decodeFlags(flagStr);\n if (flags === undefined) {\n warnings.push({\n code: \"TERM_GEM_MALFORMED_ROW\",\n line: i + 1,\n detail: \"flag field is not a 5-digit code\",\n });\n continue;\n }\n const entry: Writable<GemEntry> = { source: src, flags };\n // A No-Map row carries the sentinel target and no real code — never surface it as a target.\n if (!isNoMapSentinel(tgt)) entry.target = tgt;\n const frozen = Object.freeze(entry);\n const list = entries.get(src);\n if (list) list.push(frozen);\n else entries.set(src, [frozen]);\n count++;\n }\n return Object.freeze({\n direction: source.direction,\n ...(source.version !== undefined ? { version: source.version } : {}),\n count,\n entries,\n warnings: Object.freeze(warnings),\n });\n}\n\n/** Build the scenario→choice-list combination structure from a source's combination entries. */\nfunction buildCombinations(entries: readonly GemEntry[]): readonly GemScenario[] | undefined {\n const combo = entries.filter((e) => e.flags.combination && e.target !== undefined);\n if (combo.length === 0) return undefined;\n // Group by scenario, then by choice list, preserving file order within each choice list.\n const scenarioNums: number[] = [];\n const byScenario = new Map<number, Map<number, string[]>>();\n for (const e of combo) {\n const s = e.flags.scenario;\n let lists = byScenario.get(s);\n if (!lists) {\n lists = new Map<number, string[]>();\n byScenario.set(s, lists);\n scenarioNums.push(s);\n }\n const cl = e.flags.choiceList;\n const targets = lists.get(cl);\n if (targets) targets.push(e.target as string);\n else lists.set(cl, [e.target as string]);\n }\n const scenarios: GemScenario[] = [];\n for (const s of scenarioNums.sort((a, b) => a - b)) {\n const lists = byScenario.get(s) as Map<number, string[]>;\n const choiceLists: GemChoiceList[] = [];\n for (const cl of [...lists.keys()].sort((a, b) => a - b)) {\n choiceLists.push(\n Object.freeze({ choiceList: cl, targets: Object.freeze(lists.get(cl) as string[]) }),\n );\n }\n scenarios.push(Object.freeze({ scenario: s, choiceLists: Object.freeze(choiceLists) }));\n }\n return Object.freeze(scenarios);\n}\n\n/**\n * Apply a loaded GEM map to a source code, in the map's authored direction only.\n *\n * Returns the **full** candidate set (never collapsed to one), with each entry's steward flags; a\n * combination source additionally surfaces its scenario/choice-list structure. A source the steward\n * marked No-Map (`NoDx` sentinel) is a typed {@link CrosswalkNoMap}; a source **absent** from the map\n * is a typed {@link CrosswalkUnmapped} — the two are distinct, and neither is ever a fabricated code.\n *\n * @param map - A {@link GemMap} from {@link loadGems}.\n * @param source - The source code (in the map's source classification).\n * @returns A {@link GemApplyResult}.\n * @example\n * ```ts\n * import { loadGems, applyGem } from \"@cosyte/terminology\";\n *\n * const gems = loadGems({ direction: \"9-to-10\", content: \"V290 NoDx 11000\\n\" });\n * const r = applyGem(gems, \"V290\");\n * r.mapped; // => false\n * ```\n */\nexport function applyGem(map: GemMap, source: string): GemApplyResult {\n const all = map.entries.get(source);\n if (all === undefined || all.length === 0) {\n const unmapped: CrosswalkUnmapped = Object.freeze({\n mapped: false,\n noMap: false,\n code: \"TERM_CROSSWALK_UNMAPPED\",\n source,\n });\n return unmapped;\n }\n\n // Target presence (the `NoDx`/`NoPCS` sentinel is dropped at load) is authoritative for No-Map —\n // the ground truth for \"is there a code to return\", decoupled from the flag digit (which is\n // carried on `flags.noMap` for fidelity but, in real CMS data, always agrees with the sentinel).\n const realTargets = all.filter((e) => e.target !== undefined);\n if (realTargets.length === 0) {\n // Every entry for this source is a No-Map — the steward says it cannot be classified.\n const noMap: CrosswalkNoMap = Object.freeze({\n mapped: false,\n noMap: true,\n code: \"TERM_CROSSWALK_NO_MAP\",\n source,\n entries: Object.freeze([...all]),\n });\n return noMap;\n }\n\n const combinations = buildCombinations(realTargets);\n const matched: Writable<GemMatched> = {\n mapped: true,\n source,\n direction: map.direction,\n entries: Object.freeze([...realTargets]),\n };\n if (combinations !== undefined) matched.combinations = combinations;\n return Object.freeze(matched);\n}\n\n/**\n * The frozen fatal message per authored direction, and the fallback for anything else. A **closed-set\n * lookup, not an interpolation**: `GemSource.direction` is typed `GemDirection`, but a JavaScript\n * caller can put any string there, and interpolating it would put an unbounded caller-supplied value\n * into `TerminologyError.message` and `err.stack`. Naming the direction is worth keeping because it\n * tells the caller which file to load instead — so it is kept, from a table the engine owns.\n */\nconst NOT_INVERTIBLE_MESSAGE: ReadonlyMap<string, string> = new Map([\n [\"9-to-10\", \"GEM map (direction 9-to-10) cannot be inverted — load the 10-to-9 GEM file instead\"],\n [\"10-to-9\", \"GEM map (direction 10-to-9) cannot be inverted — load the 9-to-10 GEM file instead\"],\n]);\n\n/** The message for a map whose `direction` is not one of the two authored GEM directions. */\nconst NOT_INVERTIBLE_UNKNOWN_DIRECTION =\n \"GEM map cannot be inverted — load the reverse GEM file instead\";\n\n/**\n * Refuse to invert a directional GEM map. **Always throws** {@link FATAL_CODES.TERM_MAP_NOT_INVERTIBLE}.\n *\n * The never-invert invariant made explicit and discoverable: a forward GEM (9→10) is **not** the\n * inverse of the backward GEM (10→9) — CMS ships them as separate artifacts and *\"forward and\n * backward mappings are not simply the reverse\"*. To resolve the other direction, load\n * the other file with {@link loadGems}; the engine never synthesizes an inverse.\n *\n * @param map - The map an inversion was (incorrectly) requested for.\n * @returns Never — always throws.\n * @throws {TerminologyError} `TERM_MAP_NOT_INVERTIBLE`, always.\n * @example\n * ```ts runnable throws\n * import { loadGems, invertGem } from \"@cosyte/terminology\";\n *\n * const gems = loadGems({ direction: \"9-to-10\", content: \"0010 A000 00000\\n\" });\n * invertGem(gems); // throws TERM_MAP_NOT_INVERTIBLE\n * ```\n */\nexport function invertGem(map: GemMap): never {\n throw new TerminologyError(\n FATAL_CODES.TERM_MAP_NOT_INVERTIBLE,\n NOT_INVERTIBLE_MESSAGE.get(map.direction) ?? NOT_INVERTIBLE_UNKNOWN_DIRECTION,\n );\n}\n","/**\n * Steward-defined **map category** and **map-relationship** identifiers the crosswalk resolvers carry\n * through verbatim — the SNOMED CT complex-map `mapCategoryId` concepts and the map-correlation\n * concepts. These are SNOMED CT metadata concepts, and **they are bundled**: the four ids below and\n * their steward descriptions ship inside this package. SNOMED CT is copyright © International Health\n * Terminology Standards Development Organisation. **No SNOMED CT refset or release is bundled** — a\n * caller still supplies the map refset itself under their own SNOMED CT licence (the BYO posture).\n *\n * The category on a resolved SNOMED→ICD-10-CM map row is the steward telling the caller *how much to\n * trust the target*: a `447638001` \"cannot be classified\" row is a **No-Map**, a `447640006`\n * \"ambiguous\" row must surface its candidates rather than pick one, and a `447639009`\n * \"context-dependent\" row needs runtime patient context. The resolver never collapses these to a\n * single confident target.\n *\n * @packageDocumentation\n */\n\n/**\n * The SNOMED CT complex-map **map category** concept ids — the `mapCategoryId` column of the\n * SNOMED→ICD-10-CM extended-map refset. These four SNOMED CT concepts — id and steward description —\n * are **bundled** in this package (SNOMED CT is copyright © International Health Terminology\n * Standards Development Organisation); carried through a resolution verbatim so a caller sees the\n * steward's own trust signal.\n *\n * @example\n * ```ts\n * import { MAP_CATEGORIES } from \"@cosyte/terminology\";\n *\n * MAP_CATEGORIES.NO_MAP; // => \"447638001\"\n * ```\n */\nexport const MAP_CATEGORIES = {\n /** `447637006` — \"Map source concept is properly classified\" (a normal, usable target). */\n PROPERLY_CLASSIFIED: \"447637006\",\n /** `447638001` — \"Map source concept cannot be classified with available data\" — a **No-Map**. */\n NO_MAP: \"447638001\",\n /** `447639009` — \"Map of source concept is context dependent\" (needs runtime patient context). */\n CONTEXT_DEPENDENT: \"447639009\",\n /** `447640006` — \"Source concept is ambiguous\" — surface candidates, never pick one. */\n AMBIGUOUS: \"447640006\",\n} as const;\n\n/** A value from {@link MAP_CATEGORIES} — the SNOMED map-category id carried on a resolution. */\nexport type MapCategoryId = (typeof MAP_CATEGORIES)[keyof typeof MAP_CATEGORIES];\n\n/**\n * The set of {@link MAP_CATEGORIES} ids the resolver treats as a **No-Map** (a typed, surfaced\n * \"cannot be classified\", never a fabricated target).\n */\nexport const NO_MAP_CATEGORIES: ReadonlySet<string> = new Set([MAP_CATEGORIES.NO_MAP]);\n\n/**\n * The canonical code-system URI for **ICD-10-CM** — the target system of both crosswalks. A published\n * identity fact (mirrors {@link ../systems/registry.SYSTEM_IDENTITIES}); attached to a resolved\n * target {@link ../common/coding.Coding} so a translation is self-describing.\n */\nexport const ICD10CM_SYSTEM = \"http://hl7.org/fhir/sid/icd-10-cm\";\n\n/**\n * The canonical code-system URI for **ICD-9-CM** (the legacy diagnosis classification the GEMs bridge\n * to/from). A published identity fact; attached to a GEM target/source coding.\n */\nexport const ICD9CM_SYSTEM = \"http://hl7.org/fhir/sid/icd-9-cm\";\n\n/**\n * The canonical code-system URI for **SNOMED CT** — the source system of the SNOMED→ICD-10-CM complex\n * map. Recognised by URI only; **no SNOMED CT refset or release is bundled**.\n */\nexport const SNOMEDCT_SYSTEM = \"http://snomed.info/sct\";\n","/**\n * The **SNOMED CT → ICD-10-CM complex-map** resolver — a rule-based, **BYO**\n * resolver over the caller-supplied complex/extended-map refset. **No SNOMED CT refset or release is\n * bundled**: the engine ships the rule machinery; the caller supplies the map rows from their own\n * SNOMED CT release. (Individual SNOMED CT concepts this resolver *names* are bundled: the\n * map-category concepts a row's `mapCategoryId` refers to — see\n * {@link ../crosswalk/categories.MAP_CATEGORIES} — and the two gender findings a gender `IFA` rule\n * is written against.)\n *\n * The map is *\"semi-automated\"* by the steward's own statement — 1:many, context-dependent, with\n * first-class No-Map states. The resolver honours that:\n *\n * - **Map groups are an AND.** A source needing a manifestation *and* an etiology code has two groups;\n * {@link applyComplexMap} resolves each independently and returns one result per group.\n * - **Priorities are an if-then-else.** Within a group, rules run in ascending priority; the first\n * whose `IFA` predicate the caller's context satisfies wins.\n * - **Context it wasn't given, it never guesses.** If deciding a group requires an `IFA` predicate\n * (an age band, a gender) the caller left unspecified, the group is a typed\n * {@link ComplexMapContextRequired} carrying the candidate rules + advice — never a silently-picked\n * branch.\n * - **No-Map is typed.** A `447638001` \"cannot be classified\" row (or an empty target) is a typed\n * No-Map, never a fabricated code.\n * - **Advice rides through verbatim.** `CONSIDER LATERALITY`, `EPISODE OF CARE INFORMATION NEEDED`,\n * manifestation-code advice — carried untouched to the caller.\n * - **Never inverted.** The map is applied SNOMED→ICD-10-CM only; the reverse is a separate artifact.\n *\n * @packageDocumentation\n */\n\nimport { coding } from \"../common/coding.js\";\nimport { TerminologyError, FATAL_CODES } from \"../common/diagnostics.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { ICD10CM_SYSTEM, MAP_CATEGORIES, SNOMEDCT_SYSTEM } from \"./categories.js\";\nimport type {\n ComplexMap,\n ComplexMapApplyResult,\n ComplexMapEntry,\n ComplexMapGroupResult,\n ComplexMapLoadWarning,\n ComplexMapMatched,\n CrosswalkUnmapped,\n PatientContext,\n} from \"./types.js\";\n\n/** SNOMED concept id for the \"Female (finding)\" clinical-finding used in gender `IFA` rules. */\nconst SNOMED_FEMALE = \"248152002\";\n/** SNOMED concept id for the \"Male (finding)\" clinical-finding used in gender `IFA` rules. */\nconst SNOMED_MALE = \"248153007\";\n\n/**\n * The discriminated input {@link loadComplexMap} accepts — already-structured refset rows, or a raw\n * RF2 tab-delimited extended-map refset the caller exported from their SNOMED release.\n */\nexport type ComplexMapInput =\n | {\n readonly format: \"rows\";\n readonly rows: readonly ComplexMapEntry[];\n readonly version?: string;\n }\n | { readonly format: \"rf2\"; readonly content: string; readonly version?: string };\n\n/** Freeze a {@link ComplexMapEntry}, dropping absent optional fields (no `undefined` keys). */\nfunction freezeEntry(e: ComplexMapEntry): ComplexMapEntry {\n const out: Writable<ComplexMapEntry> = {\n source: e.source,\n group: e.group,\n priority: e.priority,\n rule: e.rule,\n advice: e.advice,\n };\n if (e.target !== undefined && e.target !== \"\") out.target = e.target;\n if (e.category !== undefined && e.category !== \"\") out.category = e.category;\n if (e.correlation !== undefined && e.correlation !== \"\") out.correlation = e.correlation;\n return Object.freeze(out);\n}\n\n/** Parse an RF2 extended-map refset (tab-delimited, header row) into structured rows + warnings. */\nfunction parseRf2(content: string): {\n rows: ComplexMapEntry[];\n warnings: ComplexMapLoadWarning[];\n} {\n const rows: ComplexMapEntry[] = [];\n const warnings: ComplexMapLoadWarning[] = [];\n const lines = content.split(/\\r?\\n/);\n if (lines.length === 0 || lines[0] === undefined || lines[0].trim() === \"\") {\n throw new TerminologyError(\n FATAL_CODES.TERM_CROSSWALK_MALFORMED,\n \"complex-map RF2: empty content (no header row)\",\n );\n }\n const header = lines[0].split(\"\\t\").map((h) => h.trim());\n const col = (name: string): number => header.indexOf(name);\n const iActive = col(\"active\");\n const iSource = col(\"referencedComponentId\");\n const iGroup = col(\"mapGroup\");\n const iPriority = col(\"mapPriority\");\n const iRule = col(\"mapRule\");\n const iAdvice = col(\"mapAdvice\");\n const iTarget = col(\"mapTarget\");\n const iCorr = col(\"correlationId\");\n const iCat = col(\"mapCategoryId\");\n if (iSource < 0 || iGroup < 0 || iPriority < 0) {\n throw new TerminologyError(\n FATAL_CODES.TERM_CROSSWALK_MALFORMED,\n \"complex-map RF2: header is missing a required column (referencedComponentId/mapGroup/mapPriority)\",\n );\n }\n const at = (fields: readonly string[], i: number): string =>\n i >= 0 && i < fields.length ? (fields[i] ?? \"\") : \"\";\n for (let i = 1; i < lines.length; i++) {\n const raw = lines[i];\n if (raw === undefined || raw === \"\") continue;\n const f = raw.split(\"\\t\");\n // Skip inactive refset members (RF2 active flag \"0\"), liberal-on-load.\n if (iActive >= 0 && at(f, iActive) === \"0\") continue;\n const source = at(f, iSource);\n const groupN = Number(at(f, iGroup));\n const priorityN = Number(at(f, iPriority));\n if (source === \"\" || !Number.isFinite(groupN) || !Number.isFinite(priorityN)) {\n warnings.push({\n code: \"TERM_COMPLEX_MAP_MALFORMED_ROW\",\n line: i + 1,\n detail: \"row is missing referencedComponentId / mapGroup / mapPriority\",\n });\n continue;\n }\n rows.push({\n source,\n group: groupN,\n priority: priorityN,\n rule: at(f, iRule),\n advice: at(f, iAdvice),\n target: at(f, iTarget),\n category: at(f, iCat),\n correlation: at(f, iCorr),\n });\n }\n return { rows, warnings };\n}\n\n/**\n * Load a SNOMED→ICD-10-CM complex map from **caller-supplied** rows or a raw RF2 refset into an\n * immutable {@link ComplexMap}, keyed by source concept and ordered by (group, priority).\n *\n * Liberal on load: a structurally unusable RF2 *row* is skipped and surfaced as a warning; only an\n * unusable *source* (empty content, header missing required columns) is a fatal\n * {@link FATAL_CODES.TERM_CROSSWALK_MALFORMED}. Ships **no** SNOMED CT release or refset — the rows\n * are the caller's, under their own licence.\n *\n * @param input - Structured `rows`, or a raw RF2 extended-map refset `content`.\n * @returns The immutable {@link ComplexMap}.\n * @throws {TerminologyError} `TERM_CROSSWALK_MALFORMED` when the source is structurally unusable.\n * @example\n * ```ts\n * import { loadComplexMap } from \"@cosyte/terminology\";\n *\n * const map = loadComplexMap({\n * format: \"rows\",\n * rows: [\n * { source: \"195967001\", group: 1, priority: 1, rule: \"TRUE\", advice: \"ALWAYS J45.909\", target: \"J45.909\", category: \"447637006\" },\n * ],\n * });\n * map.count; // => 1\n * ```\n */\nexport function loadComplexMap(input: ComplexMapInput): ComplexMap {\n let rawRows: readonly ComplexMapEntry[];\n let warnings: readonly ComplexMapLoadWarning[];\n if (input.format === \"rf2\") {\n const parsed = parseRf2(input.content);\n rawRows = parsed.rows;\n warnings = Object.freeze(parsed.warnings);\n } else {\n rawRows = input.rows;\n warnings = Object.freeze([]);\n }\n\n const bySource = new Map<string, ComplexMapEntry[]>();\n for (const r of rawRows) {\n const e = freezeEntry(r);\n const list = bySource.get(e.source);\n if (list) list.push(e);\n else bySource.set(e.source, [e]);\n }\n // Order each source's rows by (group, priority) so evaluation is deterministic regardless of input.\n const entries = new Map<string, readonly ComplexMapEntry[]>();\n let count = 0;\n for (const [src, list] of bySource) {\n const sorted = [...list].sort((a, b) => a.group - b.group || a.priority - b.priority);\n entries.set(src, Object.freeze(sorted));\n count += sorted.length;\n }\n\n const out: Writable<ComplexMap> = {\n count,\n entries,\n warnings,\n };\n if (input.version !== undefined) out.version = input.version;\n return Object.freeze(out);\n}\n\n/** How a single map rule evaluates against the caller's context. */\ntype RuleMatch = \"match\" | \"no-match\" | \"unknown\";\n\n/**\n * Evaluate a **single** `IFA` conjunct (one predicate, no `AND`) against the context. A gender or\n * age predicate whose context the caller did not supply is `unknown` (never assumed); an `IFA`\n * predicate we cannot interpret is `unknown` (never assumed true or false).\n */\nfunction evaluateConjunct(clause: string, context: PatientContext): RuleMatch {\n const trimmed = clause.trim();\n if (!/^IFA\\b/i.test(trimmed)) return \"unknown\";\n\n // Gender predicate: `IFA 248152002 | Female (finding) |` (no comparator part).\n if (trimmed.includes(SNOMED_FEMALE)) {\n if (context.gender === undefined) return \"unknown\";\n return context.gender === \"female\" ? \"match\" : \"no-match\";\n }\n if (trimmed.includes(SNOMED_MALE)) {\n if (context.gender === undefined) return \"unknown\";\n return context.gender === \"male\" ? \"match\" : \"no-match\";\n }\n\n // Age predicate: `IFA <ageObservable> | … | <op> <value> year(s)`. Comparator + numeric + \"year\".\n const ageMatch = /(<=|>=|<|>|=)\\s*([0-9]+(?:\\.[0-9]+)?)\\s*year/i.exec(trimmed);\n if (ageMatch) {\n const op = ageMatch[1];\n const bound = Number(ageMatch[2]);\n if (context.ageYears === undefined || !Number.isFinite(bound)) return \"unknown\";\n const age = context.ageYears;\n const ok =\n op === \"<=\"\n ? age <= bound\n : op === \">=\"\n ? age >= bound\n : op === \"<\"\n ? age < bound\n : op === \">\"\n ? age > bound\n : op === \"=\"\n ? age === bound\n : undefined;\n if (ok === undefined) return \"unknown\";\n return ok ? \"match\" : \"no-match\";\n }\n // An `IFA` predicate we cannot interpret — never assume it true or false.\n return \"unknown\";\n}\n\n/**\n * Evaluate a `mapRule` against the caller's {@link PatientContext}.\n *\n * A SNOMED→ICD-10-CM map rule can be a **conjunction** of `IFA` predicates joined by `AND` — the map\n * uses this for bounded age intervals (`… >= 15 years AND … < 55 years`) and gender+age combinations\n * (`IFA … | Female (finding) | AND IFA … age … < 55 years`). Each conjunct is evaluated and the\n * results combined **fail-safe**: `no-match` if *any* conjunct is a no-match; `unknown` (→\n * context-required) if any needed conjunct is `unknown` and none is a no-match; `match` **only** when\n * *every* conjunct matches. A conjunct is never dropped, so a rule is never confidently applied while\n * one of its conditions is undecided (context is never guessed).\n *\n * The split is on an uppercase `AND` that begins a new `IFA` clause, so a lowercase `and` (or an\n * uppercase `AND`) inside a concept's term description never falsely splits the rule.\n */\nfunction evaluateRule(rule: string, context: PatientContext): RuleMatch {\n const trimmed = rule.trim();\n // Unconditional fall-through — always the default branch.\n if (/^(OTHERWISE\\s+)?TRUE$/.test(trimmed)) return \"match\";\n\n const conjuncts = trimmed.split(/\\s+AND\\s+(?=IFA\\b)/);\n let sawUnknown = false;\n for (const c of conjuncts) {\n const m = evaluateConjunct(c, context);\n if (m === \"no-match\") return \"no-match\"; // any failed condition ⇒ the whole rule is false\n if (m === \"unknown\") sawUnknown = true; // an undecided condition blocks a confident match\n }\n return sawUnknown ? \"unknown\" : \"match\";\n}\n\n/** Is this entry a No-Map (steward category `447638001`, or an empty target)? */\nfunction isNoMap(e: ComplexMapEntry): boolean {\n return e.category === MAP_CATEGORIES.NO_MAP || e.target === undefined;\n}\n\n/** Resolve one map group's ordered rules against the context into a {@link ComplexMapGroupResult}. */\nfunction resolveGroup(\n group: number,\n rules: readonly ComplexMapEntry[],\n context: PatientContext,\n): ComplexMapGroupResult {\n for (const entry of rules) {\n const m = evaluateRule(entry.rule, context);\n if (m === \"no-match\") continue;\n if (m === \"unknown\") {\n // We cannot decide this branch without context the caller did not supply — surface, never pick.\n return Object.freeze({\n outcome: \"context-required\",\n code: \"TERM_CROSSWALK_CONTEXT_REQUIRED\",\n group,\n rules,\n });\n }\n // m === \"match\": this rule wins the group.\n if (isNoMap(entry)) {\n const noMap: Writable<Extract<ComplexMapGroupResult, { outcome: \"no-map\" }>> = {\n outcome: \"no-map\",\n code: \"TERM_CROSSWALK_NO_MAP\",\n group,\n advice: entry.advice,\n };\n if (entry.category !== undefined) noMap.category = entry.category;\n return Object.freeze(noMap);\n }\n const target = coding({ system: ICD10CM_SYSTEM, code: entry.target as string });\n const resolved: Writable<Extract<ComplexMapGroupResult, { outcome: \"resolved\" }>> = {\n outcome: \"resolved\",\n group,\n target,\n advice: entry.advice,\n rule: entry.rule,\n };\n if (entry.category !== undefined) resolved.category = entry.category;\n return Object.freeze(resolved);\n }\n // No rule matched and none was unknown (a map with no TRUE fallback) — refuse to guess.\n return Object.freeze({\n outcome: \"context-required\",\n code: \"TERM_CROSSWALK_CONTEXT_REQUIRED\",\n group,\n rules,\n });\n}\n\n/**\n * Apply a loaded SNOMED→ICD-10-CM complex map to a source concept and patient context.\n *\n * Resolves **each map group** independently (groups are an AND — a source needing multiple ICD-10-CM\n * codes has multiple groups) by running its rules in priority order against `context`. A group whose\n * decision needs `IFA` context the caller did not supply is a typed\n * {@link ComplexMapContextRequired}; a `447638001` row is a typed No-Map; every result carries the\n * steward's advice verbatim. **Never** fabricates a target, **never** inverts the map.\n *\n * @param map - A {@link ComplexMap} from {@link loadComplexMap}.\n * @param source - The SNOMED CT source concept id.\n * @param context - The caller-supplied {@link PatientContext} (age / gender). Optional; a missing\n * field that a rule needs yields a `context-required` group, never a guessed branch.\n * @returns A {@link ComplexMapApplyResult} — per-group resolutions, or a typed absence.\n * @example\n * ```ts\n * import { loadComplexMap, applyComplexMap } from \"@cosyte/terminology\";\n *\n * const map = loadComplexMap({\n * format: \"rows\",\n * rows: [\n * { source: \"72098002\", group: 1, priority: 1, rule: \"IFA 248152002 | Female (finding) |\", advice: \"MAP IS CONTEXT DEPENDENT FOR GENDER\", target: \"O00.9\", category: \"447639009\" },\n * { source: \"72098002\", group: 1, priority: 2, rule: \"OTHERWISE TRUE\", advice: \"CANNOT BE CLASSIFIED\", category: \"447638001\" },\n * ],\n * });\n * const r = applyComplexMap(map, \"72098002\", { gender: \"female\" });\n * r.mapped; // => true\n * ```\n */\nexport function applyComplexMap(\n map: ComplexMap,\n source: string,\n context: PatientContext = {},\n): ComplexMapApplyResult {\n const rows = map.entries.get(source);\n if (rows === undefined || rows.length === 0) {\n const unmapped: CrosswalkUnmapped = Object.freeze({\n mapped: false,\n noMap: false,\n code: \"TERM_CROSSWALK_UNMAPPED\",\n source,\n });\n return unmapped;\n }\n\n // Partition the source's ordered rows into map groups (already sorted by group, then priority).\n const groupNumbers: number[] = [];\n const byGroup = new Map<number, ComplexMapEntry[]>();\n for (const r of rows) {\n const list = byGroup.get(r.group);\n if (list) list.push(r);\n else {\n byGroup.set(r.group, [r]);\n groupNumbers.push(r.group);\n }\n }\n\n const groups: ComplexMapGroupResult[] = [];\n for (const g of groupNumbers) {\n const rules = Object.freeze(byGroup.get(g) as ComplexMapEntry[]);\n groups.push(resolveGroup(g, rules, context));\n }\n\n const matched: ComplexMapMatched = Object.freeze({\n mapped: true,\n source,\n groups: Object.freeze(groups),\n });\n return matched;\n}\n\n/** The SNOMED CT source-system URI a complex-map source concept is drawn from (re-exported for docs). */\nexport const COMPLEX_MAP_SOURCE_SYSTEM = SNOMEDCT_SYSTEM;\n","/**\n * The RxNorm **term-type (`TTY`) vocabulary** relevant to the drug graph — the normal-form ladder and\n * the cross-link kinds — encoded as published identity facts (grounded firsthand on the NLM RxNorm\n * Technical Documentation, Appendix 5). **No RxNorm release is bundled**: what ships is these\n * *labels*, not the drug list.\n *\n * The RxNorm normal-form graph runs `IN → SCDC → SCD → SBD` (ingredient → clinical-drug component →\n * semantic clinical drug → semantic branded drug), with `BN` (brand name) and `DF` (dose form) as\n * cross-links.\n *\n * **Appendix 5 splits these into two kinds, and the split is load-bearing.** A **defining** term type\n * (its \"Normalized Names\" table, `IN` … `DFG`) says what an `RXCUI` *is*. A **synonym** term type\n * (its \"Synonyms\" table, `PSN` / `SY` / `TMSY`) is Appendix 5's own word for an atom that is a\n * *\"synonym of another TTY\"*: it types a **name**, not a concept, so it can never be a concept's term\n * type. `ET` is in neither table; the appendix describes it only in prose, as \"a small number of\n * concepts with TTY=ET, a term type reserved for entry terms for dose forms\". Those are concepts in\n * their own right rather than synonyms carried on another, so `ET` counts as defining here. See\n * {@link isSynonymTermType} and {@link ../rxnorm/load.loadRxNormGraph}.\n *\n * @packageDocumentation\n */\n\nimport type { TermType } from \"./types.js\";\n\n/**\n * The drug-graph term types (`RXNCONSO.TTY`), each mapped to its **verbatim Appendix 5 name** (`ET`\n * excepted: the appendix publishes no Name for it, so the UMLS expansion \"Entry Term\" is used).\n * Encoded as an identity fact; a concept's `TTY` is carried verbatim on its\n * {@link ../rxnorm/types.RxNormConcept}, never re-labeled.\n *\n * The keys are the full Appendix 5 vocabulary, defining and synonym alike. Only the **defining** ones\n * can appear on a loaded concept (see {@link isSynonymTermType}).\n *\n * @example\n * ```ts\n * import { TERM_TYPES } from \"@cosyte/terminology\";\n *\n * TERM_TYPES.SCD; // => \"Semantic Clinical Drug\"\n * TERM_TYPES.SCDF; // => \"Semantic Clinical Drug Form\"\n * ```\n */\nexport const TERM_TYPES: Readonly<Record<TermType, string>> = Object.freeze({\n IN: \"Ingredient\",\n PIN: \"Precise Ingredient\",\n MIN: \"Multiple Ingredients\",\n BN: \"Brand Name\",\n SCDC: \"Semantic Clinical Drug Component\",\n SBDC: \"Semantic Branded Drug Component\",\n SCDF: \"Semantic Clinical Drug Form\",\n SBDF: \"Semantic Branded Drug Form\",\n SCDFP: \"Semantic Clinical Drug Form Precise\",\n SBDFP: \"Semantic Branded Drug Form Precise\",\n SCD: \"Semantic Clinical Drug\",\n SBD: \"Semantic Branded Drug\",\n SCDG: \"Semantic Clinical Drug Group\",\n SBDG: \"Semantic Branded Drug Group\",\n SCDGP: \"Semantic Clinical Drug Form Group Precise\",\n GPCK: \"Generic Pack\",\n BPCK: \"Brand Name Pack\",\n DF: \"Dose Form\",\n DFG: \"Dose Form Group\",\n PSN: \"Prescribable Name\",\n SY: \"Synonym\",\n TMSY: \"Tall Man Lettering Synonym\",\n ET: \"Entry Term\",\n});\n\n/** The set of {@link TERM_TYPES} keys, for fast recognition of a `TTY` string as a known term type. */\nconst KNOWN: ReadonlySet<string> = new Set(Object.keys(TERM_TYPES));\n\n/**\n * The **synonym-class** term types, verbatim from Appendix 5's \"Synonyms\" table. Each types a *name*\n * carried on some other concept, not a concept of its own.\n */\nconst SYNONYM: ReadonlySet<string> = new Set([\"PSN\", \"SY\", \"TMSY\"]);\n\n/**\n * Narrow a raw `RXNCONSO.TTY` string to a known {@link TermType}, or `undefined` when it is not a\n * drug-graph term type this engine models (the atom is then skipped at load, liberal-on-load, never\n * coerced to a wrong type).\n *\n * @param tty - The raw `TTY` value from an `RXNCONSO` row.\n * @returns The narrowed {@link TermType}, or `undefined` when unrecognized.\n * @example\n * ```ts\n * import { asTermType } from \"@cosyte/terminology\";\n *\n * asTermType(\"SCD\"); // => \"SCD\"\n * asTermType(\"ZZZ\"); // => undefined\n * ```\n */\nexport function asTermType(tty: string): TermType | undefined {\n return KNOWN.has(tty) ? (tty as TermType) : undefined;\n}\n\n/**\n * Is this term type a **synonym-class** one (`PSN` / `SY` / `TMSY`)?\n *\n * Appendix 5 defines each as a *\"synonym of another TTY\"*: it labels an alternate **name** for a\n * concept, never the concept's own kind. So a synonym atom can never establish an `RXCUI`'s term\n * type, and {@link ../rxnorm/load.loadRxNormGraph} will not let one: an `RXCUI` whose release\n * supplies only synonym atoms is skipped and surfaced, never typed `\"TMSY\"`.\n *\n * @param tty - A {@link TermType}.\n * @returns `true` for `PSN` / `SY` / `TMSY`; `false` for every defining term type.\n * @example\n * ```ts\n * import { isSynonymTermType } from \"@cosyte/terminology\";\n *\n * isSynonymTermType(\"TMSY\"); // => true\n * isSynonymTermType(\"SCDF\"); // => false\n * ```\n */\nexport function isSynonymTermType(tty: TermType): boolean {\n return SYNONYM.has(tty);\n}\n","/**\n * The **RxNorm drug graph loader** — build an immutable {@link RxNormGraph} from a\n * **caller-supplied** RxNorm RRF release (`RXNCONSO.RRF` + `RXNREL.RRF`, and optionally `RXNSAT.RRF`\n * for NDC attributes). Reuses the shared, zero-dep {@link ../codesystem/rrf.parseRrfLine} (pipe split,\n * reserved trailing pipe) — the same RRF reader the CodeSystem layer uses.\n *\n * **Column layouts, grounded firsthand** on the NLM RxNorm Technical Documentation (§ file\n * descriptions):\n * - `RXNCONSO.RRF` (18 cols): `RXCUI`(0) `LAT`(1) `TS`(2) `LUI`(3) `STT`(4) `SUI`(5) `ISPREF`(6)\n * `RXAUI`(7) `SAUI`(8) `SCUI`(9) `SDUI`(10) `SAB`(11) `TTY`(12) `CODE`(13) `STR`(14) `SRL`(15)\n * `SUPPRESS`(16) `CVF`(17). Only the **normalized** atoms (`SAB=RXNORM`) become graph concepts, and\n * only through a **defining** `TTY` (see \"Typing a concept\" below).\n * - `RXNREL.RRF` (16 cols): `RXCUI1`(0) `RXAUI1`(1) `STYPE1`(2) `REL`(3) `RXCUI2`(4) `RXAUI2`(5)\n * `STYPE2`(6) `RELA`(7) `RUI`(8) `SRUI`(9) `SAB`(10) `SL`(11) `RG`(12) `DIR`(13) `SUPPRESS`(14)\n * `CVF`(15). Read `subject = RXCUI2`, `predicate = RELA`, `object = RXCUI1` (the direction\n * convention — see {@link ../rxnorm/rela}). Only concept-level rows (both `RXCUI`s present) with a\n * non-empty `RELA` become edges; atom-level (`RXAUI`) rows are not part of the concept graph.\n * - `RXNSAT.RRF` (13 cols): `RXCUI`(0) … `ATN`(8) `SAB`(9) `ATV`(10) `SUPPRESS`(11) `CVF`(12). Rows\n * with `ATN=NDC` index `ATV`(the NDC) → `RXCUI`, marked `active` **as of** the loaded release.\n *\n * **Typing a concept (`RXNCONSO`).** An `RXCUI` carries one **defining** atom (its normalized\n * name, a `TTY` from Appendix 5's \"Normalized Names\" table) plus any number of **synonym** atoms, whose\n * `TTY` (`PSN`/`SY`/`TMSY`) Appendix 5 defines as a *\"synonym of another TTY\"*: it types a **name**,\n * not a concept. RxNorm documents no ordering between an `RXCUI`'s atoms, so the loader takes the\n * **defining** atom wherever it sits in the file (first-wins among defining atoms) and **never** falls\n * back to a synonym atom. An `RXCUI` that no defining atom could type, because every atom is\n * synonym-class or carries a `TTY` this engine does not model, is **skipped and surfaced** as a\n * `TERM_RXNORM_UNTYPED_CONCEPT` warning naming the line. Skipping is the deliberate choice: an absent\n * concept is already a first-class typed outcome (`TERM_RXNORM_UNKNOWN_RXCUI`), whereas a concept\n * whose `tty` reads `\"TMSY\"` is a fabricated claim about what the drug *is*, indistinguishable from a\n * real one.\n *\n * **Liberal on load**: a structurally unusable *row* (too few columns, missing a required\n * value) is **skipped and surfaced** as a `TERM_RXNORM_MALFORMED_ROW` warning, never a partial\n * concept/edge, never a crash. Rows that are simply *not of interest* (a non-`RXNORM` atom, an\n * atom-level relationship, a non-`NDC` attribute) are skipped **silently** — they are expected, not\n * faults. Ships **no** RxNorm release: every concept/edge is the caller's.\n *\n * @packageDocumentation\n */\n\nimport { parseRrfLine } from \"../codesystem/rrf.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { asTermType, isSynonymTermType } from \"./tty.js\";\nimport type {\n NdcStatus,\n RxNormConcept,\n RxNormEdge,\n RxNormGraph,\n RxNormLoadWarning,\n} from \"./types.js\";\n\n/** The normalized-content source-abbreviation whose atoms define RxNorm's own concepts. */\nconst SAB_RXNORM = \"RXNORM\";\n/** `RXNSAT.ATN` value marking an NDC attribute. */\nconst ATN_NDC = \"NDC\";\n\n// ── Column indices (grounded firsthand on the RxNorm Technical Documentation — see the module doc) ──\nconst CONSO = { RXCUI: 0, SAB: 11, TTY: 12, STR: 14, SUPPRESS: 16 } as const;\nconst REL = { RXCUI1: 0, RXCUI2: 4, RELA: 7 } as const;\nconst SAT = { RXCUI: 0, ATN: 8, ATV: 10 } as const;\n\n/**\n * A raw RxNorm RRF release, BYO. The caller supplies the public-domain Current Prescribable Content\n * subset or the full (licensed) release; the engine bundles **no** RxNorm release.\n */\nexport interface RxNormGraphSource {\n /** The raw `RXNCONSO.RRF` content (pipe-delimited concept/atom names). */\n readonly conso: string;\n /** The raw `RXNREL.RRF` content (pipe-delimited relationships). */\n readonly rel: string;\n /** The raw `RXNSAT.RRF` content (pipe-delimited attributes) — supply to resolve NDCs. Optional. */\n readonly sat?: string;\n /** The release version (e.g. `\"RXNORM_2026AA\"`), when known — mappings are release-scoped. */\n readonly version?: string;\n}\n\n/** Read a cell by index, trimmed; `undefined` when out of range. */\nfunction cell(cells: readonly string[], index: number): string | undefined {\n const v = cells[index];\n return v === undefined ? undefined : v.trim();\n}\n\n/**\n * Parse `RXNCONSO.RRF` into the `RXCUI → concept` map.\n *\n * **A concept is typed by a DEFINING atom, never by file order.** An `RXCUI` carries one defining\n * atom (its normalized name: `IN`/`SCD`/`SCDF`/`BN`/…) plus any number of synonym atoms, and RxNorm\n * documents no ordering between them within an `RXCUI`. So the defining atom wins wherever it sits\n * in the file, and the first defining atom wins among defining atoms. An `RXCUI` no defining atom\n * could type is **skipped and surfaced** (`TERM_RXNORM_UNTYPED_CONCEPT`), never typed from a synonym.\n */\nfunction parseConso(content: string, warnings: RxNormLoadWarning[]): Map<string, RxNormConcept> {\n const concepts = new Map<string, RxNormConcept>();\n const conso: RxNormLoadWarning[] = [];\n /** `RXCUI` → the first line whose atom could not type it. Cleared once a defining atom arrives. */\n const untyped = new Map<string, number>();\n\n for (const [i, raw] of content.split(/\\r?\\n/).entries()) {\n if (raw === \"\") continue;\n const cells = parseRrfLine(raw);\n // Need at least through STR(14) to be a usable concept row.\n if (cells.length <= CONSO.STR) {\n conso.push(\n Object.freeze({\n code: \"TERM_RXNORM_MALFORMED_ROW\",\n file: \"RXNCONSO\",\n line: i + 1,\n detail: `row has ${String(cells.length)} columns, need at least ${String(CONSO.STR + 1)}`,\n }),\n );\n continue;\n }\n // Only RxNorm-normalized atoms define concepts; other sources are expected, skip silently.\n if (cell(cells, CONSO.SAB) !== SAB_RXNORM) continue;\n\n const rxcui = cell(cells, CONSO.RXCUI);\n if (rxcui === undefined || rxcui === \"\") {\n conso.push(\n Object.freeze({\n code: \"TERM_RXNORM_MALFORMED_ROW\",\n file: \"RXNCONSO\",\n line: i + 1,\n detail: \"row is missing its RXCUI\",\n }),\n );\n continue;\n }\n\n // A TTY this engine does not model, or a synonym-class one (which types a NAME, not a concept),\n // cannot establish the concept's type. Remember the RXCUI so an atom-less-defining one is\n // surfaced rather than lost, and never fall back to it.\n const tty = asTermType(cell(cells, CONSO.TTY) ?? \"\");\n if (tty === undefined || isSynonymTermType(tty)) {\n if (!concepts.has(rxcui) && !untyped.has(rxcui)) untyped.set(rxcui, i + 1);\n continue;\n }\n\n if (concepts.has(rxcui)) continue; // first DEFINING atom per RXCUI wins\n untyped.delete(rxcui);\n\n const name = cell(cells, CONSO.STR) ?? \"\";\n const suppress = cell(cells, CONSO.SUPPRESS) ?? \"N\";\n concepts.set(\n rxcui,\n Object.freeze({ rxcui, tty, name, suppressed: suppress !== \"\" && suppress !== \"N\" }),\n );\n }\n\n for (const line of untyped.values()) {\n conso.push(\n Object.freeze({\n code: \"TERM_RXNORM_UNTYPED_CONCEPT\",\n file: \"RXNCONSO\",\n line,\n detail:\n \"no RXNORM atom established this RXCUI's term type (every atom was synonym-class or an unmodelled TTY); skipped rather than typed from a synonym\",\n }),\n );\n }\n // Keep the file's warnings in line order regardless of when each was decided. Appended one at a\n // time on purpose: a spread would pass every warning as an argument, and a large enough malformed\n // release (RRF files run to millions of rows) exceeds the argument limit and throws. This path\n // must never crash.\n conso.sort((a, b) => a.line - b.line);\n for (const w of conso) warnings.push(w);\n\n return concepts;\n}\n\n/** Parse `RXNREL.RRF` into `subject → edges`, normalizing each row to the documented direction. */\nfunction parseRel(\n content: string,\n warnings: RxNormLoadWarning[],\n): { edges: Map<string, RxNormEdge[]>; edgeCount: number } {\n const edges = new Map<string, RxNormEdge[]>();\n let edgeCount = 0;\n for (const [i, raw] of content.split(/\\r?\\n/).entries()) {\n if (raw === \"\") continue;\n const cells = parseRrfLine(raw);\n if (cells.length <= REL.RELA) {\n warnings.push(\n Object.freeze({\n code: \"TERM_RXNORM_MALFORMED_ROW\",\n file: \"RXNREL\",\n line: i + 1,\n detail: `row has ${String(cells.length)} columns, need at least ${String(REL.RELA + 1)}`,\n }),\n );\n continue;\n }\n const rela = cell(cells, REL.RELA);\n const rxcui1 = cell(cells, REL.RXCUI1);\n const rxcui2 = cell(cells, REL.RXCUI2);\n // No navigable predicate, or an atom-level (RXAUI) row with a blank RXCUI — not a concept edge.\n if (rela === undefined || rela === \"\") continue;\n if (rxcui1 === undefined || rxcui1 === \"\" || rxcui2 === undefined || rxcui2 === \"\") continue;\n\n // Direction convention (RxNorm techdoc §12.7): RELA is the relationship RXCUI2 HAS TO RXCUI1,\n // so subject = RXCUI2, object = RXCUI1.\n const edge: RxNormEdge = Object.freeze({ subject: rxcui2, predicate: rela, object: rxcui1 });\n const list = edges.get(rxcui2);\n if (list) list.push(edge);\n else edges.set(rxcui2, [edge]);\n edgeCount++;\n }\n return { edges, edgeCount };\n}\n\n/** Parse `RXNSAT.RRF` NDC attributes into `NDC → { rxcui, status }` (active as of the release). */\nfunction parseNdcs(\n content: string,\n warnings: RxNormLoadWarning[],\n): Map<string, { rxcui: string; status: NdcStatus }> {\n const ndcs = new Map<string, { rxcui: string; status: NdcStatus }>();\n for (const [i, raw] of content.split(/\\r?\\n/).entries()) {\n if (raw === \"\") continue;\n const cells = parseRrfLine(raw);\n if (cells.length <= SAT.ATV) {\n warnings.push(\n Object.freeze({\n code: \"TERM_RXNORM_MALFORMED_ROW\",\n file: \"RXNSAT\",\n line: i + 1,\n detail: `row has ${String(cells.length)} columns, need at least ${String(SAT.ATV + 1)}`,\n }),\n );\n continue;\n }\n if (cell(cells, SAT.ATN) !== ATN_NDC) continue; // not an NDC attribute — expected, skip silently\n const ndc = cell(cells, SAT.ATV);\n const rxcui = cell(cells, SAT.RXCUI);\n if (ndc === undefined || ndc === \"\" || rxcui === undefined || rxcui === \"\") {\n warnings.push(\n Object.freeze({\n code: \"TERM_RXNORM_MALFORMED_ROW\",\n file: \"RXNSAT\",\n line: i + 1,\n detail: \"NDC attribute row is missing its RXCUI or NDC value\",\n }),\n );\n continue;\n }\n // A first mapping per NDC wins; an NDC present in the release is active as of that release.\n if (!ndcs.has(ndc)) ndcs.set(ndc, Object.freeze({ rxcui, status: \"active\" }));\n }\n return ndcs;\n}\n\n/**\n * Load a **caller-supplied** RxNorm RRF release into an immutable {@link RxNormGraph}.\n *\n * Parses `RXNCONSO` (concepts), `RXNREL` (directed edges, normalized to the documented direction), and\n * — when supplied — `RXNSAT` (NDC attributes). Liberal on load: a structurally unusable row is a\n * skipped, surfaced {@link RxNormLoadWarning}, never partial. Ships **no** RxNorm release — the graph\n * is entirely the caller's release.\n *\n * A concept is typed only by a **defining** atom, never by a synonym-class one and never by file\n * order; an `RXCUI` no defining atom could type is skipped and surfaced as\n * `TERM_RXNORM_UNTYPED_CONCEPT`. See the module documentation.\n *\n * @param source - The {@link RxNormGraphSource} (RRF file contents + optional version).\n * @returns The immutable {@link RxNormGraph}.\n * @example\n * ```ts\n * import { loadRxNormGraph } from \"@cosyte/terminology\";\n *\n * // Synthetic rows in the RxNorm RRF wire format (no RxNorm release is bundled).\n * const graph = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|IN||lisinopril||N||\\n2|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||\",\n * // \"SCDC(2) has_ingredient IN(1)\": subject=RXCUI2=2, object=RXCUI1=1.\n * rel: \"1|||RN|2|||has_ingredient|||RXNORM||||||\",\n * });\n * graph.conceptCount; // => 2\n * ```\n */\nexport function loadRxNormGraph(source: RxNormGraphSource): RxNormGraph {\n const warnings: RxNormLoadWarning[] = [];\n const concepts = parseConso(source.conso, warnings);\n const { edges, edgeCount } = parseRel(source.rel, warnings);\n const ndcs =\n source.sat !== undefined ? parseNdcs(source.sat, warnings) : new Map<string, never>();\n\n // Freeze each edge list so the graph is deeply immutable.\n for (const list of edges.values()) Object.freeze(list);\n\n const out: Writable<RxNormGraph> = {\n concepts,\n edges,\n ndcs,\n conceptCount: concepts.size,\n edgeCount,\n warnings: Object.freeze(warnings),\n };\n if (source.version !== undefined) out.version = source.version;\n return Object.freeze(out);\n}\n","/**\n * The RxNorm **relationship (`RELA`) vocabulary** and the **direction convention** the drug graph is\n * built on — encoded here as published identity facts (like the code-system OID↔URI facts in\n * {@link ../systems/registry}), grounded firsthand on the NLM RxNorm Technical Documentation and the\n * UMLS Reference Manual. **No RxNorm release is bundled** — what ships is the relationship *names*\n * and the *rule* for reading a row's direction.\n *\n * **The direction rule (a documented medication-safety trap).** From the\n * RxNorm Technical Documentation (§12.7) and the UMLS Reference Manual, verbatim: *\"the direction of\n * REL — the relationship which the SECOND concept or atom (with … RXCUI2 …) HAS TO the FIRST concept\n * or atom (with … RXCUI1 …).\"* The doc's worked example — a row with `RXCUI1=1155862`, `RELA=isa`,\n * `RXCUI2=197589` — reads *\"197589 **isa** 1155862\"* (the second concept is-a the first).\n *\n * So an `RXNREL.RRF` row is read **`RXCUI2 ⟶RELA⟶ RXCUI1`**, and {@link ../rxnorm/load.loadRxNormGraph}\n * normalizes every row to `subject = RXCUI2`, `predicate = RELA`, `object = RXCUI1`. Concretely, a\n * `has_ingredient` row places the **having** concept in `RXCUI2` and what it *has* in `RXCUI1`; a\n * `tradename_of` row places the **branded** concept in `RXCUI2` and the **generic** in `RXCUI1` (the\n * brand *is a tradename of* the generic). Getting this backwards is a wrong-medication bug, so the\n * fixtures pin it against the doc's convention.\n *\n * **Direction is not topology, and the topology is not the obvious one.** Knowing how to read a row\n * does not tell you which rows exist. RxNorm authors `has_ingredient` from the **clinical** side\n * (`SCDC`/`SCDF`/`SCDG`) to an `IN`, and from the **branded** side (`SBD`/`SBDC`/`SBDF`/`SBDG`) to a\n * `BN` rather than to the active ingredient; it authors **no** `SCD ⟶ IN` ingredient edge at all, so\n * a clinical drug reaches its ingredient only through `consists_of`. The **precise** forms\n * (`SCDFP`/`SBDFP`/`SCDGP`) carry no `has_ingredient` row either: an `SCDFP` instead reaches its\n * basis-of-strength substances by `has_boss` (one-to-many, and its targets can be a `PIN` or a plain\n * `IN`), and the other two author no ingredient-bearing edge at all. Treat those pairings as the\n * ones RxNorm authors, not as a closed set, and read the `TTY` of what a traversal returns. See\n * {@link ../rxnorm/navigate.ingredientsOf}.\n *\n * @packageDocumentation\n */\n\n/**\n * The drug-graph `RELA` relationship names, grounded on the NLM RxNorm Technical Documentation\n * (Appendix 1). Each is directional and read `subject ⟶RELA⟶ object` after normalization (see the\n * module doc). RxNorm ships both members of an inverse pair as **separate rows**, so the graph\n * traverses the authored predicate for the direction it wants — it **never synthesizes an inverse**.\n *\n * @example\n * ```ts\n * import { RELA } from \"@cosyte/terminology\";\n *\n * RELA.HAS_INGREDIENT; // => \"has_ingredient\"\n * ```\n */\nexport const RELA = {\n /**\n * `has_ingredient`: subject *has ingredient* object. Authored from the clinical side\n * (`SCDC`/`SCDF`/`SCDG`) to an `IN` and from the branded side (`SBD`/`SBDC`/`SBDF`/`SBDG`) to a\n * `BN`; RxNorm authors no `SCD ⟶ IN` row.\n */\n HAS_INGREDIENT: \"has_ingredient\",\n /**\n * `ingredient_of`: subject *is an ingredient of* object. The authored inverse, so an `IN` reaches\n * clinical components and dose forms and a `BN` reaches branded concepts (the `SBD` included).\n * Neither reaches an `SCD`.\n */\n INGREDIENT_OF: \"ingredient_of\",\n /** `has_precise_ingredient` — subject *has precise ingredient* object (a `PIN`). */\n HAS_PRECISE_INGREDIENT: \"has_precise_ingredient\",\n /** `precise_ingredient_of` — inverse of `has_precise_ingredient`. */\n PRECISE_INGREDIENT_OF: \"precise_ingredient_of\",\n /** `tradename_of` — subject (a branded concept) *is a tradename of* object (its generic). */\n TRADENAME_OF: \"tradename_of\",\n /** `has_tradename` — subject (a generic concept) *has tradename* object (a branded concept). */\n HAS_TRADENAME: \"has_tradename\",\n /** `has_dose_form` — subject (a drug) *has dose form* object (a `DF`). */\n HAS_DOSE_FORM: \"has_dose_form\",\n /** `dose_form_of` — subject (a `DF`) *is the dose form of* object (a drug). */\n DOSE_FORM_OF: \"dose_form_of\",\n /** `has_doseformgroup` — subject *has dose-form group* object (a `DFG`). */\n HAS_DOSE_FORM_GROUP: \"has_doseformgroup\",\n /** `doseformgroup_of` — inverse of `has_doseformgroup`. */\n DOSE_FORM_GROUP_OF: \"doseformgroup_of\",\n /** `consists_of` — subject (an `SCD`/`SBD`) *consists of* object (its `SCDC`/`SBDC` component(s)). */\n CONSISTS_OF: \"consists_of\",\n /** `constitutes` — subject (a component) *constitutes* object (the drug). Inverse of `consists_of`. */\n CONSTITUTES: \"constitutes\",\n /** `contains` — subject (a pack) *contains* object (a member drug). */\n CONTAINS: \"contains\",\n /** `contained_in` — subject (a drug) *is contained in* object (a pack). Inverse of `contains`. */\n CONTAINED_IN: \"contained_in\",\n /** `has_quantified_form` — subject *has quantified form* object. */\n HAS_QUANTIFIED_FORM: \"has_quantified_form\",\n /** `quantified_form_of` — inverse of `has_quantified_form`. */\n QUANTIFIED_FORM_OF: \"quantified_form_of\",\n /** `isa` — subject *is a* object (hierarchical, e.g. `SCD isa SCDG`). */\n ISA: \"isa\",\n /** `inverse_isa` — subject *is a parent of* object. Inverse of `isa`. */\n INVERSE_ISA: \"inverse_isa\",\n} as const;\n\n/** A value from {@link RELA} — a drug-graph relationship name. */\nexport type RelaName = (typeof RELA)[keyof typeof RELA];\n\n/**\n * The authored **inverse pairs** of the drug-graph `RELA`s — a published fact (RxNorm Appendix 1),\n * used only to *document* and *validate* that a caller is traversing a real relationship. The graph\n * **never** uses this to synthesize a missing edge: RxNorm ships both directions, so\n * {@link ../rxnorm/navigate} follows whichever authored predicate points the way it wants to go.\n *\n * @example\n * ```ts\n * import { RELA_INVERSE, RELA } from \"@cosyte/terminology\";\n *\n * RELA_INVERSE[RELA.HAS_INGREDIENT]; // => \"ingredient_of\"\n * ```\n */\nexport const RELA_INVERSE: Readonly<Record<string, string>> = Object.freeze({\n [RELA.HAS_INGREDIENT]: RELA.INGREDIENT_OF,\n [RELA.INGREDIENT_OF]: RELA.HAS_INGREDIENT,\n [RELA.HAS_PRECISE_INGREDIENT]: RELA.PRECISE_INGREDIENT_OF,\n [RELA.PRECISE_INGREDIENT_OF]: RELA.HAS_PRECISE_INGREDIENT,\n [RELA.TRADENAME_OF]: RELA.HAS_TRADENAME,\n [RELA.HAS_TRADENAME]: RELA.TRADENAME_OF,\n [RELA.HAS_DOSE_FORM]: RELA.DOSE_FORM_OF,\n [RELA.DOSE_FORM_OF]: RELA.HAS_DOSE_FORM,\n [RELA.HAS_DOSE_FORM_GROUP]: RELA.DOSE_FORM_GROUP_OF,\n [RELA.DOSE_FORM_GROUP_OF]: RELA.HAS_DOSE_FORM_GROUP,\n [RELA.CONSISTS_OF]: RELA.CONSTITUTES,\n [RELA.CONSTITUTES]: RELA.CONSISTS_OF,\n [RELA.CONTAINS]: RELA.CONTAINED_IN,\n [RELA.CONTAINED_IN]: RELA.CONTAINS,\n [RELA.HAS_QUANTIFIED_FORM]: RELA.QUANTIFIED_FORM_OF,\n [RELA.QUANTIFIED_FORM_OF]: RELA.HAS_QUANTIFIED_FORM,\n [RELA.ISA]: RELA.INVERSE_ISA,\n [RELA.INVERSE_ISA]: RELA.ISA,\n});\n\n/** The canonical code-system URI for **RxNorm** — a published identity fact, attached to graph codings. */\nexport const RXNORM_SYSTEM = \"http://www.nlm.nih.gov/research/umls/rxnorm\";\n","/**\n * **RxNorm drug-graph navigation**: resolve a drug to its components and its\n * ingredient, a branded drug to its generic, a drug to its dose form, and an NDC to its `RXCUI`, over\n * a loaded {@link RxNormGraph}. Every query is **fail-safe and never-fabricate**:\n *\n * - a queried `RXCUI` absent from the graph is a typed {@link RxNormUnknown}, never a guessed concept;\n * - a present concept with no such relationship is a {@link RxNormRelated} with **empty** `targets` —\n * an honest, data-grounded \"no such edge\", distinct from \"unknown concept\";\n * - navigation follows only **authored** edges by their predicate; the engine **never synthesizes an\n * inverse** (RxNorm ships both directions as separate rows, so brand→generic follows the authored\n * `tradename_of` and generic→brand follows the authored `has_tradename`);\n * - an NDC not in the loaded release is a typed {@link NdcUnmapped}, and a resolution carries the\n * **as-of release** and temporal {@link ../rxnorm/types.NdcStatus} (never a timeless assertion);\n * - approximate matching is an **opt-in, explicitly labeled** path ({@link approximateMatch}), never\n * the default and never presented as an exact code resolution.\n *\n * @packageDocumentation\n */\n\nimport { RELA } from \"./rela.js\";\nimport type {\n NdcResult,\n RxNormApproximateMatch,\n RxNormConcept,\n RxNormGraph,\n RxNormNavResult,\n} from \"./types.js\";\n\n/**\n * Look up a single concept by `RXCUI`.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The concept unique identifier.\n * @returns The {@link RxNormConcept}, or `undefined` when the `RXCUI` is not in the release.\n * @example\n * ```ts\n * import { loadRxNormGraph, getConcept } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({ conso: \"1|ENG||||||||||RXNORM|IN||aspirin||N||\", rel: \"\" });\n * getConcept(g, \"1\")?.tty; // => \"IN\"\n * ```\n */\nexport function getConcept(graph: RxNormGraph, rxcui: string): RxNormConcept | undefined {\n return graph.concepts.get(rxcui);\n}\n\n/** Resolve the object `RXCUI`s of a source's edges (matching `predicates`) to loaded concepts. */\nfunction follow(\n graph: RxNormGraph,\n rxcui: string,\n predicates: ReadonlySet<string>,\n): RxNormNavResult {\n if (!graph.concepts.has(rxcui)) {\n return Object.freeze({ found: false, code: \"TERM_RXNORM_UNKNOWN_RXCUI\", rxcui });\n }\n const out: RxNormConcept[] = [];\n const seen = new Set<string>();\n for (const edge of graph.edges.get(rxcui) ?? []) {\n if (!predicates.has(edge.predicate)) continue;\n if (seen.has(edge.object)) continue;\n const target = graph.concepts.get(edge.object);\n // Only surface a target we actually loaded — an edge to an unloaded concept is a load-completeness\n // gap (the caller's release omitted that atom), never fabricated into a placeholder concept.\n if (target !== undefined) {\n out.push(target);\n seen.add(edge.object);\n }\n }\n return Object.freeze({\n found: true,\n rxcui,\n predicates: Object.freeze([...predicates]),\n targets: Object.freeze(out),\n });\n}\n\n/**\n * Follow one or more `RELA` predicates out of a concept (the generic navigation primitive). Direction\n * is the **authored** edge direction (`subject ⟶predicate⟶ object`); the engine never inverts.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The source concept.\n * @param predicate - A `RELA` name, or an array of them (any-of).\n * @returns A {@link RxNormNavResult}: the related concepts (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, relatedByRela, RELA } from \"@cosyte/terminology\";\n *\n * // \"SCDC(2) has_ingredient IN(1)\": subject=RXCUI2=2, object=RXCUI1=1.\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|IN||lisinopril||N||\\n2|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||\",\n * rel: \"1|||RN|2|||has_ingredient|||RXNORM||||||\",\n * });\n * const r = relatedByRela(g, \"2\", RELA.HAS_INGREDIENT);\n * r.found && r.targets[0]?.name; // => \"lisinopril\"\n * ```\n */\nexport function relatedByRela(\n graph: RxNormGraph,\n rxcui: string,\n predicate: string | readonly string[],\n): RxNormNavResult {\n const set = new Set(typeof predicate === \"string\" ? [predicate] : predicate);\n return follow(graph, rxcui, set);\n}\n\n/**\n * The **ingredients** of a concept — the concepts it links to by a **direct** `has_ingredient` /\n * `has_precise_ingredient` edge in the loaded release.\n *\n * This follows the *authored, direct* edge only (never-fabricate, never a synthesized path), and\n * **RxNorm's ingredient topology is not the obvious one**. Always read the `TTY` of what comes back:\n *\n * - concepts on the **clinical** side (`SCDC`, `SCDF`, `SCDG`) link to the ingredient itself, an\n * `IN`;\n * - concepts on the **branded** side (`SBD`, `SBDC`, `SBDF`, `SBDG`) link to their **brand name**, a\n * `BN`. That is what the release says and what is echoed back, term type included. It is *not* the\n * active ingredient. (`has_precise_ingredient`, which this function also follows, likewise reaches\n * a `PIN`.)\n * - a **clinical drug** (`SCD`) carries **no** `has_ingredient` edge at all. RxNorm authors none, in\n * any release, so this honestly returns found-with-empty-targets rather than walking a path on the\n * caller's behalf.\n * - the **precise** forms (`SCDFP`, `SBDFP`, `SCDGP`) carry **neither** edge, so this returns\n * found-with-empty-targets for them too. They do **not** behave like their non-precise siblings:\n * an `SCDFP` reaches its basis-of-strength substance(s) by `has_boss`, a one-to-many relation with\n * a different meaning whose targets can be a `PIN` or a plain `IN`, and which this function\n * deliberately does not follow; an `SBDFP` and an\n * `SCDGP` author no ingredient-bearing edge at all and are reached instead through `form_of` /\n * `tradename_of` / `isa`.\n *\n * Those pairings are the ones RxNorm authors, not a closed set a caller may rely on: check the\n * returned `TTY` rather than assuming it from the one you queried.\n *\n * **To reach an active ingredient, walk to the CLINICAL component and take its edge.** From an `SCD`\n * that is `SCD ⟶consists_of⟶ SCDC ⟶has_ingredient⟶ IN`, i.e. {@link consistsOf} then\n * `ingredientsOf`. From an `SBD` it needs one more decision, because `consists_of` returns **both**\n * its branded component (`SBDC`, whose own ingredient edge is the `BN` again) and the clinical\n * `SCDC`: it is the `SCDC` that leads to the `IN`. The engine never invents the transitive edge and\n * never picks that branch for you.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The concept (a drug or a clinical/branded component).\n * @returns The directly-linked ingredient concepts (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, ingredientsOf } from \"@cosyte/terminology\";\n *\n * // The ingredient edge is authored on the COMPONENT, not on the clinical drug.\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|IN||lisinopril||N||\\n2|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||\",\n * rel: \"1|||RN|2|||has_ingredient|||RXNORM||||||\",\n * });\n * ingredientsOf(g, \"2\").found; // => true\n * ```\n */\nexport function ingredientsOf(graph: RxNormGraph, rxcui: string): RxNormNavResult {\n return follow(graph, rxcui, new Set([RELA.HAS_INGREDIENT, RELA.HAS_PRECISE_INGREDIENT]));\n}\n\n/**\n * The **generic** form(s) of a branded concept — an `SBD`/`BN`/`BPCK` `tradename_of` its generic. The\n * authored forward edge; the engine never inverts a `has_tradename` edge to synthesize this.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The branded concept.\n * @returns The generic concept(s) (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, genericFor } from \"@cosyte/terminology\";\n *\n * // \"SBD(2) tradename_of SCD(1)\": subject=RXCUI2=2, object=RXCUI1=1.\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\\n2|ENG||||||||||RXNORM|SBD||lisinopril 10 MG Oral Tablet [Zestril]||N||\",\n * rel: \"1|||RN|2|||tradename_of|||RXNORM||||||\",\n * });\n * genericFor(g, \"2\").found; // => true\n * ```\n */\nexport function genericFor(graph: RxNormGraph, rxcui: string): RxNormNavResult {\n return follow(graph, rxcui, new Set([RELA.TRADENAME_OF]));\n}\n\n/**\n * The **branded** form(s) of a generic concept — an `SCD`/`IN`/`GPCK` that `has_tradename` a brand.\n * The authored forward edge; not a synthesized inverse of `tradename_of`.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The generic concept.\n * @returns The branded concept(s) (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, brandsFor } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\\n2|ENG||||||||||RXNORM|SBD||lisinopril 10 MG Oral Tablet [Zestril]||N||\",\n * rel: \"2|||RN|1|||has_tradename|||RXNORM||||||\",\n * });\n * brandsFor(g, \"1\").found; // => true\n * ```\n */\nexport function brandsFor(graph: RxNormGraph, rxcui: string): RxNormNavResult {\n return follow(graph, rxcui, new Set([RELA.HAS_TRADENAME]));\n}\n\n/**\n * The **dose form(s)** of a drug — the `DF`/`DFG` concepts it `has_dose_form` / `has_doseformgroup`.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The drug concept.\n * @returns The dose-form concept(s) (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, doseFormsOf } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\\n9|ENG||||||||||RXNORM|DF||Oral Tablet||N||\",\n * rel: \"9|||RN|1|||has_dose_form|||RXNORM||||||\",\n * });\n * doseFormsOf(g, \"1\").found; // => true\n * ```\n */\nexport function doseFormsOf(graph: RxNormGraph, rxcui: string): RxNormNavResult {\n return follow(graph, rxcui, new Set([RELA.HAS_DOSE_FORM, RELA.HAS_DOSE_FORM_GROUP]));\n}\n\n/**\n * The **components** a drug `consists_of` — an `SCD`/`SBD` → its `SCDC`/`SBDC` dose-form components.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The drug concept.\n * @returns The component concept(s) (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, consistsOf } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({\n * conso: \"2|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\\n3|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||\",\n * rel: \"3|||RN|2|||consists_of|||RXNORM||||||\",\n * });\n * consistsOf(g, \"2\").found; // => true\n * ```\n */\nexport function consistsOf(graph: RxNormGraph, rxcui: string): RxNormNavResult {\n return follow(graph, rxcui, new Set([RELA.CONSISTS_OF]));\n}\n\n/**\n * Resolve an **NDC** (National Drug Code) to its `RXCUI` in the loaded release, carrying the temporal\n * status and the as-of release. NDC↔RXCUI is many:1 and changes across releases, so an\n * NDC present in the release is `active` **as of that release**; an absent NDC is a typed\n * {@link NdcUnmapped}, never a guessed `RXCUI`.\n *\n * @param graph - A loaded {@link RxNormGraph} (load with `sat` supplied to populate NDC attributes).\n * @param ndc - The NDC (as it appears in the release, e.g. 11-digit).\n * @returns An {@link NdcResult} — a resolution with status + `asOf`, or a typed absence.\n * @example\n * ```ts\n * import { loadRxNormGraph, resolveNdc } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({\n * conso: \"2|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\",\n * rel: \"\",\n * sat: \"2||||||||NDC|RXNORM|00000000000|N||\",\n * version: \"RXNORM_2026AA\",\n * });\n * const r = resolveNdc(g, \"00000000000\");\n * r.resolved && r.status; // => \"active\"\n * ```\n */\nexport function resolveNdc(graph: RxNormGraph, ndc: string): NdcResult {\n const hit = graph.ndcs.get(ndc);\n if (hit === undefined) {\n return Object.freeze({ resolved: false, code: \"TERM_RXNORM_NDC_UNMAPPED\", ndc });\n }\n const out = {\n resolved: true as const,\n ndc,\n rxcui: hit.rxcui,\n status: hit.status,\n ...(graph.version !== undefined ? { asOf: graph.version } : {}),\n };\n return Object.freeze(out);\n}\n\n/** Tokenize a drug name into a set of lowercased alphanumeric tokens (for similarity only). */\nfunction tokenize(name: string): Set<string> {\n return new Set(\n name\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t !== \"\"),\n );\n}\n\n/** Jaccard similarity of two token sets in `[0, 1]` — a derived, labeled score, not a clinical claim. */\nfunction jaccard(a: ReadonlySet<string>, b: ReadonlySet<string>): number {\n if (a.size === 0 || b.size === 0) return 0;\n let inter = 0;\n for (const t of a) if (b.has(t)) inter++;\n const union = a.size + b.size - inter;\n return union === 0 ? 0 : inter / union;\n}\n\n/** Options for {@link approximateMatch}. */\nexport interface ApproximateMatchOptions {\n /** Minimum similarity (`0`–`1`) for a candidate to be returned. Default `0.34`. */\n readonly minScore?: number;\n /** Maximum number of candidates to return, best-first. Default `20`. */\n readonly limit?: number;\n}\n\n/**\n * **Opt-in, explicitly labeled** approximate name matching — find loaded concepts whose\n * names are token-similar to `query`. This is **never** the default resolution path and its results\n * are **never** an exact code assertion: every candidate is marked `approximate: true` with a derived\n * {@link RxNormApproximateMatch.score}. A caller opts in by calling this function explicitly.\n *\n * Coverage is not correctness: a \"no match\" is an **empty** array (typed, honest),\n * distinct from a fabricated nearest guess. The engine never promotes an approximate hit to an exact\n * one.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param query - A free-text drug name to match against loaded concept names.\n * @param options - {@link ApproximateMatchOptions} (min score, limit).\n * @returns The labeled approximate candidates, best-first (possibly empty). Never an exact resolution.\n * @example\n * ```ts\n * import { loadRxNormGraph, approximateMatch } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|IN||lisinopril||N||\",\n * rel: \"\",\n * });\n * approximateMatch(g, \"lisinopril\")[0]?.approximate; // => true\n * ```\n */\nexport function approximateMatch(\n graph: RxNormGraph,\n query: string,\n options: ApproximateMatchOptions = {},\n): readonly RxNormApproximateMatch[] {\n const minScore = options.minScore ?? 0.34;\n const limit = options.limit ?? 20;\n const q = tokenize(query);\n if (q.size === 0) return Object.freeze([]);\n\n const scored: RxNormApproximateMatch[] = [];\n for (const concept of graph.concepts.values()) {\n const score = jaccard(q, tokenize(concept.name));\n if (score >= minScore) scored.push(Object.freeze({ approximate: true, concept, score }));\n }\n // Best-first; ties keep a stable order by RXCUI so the result is deterministic.\n scored.sort((a, b) => b.score - a.score || a.concept.rxcui.localeCompare(b.concept.rxcui));\n return Object.freeze(scored.slice(0, limit));\n}\n","/**\n * Public entry point for **`@cosyte/terminology`** — a zero-dependency, developer-focused\n * **terminology engine** for US healthcare code systems.\n *\n * Unlike its sibling `@cosyte/*` packages, this is **not a wire-format parser**: it mirrors the\n * **FHIR Terminology Module** (`$translate`, `$lookup`, `$validate-code`, `$expand`, …), operating\n * over **consumer-supplied** FHIR resources. It ships the *engine* and **no code-system release**\n * (SNOMED CT / CPT / LOINC / UMLS / RxNorm are strictly BYO). It is not content-free: see\n * **What is bundled** at the end of this note, which includes the UCUM unit table, the code-system\n * *identities* (OID ↔ URI), the SNOMED CT concepts the crosswalk resolver names and RxNorm's\n * relationship and term-type names, each with its copyright.\n *\n * **Code-system identity and ConceptMap translation:**\n *\n * - {@link resolveSystem} — the code-system identity / canonical-URI resolver (mnemonic | OID → URI).\n * - {@link loadConceptMap} + {@link translate} — the ConceptMap `$translate` engine, with the\n * **never-fabricate / never-invert** invariants: an unmapped source is a typed\n * {@link TranslateUnmapped}, never a guessed target; a directional map is never run backwards.\n *\n * **The CodeSystem load layer**, with the FHIR `$lookup` / `$validate-code` operations:\n *\n * - {@link loadCodeSystem} — load a **consumer-supplied** release (RRF / CSV / fixed-width / FHIR\n * `CodeSystem` JSON) into an immutable model. Ships the loader; **no code-system release**.\n * - {@link lookup} — code → display + properties, carrying status (deprecated / header-not-billable).\n * - {@link validateCode} — is a code a valid member of the system, with its status flags.\n *\n * The never-fabricate invariant holds here too: an unknown code is a typed `unknown` / `valid: false`,\n * never a fabricated display or a guessed `valid: true`.\n *\n * **The ValueSet binding layer** — FHIR `$expand` / `$validate-code` over a `compose`:\n *\n * - {@link loadValueSet} — load a **consumer-supplied** FHIR `ValueSet` (intensional `compose` and/or\n * a pre-computed `expansion`) into an immutable model.\n * - {@link expand} — flatten membership over the supplied {@link CodeSystem}s (`include`/`exclude`,\n * explicit `concept` lists, `is-a`/property `filter`s, referenced value sets), with an honest\n * `complete` flag: an unresolvable part is a typed `TERM_VALUESET_CANNOT_EXPAND`, never a guess.\n * - {@link validateCodeInValueSet} — binding membership, returning a **decided** `result` only when\n * proven and a typed `undetermined` otherwise (a truncated expansion never reads as complete).\n *\n * **The UCUM unit layer** — a hand-rolled UCUM grammar parser + validation + representation\n * canonicalization (recognition only, **no** magnitude conversion):\n *\n * - {@link validateUcum} — is a string a valid UCUM unit; if so, its canonical descriptor. An\n * invalid unit is a typed `TERM_UCUM_INVALID`, never a guessed \"nearest\" unit.\n * - {@link ucumEqual} — do two expressions denote the *same unit* (`N` ≡ `kg.m/s2`), by reducing\n * both to base dimensions. Not magnitude conversion (`mg/dL` → `mmol/L` is refused).\n * - {@link parseUcum} / {@link reduce} / {@link loadUcumEssence} — the underlying grammar parser,\n * dimensional reducer, and the in-memory model of the vendored, verbatim UCUM table.\n *\n * **The crosswalk resolvers** — the never-fabricate/never-invert invariant applied to the\n * published, directional reference maps:\n *\n * - {@link loadGems} + {@link applyGem} — the CMS **ICD-9↔ICD-10 GEMs** (public-domain reference\n * mappings), honoring the steward's Approximate / No-Map / Combination (scenario→choice-list) flags.\n * A No-Map source is a typed {@link CrosswalkNoMap}; a 1:many source returns the full candidate set.\n * - {@link loadComplexMap} + {@link applyComplexMap} — the NLM **SNOMED CT → ICD-10-CM complex map**\n * (BYO — **no SNOMED CT refset bundled**), evaluating Map Group / Priority / `IFA` Rule /\n * Advice / Category against caller-supplied {@link PatientContext}; a rule needing context the\n * caller lacks is a typed {@link ComplexMapContextRequired}, never a guessed branch.\n * - {@link invertGem} — the never-invert refusal made a first-class, thrown contract\n * ({@link FATAL_CODES.TERM_MAP_NOT_INVERTIBLE}).\n *\n * **The RxNorm drug relationship graph** — ingredient / brand / clinical-drug / dose-form\n * navigation over a **caller-supplied** RxNorm RRF release:\n *\n * - {@link loadRxNormGraph} — load `RXNCONSO` (concepts, typed by `TTY`), `RXNREL` (directed `RELA`\n * edges, normalized to the documented `RXCUI2 ⟶RELA⟶ RXCUI1` direction), and optionally `RXNSAT`\n * (NDC attributes) into an immutable graph. Ships **no** RxNorm release — BYO.\n * - {@link ingredientsOf} / {@link genericFor} / {@link brandsFor} / {@link doseFormsOf} /\n * {@link consistsOf} / {@link relatedByRela} — graph navigation following **authored** edges only\n * (the engine never synthesizes an inverse). An absent `RXCUI` is a typed {@link RxNormUnknown}.\n * - {@link resolveNdc} — NDC → `RXCUI` carrying the temporal status and the as-of release; an absent\n * NDC is a typed {@link NdcUnmapped}, never a guess.\n * - {@link approximateMatch} — the **opt-in, explicitly labeled** similarity path (never the default,\n * never an exact code assertion).\n *\n * **What is bundled.** No code-system release is. What is bundled includes the following, named with\n * its copyright:\n *\n * - the **UCUM unit table** (`ucum-essence.xml`, version 2.2, revision-date 2024-06-17) — copyright\n * ©1999–2024 Regenstrief Institute, Inc., all rights reserved, reproduced **verbatim** under the\n * UCUM Copyright Notice and License (https://ucum.org/license), embedded byte-for-byte in the\n * published build and parsed at runtime; no modified or derivative copy is distributed. The UCUM\n * Specification is provided \"as is\" **without warranty of any kind** — see the License for the\n * full disclaimer. The complete notice ships with this package at `vendor/ucum/NOTICE.md`.\n * - the **code-system identity facts** ({@link SYSTEM_IDENTITIES}) — OID ↔ canonical-URI pairings,\n * which identify the systems rather than listing any system's codes.\n * - the **SNOMED CT concepts the crosswalk resolver names**, each with its description: the four\n * map-category concepts ({@link MAP_CATEGORIES}) a complex-map row's `mapCategoryId` refers to, and\n * the two gender findings (`248152002` Female, `248153007` Male) a gender `IFA` rule is written\n * against. Further SNOMED CT identifiers, and ICD-10-CM codes, appear in the API documentation\n * examples, which are distributed in the compiled declaration files and in the build's\n * sourcemaps. SNOMED CT is copyright © International Health Terminology Standards\n * Development Organisation.\n * - the **RxNorm relationship and term-type names** the drug-graph API is written against: the\n * relationship names in {@link RELA} / {@link RELA_INVERSE} (`has_ingredient`, `tradename_of`, …),\n * and the term-type codes in {@link TERM_TYPES}, each with its name as published by the U.S.\n * National Library of Medicine (`SCD` reads \"Semantic Clinical Drug\"). Individual RxNorm\n * identifiers also appear in the API documentation examples, with their RxNorm names and term\n * types (for instance `RXCUI` `316151`, \"lisinopril 10 MG\"), and in `README.md` as well as the\n * places named above. RxNorm is produced by the National Library of Medicine; no RxNorm release\n * is bundled.\n *\n * The `LICENSE` file that ships with this package carries the MIT text for the package's own code\n * and a third-party notices section naming each of the above.\n *\n * The content packs that would change this (the CMS GEM files, the RxNorm Current Prescribable\n * subset) are not bundled; a caller supplies them, as they do a SNOMED CT, CPT, LOINC, UMLS or VSAC\n * release, under whatever terms its steward sets. This states what is distributed and under whose\n * copyright; it is not legal advice, and makes no claim about whether a particular use is permitted\n * to you.\n *\n * @packageDocumentation\n */\n\n/**\n * Library version string, kept in lockstep with `package.json#version`.\n *\n * Changesets owns the bump and rewrites `package.json` only, so the release `version` script runs\n * `scripts/sync-version.mjs` to rewrite this declaration in the same commit, and\n * `test/sanity.test.ts` compares the two so a skipped sync goes red instead of shipping a version\n * string that lies. That is not hypothetical: `0.0.1` went to the registry exporting `\"0.0.0\"`.\n *\n * @example\n * ```ts\n * import { VERSION } from \"@cosyte/terminology\";\n * typeof VERSION; // => \"string\"\n * ```\n */\nexport const VERSION: string = \"0.0.7\";\n\n// ── Value types ──────────────────────────────────────────────────────────────────────────────\nexport { coding, codeableConcept, type Coding, type CodeableConcept } from \"./common/coding.js\";\n\n// ── Diagnostics (value-free stable codes + typed error) ──────────────────────────────────────\nexport {\n DIAGNOSTIC_CODES,\n FATAL_CODES,\n TerminologyError,\n type DiagnosticCode,\n type FatalCode,\n} from \"./common/diagnostics.js\";\n\n// ── FHIR JSON navigation helpers (for consumers reading untrusted resources) ───────────────────\nexport { isJsonObject, getString, getArray, getBoolean, getNumber } from \"./common/fhir-json.js\";\n\n// ── Code-system identity / canonical-URI resolver ──────────────────────────────────────────────\nexport {\n resolveSystem,\n isUnknownSystem,\n type ResolveSystemResult,\n type UnknownSystem,\n} from \"./systems/resolve.js\";\nexport {\n SYSTEM_IDENTITIES,\n HL7_V2_OID_ROOT,\n HL7_V2_URL_PREFIX,\n type SystemIdentity,\n} from \"./systems/registry.js\";\n\n// ── ConceptMap $translate engine ──────────────────────────────────────────────────────────────\nexport { loadConceptMap } from \"./conceptmap/load.js\";\nexport { translate } from \"./conceptmap/translate.js\";\nexport type {\n ConceptMap,\n ConceptMapGroup,\n ConceptMapElement,\n ConceptMapTarget,\n ConceptMapUnmapped,\n MapProvenance,\n R4Equivalence,\n Relationship,\n TranslateMatch,\n TranslateMatched,\n TranslateResult,\n TranslateUnmapped,\n UnmappedMode,\n} from \"./conceptmap/types.js\";\n\n// ── CodeSystem load layer + $lookup / $validate-code ────────────────────────────────────────────\nexport { loadCodeSystem } from \"./codesystem/load.js\";\nexport { lookup, validateCode } from \"./codesystem/lookup.js\";\nexport { parseRrf, parseRrfLine } from \"./codesystem/rrf.js\";\nexport { parseCsv, parseCsvSource } from \"./codesystem/csv.js\";\nexport {\n parseFixedWidth,\n sliceField,\n ICD10CM_ORDER_FILE_FIELDS,\n} from \"./codesystem/fixed-width.js\";\nexport { parseFhirCodeSystem } from \"./codesystem/fhir.js\";\nexport { defaultStatusMapper, makeStatus } from \"./codesystem/status.js\";\nexport type {\n CodeSystem,\n CodeSystemSource,\n Concept,\n ConceptActivity,\n ConceptStatus,\n Property,\n LoadWarning,\n LookupOutcome,\n LookupResult,\n LookupUnknown,\n ValidateCodeResult,\n StatusMapper,\n FieldSlice,\n RrfSource,\n RrfColumnMap,\n RrfPropertyColumn,\n CsvSource,\n CsvColumnMap,\n FixedWidthSource,\n FixedWidthFieldMap,\n FixedWidthPropertyField,\n BillableFlag,\n FhirCodeSystemSource,\n} from \"./codesystem/types.js\";\n\n// ── ValueSet binding: compose / $expand / $validate-code ─────────────────────────────────────────\nexport { loadValueSet } from \"./valueset/load.js\";\nexport { expand } from \"./valueset/expand.js\";\nexport { validateCodeInValueSet } from \"./valueset/validate.js\";\nexport { buildSubsumption, isA, matchesFilter, unsupportedOps } from \"./valueset/filters.js\";\nexport type { Subsumption, FilterMatch } from \"./valueset/filters.js\";\nexport type {\n ValueSet,\n ValueSetCompose,\n ConceptSetComponent,\n ConceptSetFilter,\n ConceptRef,\n FilterOperator,\n ExpansionContains,\n ValueSetExpansion,\n ExpansionContext,\n ExpansionDiagnostic,\n ExpandResult,\n ValueSetMembership,\n ValueSetMemberDecided,\n ValueSetMemberUndetermined,\n} from \"./valueset/types.js\";\n\n// ── UCUM: unit grammar validation + representation canonicalization (recognition only) ────────────\nexport { validateUcum, ucumEqual } from \"./ucum/validate.js\";\nexport { parseUcum, type ParseResult, type ParseFailure } from \"./ucum/parse.js\";\nexport { reduce } from \"./ucum/reduce.js\";\nexport { loadUcumEssence } from \"./ucum/essence.js\";\nexport type {\n UcumValidation,\n UcumEssence,\n UcumPrefix,\n UcumAtom,\n UnitNode,\n ComponentNode,\n SimpleUnitNode,\n FactorNode,\n GroupNode,\n AnnotationNode,\n Reduction,\n LinearReduction,\n SpecialReduction,\n} from \"./ucum/types.js\";\n\n// ── Crosswalk resolvers: ICD-9↔ICD-10 GEMs + SNOMED→ICD-10-CM complex map (never-fabricate) ───────\nexport { loadGems, applyGem, invertGem, type GemSource } from \"./crosswalk/gems.js\";\nexport {\n loadComplexMap,\n applyComplexMap,\n COMPLEX_MAP_SOURCE_SYSTEM,\n type ComplexMapInput,\n} from \"./crosswalk/complex-map.js\";\nexport {\n MAP_CATEGORIES,\n NO_MAP_CATEGORIES,\n ICD10CM_SYSTEM,\n ICD9CM_SYSTEM,\n SNOMEDCT_SYSTEM,\n type MapCategoryId,\n} from \"./crosswalk/categories.js\";\nexport type {\n GemDirection,\n GemFlags,\n GemEntry,\n GemMap,\n GemLoadWarning,\n GemChoiceList,\n GemScenario,\n GemMatched,\n GemApplyResult,\n ComplexMapEntry,\n ComplexMap,\n ComplexMapLoadWarning,\n PatientContext,\n ComplexMapGroupResult,\n ComplexMapGroupResolved,\n ComplexMapGroupNoMap,\n ComplexMapContextRequired,\n ComplexMapMatched,\n ComplexMapApplyResult,\n CrosswalkNoMap,\n CrosswalkUnmapped,\n} from \"./crosswalk/types.js\";\n\n// ── RxNorm drug graph: ingredient / brand / clinical-drug / dose-form navigation (never-fabricate) ──\nexport { loadRxNormGraph, type RxNormGraphSource } from \"./rxnorm/load.js\";\nexport {\n getConcept,\n relatedByRela,\n ingredientsOf,\n genericFor,\n brandsFor,\n doseFormsOf,\n consistsOf,\n resolveNdc,\n approximateMatch,\n type ApproximateMatchOptions,\n} from \"./rxnorm/navigate.js\";\nexport { RELA, RELA_INVERSE, RXNORM_SYSTEM, type RelaName } from \"./rxnorm/rela.js\";\nexport { TERM_TYPES, asTermType, isSynonymTermType } from \"./rxnorm/tty.js\";\nexport type {\n TermType,\n RxNormConcept,\n RxNormEdge,\n RxNormGraph,\n RxNormLoadWarning,\n RxNormNavResult,\n RxNormRelated,\n RxNormUnknown,\n RxNormApproximateMatch,\n NdcStatus,\n NdcResolution,\n NdcUnmapped,\n NdcResult,\n} from \"./rxnorm/types.js\";\n"]}
1
+ {"version":3,"sources":["../src/common/coding.ts","../src/common/diagnostics.ts","../src/common/fhir-json.ts","../src/systems/registry.ts","../src/systems/resolve.ts","../src/conceptmap/load.ts","../src/conceptmap/translate.ts","../src/common/frozen-map.ts","../src/codesystem/status.ts","../src/codesystem/csv.ts","../src/codesystem/fhir.ts","../src/codesystem/fixed-width.ts","../src/codesystem/rrf.ts","../src/codesystem/load.ts","../src/codesystem/lookup.ts","../src/valueset/load.ts","../src/valueset/filters.ts","../src/valueset/expand.ts","../src/valueset/validate.ts","../src/ucum/essence-data.generated.ts","../src/ucum/essence.ts","../src/ucum/parse.ts","../src/ucum/reduce.ts","../src/ucum/validate.ts","../src/crosswalk/gems.ts","../src/crosswalk/categories.ts","../src/crosswalk/complex-map.ts","../src/rxnorm/tty.ts","../src/rxnorm/load.ts","../src/rxnorm/rela.ts","../src/rxnorm/navigate.ts","../src/index.ts"],"names":["v2","coding","malformed","assignString","truncated","cached","valueSet","cannotExpand","underPath","cell"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","file":"index.mjs","sourcesContent":["/**\n * The immutable FHIR value types the engine operates over: {@link Coding} and\n * {@link CodeableConcept}.\n *\n * These mirror the FHIR R4 datatypes of the same names (the interchange lingua franca the whole\n * ecosystem speaks), reduced to the fields the terminology operations need. Every instance the\n * engine hands back is deep-frozen, so a translated result is safe to share across a pipeline\n * without defensive copying — the immutability discipline the parsers follow.\n *\n * @packageDocumentation\n */\n\n/**\n * A single coded value — a `code` drawn from a code `system`, optionally versioned and displayed.\n *\n * Models FHIR R4 `Coding`. `system` is the code system's **canonical URI** (e.g.\n * `http://loinc.org`), not a mnemonic or OID — use {@link ../systems/resolve.resolveSystem} to\n * canonicalize before constructing one. `system` is optional because a raw wire code sometimes\n * arrives without one; the engine surfaces that rather than inventing a system.\n *\n * @example\n * ```ts\n * import { coding } from \"@cosyte/terminology\";\n *\n * const c = coding({ system: \"http://loinc.org\", code: \"2160-0\", display: \"Creatinine\" });\n * c.code; // => \"2160-0\"\n * ```\n */\nexport interface Coding {\n /** The code system's canonical URI (e.g. `http://snomed.info/sct`). Optional when unknown. */\n readonly system?: string;\n /** The symbol in the code system's syntax. Required — a coding without a code is meaningless. */\n readonly code: string;\n /** The code system version this code is drawn from, when known (mappings are release-scoped). */\n readonly version?: string;\n /** The human-readable label. Carried verbatim from the source; never fabricated by the engine. */\n readonly display?: string;\n}\n\n/**\n * A concept described by one or more {@link Coding}s plus optional free text — FHIR R4\n * `CodeableConcept`. Included so the value layer is complete for downstream consumers even though\n * {@link ../conceptmap/translate.translate} operates on a single {@link Coding}.\n *\n * @example\n * ```ts\n * import { codeableConcept } from \"@cosyte/terminology\";\n *\n * const cc = codeableConcept({\n * coding: [{ system: \"http://loinc.org\", code: \"2160-0\" }],\n * text: \"Serum creatinine\",\n * });\n * cc.coding[0].code; // => \"2160-0\"\n * ```\n */\nexport interface CodeableConcept {\n /** The codings for this concept, in order of preference. Frozen and never empty-by-fabrication. */\n readonly coding: readonly Coding[];\n /** Plain-text representation of the concept, when supplied. */\n readonly text?: string;\n}\n\n/**\n * Construct a deep-frozen {@link Coding}.\n *\n * The returned object is `Object.freeze`d so it cannot be mutated in place — parsed/translated\n * values are immutable by default. Optional fields are only present when supplied (no `undefined`\n * keys), so structural equality checks stay clean.\n *\n * @param init - The coding fields; `code` is required.\n * @returns A frozen {@link Coding}.\n * @example\n * ```ts\n * import { coding } from \"@cosyte/terminology\";\n *\n * const frozen = coding({ system: \"http://loinc.org\", code: \"2160-0\" });\n * Object.isFrozen(frozen); // => true\n * ```\n */\nexport function coding(init: Coding): Coding {\n const out: { -readonly [K in keyof Coding]: Coding[K] } = { code: init.code };\n if (init.system !== undefined) out.system = init.system;\n if (init.version !== undefined) out.version = init.version;\n if (init.display !== undefined) out.display = init.display;\n return Object.freeze(out);\n}\n\n/**\n * Construct a deep-frozen {@link CodeableConcept} (its `coding` array and every member frozen).\n *\n * @param init - The concept fields; `coding` is required (may be empty).\n * @returns A frozen {@link CodeableConcept}.\n * @example\n * ```ts\n * import { codeableConcept } from \"@cosyte/terminology\";\n *\n * const cc = codeableConcept({ coding: [{ code: \"2160-0\" }] });\n * Object.isFrozen(cc.coding); // => true\n * ```\n */\nexport function codeableConcept(init: CodeableConcept): CodeableConcept {\n const frozenCodings = Object.freeze(init.coding.map((c) => coding(c)));\n const out: { -readonly [K in keyof CodeableConcept]: CodeableConcept[K] } = {\n coding: frozenCodings,\n };\n if (init.text !== undefined) out.text = init.text;\n return Object.freeze(out);\n}\n","/**\n * The engine's **stable diagnostic + fatal code registries** and its typed error.\n *\n * `@cosyte/terminology` is an engine, not a lenient wire-format parser, so its stable codes are\n * **diagnostics** (typed, surfaced outcomes a consumer branches on) and **fatals** (thrown on\n * structurally unusable input), rather than the parsers' \"Tier-2 tolerance warnings\". The\n * discipline is identical: the code strings are part of the public contract — consumers narrow on\n * them, so renaming or removing one is a **breaking change**, and the full set is snapshotted via\n * `sortedCodeSet` (`@cosyte/test-utils`) as a reviewable tripwire.\n *\n * **Value-free by construction**, and the property is stated as what it actually is: every string a\n * diagnostic or fatal message is assembled from is **owned by the engine**. Three kinds, and no\n * fourth: a string literal; an entry in a frozen table keyed on the engine's own vocabulary; and a\n * **locus this package built** — a 1-based `line`, a column count, or an index path over the\n * caller's own resource made of integers and FHIR field names (`ConceptMap group[0].element[0].target[0]`,\n * `compose.include[2]`). Nothing a caller configured and nothing their release or resource contained\n * is ever one of them, so no such string reaches a `message`, a `stack`, or a `detail`, at any\n * length.\n *\n * Read that as the rule, and note what it does **not** say. It does not say no factory takes a\n * `string` parameter. Several do: `malformed(path, fault)` in `conceptmap/load.ts` and\n * `valueset/load.ts`, and `cannotExpand(detail, path)`, `truncated(detail, path)` and\n * `underPath(d, prefix)` in `valueset/` — where `expand.ts` and `validate.ts` each carry their own\n * copy. It says every **argument** reaching them is engine-owned: each `fault` and `detail` is a\n * literal at the call site, each `path` and `prefix` is built from indices by the loader that\n * raises it. That distinction is the thing to preserve — an absolute \"no factory takes a value\n * parameter\" reads as a stronger guarantee than the one the code makes, and those factories are the\n * counter-example to it. Do not write the count down; derive it.\n *\n * Positional context is value-free the same way: a `line` integer, an `ExpansionDiagnostic.path`\n * index path into the caller's own resource (`compose.include[2]`), or a closed-set token\n * (`RXNCONSO` / `RXNREL` / `RXNSAT`) — never a URI, a column name, or a field the file supplied.\n * This matters because a code *in patient context* can be PHI, and a thrown error is the one surface\n * that reaches a log or an error reporter without the consumer choosing to put it there.\n *\n * **▶ THE CLAIM IS ABOUT THE MESSAGE FIELDS, NOT ABOUT THE OBJECTS. DO NOT SHORTEN IT TO \"A\n * DIAGNOSTIC IS SAFE TO LOG\".** The safe strings are the *message* fields:\n * `TerminologyError.message` / `.stack`, `LoadWarning.detail`, `GemLoadWarning.detail`,\n * `ComplexMapLoadWarning.detail`, `RxNormLoadWarning.detail`, `ExpansionDiagnostic.detail`,\n * `ParseFailure.reason` and `UcumValidation.reason`, plus the loci beside them.\n *\n * The **objects** these codes appear on are a different matter, and they carry verbatim text from\n * two *different* provenances, which decide differently:\n *\n * - **Your query, echoed back** — `LookupUnknown.input`, `LookupResult.code`, `UnknownSystem.input`,\n * `TranslateUnmapped.source`, `CrosswalkUnmapped.source`, `CrosswalkNoMap.source`,\n * `RxNormUnknown.rxcui`, `RxNormRelated.predicates`, `NdcUnmapped.ndc`,\n * `ValueSetMembership.coding`, and **`MapProvenance.sourceSystem`** — which is the `system` off\n * the `Coding` you passed to `translate`, verbatim and unbounded, whenever that coding\n * carries one; the map's own `group.source` is only the fallback for a coding that does not. The\n * query is the one genuinely **patient-derived** input this engine takes (a code off a parsed\n * message, a unit off an observation, an NDC off a prescription), so this is the class that\n * decides a PHI question.\n * - **Your loaded artifact, carried through** — `ComplexMapContextRequired.rules` (the map\n * document's own `rule` / `advice` text) and `MapProvenance.targetSystem` / `.conceptMapUrl` /\n * `.conceptMapVersion`, which are read off the loaded map (`group.target`, `map.url`,\n * `map.version`). These are *reference data*, bounded by the map or release you loaded, not by\n * anything a patient supplied. **`MapProvenance` straddles the two lists** — do not read the whole\n * record as reference data on the strength of the fields that are.\n *\n * Read both lists as illustrative, not closed: **assume any result field may hold what you passed\n * in.** So `JSON.stringify(lookupResult)` into a log is a PHI decision, and `String(err)` is not.\n * Log the `code` and the locus; log a value only if you would log the code you passed in.\n *\n * Those echoes are deliberate and are not going away: they are how a never-fabricate outcome says\n * *which* thing it refused to guess, they are the caller's own data returned to the caller, and\n * bounding them would mean fabricating a miss.\n *\n * @packageDocumentation\n */\n\n/**\n * Stable **diagnostic codes** — typed, surfaced, non-throwing outcomes.\n *\n * These are not errors: they are first-class results a caller inspects (an unmapped translation,\n * an unrecognized code system). `key === value` so `Object.values(...)` yields the snapshot set.\n *\n * @example\n * ```ts\n * import { DIAGNOSTIC_CODES } from \"@cosyte/terminology\";\n *\n * DIAGNOSTIC_CODES.TERM_TRANSLATE_UNMAPPED; // => \"TERM_TRANSLATE_UNMAPPED\"\n * ```\n */\nexport const DIAGNOSTIC_CODES = {\n /**\n * A `$translate` found no target for the source code. A **first-class outcome, never an error** —\n * the source is surfaced as `unmapped`, never replaced with a guessed target (the never-fabricate\n * invariant).\n */\n TERM_TRANSLATE_UNMAPPED: \"TERM_TRANSLATE_UNMAPPED\",\n /**\n * A code-system identifier (URI, OID, or mnemonic) was not recognized by the identity resolver.\n * Surfaced as a typed `unknown`, never coerced to a guessed canonical URI.\n */\n TERM_SYSTEM_UNRECOGNIZED: \"TERM_SYSTEM_UNRECOGNIZED\",\n /**\n * An RRF (pipe-delimited RxNorm/UMLS release) row was structurally unusable — too few columns to\n * reach a configured field, or a missing code. The row is **skipped and surfaced** as a load\n * warning (liberal on load), never kept as a partially-parsed concept.\n */\n TERM_RRF_MALFORMED_ROW: \"TERM_RRF_MALFORMED_ROW\",\n /**\n * A CSV (RFC-4180, e.g. LOINC `Loinc.csv`) row was structurally unusable — too few fields to reach\n * a configured column. The row is **skipped and surfaced** as a load warning, never partial.\n */\n TERM_CSV_MALFORMED: \"TERM_CSV_MALFORMED\",\n /**\n * A fixed-width (e.g. ICD-10-CM order file) row was structurally unusable — too short to contain\n * the configured code field, or a missing code. Skipped and surfaced, never partial.\n */\n TERM_FIXED_WIDTH_MALFORMED: \"TERM_FIXED_WIDTH_MALFORMED\",\n /**\n * A concept inside a FHIR `CodeSystem` resource was unusable — not an object, or missing its\n * required `code`. Skipped and surfaced (the whole resource still loads); `line` is `0` since a\n * JSON concept is not line-addressable.\n */\n TERM_FHIR_CONCEPT_MALFORMED: \"TERM_FHIR_CONCEPT_MALFORMED\",\n /**\n * A `$lookup`/`$validate-code` found no concept for the code in the loaded release. A **first-class\n * typed outcome, never a guess** — the engine returns `unknown`/`valid: false`, never a fabricated\n * display or a coerced `valid: true` (the never-fabricate invariant, applied to code identity).\n */\n TERM_CODE_UNKNOWN: \"TERM_CODE_UNKNOWN\",\n /**\n * A resolved concept is **deprecated / no longer current** (e.g. LOINC `STATUS = DEPRECATED`, or a\n * FHIR concept flagged `inactive`). Surfaced on the concept's status so a caller never presents a\n * non-current code as clean; the concept is still *found* (a lookup succeeds), it is just flagged.\n */\n TERM_CONCEPT_DEPRECATED: \"TERM_CONCEPT_DEPRECATED\",\n /**\n * A resolved concept is a **classification header, not a billable/valid leaf** (e.g. an ICD-10-CM\n * order-file row with the position-15 flag `0`). Surfaced on the concept's status: a header code is\n * found but is **not valid for claim submission**, and must never be presented as billable.\n */\n TERM_CONCEPT_HEADER_NOT_BILLABLE: \"TERM_CONCEPT_HEADER_NOT_BILLABLE\",\n /**\n * A ValueSet `compose` part could **not be expanded** — an intensional `include`/`exclude` whose\n * code system was not supplied, an unresolvable referenced value set, or a `filter` operator the\n * engine does not implement. Surfaced as a typed outcome that marks the expansion **incomplete**;\n * the engine **never** fabricates a member and **never** returns a silently-empty \"no members\"\n * answer for a part it could not compute (a false \"not a member\" is a clinical error).\n */\n TERM_VALUESET_CANNOT_EXPAND: \"TERM_VALUESET_CANNOT_EXPAND\",\n /**\n * A **pre-computed** `ValueSet.expansion` is **incomplete** — its `total` exceeds the number of\n * `contains` entries, or it is flagged too-costly (the VSAC `$expand` >1200-code truncation\n * hazard). The engine **never treats a truncated expansion as complete membership**: a code\n * absent from a truncated expansion is `undetermined`, never a confident \"not a member\".\n */\n TERM_VALUESET_EXPANSION_TRUNCATED: \"TERM_VALUESET_EXPANSION_TRUNCATED\",\n /**\n * A UCUM unit expression is **not valid** — it does not parse against the UCUM grammar, or it\n * names an atom absent from the vendored UCUM table. A **first-class typed outcome, never an\n * error and never a guess**: {@link validateUcum} returns `{ valid: false, reason }`, never a\n * coerced or \"nearest\" unit (the never-fabricate invariant, applied to units). The\n * `reason` is value-free (a grammar fault or an unknown-atom shape), never PHI.\n */\n TERM_UCUM_INVALID: \"TERM_UCUM_INVALID\",\n /**\n * A crosswalk source code has an **authored No-Map** — the steward declares it has no valid target\n * in the other classification (a GEM `NoDx`/`NoPCS` sentinel, or a SNOMED complex-map `447638001`\n * \"cannot be classified\" category). A **first-class typed outcome, never an error and never a\n * guess** (the never-fabricate invariant, applied to crosswalks). Distinct from\n * {@link TERM_CROSSWALK_UNMAPPED}: the source *is* in the map, and the map says \"no target\".\n */\n TERM_CROSSWALK_NO_MAP: \"TERM_CROSSWALK_NO_MAP\",\n /**\n * A crosswalk source code is **absent from the map entirely** — not an authored No-Map, simply not\n * present. Surfaced as a typed outcome (never a fabricated target, never a silent success), and\n * kept distinct from {@link TERM_CROSSWALK_NO_MAP} so a caller can tell \"the steward said no target\"\n * from \"this code was not in the file\".\n */\n TERM_CROSSWALK_UNMAPPED: \"TERM_CROSSWALK_UNMAPPED\",\n /**\n * A SNOMED→ICD-10-CM complex-map group's decision needs **patient context** (an `IFA` age band or\n * gender) the caller did not supply. The engine surfaces the candidate rules + advice and **refuses\n * to pick a branch** it lacks the data for — never a silently-chosen target.\n */\n TERM_CROSSWALK_CONTEXT_REQUIRED: \"TERM_CROSSWALK_CONTEXT_REQUIRED\",\n /**\n * A GEM file line was structurally unusable — not three whitespace-delimited fields, or a flag\n * field that is not a 5-digit code. The row is **skipped and surfaced** as a load warning (liberal\n * on load), never kept as a partially-parsed entry.\n */\n TERM_GEM_MALFORMED_ROW: \"TERM_GEM_MALFORMED_ROW\",\n /**\n * A SNOMED complex-map RF2 refset row was structurally unusable — missing its\n * `referencedComponentId`/`mapGroup`/`mapPriority`. Skipped and surfaced, never partial.\n */\n TERM_COMPLEX_MAP_MALFORMED_ROW: \"TERM_COMPLEX_MAP_MALFORMED_ROW\",\n /**\n * A RxNorm RRF row (`RXNCONSO` / `RXNREL` / `RXNSAT`) was structurally unusable — too few columns to\n * reach a required field, or a missing `RXCUI`/NDC value. The row is **skipped and surfaced** as a\n * load warning (liberal on load), never kept as a partial concept/edge. Rows that are simply *not of\n * interest* (a non-`RXNORM` atom, an atom-level relationship, a non-`NDC` attribute) are skipped\n * **silently** — they are expected, not faults.\n */\n TERM_RXNORM_MALFORMED_ROW: \"TERM_RXNORM_MALFORMED_ROW\",\n /**\n * An `RXCUI` appeared in the release's `SAB=RXNORM` atoms but **none of them could establish its\n * term type**, so it is **not** in the graph. Either every atom carried a synonym-class `TTY`\n * (`PSN`/`SY`/`TMSY`, which Appendix 5 defines as a \"synonym of another TTY\" and which therefore\n * types a *name* rather than a concept) or every atom carried a `TTY` this engine does not model.\n * The concept is skipped rather than typed from a synonym atom: an absent concept is already a\n * first-class typed answer (`TERM_RXNORM_UNKNOWN_RXCUI`), while a concept whose term type reads\n * `TMSY` is a fabricated claim about what a drug *is* that a caller cannot detect.\n */\n TERM_RXNORM_UNTYPED_CONCEPT: \"TERM_RXNORM_UNTYPED_CONCEPT\",\n /**\n * A RxNorm graph navigation was asked about an `RXCUI` **absent from the loaded release** — a\n * first-class typed outcome, never a fabricated concept and never an empty \"success\" (the\n * never-fabricate invariant, applied to the drug graph). Distinct from a *present*\n * concept that simply has no edge of the requested relationship (that is a found result with empty\n * targets).\n */\n TERM_RXNORM_UNKNOWN_RXCUI: \"TERM_RXNORM_UNKNOWN_RXCUI\",\n /**\n * An NDC could **not be resolved** to any `RXCUI` in the loaded RxNorm release — a typed, surfaced\n * absence, never a guessed `RXCUI`. NDC↔RXCUI is many:1 and temporal, so a resolution\n * is always release-scoped; an NDC not present in the loaded release is this diagnostic.\n */\n TERM_RXNORM_NDC_UNMAPPED: \"TERM_RXNORM_NDC_UNMAPPED\",\n} as const;\n\n/**\n * A value from {@link DIAGNOSTIC_CODES} — the type consumers narrow a diagnostic's `code` against.\n */\nexport type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];\n\n/**\n * Stable **fatal codes** — thrown (as a {@link TerminologyError}) when input cannot be loaded into\n * a usable model at all. Always thrown, never swallowed. `key === value`, part of the contract.\n *\n * @example\n * ```ts\n * import { FATAL_CODES } from \"@cosyte/terminology\";\n *\n * FATAL_CODES.TERM_CONCEPTMAP_MALFORMED; // => \"TERM_CONCEPTMAP_MALFORMED\"\n * ```\n */\nexport const FATAL_CODES = {\n /**\n * A `ConceptMap` resource was structurally unusable — wrong `resourceType`, or a group/element\n * missing a required field. Thrown rather than silently loading a partial, misleading map.\n */\n TERM_CONCEPTMAP_MALFORMED: \"TERM_CONCEPTMAP_MALFORMED\",\n /**\n * A CodeSystem *source* was structurally unusable — a FHIR resource with the wrong `resourceType`,\n * or a delimited source whose configured code/display column is absent from the header. Thrown\n * rather than silently loading an empty or mis-keyed release. (Malformed individual **rows** are\n * skipped-and-surfaced load warnings, not fatals — only an unusable *source* is fatal.)\n */\n TERM_CODESYSTEM_MALFORMED: \"TERM_CODESYSTEM_MALFORMED\",\n /**\n * A `ValueSet` resource was structurally unusable — wrong `resourceType`, or a `compose`/`expansion`\n * whose required shape (an `include` that is not an object, a `contains` entry missing its `code`)\n * is corrupt. Thrown rather than silently loading a partial value set that would bind *some* codes\n * and quietly drop others. (A `filter` operator the engine does not implement is **not** fatal — it\n * is the surfaced `TERM_VALUESET_CANNOT_EXPAND` diagnostic at expansion time.)\n */\n TERM_VALUESET_MALFORMED: \"TERM_VALUESET_MALFORMED\",\n /**\n * A crosswalk map *source* was structurally unusable — e.g. a SNOMED complex-map RF2 refset with\n * empty content or a header missing a required column. Thrown rather than silently loading an empty\n * or mis-keyed map. (Malformed individual **rows** are skipped-and-surfaced warnings, not fatals.)\n */\n TERM_CROSSWALK_MALFORMED: \"TERM_CROSSWALK_MALFORMED\",\n /**\n * An **inversion** of a directional crosswalk was requested — a forbidden operation. The GEMs and\n * the SNOMED→ICD-10-CM map are authoritative in **one direction only**; a forward map is not the\n * inverse of the backward map. Thrown by {@link ../crosswalk/gems.invertGem} so the\n * never-invert refusal is a first-class, discoverable contract rather than a silent absence.\n */\n TERM_MAP_NOT_INVERTIBLE: \"TERM_MAP_NOT_INVERTIBLE\",\n} as const;\n\n/**\n * A value from {@link FATAL_CODES} — the type carried by a thrown {@link TerminologyError}.\n */\nexport type FatalCode = (typeof FATAL_CODES)[keyof typeof FATAL_CODES];\n\n/**\n * The engine's typed error. Carries a stable {@link FatalCode} so callers branch on `err.code`\n * without string-matching the message. Thrown only for {@link FATAL_CODES} conditions.\n *\n * The `message` is **value-free**: it names the structural fault (a resource path, a missing field,\n * the *role* of a configured column) and never echoes an input value — so it is safe to log, and\n * safe in an `err.stack` that reaches an error reporter. The rule the strings are built by is in\n * this module's docblock above.\n *\n * @example\n * ```ts\n * import { loadConceptMap, TerminologyError, FATAL_CODES } from \"@cosyte/terminology\";\n *\n * try {\n * loadConceptMap({ resourceType: \"Patient\" });\n * } catch (err) {\n * (err as TerminologyError).code === FATAL_CODES.TERM_CONCEPTMAP_MALFORMED; // => true\n * }\n * ```\n */\nexport class TerminologyError extends Error {\n /** The stable fatal code. Branch on this, not on {@link message}. */\n public readonly code: FatalCode;\n\n /**\n * @param code - The stable {@link FatalCode} describing the fault.\n * @param message - A **value-free** structural description (path + fault; never an input value).\n * Every piece of it must be engine-owned — a literal, a frozen-table entry, or a locus this\n * package built. This string reaches `err.stack`, so interpolating a caller-supplied or\n * document-derived value into it is how a diagnostic becomes a leak.\n */\n public constructor(code: FatalCode, message: string) {\n super(message);\n this.name = \"TerminologyError\";\n this.code = code;\n // Restore the prototype chain for reliable `instanceof` across the ESM/CJS build boundary.\n Object.setPrototypeOf(this, TerminologyError.prototype);\n }\n}\n","/**\n * Minimal, zero-dependency navigation helpers for **untrusted FHIR JSON** (`unknown` inputs\n * decoded from a consumer-supplied `ConceptMap`/`CodeSystem`/`ValueSet`).\n *\n * The engine never trusts the shape of its inputs: every accessor here narrows an `unknown`\n * to a concrete type or returns `undefined`, so a malformed resource degrades to a typed\n * diagnostic (see {@link ../conceptmap/load}) rather than a `TypeError` deep in a getter. This\n * is the terminology-engine analogue of a parser's lenient tokenizer — liberal on load.\n *\n * These helpers are **value-free**: they read structure, never log or echo field *values*, so a\n * code-in-context (which can be PHI) never flows into a message.\n *\n * @packageDocumentation\n */\n\n/**\n * Narrow an `unknown` to a plain JSON object (a non-null, non-array `object`).\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a non-null, non-array object.\n * @example\n * ```ts\n * import { isJsonObject } from \"@cosyte/terminology\";\n *\n * isJsonObject({ resourceType: \"ConceptMap\" }); // => true\n * ```\n */\nexport function isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Read a **string** property from an untrusted object, or `undefined` if absent/not a string.\n *\n * @param obj - The source object (may be any `unknown`).\n * @param key - The property name to read.\n * @returns The string value, or `undefined` when the key is missing or not a string.\n * @example\n * ```ts\n * import { getString } from \"@cosyte/terminology\";\n *\n * getString({ url: \"http://loinc.org\" }, \"url\"); // => \"http://loinc.org\"\n * ```\n */\nexport function getString(obj: unknown, key: string): string | undefined {\n if (!isJsonObject(obj)) return undefined;\n const v = obj[key];\n return typeof v === \"string\" ? v : undefined;\n}\n\n/**\n * Read an **array** property from an untrusted object as a `readonly unknown[]`, or `undefined`.\n *\n * The elements are left as `unknown` — callers narrow each one. A non-array (including a missing\n * key) yields `undefined`, which callers treat as \"no entries\" rather than an error.\n *\n * @param obj - The source object (may be any `unknown`).\n * @param key - The property name to read.\n * @returns The array (elements untyped), or `undefined` when the key is missing or not an array.\n * @example\n * ```ts\n * import { getArray } from \"@cosyte/terminology\";\n *\n * getArray({ group: [{ source: \"a\" }] }, \"group\")?.length; // => 1\n * ```\n */\nexport function getArray(obj: unknown, key: string): readonly unknown[] | undefined {\n if (!isJsonObject(obj)) return undefined;\n const v = obj[key];\n return Array.isArray(v) ? v : undefined;\n}\n\n/**\n * Read a **boolean** property from an untrusted object, or `undefined` if absent/not a boolean.\n *\n * A non-boolean (including a missing key, or the strings `\"true\"`/`\"false\"`) yields `undefined` —\n * the accessor never coerces, so a caller can distinguish \"explicitly `false`\" from \"absent\".\n *\n * @param obj - The source object (may be any `unknown`).\n * @param key - The property name to read.\n * @returns The boolean value, or `undefined` when the key is missing or not a boolean.\n * @example\n * ```ts\n * import { getBoolean } from \"@cosyte/terminology\";\n *\n * getBoolean({ inactive: true }, \"inactive\"); // => true\n * ```\n */\nexport function getBoolean(obj: unknown, key: string): boolean | undefined {\n if (!isJsonObject(obj)) return undefined;\n const v = obj[key];\n return typeof v === \"boolean\" ? v : undefined;\n}\n\n/**\n * Read a **number** property from an untrusted object, or `undefined` if absent/not a finite number.\n *\n * @param obj - The source object (may be any `unknown`).\n * @param key - The property name to read.\n * @returns The number value, or `undefined` when the key is missing or not a finite number.\n * @example\n * ```ts\n * import { getNumber } from \"@cosyte/terminology\";\n *\n * getNumber({ valueInteger: 3 }, \"valueInteger\"); // => 3\n * ```\n */\nexport function getNumber(obj: unknown, key: string): number | undefined {\n if (!isJsonObject(obj)) return undefined;\n const v = obj[key];\n return typeof v === \"number\" && Number.isFinite(v) ? v : undefined;\n}\n","/**\n * The **code-system identity registry** — the grounded OID ↔ canonical-URI ↔ mnemonic facts the\n * ecosystem uses.\n *\n * A code-system *identity* (the triple of canonical URI, OID, and HL7 v2 mnemonic that all name\n * the same terminology) is a **published identifier** for the system, not the system's code list — so\n * it is encoded here, cited firsthand. That is where the line falls: identities are encoded; the code\n * *lists themselves* (SNOMED CT / CPT / LOINC content) are BYO and never bundled.\n *\n * **Every identity below is grounded firsthand against a primary source** (verified 2026-07-21):\n *\n * - The FHIR R4 terminology-systems registry — `https://hl7.org/fhir/R4/terminologies-systems.html`\n * — for LOINC, SNOMED CT, RxNorm, UCUM, CPT, NDC, CVX (canonical URI + OID), and for the HL7 v2\n * table URI/OID patterns (`http://terminology.hl7.org/CodeSystem/v2-[X]` ↔\n * `2.16.840.1.113883.12.[X]`).\n * - The FHIR R4 ICD page — `https://hl7.org/fhir/R4/icd.html` — for ICD-10-CM\n * (`http://hl7.org/fhir/sid/icd-10-cm` ↔ `2.16.840.1.113883.6.90`).\n * - HL7 Table 0396 (coding-system mnemonics) — the THO `v2-0396` code system — for the mnemonics\n * (`LN`, `SCT`, `I10C`, `RXNORM`, `UCUM`, `C4`, `NDC`, `CVX`).\n *\n * Identities that could not be pinned to a primary source firsthand are **omitted**, not\n * guessed — notably ICD-9-CM and ICD-10-PCS, whose OID\n * assignments were ambiguous across sources.\n *\n * @packageDocumentation\n */\n\n/**\n * A resolved code-system identity — the canonical URI plus the alternate identifiers that name the\n * same system.\n */\nexport interface SystemIdentity {\n /** The canonical URI — the single value the engine treats as the system's identity. */\n readonly url: string;\n /** The registered OID (bare, no `urn:oid:` prefix), when the system has one. */\n readonly oid?: string;\n /** A short human-readable name for diagnostics/logs (value-free — a system name, never a value). */\n readonly name: string;\n /** HL7 v2 Table 0396 mnemonic(s) and other accepted short aliases for this system. */\n readonly mnemonics: readonly string[];\n}\n\n/**\n * The seed identity table. Order is irrelevant; lookup indexes are built from it in\n * {@link ../systems/resolve}. Each entry is one firsthand-grounded system (see the module doc).\n */\nexport const SYSTEM_IDENTITIES: readonly SystemIdentity[] = Object.freeze(\n [\n {\n url: \"http://loinc.org\",\n oid: \"2.16.840.1.113883.6.1\",\n name: \"LOINC\",\n mnemonics: [\"LN\", \"LOINC\"],\n },\n {\n url: \"http://snomed.info/sct\",\n oid: \"2.16.840.1.113883.6.96\",\n name: \"SNOMED CT\",\n mnemonics: [\"SCT\", \"SNOMEDCT\", \"SNOMED\"],\n },\n {\n url: \"http://hl7.org/fhir/sid/icd-10-cm\",\n oid: \"2.16.840.1.113883.6.90\",\n name: \"ICD-10-CM\",\n mnemonics: [\"I10C\", \"ICD10CM\"],\n },\n {\n url: \"http://www.nlm.nih.gov/research/umls/rxnorm\",\n oid: \"2.16.840.1.113883.6.88\",\n name: \"RxNorm\",\n mnemonics: [\"RXNORM\"],\n },\n {\n url: \"http://unitsofmeasure.org\",\n oid: \"2.16.840.1.113883.6.8\",\n name: \"UCUM\",\n mnemonics: [\"UCUM\"],\n },\n {\n url: \"http://www.ama-assn.org/go/cpt\",\n oid: \"2.16.840.1.113883.6.12\",\n name: \"CPT\",\n mnemonics: [\"C4\", \"CPT\"],\n },\n {\n url: \"http://hl7.org/fhir/sid/ndc\",\n oid: \"2.16.840.1.113883.6.69\",\n name: \"NDC\",\n mnemonics: [\"NDC\"],\n },\n {\n url: \"http://hl7.org/fhir/sid/cvx\",\n oid: \"2.16.840.1.113883.12.292\",\n name: \"CVX (CDC Vaccine Codes)\",\n mnemonics: [\"CVX\"],\n },\n ].map((e) => Object.freeze({ ...e, mnemonics: Object.freeze([...e.mnemonics]) })),\n);\n\n/**\n * The OID root under which every HL7 v2 table code system is registered:\n * `2.16.840.1.113883.12.[table]` — grounded against the FHIR R4 terminology-systems registry.\n * The table number is appended with no leading zeros (e.g. table 0203 → `…12.203`).\n */\nexport const HL7_V2_OID_ROOT = \"2.16.840.1.113883.12\";\n\n/**\n * The canonical URI prefix for HL7 v2 table code systems in HL7 Terminology (THO):\n * `http://terminology.hl7.org/CodeSystem/v2-[XXXX]`, where `[XXXX]` is the zero-padded 4-digit\n * table id — grounded against the FHIR R4 terminology-systems registry.\n */\nexport const HL7_V2_URL_PREFIX = \"http://terminology.hl7.org/CodeSystem/v2-\";\n","/**\n * The **code-system identity / canonical-URI resolver** — `resolveSystem`.\n *\n * Given a code system named any of the ways the ecosystem names it — a canonical URI, an OID (bare\n * or `urn:oid:`-prefixed), or an HL7 v2 mnemonic (`LN`, `SCT`, …) — it returns the one canonical\n * {@link SystemIdentity}. This is the piece `@cosyte/transform` pins so a `Coding` off any parser\n * (HL7 v2 CE/CWE, C-CDA, FHIR) can be canonicalized to a single system URI before translation.\n *\n * **Never guesses.** An identifier that matches nothing known returns a typed\n * `{ unknown: true, input }` — never a fabricated URI (the never-fabricate invariant, applied to\n * system identity).\n *\n * @packageDocumentation\n */\n\nimport {\n HL7_V2_OID_ROOT,\n HL7_V2_URL_PREFIX,\n SYSTEM_IDENTITIES,\n type SystemIdentity,\n} from \"./registry.js\";\n\n/** The typed \"not recognized\" outcome from {@link resolveSystem} — surfaced, never a guess. */\nexport interface UnknownSystem {\n /** Discriminant: the identifier was not recognized. */\n readonly unknown: true;\n /** The identifier as supplied, echoed back so the caller can surface/log it. */\n readonly input: string;\n}\n\n/** The result of {@link resolveSystem}: a resolved {@link SystemIdentity} or a typed unknown. */\nexport type ResolveSystemResult = SystemIdentity | UnknownSystem;\n\n// Lookup indexes, built once from the frozen seed table. Keys are lowercased for URI/mnemonic\n// case-insensitivity; OIDs are matched exactly (digits/dots only).\nconst byUrl = new Map<string, SystemIdentity>();\nconst byOid = new Map<string, SystemIdentity>();\nconst byMnemonic = new Map<string, SystemIdentity>();\n\nfor (const id of SYSTEM_IDENTITIES) {\n byUrl.set(id.url.toLowerCase(), id);\n if (id.oid !== undefined) byOid.set(id.oid, id);\n for (const m of id.mnemonics) byMnemonic.set(m.toLowerCase(), id);\n}\n\nconst OID_RE = /^[0-2](?:\\.(?:0|[1-9]\\d*))+$/;\n\n/** Strip a `urn:oid:` prefix if present, returning the bare OID (or the input unchanged). */\nfunction stripOidPrefix(input: string): string {\n const lower = input.toLowerCase();\n return lower.startsWith(\"urn:oid:\") ? input.slice(\"urn:oid:\".length) : input;\n}\n\n/**\n * Recognize an HL7 v2 table code system by URI or OID and build its identity structurally.\n *\n * The v2 table family is huge and open-ended, so it is resolved by **pattern**, not enumerated:\n * `http://terminology.hl7.org/CodeSystem/v2-[XXXX]` ↔ `2.16.840.1.113883.12.[table]`. Both\n * patterns are grounded firsthand (see {@link ../systems/registry}). Returns `undefined` when the\n * input is not a v2 table identifier.\n */\nfunction resolveV2Table(rawInput: string, bareOid: string): SystemIdentity | undefined {\n // OID form: <v2 root>.<table>, table a 1-4 digit integer with no leading zeros. Capped at 4\n // digits to stay symmetric with the URI form (HL7 v2 table ids are 4-digit).\n if (bareOid.startsWith(`${HL7_V2_OID_ROOT}.`)) {\n const tail = bareOid.slice(HL7_V2_OID_ROOT.length + 1);\n if (/^(?:0|[1-9]\\d{0,3})$/.test(tail)) {\n const padded = tail.padStart(4, \"0\");\n return Object.freeze({\n url: `${HL7_V2_URL_PREFIX}${padded}`,\n oid: bareOid,\n name: `HL7 v2 table ${padded}`,\n mnemonics: Object.freeze([`v2-${padded}`]),\n });\n }\n }\n // URI form: <prefix><4-digit table>. Accept case-insensitively on the prefix.\n const lower = rawInput.toLowerCase();\n if (lower.startsWith(HL7_V2_URL_PREFIX.toLowerCase())) {\n const tail = rawInput.slice(HL7_V2_URL_PREFIX.length);\n if (/^\\d{1,4}$/.test(tail)) {\n const padded = tail.padStart(4, \"0\");\n const table = String(Number(tail));\n return Object.freeze({\n url: `${HL7_V2_URL_PREFIX}${padded}`,\n oid: `${HL7_V2_OID_ROOT}.${table}`,\n name: `HL7 v2 table ${padded}`,\n mnemonics: Object.freeze([`v2-${padded}`]),\n });\n }\n }\n return undefined;\n}\n\n/**\n * Resolve a code-system identifier to its canonical {@link SystemIdentity}.\n *\n * Accepts, in order of attempt: a canonical URI (case-insensitive), a `v2-XXXX` mnemonic or a\n * v2 table URI/OID (resolved structurally), a bare or `urn:oid:`-prefixed OID, or an HL7 v2\n * Table 0396 mnemonic. Whitespace is trimmed. An empty or unrecognized identifier yields a typed\n * {@link UnknownSystem} — the resolver **never** invents a URI.\n *\n * @param id - The identifier (canonical URI, OID, `urn:oid:` OID, or mnemonic).\n * @returns The resolved {@link SystemIdentity}, or `{ unknown: true, input }`.\n * @example\n * ```ts\n * import { resolveSystem } from \"@cosyte/terminology\";\n *\n * resolveSystem(\"2.16.840.1.113883.6.1\"); // => { url: \"http://loinc.org\", … }\n * resolveSystem(\"SCT\"); // => { url: \"http://snomed.info/sct\", … }\n * resolveSystem(\"http://example.com/nope\"); // => { unknown: true, input: \"http://example.com/nope\" }\n * ```\n */\nexport function resolveSystem(id: string): ResolveSystemResult {\n // Defensive against JS callers that ignore the `string` type.\n if (typeof id !== \"string\") return { unknown: true, input: \"\" };\n const input = id.trim();\n if (input === \"\") return { unknown: true, input: id };\n\n // 1. Exact canonical URI (case-insensitive).\n const urlHit = byUrl.get(input.toLowerCase());\n if (urlHit) return urlHit;\n\n // 2. HL7 v2 mnemonic (case-insensitive), e.g. LN / SCT / RXNORM.\n const mnemonicHit = byMnemonic.get(input.toLowerCase());\n if (mnemonicHit) return mnemonicHit;\n\n // 3. OID (bare or urn:oid:-prefixed).\n const bareOid = stripOidPrefix(input);\n if (OID_RE.test(bareOid)) {\n const oidHit = byOid.get(bareOid);\n if (oidHit) return oidHit;\n const v2 = resolveV2Table(input, bareOid);\n if (v2) return v2;\n return { unknown: true, input };\n }\n\n // 4. HL7 v2 table by URI/`v2-XXXX` form.\n const v2 = resolveV2Table(input, bareOid);\n if (v2) return v2;\n\n return { unknown: true, input };\n}\n\n/**\n * Type guard: did {@link resolveSystem} fail to recognize the identifier?\n *\n * @param result - A {@link resolveSystem} result.\n * @returns `true` when the result is a typed {@link UnknownSystem}.\n * @example\n * ```ts\n * import { resolveSystem, isUnknownSystem } from \"@cosyte/terminology\";\n *\n * isUnknownSystem(resolveSystem(\"nope\")); // => true\n * ```\n */\nexport function isUnknownSystem(result: ResolveSystemResult): result is UnknownSystem {\n return \"unknown\" in result;\n}\n","/**\n * {@link loadConceptMap} — validate and normalize an untrusted FHIR R4 `ConceptMap` JSON resource\n * into the immutable {@link ConceptMap} model the `$translate` engine runs over.\n *\n * **Conservative on load** (unlike a wire parser's lenient posture): a ConceptMap drives a clinical\n * translation, so a structurally unusable map is a typed **fatal**\n * ({@link FATAL_CODES.TERM_CONCEPTMAP_MALFORMED}), never a silently partial map that would translate\n * *some* codes and quietly drop others. Fault messages are **value-free** — they name the resource\n * *path* and the fault, never echo a code or display *value*.\n *\n * @packageDocumentation\n */\n\nimport { TerminologyError, FATAL_CODES } from \"../common/diagnostics.js\";\nimport { getArray, getString, isJsonObject } from \"../common/fhir-json.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport type {\n ConceptMap,\n ConceptMapElement,\n ConceptMapGroup,\n ConceptMapTarget,\n ConceptMapUnmapped,\n R4Equivalence,\n UnmappedMode,\n} from \"./types.js\";\n\nconst R4_EQUIVALENCES: ReadonlySet<string> = new Set<R4Equivalence>([\n \"relatedto\",\n \"equivalent\",\n \"equal\",\n \"wider\",\n \"subsumes\",\n \"narrower\",\n \"specializes\",\n \"inexact\",\n \"unmatched\",\n \"disjoint\",\n]);\n\nconst INPUT_UNMAPPED_MODES: ReadonlySet<string> = new Set<UnmappedMode>([\n \"provided\",\n \"fixed\",\n \"other-map\",\n]);\n\n/** Throw a value-free {@link TerminologyError} for a malformed ConceptMap at `path`. */\nfunction malformed(path: string, fault: string): never {\n throw new TerminologyError(FATAL_CODES.TERM_CONCEPTMAP_MALFORMED, `ConceptMap ${path}: ${fault}`);\n}\n\n/** Copy an optional string property onto `out[key]` only when present (no `undefined` keys). */\nfunction assignString<T extends Record<string, unknown>>(out: T, src: unknown, key: string): void {\n const v = getString(src, key);\n if (v !== undefined) (out as Record<string, unknown>)[key] = v;\n}\n\nfunction loadTarget(raw: unknown, path: string): ConceptMapTarget {\n if (!isJsonObject(raw)) malformed(path, \"target is not an object\");\n const equivalence = getString(raw, \"equivalence\");\n if (equivalence === undefined) {\n malformed(path, \"target is missing the required 'equivalence' field\");\n }\n if (!R4_EQUIVALENCES.has(equivalence)) {\n malformed(path, \"target has an unrecognized 'equivalence' value\");\n }\n const out: Writable<ConceptMapTarget> = { equivalence: equivalence as R4Equivalence };\n assignString(out, raw, \"code\");\n assignString(out, raw, \"display\");\n assignString(out, raw, \"comment\");\n return Object.freeze(out);\n}\n\nfunction loadElement(raw: unknown, path: string): ConceptMapElement {\n if (!isJsonObject(raw)) malformed(path, \"element is not an object\");\n const rawTargets = getArray(raw, \"target\") ?? [];\n const target = Object.freeze(\n rawTargets.map((t, i) => loadTarget(t, `${path}.target[${String(i)}]`)),\n );\n const out: Writable<ConceptMapElement> = { target };\n assignString(out, raw, \"code\");\n assignString(out, raw, \"display\");\n return Object.freeze(out);\n}\n\nfunction loadUnmapped(raw: unknown, path: string): ConceptMapUnmapped {\n if (!isJsonObject(raw)) malformed(path, \"unmapped is not an object\");\n const mode = getString(raw, \"mode\");\n if (mode === undefined || !INPUT_UNMAPPED_MODES.has(mode)) {\n malformed(path, \"unmapped has a missing or unrecognized 'mode'\");\n }\n const out: Writable<ConceptMapUnmapped> = { mode: mode as UnmappedMode };\n assignString(out, raw, \"code\");\n assignString(out, raw, \"display\");\n assignString(out, raw, \"url\");\n return Object.freeze(out);\n}\n\nfunction loadGroup(raw: unknown, path: string): ConceptMapGroup {\n if (!isJsonObject(raw)) malformed(path, \"group is not an object\");\n const rawElements = getArray(raw, \"element\") ?? [];\n const element = Object.freeze(\n rawElements.map((e, i) => loadElement(e, `${path}.element[${String(i)}]`)),\n );\n const out: Writable<ConceptMapGroup> = { element };\n assignString(out, raw, \"source\");\n assignString(out, raw, \"sourceVersion\");\n assignString(out, raw, \"target\");\n assignString(out, raw, \"targetVersion\");\n if (isJsonObject(raw) && raw[\"unmapped\"] !== undefined) {\n out.unmapped = loadUnmapped(raw[\"unmapped\"], `${path}.unmapped`);\n }\n return Object.freeze(out);\n}\n\n/**\n * Load an untrusted FHIR R4 `ConceptMap` JSON value into an immutable {@link ConceptMap}.\n *\n * Accepts the standard resource shape: a top-level object with `resourceType: \"ConceptMap\"` and an\n * optional `group[]`. `source[x]`/`target[x]` scopes are read from either the `Uri` or `Canonical`\n * variant. The result is deep-frozen. Anything structurally unusable throws a\n * {@link TerminologyError} carrying {@link FATAL_CODES.TERM_CONCEPTMAP_MALFORMED}.\n *\n * @param json - The untrusted resource (typically `JSON.parse` output — hence `unknown`).\n * @returns The immutable, validated {@link ConceptMap}.\n * @throws {TerminologyError} `TERM_CONCEPTMAP_MALFORMED` when the resource is not a usable ConceptMap.\n * @example\n * ```ts\n * import { loadConceptMap } from \"@cosyte/terminology\";\n *\n * const map = loadConceptMap({\n * resourceType: \"ConceptMap\",\n * url: \"http://example.org/cm/gender\",\n * group: [\n * {\n * source: \"http://hl7.org/fhir/administrative-gender\",\n * target: \"http://terminology.hl7.org/CodeSystem/v2-0001\",\n * element: [{ code: \"male\", target: [{ code: \"M\", equivalence: \"equivalent\" }] }],\n * },\n * ],\n * });\n * map.group.length; // => 1\n * ```\n */\nexport function loadConceptMap(json: unknown): ConceptMap {\n if (!isJsonObject(json)) malformed(\"\", \"resource is not a JSON object\");\n const resourceType = getString(json, \"resourceType\");\n if (resourceType !== \"ConceptMap\") {\n malformed(\"\", \"resource is not a ConceptMap (wrong or missing resourceType)\");\n }\n const rawGroups = getArray(json, \"group\") ?? [];\n const group = Object.freeze(rawGroups.map((g, i) => loadGroup(g, `group[${String(i)}]`)));\n const out: Writable<ConceptMap> = { group };\n assignString(out, json, \"url\");\n assignString(out, json, \"version\");\n // R4 source[x]/target[x] — accept either the Uri or Canonical form.\n const sourceScope = getString(json, \"sourceUri\") ?? getString(json, \"sourceCanonical\");\n const targetScope = getString(json, \"targetUri\") ?? getString(json, \"targetCanonical\");\n if (sourceScope !== undefined) out.sourceScope = sourceScope;\n if (targetScope !== undefined) out.targetScope = targetScope;\n return Object.freeze(out);\n}\n","/**\n * {@link translate} — the ConceptMap `$translate` engine, modeled on the FHIR\n * `ConceptMap/$translate` operation.\n *\n * Given a source {@link Coding} and a loaded {@link ConceptMap}, it returns the declared target\n * code(s) with their FHIR relationship and the map's provenance — or, when the source does not map,\n * a **typed {@link TranslateUnmapped}**. Two invariants govern it:\n *\n * 1. **Never fabricate.** An unmapped source yields a surfaced `unmapped` result — never a guessed\n * target. Every target returned is drawn verbatim from the map; the engine invents nothing.\n * 2. **Never invert.** Translation reads the map in its authored direction only: a source coding is\n * matched against `group.element.code` (the source side) and **never** against target codes. A\n * directional map therefore cannot be run backwards — reverse translation requires an explicit\n * inverse map; it is never synthesized here.\n *\n * @packageDocumentation\n */\n\nimport { coding, type Coding } from \"../common/coding.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport type {\n ConceptMap,\n ConceptMapGroup,\n MapProvenance,\n R4Equivalence,\n Relationship,\n TranslateMatch,\n TranslateResult,\n TranslateUnmapped,\n UnmappedMode,\n} from \"./types.js\";\n\n/**\n * Map a verbatim FHIR R4 `equivalence` token to the normalized, version-neutral\n * {@link Relationship} (the R5 vocabulary). The full R4 enum folds in; this is total.\n */\nfunction equivalenceToRelationship(equivalence: R4Equivalence): Relationship {\n switch (equivalence) {\n case \"equivalent\":\n case \"equal\":\n return \"equivalent\";\n case \"wider\":\n case \"subsumes\":\n // The source concept is-a the target ⇒ the source is narrower than the target.\n return \"source-is-narrower-than-target\";\n case \"narrower\":\n case \"specializes\":\n // The target concept is-a the source ⇒ the source is broader than the target.\n return \"source-is-broader-than-target\";\n case \"relatedto\":\n case \"inexact\":\n return \"related-to\";\n case \"disjoint\":\n case \"unmatched\":\n return \"not-related-to\";\n }\n}\n\n/** Does this group apply to a source coding in `system`? A group with no declared source is a\n * single-system wildcard; a coding with no system cannot be discriminated, so all groups apply. */\nfunction groupApplies(group: ConceptMapGroup, system: string | undefined): boolean {\n if (system === undefined) return true;\n return group.source === undefined || group.source === system;\n}\n\n/** Build the provenance record for a translation attempt against `map`, optionally within `group`. */\nfunction provenanceOf(\n map: ConceptMap,\n group: ConceptMapGroup | undefined,\n sourceSystem: string | undefined,\n): MapProvenance {\n const out: { -readonly [K in keyof MapProvenance]: MapProvenance[K] } = {};\n if (map.url !== undefined) out.conceptMapUrl = map.url;\n if (map.version !== undefined) out.conceptMapVersion = map.version;\n const src = sourceSystem ?? group?.source;\n if (src !== undefined) out.sourceSystem = src;\n if (group?.target !== undefined) out.targetSystem = group.target;\n return Object.freeze(out);\n}\n\n/** Assemble the typed unmapped result, reporting (never applying) any declared fallback. */\nfunction unmappedResult(\n source: Coding,\n mode: UnmappedMode,\n provenance: MapProvenance,\n fixedTarget: Coding | undefined,\n otherMapUrl: string | undefined,\n): TranslateResult {\n const out: Writable<TranslateUnmapped> = {\n unmapped: true,\n code: \"TERM_TRANSLATE_UNMAPPED\",\n mode,\n source,\n provenance,\n };\n if (fixedTarget !== undefined) out.fixedTarget = fixedTarget;\n if (otherMapUrl !== undefined) out.otherMapUrl = otherMapUrl;\n return Object.freeze(out);\n}\n\n/**\n * Translate a source {@link Coding} through a loaded {@link ConceptMap}.\n *\n * Matches the coding's `code` against each applicable group's `element.code` (the **source** side —\n * never targets, so the map is never inverted) and returns every declared target for it. A target\n * with an `unmatched` equivalence, or with no `code`, is treated as \"no target\" — the FHIR way of\n * asserting a non-mapping — and does not count as a match. When nothing matches, the map author's\n * `group.unmapped` directive (if any) is *reported* via the result's {@link UnmappedMode} but never\n * silently applied.\n *\n * @param sourceCoding - The source concept to translate.\n * @param map - A {@link ConceptMap} from {@link loadConceptMap}.\n * @returns A {@link TranslateResult} — matched targets, or a typed unmapped outcome.\n * @example\n * ```ts\n * import { loadConceptMap, translate } from \"@cosyte/terminology\";\n *\n * const map = loadConceptMap({\n * resourceType: \"ConceptMap\",\n * group: [\n * {\n * source: \"http://hl7.org/fhir/administrative-gender\",\n * target: \"http://terminology.hl7.org/CodeSystem/v2-0001\",\n * element: [{ code: \"male\", target: [{ code: \"M\", equivalence: \"equivalent\" }] }],\n * },\n * ],\n * });\n * const r = translate(\n * { system: \"http://hl7.org/fhir/administrative-gender\", code: \"male\" },\n * map,\n * );\n * r.unmapped; // => false\n * ```\n */\nexport function translate(sourceCoding: Coding, map: ConceptMap): TranslateResult {\n const source = coding(sourceCoding);\n const system = source.system;\n\n const matches: TranslateMatch[] = [];\n let firstMatchGroup: ConceptMapGroup | undefined;\n let sourceCodePresent = false;\n let fallbackGroup: ConceptMapGroup | undefined;\n\n for (const group of map.group) {\n if (!groupApplies(group, system)) continue;\n if (fallbackGroup === undefined && group.unmapped !== undefined) fallbackGroup = group;\n\n for (const element of group.element) {\n if (element.code !== source.code) continue;\n sourceCodePresent = true;\n for (const t of element.target) {\n // A target without a code, or an explicit `unmatched`, asserts \"no target\" — not a match.\n if (t.code === undefined || t.equivalence === \"unmatched\") continue;\n const targetCoding = coding({\n ...(group.target !== undefined ? { system: group.target } : {}),\n code: t.code,\n ...(t.display !== undefined ? { display: t.display } : {}),\n ...(group.targetVersion !== undefined ? { version: group.targetVersion } : {}),\n });\n const match: {\n -readonly [K in keyof TranslateMatch]: TranslateMatch[K];\n } = {\n target: targetCoding,\n relationship: equivalenceToRelationship(t.equivalence),\n equivalence: t.equivalence,\n };\n if (t.comment !== undefined) match.comment = t.comment;\n matches.push(Object.freeze(match));\n if (firstMatchGroup === undefined) firstMatchGroup = group;\n }\n }\n }\n\n if (matches.length > 0) {\n return Object.freeze({\n unmapped: false,\n matches: Object.freeze(matches),\n provenance: provenanceOf(map, firstMatchGroup, system),\n });\n }\n\n // No usable target. If the source code appeared but every target was a non-mapping, this is an\n // authored \"no map\" (mode 'none'). Otherwise consult a declared group.unmapped fallback.\n if (!sourceCodePresent && fallbackGroup?.unmapped !== undefined) {\n const um = fallbackGroup.unmapped;\n const provenance = provenanceOf(map, fallbackGroup, system);\n if (um.mode === \"fixed\" && um.code !== undefined) {\n const fixed = coding({\n ...(fallbackGroup.target !== undefined ? { system: fallbackGroup.target } : {}),\n code: um.code,\n ...(um.display !== undefined ? { display: um.display } : {}),\n });\n return unmappedResult(source, \"fixed\", provenance, fixed, undefined);\n }\n if (um.mode === \"other-map\") {\n return unmappedResult(source, \"other-map\", provenance, undefined, um.url);\n }\n if (um.mode === \"provided\") {\n return unmappedResult(source, \"provided\", provenance, undefined, undefined);\n }\n }\n\n return unmappedResult(\n source,\n \"none\",\n provenanceOf(map, firstMatchGroup, system),\n undefined,\n undefined,\n );\n}\n","/**\n * {@link frozenMap} — hand a caller a **read-only view** of a loaded model's lookup map instead of\n * the map itself.\n *\n * A loaded release is the engine's answer to \"what does this code mean\", and every `load*` function\n * returns it through `Object.freeze`. `Object.freeze` cannot reach a `Map`: its entries live in an\n * internal slot rather than in properties, so freezing the wrapper leaves `set` / `delete` / `clear`\n * working on the map the wrapper points at. A holder could therefore empty a drug graph's edges,\n * delete an ICD-9 → ICD-10 mapping, or add one the release never authored — on a package whose\n * stated invariant is that it never fabricates.\n *\n * @packageDocumentation\n */\n\n/**\n * The view {@link frozenMap} returns: a {@link ReadonlyMap} that additionally carries the three\n * mutators, so calling one is a named refusal rather than a `TypeError: … is not a function`.\n */\ninterface FrozenMapView<K, V> extends ReadonlyMap<K, V> {\n /** Refuses. Present so a mistaken `set` names the model it tried to mutate. */\n readonly set: () => never;\n /** Refuses. Present so a mistaken `delete` names the model it tried to mutate. */\n readonly delete: () => never;\n /** Refuses. Present so a mistaken `clear` names the model it tried to mutate. */\n readonly clear: () => never;\n}\n\n/**\n * Wrap a built lookup map in a frozen, read-only view of it.\n *\n * **The view is not a `Map`, and that is the point.** Sealing a `Map` by overwriting its mutators\n * closes one route and leaves another: `Map.prototype.set.call(theMap, …)` reaches the internal slot\n * directly and still inserts. The view has no such slot, so the prototype method has no receiver to\n * write to and throws instead — the same reason it cannot be reached by re-defining a property\n * either, since the view is frozen. Reads are unchanged: `get` / `has` / `size` / `keys` / `values` /\n * `entries` / `forEach` / iteration all delegate to the map, which nothing else holds a reference to.\n *\n * The guarantee is **that the model does not change**, not that a write throws — this package ships\n * a CJS build a sloppy-mode caller can `require`, where a refused *property* write is a silent no-op.\n * The three mutators here throw in both modes because they throw explicitly; assert the readings\n * regardless.\n *\n * **What the view costs, and why the cost is paid this way.** Not being a `Map` is observable, and\n * measured rather than reasoned: a view is `instanceof Object` rather than `instanceof Map`, prints\n * as a plain object, `Object.keys` lists its ten own keys (nine methods and the `size` getter, which\n * is why the next clause reads as it does — a method does not survive `JSON.stringify`),\n * `JSON.stringify` renders it as\n * `{\"size\":N}` where a `Map` rendered `{}`, and a model holding one **cannot be structured-cloned** —\n * `structuredClone` and `worker.postMessage` raise a `DataCloneError`, `v8.serialize` a plain `Error`,\n * both naming an uncloneable function. Clone what you need out of it instead\n * (`new Map(model.concepts)`). That refusal is deliberate: the view's methods are left **enumerable**\n * precisely so a clone attempt raises on one of them. Hiding them would make the clone *succeed* and\n * hand back a model whose indexes are empty while its counts still report the loaded figures — the\n * same shape as the defect this function exists to close, arriving silently.\n *\n * @param source - The built map. The caller must not retain a reference to it after wrapping.\n * @param what - What a refusal names, e.g. `\"a loaded RxNorm graph's concepts\"`. **A string literal\n * at the call site**, never a caller- or document-supplied value: it is interpolated into a\n * `TypeError` message, and this engine owns every string a message is built from.\n * @returns A frozen {@link ReadonlyMap} view of `source`.\n * @example\n * ```ts\n * import { frozenMap } from \"./frozen-map.js\";\n *\n * const view = frozenMap(new Map([[\"a\", 1]]), \"the example map\");\n * view.get(\"a\"); // => 1\n * ```\n */\nexport function frozenMap<K, V>(source: Map<K, V>, what: string): ReadonlyMap<K, V> {\n const refuse = (): never => {\n throw new TypeError(`Cannot mutate ${what} (it is immutable)`);\n };\n const view: FrozenMapView<K, V> = {\n get size(): number {\n return source.size;\n },\n get: (key: K): V | undefined => source.get(key),\n has: (key: K): boolean => source.has(key),\n keys: (): ReturnType<Map<K, V>[\"keys\"]> => source.keys(),\n values: (): ReturnType<Map<K, V>[\"values\"]> => source.values(),\n entries: (): ReturnType<Map<K, V>[\"entries\"]> => source.entries(),\n forEach: (\n callback: (value: V, key: K, map: ReadonlyMap<K, V>) => void,\n thisArg?: unknown,\n ): void => {\n for (const [key, value] of source) callback.call(thisArg, value, key, view);\n },\n [Symbol.iterator]: (): ReturnType<Map<K, V>[typeof Symbol.iterator]> =>\n source[Symbol.iterator](),\n set: refuse,\n delete: refuse,\n clear: refuse,\n };\n return Object.freeze(view);\n}\n","/**\n * Status interpretation shared by the loaders — the {@link defaultStatusMapper} that turns a raw\n * steward status token into a normalized {@link ConceptActivity}, and {@link makeStatus} which\n * assembles the frozen {@link ConceptStatus} (attaching the stable diagnostic code for the two\n * concerns it distinguishes: deprecated and header-not-billable).\n *\n * The mapper is deliberately **conservative**: it recognizes only the tokens grounded in the format\n * docs (LOINC `STATUS` lifecycle values and RxNorm/UMLS `SUPPRESS` values), and maps\n * everything else to `unknown` — a non-active state carrying the raw token, **never** a guessed\n * clean-active. Every loader lets the consumer override it for a release with bespoke semantics.\n *\n * @packageDocumentation\n */\n\nimport { DIAGNOSTIC_CODES } from \"../common/diagnostics.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport type { ConceptActivity, ConceptStatus, StatusMapper } from \"./types.js\";\n\n/**\n * The default raw-token → {@link ConceptActivity} mapping, case-insensitive.\n *\n * Recognized (grounded in the format docs): `\"\"`/`N`/`ACTIVE` → active; `DEPRECATED` → deprecated;\n * `DISCOURAGED`; `TRIAL`; `O`/`OBSOLETE` → obsolete; `Y`/`E`/`SUPPRESSED` → suppressed. Anything else\n * → `unknown` (surfaced with its raw token, never coerced to active).\n *\n * @param raw - The steward's raw status token.\n * @returns The normalized activity.\n * @example\n * ```ts\n * import { defaultStatusMapper } from \"@cosyte/terminology\";\n *\n * defaultStatusMapper(\"DEPRECATED\"); // => \"deprecated\"\n * defaultStatusMapper(\"N\"); // => \"active\"\n * ```\n */\nexport const defaultStatusMapper: StatusMapper = (raw: string): ConceptActivity => {\n switch (raw.trim().toUpperCase()) {\n case \"\":\n case \"N\":\n case \"ACTIVE\":\n return \"active\";\n case \"DEPRECATED\":\n return \"deprecated\";\n case \"DISCOURAGED\":\n return \"discouraged\";\n case \"TRIAL\":\n return \"trial\";\n case \"O\":\n case \"OBSOLETE\":\n return \"obsolete\";\n case \"Y\":\n case \"E\":\n case \"SUPPRESSED\":\n return \"suppressed\";\n default:\n return \"unknown\";\n }\n};\n\n/**\n * Assemble a frozen {@link ConceptStatus} from a normalized activity, carrying the raw token and (for\n * classification systems) the billable flag, and attaching the stable diagnostic code for the two\n * concerns it distinguishes — `TERM_CONCEPT_DEPRECATED` and `TERM_CONCEPT_HEADER_NOT_BILLABLE`.\n *\n * @param activity - The normalized activity.\n * @param raw - The verbatim steward token, if any (omitted from the result when empty).\n * @param billable - The billable flag for a classification system, if applicable.\n * @returns A frozen {@link ConceptStatus}.\n * @example\n * ```ts\n * import { makeStatus } from \"@cosyte/terminology\";\n *\n * makeStatus(\"deprecated\", \"DEPRECATED\").code; // => \"TERM_CONCEPT_DEPRECATED\"\n * ```\n */\nexport function makeStatus(\n activity: ConceptActivity,\n raw?: string,\n billable?: boolean,\n): ConceptStatus {\n const out: Writable<ConceptStatus> = { activity, active: activity === \"active\" };\n if (raw !== undefined && raw !== \"\") out.raw = raw;\n if (billable !== undefined) out.billable = billable;\n if (activity === \"deprecated\") out.code = DIAGNOSTIC_CODES.TERM_CONCEPT_DEPRECATED;\n else if (activity === \"header\") out.code = DIAGNOSTIC_CODES.TERM_CONCEPT_HEADER_NOT_BILLABLE;\n return Object.freeze(out);\n}\n","/**\n * The **RFC-4180 CSV** reader — the one release format that needs real quote handling (LOINC's\n * `Loinc.csv`). Fields may be quoted with `\"`; inside a quoted field a literal quote is escaped as\n * `\"\"`, and commas and newlines are data. Hand-rolled, zero-dep (the CSV surface is small and\n * well-specified enough to hand-roll rather than pull a dependency).\n *\n * **Liberal on load:** a data row with too few fields to reach a configured column is **skipped and\n * surfaced** as a `TERM_CSV_MALFORMED` warning; an unterminated final quote is surfaced too — never a\n * crash. A configured code/display header that is **absent from the header row** is a *fatal*\n * (`TERM_CODESYSTEM_MALFORMED`): the source config does not match the file, so nothing loads cleanly.\n * That fatal names the missing column's **role** (`code`, `display`, `status`, a property column)\n * from a frozen table, never the column name you configured — the message reaches `err.stack`, and a\n * column name is consumer-supplied text of unbounded length.\n *\n * @packageDocumentation\n */\n\nimport { DIAGNOSTIC_CODES, FATAL_CODES, TerminologyError } from \"../common/diagnostics.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { defaultStatusMapper, makeStatus } from \"./status.js\";\nimport type { Concept, CsvSource, LoadWarning, Property } from \"./types.js\";\n\n/** The lenient RFC-4180 parse result: the rows, plus whether a quoted field was left unterminated. */\ninterface CsvParse {\n /** The parsed rows, each an array of field strings (untrimmed — CSV whitespace can be significant). */\n readonly rows: string[][];\n /** True when a quoted field opened but never closed before end-of-input (a malformed final field). */\n readonly unterminatedQuote: boolean;\n}\n\n/**\n * Parse RFC-4180 CSV content into rows and fields, **lenient** in the one place a strict RFC-4180\n * parser is dangerous: a `\"` is a field-quote **only at the start of a field**. A stray/unescaped\n * quote in the *middle* of an otherwise-unquoted field (e.g. an inch mark, `12\" fitting`) is a\n * **literal character**, not a quote-open — so it can never flip quote-mode and silently swallow the\n * rest of the file into one garbled field. Inside a quoted field, `\"\"` is an escaped quote and commas\n * and newlines are literal data. An opened quote that never closes before EOF is reported via\n * {@link CsvParse.unterminatedQuote} (surfaced by {@link parseCsvSource}), never swallowed.\n *\n * @param content - The raw CSV text.\n * @returns The parsed {@link CsvParse}.\n */\nfunction parseCsvRows(content: string): CsvParse {\n const rows: string[][] = [];\n let row: string[] = [];\n let field = \"\";\n let inQuotes = false;\n let fieldStart = true; // are we at the first char of the current field?\n let sawAny = false; // any content on the current (possibly-empty) logical row\n const n = content.length;\n\n for (let i = 0; i < n; i++) {\n const ch = content.charAt(i);\n if (inQuotes) {\n if (ch === '\"') {\n if (content.charAt(i + 1) === '\"') {\n field += '\"';\n i++;\n } else {\n inQuotes = false; // close the quoted field; stay in the same (non-start) field\n }\n } else {\n field += ch;\n }\n continue;\n }\n if (ch === '\"' && fieldStart) {\n inQuotes = true;\n fieldStart = false;\n sawAny = true;\n } else if (ch === \",\") {\n row.push(field);\n field = \"\";\n fieldStart = true;\n sawAny = true;\n } else if (ch === \"\\n\") {\n row.push(field);\n rows.push(row);\n row = [];\n field = \"\";\n fieldStart = true;\n sawAny = false;\n } else if (ch === \"\\r\") {\n // CRLF: ignore the CR; the LF ends the row.\n } else {\n // Any other char (including a `\"` that is NOT at field start) is literal.\n field += ch;\n fieldStart = false;\n sawAny = true;\n }\n }\n // Flush a trailing row that did not end with a newline.\n if (sawAny || field !== \"\" || row.length > 0) {\n row.push(field);\n rows.push(row);\n }\n return { rows, unterminatedQuote: inQuotes };\n}\n\n/**\n * Parse RFC-4180 CSV content into rows of fields (the `.rows` of {@link parseCsvRows}). Lenient: a\n * stray mid-field quote is literal, so a malformed quote never silently swallows subsequent rows.\n *\n * @param content - The raw CSV text.\n * @returns The rows, each an array of field strings (untrimmed).\n * @example\n * ```ts\n * import { parseCsv } from \"@cosyte/terminology\";\n *\n * parseCsv('a,b\\n\"x,y\",\"z\"\"q\"'); // => [[\"a\", \"b\"], [\"x,y\", 'z\"q']]\n * ```\n */\nexport function parseCsv(content: string): string[][] {\n return parseCsvRows(content).rows;\n}\n\n/**\n * The **role** a configured CSV column plays. A closed set: it is the engine's own vocabulary, never\n * a string that came from the caller or the file.\n */\ntype CsvColumnRole = \"code\" | \"display\" | \"status\" | \"property\";\n\n/**\n * The frozen fatal message per {@link CsvColumnRole}. A **table lookup, not an interpolation** — the\n * factory below takes no value parameter, so no caller-supplied or document-derived string can reach\n * `TerminologyError.message` (and from there `err.stack`, and from there an error reporter) however\n * long or however hostile it is.\n *\n * The role is the useful half anyway: a caller who configured `columns.code = \"LOINC_NUM\"` already\n * holds that string, and what they need from the engine is *which* configured column their file does\n * not have. Naming a property column's own string would echo an unbounded value to say something the\n * caller can recover in one line from their own `columns.properties` and the file's header row.\n */\nconst MISSING_COLUMN_MESSAGE: Readonly<Record<CsvColumnRole, string>> = Object.freeze({\n code: \"CSV source: the configured 'code' column is not present in the header row\",\n display: \"CSV source: the configured 'display' column is not present in the header row\",\n status: \"CSV source: the configured 'status' column is not present in the header row\",\n property: \"CSV source: a configured property column is not present in the header row\",\n});\n\n/** Resolve a header name to its column index, or throw a value-free fatal naming only its role. */\nfunction requireHeader(header: readonly string[], name: string, role: CsvColumnRole): number {\n const idx = header.indexOf(name);\n if (idx < 0) {\n throw new TerminologyError(FATAL_CODES.TERM_CODESYSTEM_MALFORMED, MISSING_COLUMN_MESSAGE[role]);\n }\n return idx;\n}\n\n/**\n * Parse a {@link CsvSource} into concepts and skipped-row warnings.\n *\n * @param source - The CSV source.\n * @returns The parsed concepts (by code) and the load warnings.\n * @throws {TerminologyError} `TERM_CODESYSTEM_MALFORMED` when the file has no header row, or a\n * configured `code`/`display`/`status`/property column is absent from the header. The message\n * names the missing column's **role**, never the name you configured.\n * @example\n * ```ts\n * import { parseCsvSource } from \"@cosyte/terminology\";\n *\n * const { concepts } = parseCsvSource({\n * format: \"csv\",\n * content: \"CODE,NAME\\n2160-0,Creatinine\",\n * columns: { code: \"CODE\", display: \"NAME\" },\n * });\n * concepts.get(\"2160-0\")?.display; // => \"Creatinine\"\n * ```\n */\nexport function parseCsvSource(source: CsvSource): {\n concepts: Map<string, Concept>;\n warnings: LoadWarning[];\n} {\n const statusMap = source.statusMap ?? defaultStatusMapper;\n const { rows, unterminatedQuote } = parseCsvRows(source.content);\n const header = rows[0];\n if (header === undefined) {\n throw new TerminologyError(\n FATAL_CODES.TERM_CODESYSTEM_MALFORMED,\n \"CSV source: the file has no header row\",\n );\n }\n const warnings: LoadWarning[] = [];\n if (unterminatedQuote) {\n // A quoted field opened but never closed before EOF — the final logical row is malformed. Surface\n // it (never silently keep a garbled field), pointing at the last parsed row.\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_CSV_MALFORMED,\n line: rows.length,\n detail: \"an opened quoted field was not terminated before end-of-input\",\n }),\n );\n }\n\n const codeIdx = requireHeader(header, source.columns.code, \"code\");\n const displayIdx = requireHeader(header, source.columns.display, \"display\");\n const statusIdx =\n source.columns.status !== undefined\n ? requireHeader(header, source.columns.status, \"status\")\n : undefined;\n const propIdx: { name: string; index: number }[] = (source.columns.properties ?? []).map((n) => ({\n name: n,\n index: requireHeader(header, n, \"property\"),\n }));\n const needCols =\n Math.max(codeIdx, displayIdx, statusIdx ?? 0, ...propIdx.map((p) => p.index)) + 1;\n\n const concepts = new Map<string, Concept>();\n\n for (let r = 1; r < rows.length; r++) {\n const cells = rows[r] ?? [];\n const lineNo = r + 1;\n if (cells.length < needCols) {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_CSV_MALFORMED,\n line: lineNo,\n detail: `row has ${String(cells.length)} fields, need ${String(needCols)}`,\n }),\n );\n continue;\n }\n const code = (cells[codeIdx] ?? \"\").trim();\n if (code === \"\") {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_CSV_MALFORMED,\n line: lineNo,\n detail: \"row is missing its code\",\n }),\n );\n continue;\n }\n if (concepts.has(code)) continue; // first row per code wins\n\n const out: Writable<Concept> = { code, properties: [] };\n const display = (cells[displayIdx] ?? \"\").trim();\n if (display !== \"\") out.display = display;\n if (statusIdx !== undefined) {\n const rawStatus = (cells[statusIdx] ?? \"\").trim();\n out.status = makeStatus(statusMap(rawStatus), rawStatus);\n }\n const props: Property[] = [];\n for (const p of propIdx) {\n const value = (cells[p.index] ?? \"\").trim();\n if (value !== \"\") props.push(Object.freeze({ code: p.name, value }));\n }\n out.properties = Object.freeze(props);\n concepts.set(code, Object.freeze(out));\n }\n\n return { concepts, warnings };\n}\n","/**\n * The **FHIR R4 `CodeSystem`** JSON loader — the native, consumer-supplied model. Reads the untrusted\n * resource into the engine's {@link Concept} map, flattening nested `concept` hierarchies and mapping\n * the standard concept properties to {@link ConceptStatus}.\n *\n * Grounded firsthand on FHIR R4 (`https://hl7.org/fhir/R4/codesystem.html` and the concept-properties\n * code system, `https://hl7.org/fhir/R4/codesystem-concept-properties.html`): a concept has\n * `code`/`display`/`definition`/`designation`/`property`/nested `concept`; the base property\n * **`inactive`** (boolean) is *\"True if the concept is not considered active — e.g. not a valid\n * concept any more\"*, **`deprecated`** (dateTime) marks a deprecation, and a `status` string property\n * is common in real systems.\n *\n * **Conservative on load:** the wrong `resourceType` is a *fatal* (`TERM_CODESYSTEM_MALFORMED`); a\n * concept missing its required `code` is skipped and surfaced (a malformed row, not a whole-file\n * fatal).\n *\n * @packageDocumentation\n */\n\nimport { DIAGNOSTIC_CODES, FATAL_CODES, TerminologyError } from \"../common/diagnostics.js\";\nimport { getArray, getBoolean, getNumber, getString, isJsonObject } from \"../common/fhir-json.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { makeStatus } from \"./status.js\";\nimport type {\n Concept,\n ConceptStatus,\n FhirCodeSystemSource,\n LoadWarning,\n Property,\n} from \"./types.js\";\n\n/** Read a FHIR `property.value[x]` into a primitive Property value, or `undefined` if none present. */\nfunction readPropertyValue(raw: Record<string, unknown>): string | boolean | number | undefined {\n const s =\n getString(raw, \"valueString\") ?? getString(raw, \"valueCode\") ?? getString(raw, \"valueDateTime\");\n if (s !== undefined) return s;\n const b = getBoolean(raw, \"valueBoolean\");\n if (b !== undefined) return b;\n const num = getNumber(raw, \"valueInteger\") ?? getNumber(raw, \"valueDecimal\");\n if (num !== undefined) return num;\n // valueCoding: surface its code (the identity that matters), when present.\n const coding = raw[\"valueCoding\"];\n const codingCode = getString(coding, \"code\");\n if (codingCode !== undefined) return codingCode;\n return undefined;\n}\n\n/** Derive a {@link ConceptStatus} from a concept's raw properties, or `undefined` when none signal it. */\nfunction deriveStatus(props: readonly Property[]): ConceptStatus | undefined {\n const statusProp = props.find((p) => p.code === \"status\");\n if (statusProp !== undefined && typeof statusProp.value === \"string\") {\n // A `status` string is release-specific; carry it verbatim as an `unknown`-unless-active signal.\n const raw = statusProp.value;\n const activity = raw.trim().toLowerCase() === \"active\" ? \"active\" : \"deprecated\";\n return makeStatus(activity, raw);\n }\n const inactive = props.find((p) => p.code === \"inactive\");\n const deprecated = props.find((p) => p.code === \"deprecated\");\n if (inactive?.value === true || deprecated !== undefined) {\n // FHIR `inactive: true` / a `deprecated` date ⇒ not current. Flagged, never presented clean.\n return makeStatus(\"deprecated\");\n }\n return undefined;\n}\n\n/**\n * Recursively collect concepts from a `concept[]` array into `into`, surfacing skipped rows.\n *\n * `parentCode` is the code of the enclosing concept when this array is a nested `concept` list. FHIR\n * `CodeSystem` nesting is the default **is-a** hierarchy (`hierarchyMeaning` defaults to `is-a`), so a\n * nested child gains a synthesized standard **`parent`** concept-property\n * (`http://hl7.org/fhir/concept-properties#parent`) pointing at its enclosing code — the subsumption\n * signal the ValueSet `is-a`/`descendent-of` filter reads. A `parent` property already declared\n * verbatim for the same value is never duplicated; the flattened concept map is otherwise unchanged.\n */\nfunction collectConcepts(\n rawConcepts: readonly unknown[],\n into: Map<string, Concept>,\n warnings: LoadWarning[],\n parentCode?: string,\n): void {\n for (const raw of rawConcepts) {\n if (!isJsonObject(raw)) {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_FHIR_CONCEPT_MALFORMED,\n line: 0,\n detail: \"concept is not an object\",\n }),\n );\n continue;\n }\n const code = getString(raw, \"code\");\n if (code !== undefined && code !== \"\" && !into.has(code)) {\n const props: Property[] = [];\n for (const p of getArray(raw, \"property\") ?? []) {\n const pcode = getString(p, \"code\");\n if (pcode === undefined) continue;\n const value = isJsonObject(p) ? readPropertyValue(p) : undefined;\n if (value !== undefined) props.push(Object.freeze({ code: pcode, value }));\n }\n // Synthesize the nesting-derived `parent` edge (unless the release already declared it), so a\n // nested hierarchy is queryable by `is-a`/`descendent-of` exactly like an explicit `parent`.\n if (\n parentCode !== undefined &&\n !props.some((p) => p.code === \"parent\" && p.value === parentCode)\n ) {\n props.push(Object.freeze({ code: \"parent\", value: parentCode }));\n }\n const out: Writable<Concept> = { code, properties: Object.freeze(props) };\n const display = getString(raw, \"display\");\n if (display !== undefined) out.display = display;\n const definition = getString(raw, \"definition\");\n if (definition !== undefined) out.definition = definition;\n const status = deriveStatus(props);\n if (status !== undefined) out.status = status;\n into.set(code, Object.freeze(out));\n } else if (code === undefined || code === \"\") {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_FHIR_CONCEPT_MALFORMED,\n line: 0,\n detail: \"concept is missing its required code\",\n }),\n );\n }\n // Recurse into nested children regardless (a header concept still has valid leaf children). The\n // enclosing concept's code becomes the child's synthesized `parent` (when the child has a code).\n const children = getArray(raw, \"concept\");\n if (children !== undefined) {\n collectConcepts(children, into, warnings, code !== \"\" ? code : undefined);\n }\n }\n}\n\n/**\n * Parse a {@link FhirCodeSystemSource} into concepts, a resolved url/version/name, and warnings.\n *\n * @param source - The FHIR CodeSystem source.\n * @returns The parsed concepts (by code), the load warnings, and the resource metadata.\n * @throws {TerminologyError} `TERM_CODESYSTEM_MALFORMED` when the resource is not a FHIR `CodeSystem`.\n * @example\n * ```ts\n * import { parseFhirCodeSystem } from \"@cosyte/terminology\";\n *\n * const { concepts } = parseFhirCodeSystem({\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"A\", display: \"Alpha\" }] },\n * format: \"fhir\",\n * });\n * concepts.get(\"A\")?.display; // => \"Alpha\"\n * ```\n */\nexport function parseFhirCodeSystem(source: FhirCodeSystemSource): {\n concepts: Map<string, Concept>;\n warnings: LoadWarning[];\n url?: string;\n version?: string;\n name?: string;\n} {\n const resource = source.resource;\n if (!isJsonObject(resource) || getString(resource, \"resourceType\") !== \"CodeSystem\") {\n throw new TerminologyError(\n FATAL_CODES.TERM_CODESYSTEM_MALFORMED,\n \"FHIR source: resource is not a CodeSystem (wrong or missing resourceType)\",\n );\n }\n const concepts = new Map<string, Concept>();\n const warnings: LoadWarning[] = [];\n collectConcepts(getArray(resource, \"concept\") ?? [], concepts, warnings);\n\n const out: { concepts: Map<string, Concept>; warnings: LoadWarning[] } & {\n url?: string;\n version?: string;\n name?: string;\n } = { concepts, warnings };\n const url = getString(resource, \"url\");\n if (url !== undefined) out.url = url;\n const version = getString(resource, \"version\");\n if (version !== undefined) out.version = version;\n const name = getString(resource, \"name\");\n if (name !== undefined) out.name = name;\n return out;\n}\n","/**\n * The **fixed-width** reader — slice a line by column, for order-file layouts like the ICD-10-CM\n * order file (`icd10cm_order_YYYY.txt`). Fully parameterized: the consumer supplies the field slices,\n * so the *engine* is content-agnostic and the byte offsets live in the caller's config, not baked in.\n *\n * The documented ICD-10-CM preset is {@link ICD10CM_ORDER_FILE_FIELDS} — the position-15 flag\n * (0-based char index 14) is `1` for a **billable/valid** code and `0` for a **header** (grounded on\n * the CMS/CDC order-file layout). Confirm the exact offsets against your release's README before\n * relying on the preset — which is exactly why the reader takes the slices as a parameter.\n *\n * **Liberal on load:** a line too short to contain the code slice, or with an empty code, is skipped\n * and surfaced as a `TERM_FIXED_WIDTH_MALFORMED` warning.\n *\n * @packageDocumentation\n */\n\nimport { DIAGNOSTIC_CODES } from \"../common/diagnostics.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { defaultStatusMapper, makeStatus } from \"./status.js\";\nimport type {\n Concept,\n ConceptActivity,\n FieldSlice,\n FixedWidthFieldMap,\n FixedWidthSource,\n LoadWarning,\n Property,\n} from \"./types.js\";\n\n/**\n * Extract and trim a {@link FieldSlice} from a line (`end` omitted slices to end of line).\n *\n * @param line - The source line.\n * @param slice - The half-open `[start, end)` slice.\n * @returns The trimmed field text (empty when the slice is entirely past the line's end).\n * @example\n * ```ts\n * import { sliceField } from \"@cosyte/terminology\";\n *\n * sliceField(\"00001 A00 1 Cholera\", { start: 6, end: 13 }); // => \"A00\"\n * ```\n */\nexport function sliceField(line: string, slice: FieldSlice): string {\n const raw =\n slice.end === undefined ? line.slice(slice.start) : line.slice(slice.start, slice.end);\n return raw.trim();\n}\n\n/**\n * The documented **ICD-10-CM order file** field layout (0-based char indices).\n *\n * - `code` — the ICD-10-CM code (no decimal point).\n * - `billable` — position-15 flag at index 14: `\"1\"` = billable/valid leaf, `\"0\"` = header.\n * - `display` — the long description (to end of line).\n * - property `shortDescription` — the 60-char short description.\n *\n * Grounded on the CMS/CDC order-file layout; **verify against your release's README** before relying\n * on the exact offsets, which are not confirmed against an authoritative machine-readable source.\n * The reader takes the layout as a parameter precisely so this preset is a starting point, not a\n * hardcoded assumption.\n */\nexport const ICD10CM_ORDER_FILE_FIELDS: FixedWidthFieldMap = Object.freeze({\n code: Object.freeze({ start: 6, end: 13 }),\n display: Object.freeze({ start: 77 }),\n billable: Object.freeze({ at: 14, billableValue: \"1\" }),\n properties: Object.freeze([\n Object.freeze({ name: \"shortDescription\", slice: Object.freeze({ start: 16, end: 76 }) }),\n ]),\n});\n\n/**\n * Parse a {@link FixedWidthSource} into concepts and skipped-row warnings.\n *\n * @param source - The fixed-width source.\n * @returns The parsed concepts (by code) and the load warnings.\n * @example\n * ```ts\n * import { parseFixedWidth } from \"@cosyte/terminology\";\n *\n * const { concepts } = parseFixedWidth({\n * format: \"fixed-width\",\n * content: \"A00 1 Cholera\",\n * fields: { code: { start: 0, end: 3 }, display: { start: 6 } },\n * });\n * concepts.get(\"A00\")?.display; // => \"Cholera\"\n * ```\n */\nexport function parseFixedWidth(source: FixedWidthSource): {\n concepts: Map<string, Concept>;\n warnings: LoadWarning[];\n} {\n const statusMap = source.statusMap ?? defaultStatusMapper;\n const fields: FixedWidthFieldMap = source.fields;\n const concepts = new Map<string, Concept>();\n const warnings: LoadWarning[] = [];\n\n const lines = source.content.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n if (line.trim() === \"\") continue;\n const lineNo = i + 1;\n if (line.length <= fields.code.start) {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_FIXED_WIDTH_MALFORMED,\n line: lineNo,\n detail: `line length ${String(line.length)} does not reach the code field`,\n }),\n );\n continue;\n }\n const code = sliceField(line, fields.code);\n if (code === \"\") {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_FIXED_WIDTH_MALFORMED,\n line: lineNo,\n detail: \"row is missing its code\",\n }),\n );\n continue;\n }\n if (concepts.has(code)) continue;\n\n const out: Writable<Concept> = { code, properties: [] };\n const display = sliceField(line, fields.display);\n if (display !== \"\") out.display = display;\n\n // Status: a billable flag takes precedence (header vs leaf); otherwise a status slice, if any.\n if (fields.billable !== undefined) {\n const flag = line.charAt(fields.billable.at);\n const billable = flag === fields.billable.billableValue;\n const activity: ConceptActivity = billable ? \"active\" : \"header\";\n out.status = makeStatus(activity, flag, billable);\n } else if (fields.status !== undefined) {\n const rawStatus = sliceField(line, fields.status);\n out.status = makeStatus(statusMap(rawStatus), rawStatus);\n }\n\n const props: Property[] = [];\n for (const p of fields.properties ?? []) {\n const value = sliceField(line, p.slice);\n if (value !== \"\") props.push(Object.freeze({ code: p.name, value }));\n }\n out.properties = Object.freeze(props);\n concepts.set(code, Object.freeze(out));\n }\n\n return { concepts, warnings };\n}\n","/**\n * The **RRF** (Rich Release Format) reader — the pipe-delimited layer shared by RxNorm (`RXNCONSO`/\n * `RXNSAT`) and UMLS (`MRCONSO`/`MRSAT`). One parameterized reader serves both: they share the RRF\n * shape — fields separated by `|`, with **one trailing pipe per line** (grounded firsthand on the\n * UMLS Reference Manual, `https://www.ncbi.nlm.nih.gov/books/NBK9685/`: *\"values … are separated by\n * vertical bars (|)\"* and each row ends with *\"a vertical bar and line termination\"*).\n *\n * **Liberal on load**: a row too short to reach a configured column, or with an empty\n * code, is **skipped and surfaced** as a `TERM_RRF_MALFORMED_ROW` warning — never kept as a partial\n * concept, never a crash. RRF reserves `|` as the delimiter (fields never contain a literal pipe), so\n * a plain split is exact.\n *\n * @packageDocumentation\n */\n\nimport { DIAGNOSTIC_CODES } from \"../common/diagnostics.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { defaultStatusMapper, makeStatus } from \"./status.js\";\nimport type { Concept, LoadWarning, Property, RrfSource } from \"./types.js\";\n\n/**\n * Split one RRF line into its fields, dropping the single reserved trailing pipe.\n *\n * @param line - One RRF line (no line terminator).\n * @returns The fields, in column order.\n * @example\n * ```ts\n * import { parseRrfLine } from \"@cosyte/terminology\";\n *\n * parseRrfLine(\"316151|ENG|lisinopril 10 MG|\"); // => [\"316151\", \"ENG\", \"lisinopril 10 MG\"]\n * ```\n */\nexport function parseRrfLine(line: string): readonly string[] {\n const cells = line.split(\"|\");\n // RRF terminates each row with a reserved trailing '|', yielding one trailing empty cell — drop it.\n if (cells.length > 0 && cells[cells.length - 1] === \"\") cells.pop();\n return cells;\n}\n\n/** The highest column index the mapping references — a row must have at least this many cells. */\nfunction maxColumn(source: RrfSource): number {\n const { code, display, status, properties } = source.columns;\n let max = Math.max(code, display, status ?? 0);\n for (const p of properties ?? []) max = Math.max(max, p.column);\n return max;\n}\n\n/** Read a cell by index, trimmed; `undefined` when the index is out of range. */\nfunction cell(cells: readonly string[], index: number): string | undefined {\n const v = cells[index];\n return v === undefined ? undefined : v.trim();\n}\n\n/**\n * Parse an {@link RrfSource} into concepts (first row per code wins) and skipped-row warnings.\n *\n * A code that recurs across rows (RRF repeats a code once per atom/attribute) keeps its **first**\n * occurrence — a documented v1 limitation: preferred-atom selection (`TS`/`STT`/`ISPREF`) and\n * attribute merging are later work. The result is data only; {@link loadCodeSystem} freezes it.\n *\n * @param source - The RRF source.\n * @returns The parsed concepts (by code) and the load warnings.\n * @example\n * ```ts\n * import { parseRrf } from \"@cosyte/terminology\";\n *\n * const { concepts } = parseRrf({\n * format: \"rrf\",\n * content: \"1|Aspirin|\",\n * columns: { code: 0, display: 1 },\n * });\n * concepts.get(\"1\")?.display; // => \"Aspirin\"\n * ```\n */\nexport function parseRrf(source: RrfSource): {\n concepts: Map<string, Concept>;\n warnings: LoadWarning[];\n} {\n const statusMap = source.statusMap ?? defaultStatusMapper;\n const needCols = maxColumn(source) + 1;\n const concepts = new Map<string, Concept>();\n const warnings: LoadWarning[] = [];\n\n const lines = source.content.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i] ?? \"\";\n if (raw === \"\") continue; // blank line (e.g. trailing newline) — not a row\n const lineNo = i + 1;\n const cells = parseRrfLine(raw);\n if (cells.length < needCols) {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_RRF_MALFORMED_ROW,\n line: lineNo,\n detail: `row has ${String(cells.length)} columns, need ${String(needCols)}`,\n }),\n );\n continue;\n }\n const code = cell(cells, source.columns.code);\n if (code === undefined || code === \"\") {\n warnings.push(\n Object.freeze({\n code: DIAGNOSTIC_CODES.TERM_RRF_MALFORMED_ROW,\n line: lineNo,\n detail: \"row is missing its code\",\n }),\n );\n continue;\n }\n if (concepts.has(code)) continue; // first row per code wins\n\n const out: Writable<Concept> = { code, properties: [] };\n const display = cell(cells, source.columns.display);\n if (display !== undefined && display !== \"\") out.display = display;\n if (source.columns.status !== undefined) {\n const rawStatus = cell(cells, source.columns.status) ?? \"\";\n out.status = makeStatus(statusMap(rawStatus), rawStatus);\n }\n const props: Property[] = [];\n for (const p of source.columns.properties ?? []) {\n const value = cell(cells, p.column);\n if (value !== undefined && value !== \"\") {\n props.push(Object.freeze({ code: p.name, value }));\n }\n }\n out.properties = Object.freeze(props);\n concepts.set(code, Object.freeze(out));\n }\n\n return { concepts, warnings };\n}\n","/**\n * {@link loadCodeSystem} — the single entry point that dispatches a {@link CodeSystemSource} to the\n * right reader (RRF / CSV / fixed-width / FHIR) and assembles the immutable {@link CodeSystem}.\n *\n * The engine is **content-agnostic**: it loads a *consumer-supplied* release and ships\n * **no code-system release** of its own. The loaded model is deep-frozen and keyed by code\n * for O(1) {@link lookup}/{@link validateCode}.\n *\n * @packageDocumentation\n */\n\nimport { frozenMap } from \"../common/frozen-map.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { parseCsvSource } from \"./csv.js\";\nimport { parseFhirCodeSystem } from \"./fhir.js\";\nimport { parseFixedWidth } from \"./fixed-width.js\";\nimport { parseRrf } from \"./rrf.js\";\nimport type { CodeSystem, CodeSystemSource, Concept, LoadWarning } from \"./types.js\";\n\n/**\n * Load a consumer-supplied code-system release into an immutable, queryable {@link CodeSystem}.\n *\n * Dispatches on `source.format`:\n * - `\"rrf\"` — pipe-delimited RxNorm/UMLS release (one parameterized reader for both).\n * - `\"csv\"` — RFC-4180 CSV (e.g. LOINC `Loinc.csv`), with real quote handling.\n * - `\"fixed-width\"` — slice-by-column order files (e.g. ICD-10-CM; see `ICD10CM_ORDER_FILE_FIELDS`).\n * - `\"fhir\"` — a native FHIR R4 `CodeSystem` JSON resource.\n *\n * **Liberal on load:** a malformed *row* is skipped and surfaced in `warnings` (never a crash, never a\n * partial concept). **Conservative on structure:** an unusable *source* (wrong FHIR `resourceType`, or\n * a CSV whose configured columns are absent from the header) throws a typed `TerminologyError`\n * carrying `TERM_CODESYSTEM_MALFORMED`.\n *\n * @param source - The release descriptor (a discriminated {@link CodeSystemSource}).\n * @returns The immutable, deep-frozen {@link CodeSystem}.\n * @throws {TerminologyError} `TERM_CODESYSTEM_MALFORMED` when the source is structurally unusable.\n * @example\n * ```ts\n * import { loadCodeSystem } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: {\n * resourceType: \"CodeSystem\",\n * url: \"http://example.org/cs\",\n * concept: [{ code: \"A\", display: \"Alpha\" }],\n * },\n * });\n * cs.count; // => 1\n * ```\n */\nexport function loadCodeSystem(source: CodeSystemSource): CodeSystem {\n let concepts: Map<string, Concept>;\n let warnings: LoadWarning[];\n const out: Writable<CodeSystem> = { count: 0, concepts: new Map(), warnings: [] };\n\n switch (source.format) {\n case \"rrf\": {\n ({ concepts, warnings } = parseRrf(source));\n if (source.url !== undefined) out.url = source.url;\n if (source.version !== undefined) out.version = source.version;\n if (source.name !== undefined) out.name = source.name;\n break;\n }\n case \"csv\": {\n ({ concepts, warnings } = parseCsvSource(source));\n if (source.url !== undefined) out.url = source.url;\n if (source.version !== undefined) out.version = source.version;\n if (source.name !== undefined) out.name = source.name;\n break;\n }\n case \"fixed-width\": {\n ({ concepts, warnings } = parseFixedWidth(source));\n if (source.url !== undefined) out.url = source.url;\n if (source.version !== undefined) out.version = source.version;\n if (source.name !== undefined) out.name = source.name;\n break;\n }\n case \"fhir\": {\n const parsed = parseFhirCodeSystem(source);\n concepts = parsed.concepts;\n warnings = parsed.warnings;\n if (parsed.url !== undefined) out.url = parsed.url;\n if (parsed.version !== undefined) out.version = parsed.version;\n if (parsed.name !== undefined) out.name = parsed.name;\n break;\n }\n }\n\n out.count = concepts.size;\n // A read-only view, not the map: `Object.freeze` below cannot reach a `Map`'s entries, and a\n // mutated one would let a holder inject a **fabricated** concept past never-fabricate (and desync\n // `count`). This used to replace the three mutators on the map itself, which left\n // `Map.prototype.set.call(cs.concepts, …)` inserting; the view has no internal slot to write to.\n out.concepts = frozenMap(concepts, \"a loaded CodeSystem's concepts map\");\n out.warnings = Object.freeze(warnings);\n return Object.freeze(out);\n}\n","/**\n * {@link lookup} and {@link validateCode} — the FHIR R4 CodeSystem `$lookup` and `$validate-code`\n * operations over a loaded {@link CodeSystem}.\n *\n * Grounded firsthand on FHIR R4 (`https://hl7.org/fhir/R4/codesystem-operation-lookup.html`,\n * `https://hl7.org/fhir/R4/codesystem-operation-validate-code.html`):\n *\n * - `$lookup` returns the concept's `display` (*\"The preferred display for this concept\"*) and its\n * `property` values (*\"additional information about the code, including status\"*).\n * - `$validate-code` returns `result` (*\"True if the concept details supplied are valid\"*).\n *\n * Both honor the **never-fabricate invariant**, applied here to code identity: an\n * unknown code yields a typed `unknown` / `valid: false` — **never** a fabricated display and\n * **never** a guessed `valid: true`. A found-but-non-current concept (deprecated, or an ICD-10-CM\n * header) validates as present **but carries its status flag**, so a caller never treats it as clean.\n *\n * @packageDocumentation\n */\n\nimport type { Writable } from \"../common/writable.js\";\nimport type {\n CodeSystem,\n LookupOutcome,\n LookupResult,\n LookupUnknown,\n ValidateCodeResult,\n} from \"./types.js\";\n\n/**\n * `$lookup`: resolve a code to its display, definition, status, and properties in a loaded release.\n *\n * @param cs - The loaded {@link CodeSystem}.\n * @param code - The code to look up.\n * @returns A {@link LookupResult} when found, or a typed {@link LookupUnknown} — never a guess.\n * @example\n * ```ts\n * import { loadCodeSystem, lookup } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"A\", display: \"Alpha\" }] },\n * });\n * const r = lookup(cs, \"A\");\n * r.found === true && r.display; // => \"Alpha\"\n * ```\n */\nexport function lookup(cs: CodeSystem, code: string): LookupOutcome {\n const concept = cs.concepts.get(code);\n if (concept === undefined) {\n const unknown: LookupUnknown = { found: false, code: \"TERM_CODE_UNKNOWN\", input: code };\n return Object.freeze(unknown);\n }\n const out: Writable<LookupResult> = {\n found: true,\n code: concept.code,\n properties: concept.properties,\n };\n if (concept.display !== undefined) out.display = concept.display;\n if (concept.definition !== undefined) out.definition = concept.definition;\n if (concept.status !== undefined) out.status = concept.status;\n if (cs.url !== undefined) out.system = cs.url;\n if (cs.version !== undefined) out.version = cs.version;\n return Object.freeze(out);\n}\n\n/**\n * `$validate-code`: is `code` a valid member of the loaded code system?\n *\n * A found code is `valid: true`, **carrying its status** (a deprecated or header code is present but\n * flagged — never silently clean). An absent code is `valid: false` with `TERM_CODE_UNKNOWN`, never a\n * guessed `true`.\n *\n * @param cs - The loaded {@link CodeSystem}.\n * @param code - The code to validate.\n * @returns A {@link ValidateCodeResult}.\n * @example\n * ```ts\n * import { loadCodeSystem, validateCode } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"A\", display: \"Alpha\" }] },\n * });\n * validateCode(cs, \"A\").valid; // => true\n * validateCode(cs, \"ZZZ\").valid; // => false\n * ```\n */\nexport function validateCode(cs: CodeSystem, code: string): ValidateCodeResult {\n const concept = cs.concepts.get(code);\n if (concept === undefined) {\n return Object.freeze({ valid: false, code: \"TERM_CODE_UNKNOWN\" });\n }\n const out: Writable<ValidateCodeResult> = { valid: true };\n if (concept.status !== undefined) out.status = concept.status;\n return Object.freeze(out);\n}\n","/**\n * {@link loadValueSet} — validate and normalize an untrusted FHIR R4 `ValueSet` JSON resource into\n * the immutable {@link ValueSet} model the `$expand` / `$validate-code` binding operations run over.\n *\n * **Conservative on load** (like {@link ../conceptmap/load.loadConceptMap}, unlike a lenient wire\n * parser): a value set *binds* whether a code is allowed in a clinical slot, so a structurally\n * unusable resource is a typed **fatal** ({@link FATAL_CODES.TERM_VALUESET_MALFORMED}) rather than a\n * silently partial value set that would admit *some* codes and quietly drop others. A `filter`\n * operator the engine does not implement is **not** fatal — the value set loads, and the gap surfaces\n * at expansion time as a {@link DIAGNOSTIC_CODES.TERM_VALUESET_CANNOT_EXPAND} diagnostic. Fault\n * messages are **value-free**: they name the resource *path* and the fault, never echo a code value.\n *\n * @packageDocumentation\n */\n\nimport { FATAL_CODES, TerminologyError } from \"../common/diagnostics.js\";\nimport { getArray, getBoolean, getNumber, getString, isJsonObject } from \"../common/fhir-json.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport type {\n ConceptRef,\n ConceptSetComponent,\n ConceptSetFilter,\n ExpansionContains,\n FilterOperator,\n ValueSet,\n ValueSetCompose,\n ValueSetExpansion,\n} from \"./types.js\";\n\n/** The FHIR `valueset-toocostly` extension URL — flags a pre-computed expansion as incomplete. */\nconst TOO_COSTLY_EXTENSION = \"http://hl7.org/fhir/StructureDefinition/valueset-toocostly\";\n\n/** Throw a value-free {@link TerminologyError} for a malformed ValueSet at `path`. */\nfunction malformed(path: string, fault: string): never {\n throw new TerminologyError(FATAL_CODES.TERM_VALUESET_MALFORMED, `ValueSet ${path}: ${fault}`);\n}\n\n/** Copy an optional string property onto `out[key]` only when present (no `undefined` keys). */\nfunction assignString<T extends Record<string, unknown>>(out: T, src: unknown, key: string): void {\n const v = getString(src, key);\n if (v !== undefined) (out as Record<string, unknown>)[key] = v;\n}\n\nfunction loadFilter(raw: unknown, path: string): ConceptSetFilter {\n if (!isJsonObject(raw)) malformed(path, \"filter is not an object\");\n const property = getString(raw, \"property\");\n const op = getString(raw, \"op\");\n const value = getString(raw, \"value\");\n if (property === undefined || op === undefined || value === undefined) {\n malformed(path, \"filter is missing a required 'property', 'op', or 'value'\");\n }\n // `op` is carried verbatim — an operator the engine does not implement is surfaced at expansion\n // time as TERM_VALUESET_CANNOT_EXPAND, not rejected here (a value set may still be usable via its\n // other components). The cast is safe: unknown strings widen to the not-implemented arm.\n return Object.freeze({ property, op: op as FilterOperator, value });\n}\n\nfunction loadConcept(raw: unknown, path: string): ConceptRef {\n if (!isJsonObject(raw)) malformed(path, \"concept is not an object\");\n const code = getString(raw, \"code\");\n if (code === undefined) malformed(path, \"concept is missing its required 'code'\");\n const out: Writable<ConceptRef> = { code };\n assignString(out, raw, \"display\");\n return Object.freeze(out);\n}\n\nfunction loadComponent(raw: unknown, path: string): ConceptSetComponent {\n if (!isJsonObject(raw)) malformed(path, \"component is not an object\");\n const out: Writable<ConceptSetComponent> = {};\n assignString(out, raw, \"system\");\n assignString(out, raw, \"version\");\n const rawConcepts = getArray(raw, \"concept\");\n if (rawConcepts !== undefined) {\n out.concept = Object.freeze(\n rawConcepts.map((c, i) => loadConcept(c, `${path}.concept[${String(i)}]`)),\n );\n }\n const rawFilters = getArray(raw, \"filter\");\n if (rawFilters !== undefined) {\n out.filter = Object.freeze(\n rawFilters.map((f, i) => loadFilter(f, `${path}.filter[${String(i)}]`)),\n );\n }\n const rawValueSets = getArray(raw, \"valueSet\");\n if (rawValueSets !== undefined) {\n const urls: string[] = [];\n for (const [i, vsRef] of rawValueSets.entries()) {\n if (typeof vsRef !== \"string\") {\n malformed(\n `${path}.valueSet[${String(i)}]`,\n \"value set reference is not a canonical URL string\",\n );\n }\n urls.push(vsRef);\n }\n out.valueSet = Object.freeze(urls);\n }\n // FHIR R4 ValueSet.compose invariants: a `concept`/`filter` selection SHALL name a `system`, and a\n // component SHALL have a `system` or a `valueSet`. A constraint-less component (`{}`) is refused\n // here — never loaded as a silently \"matches everything\" set that binding would then admit blindly.\n const hasSystem = out.system !== undefined;\n const hasValueSet = out.valueSet !== undefined;\n if ((out.concept !== undefined || out.filter !== undefined) && !hasSystem) {\n malformed(path, \"a component with 'concept' or 'filter' must name a 'system'\");\n }\n if (!hasSystem && !hasValueSet) {\n malformed(path, \"a component must have a 'system' or a 'valueSet'\");\n }\n return Object.freeze(out);\n}\n\nfunction loadCompose(raw: unknown, path: string): ValueSetCompose {\n if (!isJsonObject(raw)) malformed(path, \"compose is not an object\");\n const include = Object.freeze(\n (getArray(raw, \"include\") ?? []).map((c, i) =>\n loadComponent(c, `${path}.include[${String(i)}]`),\n ),\n );\n const exclude = Object.freeze(\n (getArray(raw, \"exclude\") ?? []).map((c, i) =>\n loadComponent(c, `${path}.exclude[${String(i)}]`),\n ),\n );\n return Object.freeze({ include, exclude });\n}\n\nfunction loadContains(raw: unknown, path: string): ExpansionContains {\n if (!isJsonObject(raw)) malformed(path, \"contains entry is not an object\");\n const code = getString(raw, \"code\");\n if (code === undefined) malformed(path, \"contains entry is missing its required 'code'\");\n const out: Writable<ExpansionContains> = { code };\n assignString(out, raw, \"system\");\n assignString(out, raw, \"display\");\n assignString(out, raw, \"version\");\n return Object.freeze(out);\n}\n\n/** True when the `expansion.extension` array flags a `valueset-toocostly: true`. */\nfunction isTooCostly(raw: Record<string, unknown>): boolean {\n for (const ext of getArray(raw, \"extension\") ?? []) {\n if (\n getString(ext, \"url\") === TOO_COSTLY_EXTENSION &&\n getBoolean(ext, \"valueBoolean\") === true\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction loadExpansion(raw: unknown, path: string): ValueSetExpansion {\n if (!isJsonObject(raw)) malformed(path, \"expansion is not an object\");\n const contains = Object.freeze(\n (getArray(raw, \"contains\") ?? []).map((c, i) =>\n loadContains(c, `${path}.contains[${String(i)}]`),\n ),\n );\n const total = getNumber(raw, \"total\");\n // Truncated when the server-reported total exceeds what it actually returned, or it flagged the\n // expansion too-costly. Either way the snapshot is a lower bound, never complete membership.\n const truncated = (total !== undefined && total > contains.length) || isTooCostly(raw);\n const out: Writable<ValueSetExpansion> = { contains, truncated };\n if (total !== undefined) out.total = total;\n return Object.freeze(out);\n}\n\n/**\n * Load an untrusted FHIR R4 `ValueSet` JSON value into an immutable {@link ValueSet}.\n *\n * Accepts the standard resource shape: `resourceType: \"ValueSet\"` with an optional intensional\n * `compose` (`include`/`exclude` of `system`/`concept`/`filter`/`valueSet`) and/or a **pre-computed**\n * `expansion` (`contains`, with `total` and the `valueset-toocostly` extension read into a derived\n * `truncated` flag). The result is deep-frozen. Anything structurally unusable throws a\n * {@link TerminologyError} carrying {@link FATAL_CODES.TERM_VALUESET_MALFORMED}.\n *\n * @param json - The untrusted resource (typically `JSON.parse` output — hence `unknown`).\n * @returns The immutable, validated {@link ValueSet}.\n * @throws {TerminologyError} `TERM_VALUESET_MALFORMED` when the resource is not a usable ValueSet.\n * @example\n * ```ts\n * import { loadValueSet } from \"@cosyte/terminology\";\n *\n * const vs = loadValueSet({\n * resourceType: \"ValueSet\",\n * url: \"http://example.org/vs/colors\",\n * compose: {\n * include: [{ system: \"http://example.org/cs\", concept: [{ code: \"red\" }, { code: \"green\" }] }],\n * },\n * });\n * vs.compose?.include.length; // => 1\n * ```\n */\nexport function loadValueSet(json: unknown): ValueSet {\n if (!isJsonObject(json)) malformed(\"\", \"resource is not a JSON object\");\n if (getString(json, \"resourceType\") !== \"ValueSet\") {\n malformed(\"\", \"resource is not a ValueSet (wrong or missing resourceType)\");\n }\n const out: Writable<ValueSet> = {};\n assignString(out, json, \"url\");\n assignString(out, json, \"version\");\n assignString(out, json, \"name\");\n if (json[\"compose\"] !== undefined) out.compose = loadCompose(json[\"compose\"], \"compose\");\n if (json[\"expansion\"] !== undefined)\n out.expansion = loadExpansion(json[\"expansion\"], \"expansion\");\n return Object.freeze(out);\n}\n","/**\n * Subsumption + `compose.include.filter` evaluation — the shared machinery {@link ./expand.expand}\n * and {@link ./validate.validateCodeInValueSet} both draw on.\n *\n * **Subsumption** is read from the loaded {@link CodeSystem}'s **`parent`** concept-properties\n * (`http://hl7.org/fhir/concept-properties#parent`) — which the FHIR loader synthesizes from a nested\n * `concept` hierarchy and carries verbatim from an explicit `parent` property. This is deliberately\n * the release's **own** hierarchy: subsumption across two separate releases is not computed, and a\n * code system that encodes no parent edges has no descendants beyond identity, which is treated as\n * complete — not guessed deeper.\n *\n * **Filter support is explicit.** `is-a` / `descendent-of` / `is-not-a` / `=` / `in` / `not-in` /\n * `exists` are implemented; `regex` / `generalizes` / anything unrecognized report `supported: false`\n * so the caller surfaces a typed {@link DIAGNOSTIC_CODES.TERM_VALUESET_CANNOT_EXPAND} rather than\n * silently mis-including or dropping codes.\n *\n * @packageDocumentation\n */\n\nimport type { CodeSystem, Concept } from \"../codesystem/types.js\";\nimport type { ConceptSetFilter, FilterOperator } from \"./types.js\";\n\n/** The `filter` operators the engine implements; anything else surfaces as cannot-expand. */\nconst SUPPORTED_OPS: ReadonlySet<FilterOperator> = new Set<FilterOperator>([\n \"=\",\n \"is-a\",\n \"descendent-of\",\n \"is-not-a\",\n \"in\",\n \"not-in\",\n \"exists\",\n]);\n\n/**\n * The filters whose operator the engine does **not** implement (`regex` / `generalizes` / unknown) —\n * a non-empty result means the caller must surface a typed cannot-expand, never mis-expand.\n *\n * @param filters - The component's filters.\n * @returns The subset with an unimplemented operator (empty when all are supported).\n * @example\n * ```ts\n * import { unsupportedOps } from \"@cosyte/terminology\";\n *\n * unsupportedOps([{ property: \"concept\", op: \"is-a\", value: \"x\" }]).length; // => 0\n * ```\n */\nexport function unsupportedOps(filters: readonly ConceptSetFilter[]): readonly ConceptSetFilter[] {\n return filters.filter((f) => !SUPPORTED_OPS.has(f.op));\n}\n\n/** An immutable ancestor index over a {@link CodeSystem}'s `parent` edges. */\nexport interface Subsumption {\n /** All (transitive) ancestor codes of `code`, cycle-safe. Excludes `code` itself. */\n ancestorsOf(code: string): ReadonlySet<string>;\n}\n\n/** Read the direct `parent` codes a concept declares (synthesized-from-nesting or verbatim). */\nfunction directParents(concept: Concept): string[] {\n const parents: string[] = [];\n for (const p of concept.properties) {\n if (p.code === \"parent\" && typeof p.value === \"string\") parents.push(p.value);\n }\n return parents;\n}\n\n/**\n * Build a cycle-safe ancestor index from a loaded {@link CodeSystem}'s `parent` concept-properties.\n *\n * @param cs - The loaded code system.\n * @returns A {@link Subsumption} answering transitive-ancestor queries.\n * @example\n * ```ts\n * import { loadCodeSystem, buildSubsumption } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"p\", concept: [{ code: \"c\" }] }] },\n * });\n * buildSubsumption(cs).ancestorsOf(\"c\").has(\"p\"); // => true\n * ```\n */\nexport function buildSubsumption(cs: CodeSystem): Subsumption {\n const parentsOf = new Map<string, readonly string[]>();\n for (const concept of cs.concepts.values()) {\n const parents = directParents(concept);\n if (parents.length > 0) parentsOf.set(concept.code, parents);\n }\n const cache = new Map<string, ReadonlySet<string>>();\n const ancestorsOf = (code: string): ReadonlySet<string> => {\n const cached = cache.get(code);\n if (cached !== undefined) return cached;\n const acc = new Set<string>();\n const stack = [...(parentsOf.get(code) ?? [])];\n while (stack.length > 0) {\n const next = stack.pop();\n if (next === undefined || acc.has(next) || next === code) continue;\n acc.add(next);\n for (const p of parentsOf.get(next) ?? []) stack.push(p);\n }\n cache.set(code, acc);\n return acc;\n };\n return { ancestorsOf };\n}\n\n/**\n * True when `code` is-a `anchor` — the same code, or a (transitive) descendant of it.\n *\n * @param sub - The subsumption index (from {@link buildSubsumption}).\n * @param code - The candidate code.\n * @param anchor - The ancestor code to test against.\n * @returns Whether `code` is `anchor` or a descendant of it.\n * @example\n * ```ts\n * import { loadCodeSystem, buildSubsumption, isA } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"p\", concept: [{ code: \"c\" }] }] },\n * });\n * isA(buildSubsumption(cs), \"c\", \"p\"); // => true\n * ```\n */\nexport function isA(sub: Subsumption, code: string, anchor: string): boolean {\n return code === anchor || sub.ancestorsOf(code).has(anchor);\n}\n\n/** Split a `,`-separated filter value (`in`/`not-in`) into a trimmed, non-empty token set. */\nfunction valueSet(value: string): ReadonlySet<string> {\n return new Set(\n value\n .split(\",\")\n .map((v) => v.trim())\n .filter((v) => v.length > 0),\n );\n}\n\n/** Read a concept's first property value for `property`, as a string, or `undefined`. */\nfunction propertyValue(concept: Concept, property: string): string | undefined {\n for (const p of concept.properties) {\n if (p.code === property) return typeof p.value === \"string\" ? p.value : String(p.value);\n }\n return undefined;\n}\n\n/** The outcome of evaluating a single filter against a single concept. */\nexport interface FilterMatch {\n /** Whether the concept satisfies the filter (meaningful only when {@link supported}). */\n readonly matched: boolean;\n /** Whether the engine implements this filter operator; `false` ⇒ the caller must surface it. */\n readonly supported: boolean;\n}\n\nconst UNSUPPORTED: FilterMatch = Object.freeze({ matched: false, supported: false });\n\n/**\n * Evaluate one {@link ConceptSetFilter} against one {@link Concept}, using the release's hierarchy.\n *\n * The `concept` filter property (and the hierarchy operators regardless of property) reads the code\n * itself / its subsumption; other properties read the concept's `property` values. An unimplemented\n * operator returns `{ supported: false }` — never a coerced `matched`.\n *\n * @param concept - The concept under test.\n * @param filter - The filter predicate.\n * @param sub - The subsumption index for the concept's code system.\n * @returns A {@link FilterMatch}.\n * @example\n * ```ts\n * import { loadCodeSystem, buildSubsumption, matchesFilter } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"p\", concept: [{ code: \"c\" }] }] },\n * });\n * const dog = cs.concepts.get(\"c\");\n * dog && matchesFilter(dog, { property: \"concept\", op: \"is-a\", value: \"p\" }, buildSubsumption(cs)).matched; // => true\n * ```\n */\nexport function matchesFilter(\n concept: Concept,\n filter: ConceptSetFilter,\n sub: Subsumption,\n): FilterMatch {\n const onCode = filter.property === \"concept\";\n switch (filter.op) {\n case \"is-a\":\n return { matched: isA(sub, concept.code, filter.value), supported: true };\n case \"descendent-of\":\n // Strict: descendants only, excluding the anchor itself.\n return {\n matched: concept.code !== filter.value && sub.ancestorsOf(concept.code).has(filter.value),\n supported: true,\n };\n case \"is-not-a\":\n return { matched: !isA(sub, concept.code, filter.value), supported: true };\n case \"=\": {\n const actual = onCode ? concept.code : propertyValue(concept, filter.property);\n return { matched: actual === filter.value, supported: true };\n }\n case \"in\": {\n const set = valueSet(filter.value);\n const actual = onCode ? concept.code : propertyValue(concept, filter.property);\n return { matched: actual !== undefined && set.has(actual), supported: true };\n }\n case \"not-in\": {\n const set = valueSet(filter.value);\n const actual = onCode ? concept.code : propertyValue(concept, filter.property);\n // A concept the property is absent on is not \"in\" the set, hence \"not-in\" is true.\n return { matched: actual === undefined || !set.has(actual), supported: true };\n }\n case \"exists\": {\n const present = onCode ? true : propertyValue(concept, filter.property) !== undefined;\n const wantPresent = filter.value.trim().toLowerCase() === \"true\";\n return { matched: present === wantPresent, supported: true };\n }\n case \"regex\":\n case \"generalizes\":\n default:\n // Not implemented (or an unrecognized runtime operator) — surfaced, never mis-expanded.\n return UNSUPPORTED;\n }\n}\n\n/**\n * Evaluate every filter in a component against one concept: does it satisfy **all** of them, and were\n * they **all** supported? An unsupported operator short-circuits `supported: false`.\n *\n * @param concept - The concept under test.\n * @param filters - The component's filters (ANDed).\n * @param sub - The subsumption index.\n * @returns A {@link FilterMatch} over the conjunction.\n * @example\n * ```ts\n * import { loadCodeSystem, buildSubsumption, matchesAllFilters } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: { resourceType: \"CodeSystem\", concept: [{ code: \"c\" }] },\n * });\n * const c = cs.concepts.get(\"c\");\n * c && matchesAllFilters(c, [{ property: \"concept\", op: \"=\", value: \"c\" }], buildSubsumption(cs)).matched; // => true\n * ```\n */\nexport function matchesAllFilters(\n concept: Concept,\n filters: readonly ConceptSetFilter[],\n sub: Subsumption,\n): FilterMatch {\n let matched = true;\n for (const f of filters) {\n const r = matchesFilter(concept, f, sub);\n if (!r.supported) return UNSUPPORTED;\n if (!r.matched) matched = false;\n }\n return { matched, supported: true };\n}\n","/**\n * {@link expand} — the FHIR R4 ValueSet `$expand` operation over a loaded {@link ValueSet}.\n *\n * Grounded firsthand on FHIR R4 (`https://hl7.org/fhir/R4/valueset-operation-expand.html`,\n * `https://hl7.org/fhir/R4/valueset.html#compose`):\n *\n * - A **pre-computed** `expansion` is used as-is (extensional), and its completeness is checked — a\n * truncated snapshot is flagged, never treated as full membership.\n * - An intensional `compose` is expanded over **consumer-supplied** {@link ../codesystem/types.CodeSystem}\n * releases: the union of `include` components minus the union of `exclude` components. Each component\n * selects by explicit `concept`, by `filter` (subsumption + property predicates), by the whole\n * `system`, and/or by intersecting referenced value sets.\n *\n * **Never fabricate.** A part that cannot be computed — a missing code system, an unresolved\n * referenced value set, an unimplemented `filter` operator — yields a typed\n * {@link ../common/diagnostics.DIAGNOSTIC_CODES.TERM_VALUESET_CANNOT_EXPAND} and marks the result\n * `complete: false`, so the `contains` set is an explicit **lower bound**, never a silently-empty or\n * fabricated membership.\n *\n * @packageDocumentation\n */\n\nimport { coding, type Coding } from \"../common/coding.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { buildSubsumption, matchesAllFilters, unsupportedOps } from \"./filters.js\";\nimport type {\n ConceptSetComponent,\n ExpandResult,\n ExpansionContext,\n ExpansionDiagnostic,\n ValueSet,\n} from \"./types.js\";\n\n/** The stable identity of a coding for set operations — `system` + `code` (version is a refinement). */\nfunction codingKey(system: string | undefined, code: string): string {\n return `${system ?? \"\"}\\u001f${code}`;\n}\n\n/** Build a frozen {@link Coding} from a value set's parts, dropping absent optionals. */\nfunction makeCoding(\n system: string | undefined,\n code: string,\n display?: string,\n version?: string,\n): Coding {\n const init: Writable<Coding> = { code };\n if (system !== undefined) init.system = system;\n if (version !== undefined) init.version = version;\n if (display !== undefined) init.display = display;\n return coding(init);\n}\n\nfunction cannotExpand(detail: string, path?: string): ExpansionDiagnostic {\n const d: Writable<ExpansionDiagnostic> = { code: \"TERM_VALUESET_CANNOT_EXPAND\", detail };\n if (path !== undefined) d.path = path;\n return Object.freeze(d);\n}\n\nfunction truncated(detail: string, path?: string): ExpansionDiagnostic {\n const d: Writable<ExpansionDiagnostic> = { code: \"TERM_VALUESET_EXPANSION_TRUNCATED\", detail };\n if (path !== undefined) d.path = path;\n return Object.freeze(d);\n}\n\n/**\n * Re-root a diagnostic raised inside a *referenced* value set onto the reference that reached it, so\n * a nested `compose.include[3]` is still navigable from the caller's own resource. Value-free: both\n * halves are index paths this module built.\n */\nfunction underPath(d: ExpansionDiagnostic, prefix: string): ExpansionDiagnostic {\n const out: Writable<ExpansionDiagnostic> = { code: d.code, detail: d.detail };\n out.path = d.path === undefined ? prefix : `${prefix}/${d.path}`;\n return Object.freeze(out);\n}\n\n/** The internal result of expanding a single `include`/`exclude` component: a keyed member map. */\ninterface ComponentExpansion {\n readonly members: Map<string, Coding>;\n readonly complete: boolean;\n readonly diagnostics: readonly ExpansionDiagnostic[];\n}\n\n/** Intersect `into` down to the keys also present in `other` (mutates and returns `into`). */\nfunction intersectInto(into: Map<string, Coding>, other: Map<string, Coding>): Map<string, Coding> {\n for (const k of into.keys()) if (!other.has(k)) into.delete(k);\n return into;\n}\n\n/** Expand every referenced value set and intersect their memberships (a code must be in all). */\nfunction expandReferencedValueSets(\n urls: readonly string[],\n ctx: ExpansionContext,\n visited: ReadonlySet<string>,\n path: string,\n): ComponentExpansion {\n const diagnostics: ExpansionDiagnostic[] = [];\n let complete = true;\n let acc: Map<string, Coding> | null = null;\n for (const [i, url] of urls.entries()) {\n const refPath = `${path}.valueSet[${String(i)}]`;\n if (visited.has(url)) {\n diagnostics.push(cannotExpand(\"cyclic value set reference\", refPath));\n complete = false;\n acc = new Map();\n continue;\n }\n const vs = ctx.valueSets?.get(url);\n if (vs === undefined) {\n diagnostics.push(cannotExpand(\"referenced value set not supplied\", refPath));\n complete = false;\n acc = new Map();\n continue;\n }\n const exp = expandInternal(vs, ctx, new Set([...visited, url]));\n if (!exp.complete) complete = false;\n for (const d of exp.diagnostics) diagnostics.push(underPath(d, refPath));\n const members = new Map<string, Coding>();\n for (const c of exp.contains) members.set(codingKey(c.system, c.code), c);\n acc = acc === null ? members : intersectInto(acc, members);\n }\n return { members: acc ?? new Map<string, Coding>(), complete, diagnostics };\n}\n\n/** Expand one `include`/`exclude` component into a keyed member map. */\nfunction expandComponent(\n component: ConceptSetComponent,\n ctx: ExpansionContext,\n visited: ReadonlySet<string>,\n path: string,\n): ComponentExpansion {\n const diagnostics: ExpansionDiagnostic[] = [];\n let complete = true;\n const { system, version, concept, filter, valueSet } = component;\n // A present `concept` (even empty) is an **enumeration** — never re-read as a whole-system include;\n // \"all of system\" is only the concept-absent, filter-absent case (FHIR ValueSet.compose semantics).\n const hasConcept = concept !== undefined;\n const hasFilter = filter !== undefined && filter.length > 0;\n const hasVs = valueSet !== undefined && valueSet.length > 0;\n\n let base: Map<string, Coding> | null = null;\n\n if (hasConcept) {\n // Extensional: enumerated codes are always fully computable.\n base = new Map();\n for (const c of concept) {\n base.set(codingKey(system, c.code), makeCoding(system, c.code, c.display, version));\n }\n } else if (hasFilter || (system !== undefined && !hasVs)) {\n // Intensional filter, or a whole-system include — both need the loaded code system.\n if (system === undefined) {\n diagnostics.push(cannotExpand(\"intensional filter without a code system 'system'\", path));\n return { members: new Map(), complete: false, diagnostics };\n }\n const cs = ctx.codeSystems?.get(system);\n if (cs === undefined) {\n diagnostics.push(cannotExpand(\"code system not supplied for intensional include\", path));\n return { members: new Map(), complete: false, diagnostics };\n }\n if (hasFilter) {\n const unsupported = unsupportedOps(filter);\n if (unsupported.length > 0) {\n diagnostics.push(cannotExpand(\"unsupported filter operator\", path));\n return { members: new Map(), complete: false, diagnostics };\n }\n const sub = buildSubsumption(cs);\n base = new Map();\n for (const concpt of cs.concepts.values()) {\n if (matchesAllFilters(concpt, filter, sub).matched) {\n base.set(\n codingKey(system, concpt.code),\n makeCoding(system, concpt.code, concpt.display, version),\n );\n }\n }\n } else {\n base = new Map();\n for (const concpt of cs.concepts.values()) {\n base.set(\n codingKey(system, concpt.code),\n makeCoding(system, concpt.code, concpt.display, version),\n );\n }\n }\n }\n\n if (hasVs) {\n const refs = expandReferencedValueSets(valueSet, ctx, visited, path);\n for (const d of refs.diagnostics) diagnostics.push(d);\n if (!refs.complete) complete = false;\n base = base === null ? refs.members : intersectInto(base, refs.members);\n // A component that names a `system` alongside a `valueSet` (with no `concept`/`filter` base) is\n // an **intersection**: keep only referenced-value-set members drawn from that system. Without this\n // the system scope is silently dropped and a cross-system code is fabricated into membership\n // (FHIR R4 ValueSet.compose.include combines system + valueSet by intersection). For the\n // concept/filter/whole-system branches every member already carries `system`, so this is a no-op.\n if (system !== undefined) {\n for (const [k, c] of [...base]) if (c.system !== system) base.delete(k);\n }\n }\n\n // A component that selects nothing (no system, concept, filter, or valueSet) adds no members.\n return { members: base ?? new Map<string, Coding>(), complete, diagnostics };\n}\n\n/** Expand a compose, or pass through a pre-computed expansion, with a cycle-visited set. */\nfunction expandInternal(\n vs: ValueSet,\n ctx: ExpansionContext,\n visited: ReadonlySet<string>,\n): ExpandResult {\n if (vs.expansion !== undefined) {\n const seen = new Set<string>();\n const contains: Coding[] = [];\n for (const c of vs.expansion.contains) {\n const key = codingKey(c.system, c.code);\n if (seen.has(key)) continue;\n seen.add(key);\n contains.push(makeCoding(c.system, c.code, c.display, c.version));\n }\n const diagnostics: ExpansionDiagnostic[] = [];\n let complete = true;\n if (vs.expansion.truncated) {\n complete = false;\n diagnostics.push(\n truncated(\"pre-computed expansion is incomplete (truncated or too-costly)\", \"expansion\"),\n );\n }\n const out: Writable<ExpandResult> = {\n complete,\n contains: Object.freeze(contains),\n diagnostics: Object.freeze(diagnostics),\n };\n if (vs.expansion.total !== undefined) out.total = vs.expansion.total;\n return Object.freeze(out);\n }\n\n if (vs.compose !== undefined) {\n const included = new Map<string, Coding>();\n const diagnostics: ExpansionDiagnostic[] = [];\n let complete = true;\n for (const [i, inc] of vs.compose.include.entries()) {\n const r = expandComponent(inc, ctx, visited, `compose.include[${String(i)}]`);\n if (!r.complete) complete = false;\n for (const d of r.diagnostics) diagnostics.push(d);\n for (const [k, c] of r.members) if (!included.has(k)) included.set(k, c);\n }\n for (const [i, exc] of vs.compose.exclude.entries()) {\n const r = expandComponent(exc, ctx, visited, `compose.exclude[${String(i)}]`);\n for (const d of r.diagnostics) diagnostics.push(d);\n // Remove the members we could prove are excluded.\n for (const k of r.members.keys()) included.delete(k);\n if (!r.complete) {\n complete = false;\n // An exclude we could not fully compute may exclude MORE than we proved. To keep `contains` a\n // true LOWER bound (never retain a possible non-member), drop every remaining member the\n // exclude could still match — a member in the exclude's system (or all members when the\n // exclude names no system). A dropped genuine member is fine for a lower bound; a retained\n // excluded one would be a fabricated membership (the never-fabricate contract).\n for (const [k, c] of [...included]) {\n if (exc.system === undefined || c.system === exc.system) included.delete(k);\n }\n }\n }\n return Object.freeze({\n complete,\n contains: Object.freeze([...included.values()]),\n diagnostics: Object.freeze(diagnostics),\n });\n }\n\n // A value set with neither compose nor expansion has an empty, complete membership.\n return Object.freeze({\n complete: true,\n contains: Object.freeze([]),\n diagnostics: Object.freeze([]),\n });\n}\n\n/**\n * `$expand`: compute the flattened membership of a {@link ValueSet} over the supplied code systems.\n *\n * @param vs - The loaded value set.\n * @param ctx - The loaded code systems / referenced value sets the intensional parts resolve against.\n * @returns An {@link ExpandResult} — the `contains` members plus an honest `complete` flag. When\n * `complete` is `false`, `contains` is a lower bound (never treat it as exhaustive membership).\n * @example\n * ```ts\n * import { loadValueSet, loadCodeSystem, expand } from \"@cosyte/terminology\";\n *\n * const cs = loadCodeSystem({\n * format: \"fhir\",\n * resource: {\n * resourceType: \"CodeSystem\",\n * url: \"http://example.org/cs\",\n * concept: [{ code: \"a\" }, { code: \"b\" }, { code: \"c\" }],\n * },\n * });\n * const vs = loadValueSet({\n * resourceType: \"ValueSet\",\n * compose: { include: [{ system: \"http://example.org/cs\", concept: [{ code: \"a\" }, { code: \"b\" }] }] },\n * });\n * const result = expand(vs, { codeSystems: new Map([[\"http://example.org/cs\", cs]]) });\n * result.complete; // => true\n * result.contains.length; // => 2\n * ```\n */\nexport function expand(vs: ValueSet, ctx: ExpansionContext = {}): ExpandResult {\n return expandInternal(vs, ctx, new Set(vs.url !== undefined ? [vs.url] : []));\n}\n","/**\n * {@link validateCodeInValueSet} — the FHIR R4 ValueSet `$validate-code` operation (value-set\n * binding): is a {@link Coding} a member of a {@link ValueSet}?\n *\n * Grounded firsthand on FHIR R4 (`https://hl7.org/fhir/R4/valueset-operation-validate-code.html`): a\n * binding decides whether a code is *allowed* in a slot. The engine returns a **decided** membership\n * (`result: true`/`false`) **only when it can prove it** — a code found in a computable `include` and\n * not removed by any computable `exclude` is a definite member; a code absent from a fully-evaluated\n * value set is a definite non-member. When any relevant part cannot be evaluated (a missing code\n * system, a truncated pre-computed expansion, an unimplemented `filter`), the answer is a typed\n * {@link ValueSetMemberUndetermined} — **never** a fabricated `false` (a false \"not a member\" is a\n * clinical error).\n *\n * @packageDocumentation\n */\n\nimport type { Coding } from \"../common/coding.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { buildSubsumption, matchesAllFilters, unsupportedOps } from \"./filters.js\";\nimport type {\n ConceptSetComponent,\n ExpansionContext,\n ExpansionDiagnostic,\n ValueSet,\n ValueSetMembership,\n} from \"./types.js\";\n\nfunction cannotExpand(detail: string, path?: string): ExpansionDiagnostic {\n const d: Writable<ExpansionDiagnostic> = { code: \"TERM_VALUESET_CANNOT_EXPAND\", detail };\n if (path !== undefined) d.path = path;\n return Object.freeze(d);\n}\n\n/**\n * Re-root a diagnostic raised inside a *referenced* value set onto the reference that reached it.\n *\n * The **path format and its construction** are shared with `expand` (index paths over `compose`,\n * `/`-joined across a reference). The **sets of diagnostics are not**, and must not be read as\n * identical: membership short-circuits where expansion cannot. A component whose target system\n * differs is a definite non-match here before any diagnostic is raised, an unresolvable `exclude`\n * that cannot change a decided verdict yields nothing here while expansion still reports it, and\n * expansion returns early from a component that names both an unusable `system` and a `valueSet`\n * where membership goes on to evaluate the reference. Same vocabulary, different question.\n */\nfunction underPath(d: ExpansionDiagnostic, prefix: string): ExpansionDiagnostic {\n const out: Writable<ExpansionDiagnostic> = { code: d.code, detail: d.detail };\n out.path = d.path === undefined ? prefix : `${prefix}/${d.path}`;\n return Object.freeze(out);\n}\n\n/** Whether a single `include`/`exclude` component matches `target`, and whether that is decidable. */\ninterface ComponentMatch {\n /** The match verdict — meaningful only when {@link complete}. */\n readonly matched: boolean;\n /** Whether the verdict is trustworthy (both a match and a non-match were fully evaluated). */\n readonly complete: boolean;\n readonly diagnostics: readonly ExpansionDiagnostic[];\n}\n\nfunction matchComponent(\n target: Coding,\n component: ConceptSetComponent,\n ctx: ExpansionContext,\n visited: ReadonlySet<string>,\n path: string,\n): ComponentMatch {\n const diagnostics: ExpansionDiagnostic[] = [];\n const { system, concept, filter, valueSet } = component;\n // A present `concept` (even empty) is an enumeration; \"all of system\" is the concept/filter-absent\n // case only — mirrors expandComponent so membership and expansion agree.\n const hasConcept = concept !== undefined;\n const hasFilter = filter !== undefined && filter.length > 0;\n const hasVs = valueSet !== undefined && valueSet.length > 0;\n\n // ── base (concept / filter / whole-system) ──\n let baseMatched: boolean | null = null; // null ⇒ no base constraint\n let baseComplete = true;\n\n if (system !== undefined && target.system !== undefined && system !== target.system) {\n // The component's concept/filter selection is scoped to `system`; a different target system is a\n // definite non-match on the base.\n baseMatched = false;\n } else if (hasConcept) {\n baseMatched = concept.some((c) => c.code === target.code);\n } else if (hasFilter || (system !== undefined && !hasVs)) {\n if (system === undefined) {\n diagnostics.push(cannotExpand(\"intensional filter without a code system 'system'\", path));\n baseMatched = false;\n baseComplete = false;\n } else {\n const cs = ctx.codeSystems?.get(system);\n if (cs === undefined) {\n diagnostics.push(cannotExpand(\"code system not supplied for intensional include\", path));\n baseMatched = false;\n baseComplete = false;\n } else if (hasFilter) {\n if (unsupportedOps(filter).length > 0) {\n diagnostics.push(cannotExpand(\"unsupported filter operator\", path));\n baseMatched = false;\n baseComplete = false;\n } else {\n const concpt = cs.concepts.get(target.code);\n // A code absent from the system is a definite non-member of any filter over it.\n baseMatched =\n concpt !== undefined && matchesAllFilters(concpt, filter, buildSubsumption(cs)).matched;\n }\n } else {\n baseMatched = cs.concepts.get(target.code) !== undefined;\n }\n }\n }\n\n // ── referenced value sets (intersection: member of every one) ──\n let refDefiniteFalse = false;\n let refUndetermined = false;\n if (hasVs) {\n for (const [i, url] of valueSet.entries()) {\n const refPath = `${path}.valueSet[${String(i)}]`;\n if (visited.has(url)) {\n diagnostics.push(cannotExpand(\"cyclic value set reference\", refPath));\n refUndetermined = true;\n continue;\n }\n const vs = ctx.valueSets?.get(url);\n if (vs === undefined) {\n diagnostics.push(cannotExpand(\"referenced value set not supplied\", refPath));\n refUndetermined = true;\n continue;\n }\n const m = validateInternal(target, vs, ctx, new Set([...visited, url]));\n if (m.undetermined) {\n for (const d of m.diagnostics) diagnostics.push(underPath(d, refPath));\n refUndetermined = true;\n } else if (!m.result) {\n refDefiniteFalse = true;\n }\n }\n }\n\n // ── combine base ∩ refs ──\n const baseDefiniteFalse = baseMatched === false && baseComplete;\n const baseDefiniteTrue = baseMatched === null || (baseMatched === true && baseComplete);\n const refDefiniteTrue = !hasVs || (!refDefiniteFalse && !refUndetermined);\n\n if (baseDefiniteFalse || refDefiniteFalse) {\n return { matched: false, complete: true, diagnostics };\n }\n if (baseDefiniteTrue && refDefiniteTrue) {\n return { matched: true, complete: true, diagnostics };\n }\n return { matched: false, complete: false, diagnostics };\n}\n\nfunction decided(result: boolean, coding: Coding): ValueSetMembership {\n return Object.freeze({ undetermined: false, result, coding });\n}\n\nfunction undetermined(\n coding: Coding,\n diagnostics: readonly ExpansionDiagnostic[],\n): ValueSetMembership {\n return Object.freeze({\n undetermined: true,\n code: \"TERM_VALUESET_CANNOT_EXPAND\",\n coding,\n diagnostics: Object.freeze([...diagnostics]),\n });\n}\n\nfunction validateInternal(\n target: Coding,\n vs: ValueSet,\n ctx: ExpansionContext,\n visited: ReadonlySet<string>,\n): ValueSetMembership {\n if (vs.expansion !== undefined) {\n const found = vs.expansion.contains.some(\n (c) =>\n c.code === target.code &&\n (c.system === undefined || target.system === undefined || c.system === target.system),\n );\n if (found) return decided(true, target);\n if (vs.expansion.truncated) {\n return undetermined(target, [\n cannotExpand(\"pre-computed expansion is incomplete (truncated or too-costly)\", \"expansion\"),\n ]);\n }\n return decided(false, target);\n }\n\n if (vs.compose !== undefined) {\n const diagnostics: ExpansionDiagnostic[] = [];\n let includedDefinite = false;\n let anyIncludeUndetermined = false;\n for (const [i, inc] of vs.compose.include.entries()) {\n const m = matchComponent(target, inc, ctx, visited, `compose.include[${String(i)}]`);\n for (const d of m.diagnostics) diagnostics.push(d);\n if (m.complete && m.matched) includedDefinite = true;\n if (!m.complete) anyIncludeUndetermined = true;\n }\n let excludedDefinite = false;\n let anyExcludeUndetermined = false;\n for (const [i, exc] of vs.compose.exclude.entries()) {\n const m = matchComponent(target, exc, ctx, visited, `compose.exclude[${String(i)}]`);\n for (const d of m.diagnostics) diagnostics.push(d);\n if (m.complete && m.matched) excludedDefinite = true;\n if (!m.complete) anyExcludeUndetermined = true;\n }\n\n if (excludedDefinite) return decided(false, target);\n if (includedDefinite && !anyExcludeUndetermined) return decided(true, target);\n if (!includedDefinite && !anyIncludeUndetermined && !anyExcludeUndetermined) {\n return decided(false, target);\n }\n return undetermined(target, diagnostics);\n }\n\n // Neither compose nor expansion ⇒ an empty value set ⇒ nothing is a member (definite).\n return decided(false, target);\n}\n\n/**\n * `$validate-code` (ValueSet): is `coding` a member of `valueSet`?\n *\n * @param coding - The code to test (system + code).\n * @param valueSet - The loaded value set.\n * @param ctx - The loaded code systems / referenced value sets the intensional parts resolve against.\n * @returns A decided {@link ValueSetMembership} (`result: true`/`false`), or a typed\n * {@link ValueSetMemberUndetermined} when membership could not be proven — never a fabricated `false`.\n * @example\n * ```ts\n * import { loadValueSet, validateCodeInValueSet } from \"@cosyte/terminology\";\n *\n * const vs = loadValueSet({\n * resourceType: \"ValueSet\",\n * compose: { include: [{ system: \"http://example.org/cs\", concept: [{ code: \"a\" }, { code: \"b\" }] }] },\n * });\n * const r = validateCodeInValueSet({ system: \"http://example.org/cs\", code: \"a\" }, vs);\n * r.undetermined === false && r.result; // => true\n * ```\n */\nexport function validateCodeInValueSet(\n coding: Coding,\n valueSet: ValueSet,\n ctx: ExpansionContext = {},\n): ValueSetMembership {\n return validateInternal(\n coding,\n valueSet,\n ctx,\n new Set(valueSet.url !== undefined ? [valueSet.url] : []),\n );\n}\n","/**\n * The **verbatim, unmodified** UCUM unit table (`ucum-essence.xml`), embedded as a string.\n *\n * GENERATED by `scripts/generate-ucum-essence-data.ts` from `vendor/ucum/ucum-essence.xml` —\n * **do not edit by hand**. The content is UCUM's, reproduced byte-for-byte; only the string wrapper\n * is added. Regenerate with `pnpm gen:ucum`.\n *\n * The Unified Code for Units of Measure (UCUM) is copyright ©1999–2024, Regenstrief Institute, Inc.\n * All rights reserved. Reproduced under the UCUM Copyright Notice and License\n * (https://ucum.org/license); this copy is unmodified. Provided \"as is\" without warranty of any\n * kind. See `vendor/ucum/NOTICE.md`.\n *\n * @packageDocumentation\n */\n\n// prettier-ignore\n/**\n * The verbatim UCUM `ucum-essence.xml` v2.2 (revision-date 2024-06-17). Parsed lazily by\n * {@link ../ucum/essence.loadUcumEssence} into the engine's in-memory unit table.\n */\nexport const UCUM_ESSENCE_XML: string = `<?xml version=\"1.0\" encoding=\"ascii\"?>\n<root xmlns=\"http://unitsofmeasure.org/ucum-essence\" version=\"2.2\" revision=\"N/A\"\n revision-date=\"2024-06-17\">\n <prefix Code=\"Y\" CODE=\"YA\">\n <name>yotta</name>\n <printSymbol>Y</printSymbol>\n <value value=\"1e24\">1 &#215; 10<sup>24</sup>\n </value>\n </prefix>\n <prefix Code=\"Z\" CODE=\"ZA\">\n <name>zetta</name>\n <printSymbol>Z</printSymbol>\n <value value=\"1e21\">1 &#215; 10<sup>21</sup>\n </value>\n </prefix>\n <prefix Code=\"E\" CODE=\"EX\">\n <name>exa</name>\n <printSymbol>E</printSymbol>\n <value value=\"1e18\">1 &#215; 10<sup>18</sup>\n </value>\n </prefix>\n <prefix Code=\"P\" CODE=\"PT\">\n <name>peta</name>\n <printSymbol>P</printSymbol>\n <value value=\"1e15\">1 &#215; 10<sup>15</sup>\n </value>\n </prefix>\n <prefix Code=\"T\" CODE=\"TR\">\n <name>tera</name>\n <printSymbol>T</printSymbol>\n <value value=\"1e12\">1 &#215; 10<sup>12</sup>\n </value>\n </prefix>\n <prefix Code=\"G\" CODE=\"GA\">\n <name>giga</name>\n <printSymbol>G</printSymbol>\n <value value=\"1e9\">1 &#215; 10<sup>9</sup>\n </value>\n </prefix>\n <prefix Code=\"M\" CODE=\"MA\">\n <name>mega</name>\n <printSymbol>M</printSymbol>\n <value value=\"1e6\">1 &#215; 10<sup>6</sup>\n </value>\n </prefix>\n <prefix Code=\"k\" CODE=\"K\">\n <name>kilo</name>\n <printSymbol>k</printSymbol>\n <value value=\"1e3\">1 &#215; 10<sup>3</sup>\n </value>\n </prefix>\n <prefix Code=\"h\" CODE=\"H\">\n <name>hecto</name>\n <printSymbol>h</printSymbol>\n <value value=\"1e2\">1 &#215; 10<sup>2</sup>\n </value>\n </prefix>\n <prefix Code=\"da\" CODE=\"DA\">\n <name>deka</name>\n <printSymbol>da</printSymbol>\n <value value=\"1e1\">1 &#215; 10<sup>1</sup>\n </value>\n </prefix>\n <prefix Code=\"d\" CODE=\"D\">\n <name>deci</name>\n <printSymbol>d</printSymbol>\n <value value=\"1e-1\">1 &#215; 10<sup>-1</sup>\n </value>\n </prefix>\n <prefix Code=\"c\" CODE=\"C\">\n <name>centi</name>\n <printSymbol>c</printSymbol>\n <value value=\"1e-2\">1 &#215; 10<sup>-2</sup>\n </value>\n </prefix>\n <prefix Code=\"m\" CODE=\"M\">\n <name>milli</name>\n <printSymbol>m</printSymbol>\n <value value=\"1e-3\">1 &#215; 10<sup>-3</sup>\n </value>\n </prefix>\n <prefix Code=\"u\" CODE=\"U\">\n <name>micro</name>\n <printSymbol>&#956;</printSymbol>\n <value value=\"1e-6\">1 &#215; 10<sup>-6</sup>\n </value>\n </prefix>\n <prefix Code=\"n\" CODE=\"N\">\n <name>nano</name>\n <printSymbol>n</printSymbol>\n <value value=\"1e-9\">1 &#215; 10<sup>-9</sup>\n </value>\n </prefix>\n <prefix Code=\"p\" CODE=\"P\">\n <name>pico</name>\n <printSymbol>p</printSymbol>\n <value value=\"1e-12\">1 &#215; 10<sup>-12</sup>\n </value>\n </prefix>\n <prefix Code=\"f\" CODE=\"F\">\n <name>femto</name>\n <printSymbol>f</printSymbol>\n <value value=\"1e-15\">1 &#215; 10<sup>-15</sup>\n </value>\n </prefix>\n <prefix Code=\"a\" CODE=\"A\">\n <name>atto</name>\n <printSymbol>a</printSymbol>\n <value value=\"1e-18\">1 &#215; 10<sup>-18</sup>\n </value>\n </prefix>\n <prefix Code=\"z\" CODE=\"ZO\">\n <name>zepto</name>\n <printSymbol>z</printSymbol>\n <value value=\"1e-21\">1 &#215; 10<sup>-21</sup>\n </value>\n </prefix>\n <prefix Code=\"y\" CODE=\"YO\">\n <name>yocto</name>\n <printSymbol>y</printSymbol>\n <value value=\"1e-24\">1 &#215; 10<sup>-24</sup>\n </value>\n </prefix>\n <base-unit Code=\"m\" CODE=\"M\" dim=\"L\">\n <name>meter</name>\n <printSymbol>m</printSymbol>\n <property>length</property>\n </base-unit>\n <base-unit Code=\"s\" CODE=\"S\" dim=\"T\">\n <name>second</name>\n <printSymbol>s</printSymbol>\n <property>time</property>\n </base-unit>\n <base-unit Code=\"g\" CODE=\"G\" dim=\"M\">\n <name>gram</name>\n <printSymbol>g</printSymbol>\n <property>mass</property>\n </base-unit>\n <base-unit Code=\"rad\" CODE=\"RAD\" dim=\"A\">\n <name>radian</name>\n <printSymbol>rad</printSymbol>\n <property>plane angle</property>\n </base-unit>\n <base-unit Code=\"K\" CODE=\"K\" dim=\"C\">\n <name>kelvin</name>\n <printSymbol>K</printSymbol>\n <property>temperature</property>\n </base-unit>\n <base-unit Code=\"C\" CODE=\"C\" dim=\"Q\">\n <name>coulomb</name>\n <printSymbol>C</printSymbol>\n <property>electric charge</property>\n </base-unit>\n <base-unit Code=\"cd\" CODE=\"CD\" dim=\"F\">\n <name>candela</name>\n <printSymbol>cd</printSymbol>\n <property>luminous intensity</property>\n </base-unit>\n <unit Code=\"10*\" CODE=\"10*\" isMetric=\"no\" class=\"dimless\">\n <name>the number ten for arbitrary powers</name>\n <printSymbol>10</printSymbol>\n <property>number</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"10\">10</value>\n </unit>\n <unit Code=\"10^\" CODE=\"10^\" isMetric=\"no\" class=\"dimless\">\n <name>the number ten for arbitrary powers</name>\n <printSymbol>10</printSymbol>\n <property>number</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"10\">10</value>\n </unit>\n <unit Code=\"[pi]\" CODE=\"[PI]\" isMetric=\"no\" class=\"dimless\">\n <name>the number pi</name>\n <printSymbol>&#960;</printSymbol>\n <property>number</property>\n <value Unit=\"1\" UNIT=\"1\"\n value=\"3.1415926535897932384626433832795028841971693993751058209749445923\">&#960;</value>\n </unit>\n <unit Code=\"%\" CODE=\"%\" isMetric=\"no\" class=\"dimless\">\n <name>percent</name>\n <printSymbol>%</printSymbol>\n <property>fraction</property>\n <value Unit=\"10*-2\" UNIT=\"10*-2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ppth]\" CODE=\"[PPTH]\" isMetric=\"no\" class=\"dimless\">\n <name>parts per thousand</name>\n <printSymbol>ppth</printSymbol>\n <property>fraction</property>\n <value Unit=\"10*-3\" UNIT=\"10*-3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ppm]\" CODE=\"[PPM]\" isMetric=\"no\" class=\"dimless\">\n <name>parts per million</name>\n <printSymbol>ppm</printSymbol>\n <property>fraction</property>\n <value Unit=\"10*-6\" UNIT=\"10*-6\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ppb]\" CODE=\"[PPB]\" isMetric=\"no\" class=\"dimless\">\n <name>parts per billion</name>\n <printSymbol>ppb</printSymbol>\n <property>fraction</property>\n <value Unit=\"10*-9\" UNIT=\"10*-9\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pptr]\" CODE=\"[PPTR]\" isMetric=\"no\" class=\"dimless\">\n <name>parts per trillion</name>\n <printSymbol>pptr</printSymbol>\n <property>fraction</property>\n <value Unit=\"10*-12\" UNIT=\"10*-12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"mol\" CODE=\"MOL\" isMetric=\"yes\" class=\"si\">\n <name>mole</name>\n <printSymbol>mol</printSymbol>\n <property>amount of substance</property>\n <value Unit=\"10*23\" UNIT=\"10*23\" value=\"6.02214076\">6.02214076</value>\n </unit>\n <unit Code=\"sr\" CODE=\"SR\" isMetric=\"yes\" class=\"si\">\n <name>steradian</name>\n <printSymbol>sr</printSymbol>\n <property>solid angle</property>\n <value Unit=\"rad2\" UNIT=\"RAD2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Hz\" CODE=\"HZ\" isMetric=\"yes\" class=\"si\">\n <name>hertz</name>\n <printSymbol>Hz</printSymbol>\n <property>frequency</property>\n <value Unit=\"s-1\" UNIT=\"S-1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"N\" CODE=\"N\" isMetric=\"yes\" class=\"si\">\n <name>newton</name>\n <printSymbol>N</printSymbol>\n <property>force</property>\n <value Unit=\"kg.m/s2\" UNIT=\"KG.M/S2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Pa\" CODE=\"PAL\" isMetric=\"yes\" class=\"si\">\n <name>pascal</name>\n <printSymbol>Pa</printSymbol>\n <property>pressure</property>\n <value Unit=\"N/m2\" UNIT=\"N/M2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"J\" CODE=\"J\" isMetric=\"yes\" class=\"si\">\n <name>joule</name>\n <printSymbol>J</printSymbol>\n <property>energy</property>\n <value Unit=\"N.m\" UNIT=\"N.M\" value=\"1\">1</value>\n </unit>\n <unit Code=\"W\" CODE=\"W\" isMetric=\"yes\" class=\"si\">\n <name>watt</name>\n <printSymbol>W</printSymbol>\n <property>power</property>\n <value Unit=\"J/s\" UNIT=\"J/S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"A\" CODE=\"A\" isMetric=\"yes\" class=\"si\">\n <name>amp&#232;re</name>\n <printSymbol>A</printSymbol>\n <property>electric current</property>\n <value Unit=\"C/s\" UNIT=\"C/S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"V\" CODE=\"V\" isMetric=\"yes\" class=\"si\">\n <name>volt</name>\n <printSymbol>V</printSymbol>\n <property>electric potential</property>\n <value Unit=\"J/C\" UNIT=\"J/C\" value=\"1\">1</value>\n </unit>\n <unit Code=\"F\" CODE=\"F\" isMetric=\"yes\" class=\"si\">\n <name>farad</name>\n <printSymbol>F</printSymbol>\n <property>electric capacitance</property>\n <value Unit=\"C/V\" UNIT=\"C/V\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Ohm\" CODE=\"OHM\" isMetric=\"yes\" class=\"si\">\n <name>ohm</name>\n <printSymbol>&#937;</printSymbol>\n <property>electric resistance</property>\n <value Unit=\"V/A\" UNIT=\"V/A\" value=\"1\">1</value>\n </unit>\n <unit Code=\"S\" CODE=\"SIE\" isMetric=\"yes\" class=\"si\">\n <name>siemens</name>\n <printSymbol>S</printSymbol>\n <property>electric conductance</property>\n <value Unit=\"Ohm-1\" UNIT=\"OHM-1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Wb\" CODE=\"WB\" isMetric=\"yes\" class=\"si\">\n <name>weber</name>\n <printSymbol>Wb</printSymbol>\n <property>magnetic flux</property>\n <value Unit=\"V.s\" UNIT=\"V.S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Cel\" CODE=\"CEL\" isMetric=\"yes\" isSpecial=\"yes\" class=\"si\">\n <name>degree Celsius</name>\n <printSymbol>&#176;C</printSymbol>\n <property>temperature</property>\n <value Unit=\"cel(1 K)\" UNIT=\"CEL(1 K)\">\n <function name=\"Cel\" value=\"1\" Unit=\"K\"/>\n </value>\n </unit>\n <unit Code=\"T\" CODE=\"T\" isMetric=\"yes\" class=\"si\">\n <name>tesla</name>\n <printSymbol>T</printSymbol>\n <property>magnetic flux density</property>\n <value Unit=\"Wb/m2\" UNIT=\"WB/M2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"H\" CODE=\"H\" isMetric=\"yes\" class=\"si\">\n <name>henry</name>\n <printSymbol>H</printSymbol>\n <property>inductance</property>\n <value Unit=\"Wb/A\" UNIT=\"WB/A\" value=\"1\">1</value>\n </unit>\n <unit Code=\"lm\" CODE=\"LM\" isMetric=\"yes\" class=\"si\">\n <name>lumen</name>\n <printSymbol>lm</printSymbol>\n <property>luminous flux</property>\n <value Unit=\"cd.sr\" UNIT=\"CD.SR\" value=\"1\">1</value>\n </unit>\n <unit Code=\"lx\" CODE=\"LX\" isMetric=\"yes\" class=\"si\">\n <name>lux</name>\n <printSymbol>lx</printSymbol>\n <property>illuminance</property>\n <value Unit=\"lm/m2\" UNIT=\"LM/M2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Bq\" CODE=\"BQ\" isMetric=\"yes\" class=\"si\">\n <name>becquerel</name>\n <printSymbol>Bq</printSymbol>\n <property>radioactivity</property>\n <value Unit=\"s-1\" UNIT=\"S-1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Gy\" CODE=\"GY\" isMetric=\"yes\" class=\"si\">\n <name>gray</name>\n <printSymbol>Gy</printSymbol>\n <property>energy dose</property>\n <value Unit=\"J/kg\" UNIT=\"J/KG\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Sv\" CODE=\"SV\" isMetric=\"yes\" class=\"si\">\n <name>sievert</name>\n <printSymbol>Sv</printSymbol>\n <property>dose equivalent</property>\n <value Unit=\"J/kg\" UNIT=\"J/KG\" value=\"1\">1</value>\n </unit>\n <unit Code=\"gon\" CODE=\"GON\" isMetric=\"no\" class=\"iso1000\">\n <name>gon</name>\n <name>grade</name>\n <printSymbol>\n <sup>g</sup>\n </printSymbol>\n <property>plane angle</property>\n <value Unit=\"deg\" UNIT=\"DEG\" value=\"0.9\">0.9</value>\n </unit>\n <unit Code=\"deg\" CODE=\"DEG\" isMetric=\"no\" class=\"iso1000\">\n <name>degree</name>\n <printSymbol>&#176;</printSymbol>\n <property>plane angle</property>\n <value Unit=\"[pi].rad/360\" UNIT=\"[PI].RAD/360\" value=\"2\">2</value>\n </unit>\n <unit Code=\"'\" CODE=\"'\" isMetric=\"no\" class=\"iso1000\">\n <name>minute</name>\n <printSymbol>'</printSymbol>\n <property>plane angle</property>\n <value Unit=\"deg/60\" UNIT=\"DEG/60\" value=\"1\">1</value>\n </unit>\n <unit Code=\"''\" CODE=\"''\" isMetric=\"no\" class=\"iso1000\">\n <name>second</name>\n <printSymbol>''</printSymbol>\n <property>plane angle</property>\n <value Unit=\"'/60\" UNIT=\"'/60\" value=\"1\">1</value>\n </unit>\n <unit Code=\"l\" CODE=\"L\" isMetric=\"yes\" class=\"iso1000\">\n <name>liter</name>\n <printSymbol>l</printSymbol>\n <property>volume</property>\n <value Unit=\"dm3\" UNIT=\"DM3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"L\" CODE=\"L\" isMetric=\"yes\" class=\"iso1000\">\n <name>liter</name>\n <printSymbol>L</printSymbol>\n <property>volume</property>\n <value Unit=\"l\" UNIT=\"L\" value=\"1\">1</value>\n </unit>\n <unit Code=\"ar\" CODE=\"AR\" isMetric=\"yes\" class=\"iso1000\">\n <name>are</name>\n <printSymbol>a</printSymbol>\n <property>area</property>\n <value Unit=\"m2\" UNIT=\"M2\" value=\"100\">100</value>\n </unit>\n <unit Code=\"min\" CODE=\"MIN\" isMetric=\"no\" class=\"iso1000\">\n <name>minute</name>\n <printSymbol>min</printSymbol>\n <property>time</property>\n <value Unit=\"s\" UNIT=\"S\" value=\"60\">60</value>\n </unit>\n <unit Code=\"h\" CODE=\"HR\" isMetric=\"no\" class=\"iso1000\">\n <name>hour</name>\n <printSymbol>h</printSymbol>\n <property>time</property>\n <value Unit=\"min\" UNIT=\"MIN\" value=\"60\">60</value>\n </unit>\n <unit Code=\"d\" CODE=\"D\" isMetric=\"no\" class=\"iso1000\">\n <name>day</name>\n <printSymbol>d</printSymbol>\n <property>time</property>\n <value Unit=\"h\" UNIT=\"HR\" value=\"24\">24</value>\n </unit>\n <unit Code=\"a_t\" CODE=\"ANN_T\" isMetric=\"no\" class=\"iso1000\">\n <name>tropical year</name>\n <printSymbol>a<sub>t</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"d\" UNIT=\"D\" value=\"365.24219\">365.24219</value>\n </unit>\n <unit Code=\"a_j\" CODE=\"ANN_J\" isMetric=\"no\" class=\"iso1000\">\n <name>mean Julian year</name>\n <printSymbol>a<sub>j</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"d\" UNIT=\"D\" value=\"365.25\">365.25</value>\n </unit>\n <unit Code=\"a_g\" CODE=\"ANN_G\" isMetric=\"no\" class=\"iso1000\">\n <name>mean Gregorian year</name>\n <printSymbol>a<sub>g</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"d\" UNIT=\"D\" value=\"365.2425\">365.2425</value>\n </unit>\n <unit Code=\"a\" CODE=\"ANN\" isMetric=\"no\" class=\"iso1000\">\n <name>year</name>\n <printSymbol>a</printSymbol>\n <property>time</property>\n <value Unit=\"a_j\" UNIT=\"ANN_J\" value=\"1\">1</value>\n </unit>\n <unit Code=\"wk\" CODE=\"WK\" isMetric=\"no\" class=\"iso1000\">\n <name>week</name>\n <printSymbol>wk</printSymbol>\n <property>time</property>\n <value Unit=\"d\" UNIT=\"D\" value=\"7\">7</value>\n </unit>\n <unit Code=\"mo_s\" CODE=\"MO_S\" isMetric=\"no\" class=\"iso1000\">\n <name>synodal month</name>\n <printSymbol>mo<sub>s</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"d\" UNIT=\"D\" value=\"29.53059\">29.53059</value>\n </unit>\n <unit Code=\"mo_j\" CODE=\"MO_J\" isMetric=\"no\" class=\"iso1000\">\n <name>mean Julian month</name>\n <printSymbol>mo<sub>j</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"a_j/12\" UNIT=\"ANN_J/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"mo_g\" CODE=\"MO_G\" isMetric=\"no\" class=\"iso1000\">\n <name>mean Gregorian month</name>\n <printSymbol>mo<sub>g</sub>\n </printSymbol>\n <property>time</property>\n <value Unit=\"a_g/12\" UNIT=\"ANN_G/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"mo\" CODE=\"MO\" isMetric=\"no\" class=\"iso1000\">\n <name>month</name>\n <printSymbol>mo</printSymbol>\n <property>time</property>\n <value Unit=\"mo_j\" UNIT=\"MO_J\" value=\"1\">1</value>\n </unit>\n <unit Code=\"t\" CODE=\"TNE\" isMetric=\"yes\" class=\"iso1000\">\n <name>tonne</name>\n <printSymbol>t</printSymbol>\n <property>mass</property>\n <value Unit=\"kg\" UNIT=\"KG\" value=\"1e3\">1 &#215; 10<sup>3</sup>\n </value>\n </unit>\n <unit Code=\"bar\" CODE=\"BAR\" isMetric=\"yes\" class=\"iso1000\">\n <name>bar</name>\n <printSymbol>bar</printSymbol>\n <property>pressure</property>\n <value Unit=\"Pa\" UNIT=\"PAL\" value=\"1e5\">1 &#215; 10<sup>5</sup>\n </value>\n </unit>\n <unit Code=\"u\" CODE=\"AMU\" isMetric=\"yes\" class=\"iso1000\">\n <name>unified atomic mass unit</name>\n <printSymbol>u</printSymbol>\n <property>mass</property>\n <value Unit=\"g\" UNIT=\"G\" value=\"1.66053906660e-24\">1.66053906660 &#215; 10<sup>-24</sup>\n </value>\n </unit>\n <unit Code=\"eV\" CODE=\"EV\" isMetric=\"yes\" class=\"iso1000\">\n <name>electronvolt</name>\n <printSymbol>eV</printSymbol>\n <property>energy</property>\n <value Unit=\"[e].V\" UNIT=\"[E].V\" value=\"1\">1</value>\n </unit>\n <unit Code=\"AU\" CODE=\"ASU\" isMetric=\"no\" class=\"iso1000\">\n <name>astronomic unit</name>\n <printSymbol>AU</printSymbol>\n <property>length</property>\n <value Unit=\"Mm\" UNIT=\"MAM\" value=\"149597.870691\">149597.870691</value>\n </unit>\n <unit Code=\"pc\" CODE=\"PRS\" isMetric=\"yes\" class=\"iso1000\">\n <name>parsec</name>\n <printSymbol>pc</printSymbol>\n <property>length</property>\n <value Unit=\"m\" UNIT=\"M\" value=\"3.085678e16\">3.085678 &#215; 10<sup>16</sup>\n </value>\n </unit>\n <unit Code=\"[c]\" CODE=\"[C]\" isMetric=\"yes\" class=\"const\">\n <name>velocity of light</name>\n <printSymbol>\n <i>c</i>\n </printSymbol>\n <property>velocity</property>\n <value Unit=\"m/s\" UNIT=\"M/S\" value=\"299792458\">299792458</value>\n </unit>\n <unit Code=\"[h]\" CODE=\"[H]\" isMetric=\"yes\" class=\"const\">\n <name>Planck constant</name>\n <printSymbol>\n <i>h</i>\n </printSymbol>\n <property>action</property>\n <value Unit=\"J.s\" UNIT=\"J.S\" value=\"6.62607015e-34\">6.62607015 &#215; 10<sup>-34</sup>\n </value>\n </unit>\n <unit Code=\"[k]\" CODE=\"[K]\" isMetric=\"yes\" class=\"const\">\n <name>Boltzmann constant</name>\n <printSymbol>\n <i>k</i>\n </printSymbol>\n <property>(unclassified)</property>\n <value Unit=\"J/K\" UNIT=\"J/K\" value=\"1.380649e-23\">1.380649 &#215; 10<sup>-23</sup>\n </value>\n </unit>\n <unit Code=\"[eps_0]\" CODE=\"[EPS_0]\" isMetric=\"yes\" class=\"const\">\n <name>permittivity of vacuum</name>\n <printSymbol>\n <i>&#949;<sub>\n <r>0</r>\n </sub>\n </i>\n </printSymbol>\n <property>electric permittivity</property>\n <value Unit=\"F/m\" UNIT=\"F/M\" value=\"8.854187817e-12\">8.854187817 &#215; 10<sup>-12</sup>\n </value>\n </unit>\n <unit Code=\"[mu_0]\" CODE=\"[MU_0]\" isMetric=\"yes\" class=\"const\">\n <name>permeability of vacuum</name>\n <printSymbol>\n <i>&#956;<sub>\n <r>0</r>\n </sub>\n </i>\n </printSymbol>\n <property>magnetic permeability</property>\n <value Unit=\"4.[pi].10*-7.N/A2\" UNIT=\"4.[PI].10*-7.N/A2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[e]\" CODE=\"[E]\" isMetric=\"yes\" class=\"const\">\n <name>elementary charge</name>\n <printSymbol>\n <i>e</i>\n </printSymbol>\n <property>electric charge</property>\n <value Unit=\"C\" UNIT=\"C\" value=\"1.602176634e-19\">1.602176634 &#215; 10<sup>-19</sup>\n </value>\n </unit>\n <unit Code=\"[m_e]\" CODE=\"[M_E]\" isMetric=\"yes\" class=\"const\">\n <name>electron mass</name>\n <printSymbol>\n <i>m<sub>\n <r>e</r>\n </sub>\n </i>\n </printSymbol>\n <property>mass</property>\n <value Unit=\"kg\" UNIT=\"kg\" value=\"9.1093837139e-31\">9.1093837139 &#215; 10<sup>-31</sup>\n </value>\n </unit>\n <unit Code=\"[m_p]\" CODE=\"[M_P]\" isMetric=\"yes\" class=\"const\">\n <name>proton mass</name>\n <printSymbol>\n <i>m<sub>\n <r>p</r>\n </sub>\n </i>\n </printSymbol>\n <property>mass</property>\n <value Unit=\"kg\" UNIT=\"kg\" value=\"1.67262192595e-27\">1.67262192595 &#215; 10<sup>-27</sup>\n </value>\n </unit>\n <unit Code=\"[G]\" CODE=\"[GC]\" isMetric=\"yes\" class=\"const\">\n <name>Newtonian constant of gravitation</name>\n <printSymbol>\n <i>G</i>\n </printSymbol>\n <property>(unclassified)</property>\n <value Unit=\"m3.kg-1.s-2\" UNIT=\"M3.KG-1.S-2\" value=\"6.67430e-11\">6.67430 &#215; 10<sup>-11</sup>\n </value>\n </unit>\n <unit Code=\"[g]\" CODE=\"[G]\" isMetric=\"yes\" class=\"const\">\n <name>standard acceleration of free fall</name>\n <printSymbol>\n <i>g<sub>n</sub>\n </i>\n </printSymbol>\n <property>acceleration</property>\n <value Unit=\"m/s2\" UNIT=\"M/S2\" value=\"980665e-5\">9.80665</value>\n </unit>\n <unit Code=\"atm\" CODE=\"ATM\" isMetric=\"no\" class=\"const\">\n <name>standard atmosphere</name>\n <printSymbol>atm</printSymbol>\n <property>pressure</property>\n <value Unit=\"Pa\" UNIT=\"PAL\" value=\"101325\">101325</value>\n </unit>\n <unit Code=\"[ly]\" CODE=\"[LY]\" isMetric=\"yes\" class=\"const\">\n <name>light-year</name>\n <printSymbol>l.y.</printSymbol>\n <property>length</property>\n <value Unit=\"[c].a_j\" UNIT=\"[C].ANN_J\" value=\"1\">1</value>\n </unit>\n <unit Code=\"gf\" CODE=\"GF\" isMetric=\"yes\" class=\"const\">\n <name>gram-force</name>\n <printSymbol>gf</printSymbol>\n <property>force</property>\n <value Unit=\"g.[g]\" UNIT=\"G.[G]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[lbf_av]\" CODE=\"[LBF_AV]\" isMetric=\"no\" class=\"const\">\n <name>pound force</name>\n <printSymbol>lbf</printSymbol>\n <property>force</property>\n <value Unit=\"[lb_av].[g]\" UNIT=\"[LB_AV].[G]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Ky\" CODE=\"KY\" isMetric=\"yes\" class=\"cgs\">\n <name>Kayser</name>\n <printSymbol>K</printSymbol>\n <property>lineic number</property>\n <value Unit=\"cm-1\" UNIT=\"CM-1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Gal\" CODE=\"GL\" isMetric=\"yes\" class=\"cgs\">\n <name>Gal</name>\n <printSymbol>Gal</printSymbol>\n <property>acceleration</property>\n <value Unit=\"cm/s2\" UNIT=\"CM/S2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"dyn\" CODE=\"DYN\" isMetric=\"yes\" class=\"cgs\">\n <name>dyne</name>\n <printSymbol>dyn</printSymbol>\n <property>force</property>\n <value Unit=\"g.cm/s2\" UNIT=\"G.CM/S2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"erg\" CODE=\"ERG\" isMetric=\"yes\" class=\"cgs\">\n <name>erg</name>\n <printSymbol>erg</printSymbol>\n <property>energy</property>\n <value Unit=\"dyn.cm\" UNIT=\"DYN.CM\" value=\"1\">1</value>\n </unit>\n <unit Code=\"P\" CODE=\"P\" isMetric=\"yes\" class=\"cgs\">\n <name>Poise</name>\n <printSymbol>P</printSymbol>\n <property>dynamic viscosity</property>\n <value Unit=\"dyn.s/cm2\" UNIT=\"DYN.S/CM2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Bi\" CODE=\"BI\" isMetric=\"yes\" class=\"cgs\">\n <name>Biot</name>\n <printSymbol>Bi</printSymbol>\n <property>electric current</property>\n <value Unit=\"A\" UNIT=\"A\" value=\"10\">10</value>\n </unit>\n <unit Code=\"St\" CODE=\"ST\" isMetric=\"yes\" class=\"cgs\">\n <name>Stokes</name>\n <printSymbol>St</printSymbol>\n <property>kinematic viscosity</property>\n <value Unit=\"cm2/s\" UNIT=\"CM2/S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Mx\" CODE=\"MX\" isMetric=\"yes\" class=\"cgs\">\n <name>Maxwell</name>\n <printSymbol>Mx</printSymbol>\n <property>flux of magnetic induction</property>\n <value Unit=\"Wb\" UNIT=\"WB\" value=\"1e-8\">1 &#215; 10<sup>-8</sup>\n </value>\n </unit>\n <unit Code=\"G\" CODE=\"GS\" isMetric=\"yes\" class=\"cgs\">\n <name>Gauss</name>\n <printSymbol>Gs</printSymbol>\n <property>magnetic flux density</property>\n <value Unit=\"T\" UNIT=\"T\" value=\"1e-4\">1 &#215; 10<sup>-4</sup>\n </value>\n </unit>\n <unit Code=\"Oe\" CODE=\"OE\" isMetric=\"yes\" class=\"cgs\">\n <name>Oersted</name>\n <printSymbol>Oe</printSymbol>\n <property>magnetic field intensity</property>\n <value Unit=\"/[pi].A/m\" UNIT=\"/[PI].A/M\" value=\"250\">250</value>\n </unit>\n <unit Code=\"Gb\" CODE=\"GB\" isMetric=\"yes\" class=\"cgs\">\n <name>Gilbert</name>\n <printSymbol>Gb</printSymbol>\n <property>magnetic tension</property>\n <value Unit=\"Oe.cm\" UNIT=\"OE.CM\" value=\"1\">1</value>\n </unit>\n <unit Code=\"sb\" CODE=\"SB\" isMetric=\"yes\" class=\"cgs\">\n <name>stilb</name>\n <printSymbol>sb</printSymbol>\n <property>lum. intensity density</property>\n <value Unit=\"cd/cm2\" UNIT=\"CD/CM2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Lmb\" CODE=\"LMB\" isMetric=\"yes\" class=\"cgs\">\n <name>Lambert</name>\n <printSymbol>L</printSymbol>\n <property>brightness</property>\n <value Unit=\"cd/cm2/[pi]\" UNIT=\"CD/CM2/[PI]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"ph\" CODE=\"PHT\" isMetric=\"yes\" class=\"cgs\">\n <name>phot</name>\n <printSymbol>ph</printSymbol>\n <property>illuminance</property>\n <value Unit=\"lx\" UNIT=\"LX\" value=\"1e-4\">1 &#215; 10<sup>-4</sup>\n </value>\n </unit>\n <unit Code=\"Ci\" CODE=\"CI\" isMetric=\"yes\" class=\"cgs\">\n <name>Curie</name>\n <printSymbol>Ci</printSymbol>\n <property>radioactivity</property>\n <value Unit=\"Bq\" UNIT=\"BQ\" value=\"37e9\">3.7 &#215; 10<sup>10</sup>\n </value>\n </unit>\n <unit Code=\"R\" CODE=\"ROE\" isMetric=\"yes\" class=\"cgs\">\n <name>Roentgen</name>\n <printSymbol>R</printSymbol>\n <property>ion dose</property>\n <value Unit=\"C/kg\" UNIT=\"C/KG\" value=\"2.58e-4\">2.58 &#215; 10<sup>-4</sup>\n </value>\n </unit>\n <unit Code=\"RAD\" CODE=\"[RAD]\" isMetric=\"yes\" class=\"cgs\">\n <name>radiation absorbed dose</name>\n <printSymbol>RAD</printSymbol>\n <property>energy dose</property>\n <value Unit=\"erg/g\" UNIT=\"ERG/G\" value=\"100\">100</value>\n </unit>\n <unit Code=\"REM\" CODE=\"[REM]\" isMetric=\"yes\" class=\"cgs\">\n <name>radiation equivalent man</name>\n <printSymbol>REM</printSymbol>\n <property>dose equivalent</property>\n <value Unit=\"RAD\" UNIT=\"[RAD]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[in_i]\" CODE=\"[IN_I]\" isMetric=\"no\" class=\"intcust\">\n <name>inch</name>\n <printSymbol>in</printSymbol>\n <property>length</property>\n <value Unit=\"cm\" UNIT=\"CM\" value=\"254e-2\">2.54</value>\n </unit>\n <unit Code=\"[ft_i]\" CODE=\"[FT_I]\" isMetric=\"no\" class=\"intcust\">\n <name>foot</name>\n <printSymbol>ft</printSymbol>\n <property>length</property>\n <value Unit=\"[in_i]\" UNIT=\"[IN_I]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[yd_i]\" CODE=\"[YD_I]\" isMetric=\"no\" class=\"intcust\">\n <name>yard</name>\n <printSymbol>yd</printSymbol>\n <property>length</property>\n <value Unit=\"[ft_i]\" UNIT=\"[FT_I]\" value=\"3\">3</value>\n </unit>\n <unit Code=\"[mi_i]\" CODE=\"[MI_I]\" isMetric=\"no\" class=\"intcust\">\n <name>mile</name>\n <printSymbol>mi</printSymbol>\n <property>length</property>\n <value Unit=\"[ft_i]\" UNIT=\"[FT_I]\" value=\"5280\">5280</value>\n </unit>\n <unit Code=\"[fth_i]\" CODE=\"[FTH_I]\" isMetric=\"no\" class=\"intcust\">\n <name>fathom</name>\n <printSymbol>fth</printSymbol>\n <property>depth of water</property>\n <value Unit=\"[ft_i]\" UNIT=\"[FT_I]\" value=\"6\">6</value>\n </unit>\n <unit Code=\"[nmi_i]\" CODE=\"[NMI_I]\" isMetric=\"no\" class=\"intcust\">\n <name>nautical mile</name>\n <printSymbol>n.mi</printSymbol>\n <property>length</property>\n <value Unit=\"m\" UNIT=\"M\" value=\"1852\">1852</value>\n </unit>\n <unit Code=\"[kn_i]\" CODE=\"[KN_I]\" isMetric=\"no\" class=\"intcust\">\n <name>knot</name>\n <printSymbol>knot</printSymbol>\n <property>velocity</property>\n <value Unit=\"[nmi_i]/h\" UNIT=\"[NMI_I]/H\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[sin_i]\" CODE=\"[SIN_I]\" isMetric=\"no\" class=\"intcust\">\n <name>square inch</name>\n <property>area</property>\n <value Unit=\"[in_i]2\" UNIT=\"[IN_I]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[sft_i]\" CODE=\"[SFT_I]\" isMetric=\"no\" class=\"intcust\">\n <name>square foot</name>\n <property>area</property>\n <value Unit=\"[ft_i]2\" UNIT=\"[FT_I]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[syd_i]\" CODE=\"[SYD_I]\" isMetric=\"no\" class=\"intcust\">\n <name>square yard</name>\n <property>area</property>\n <value Unit=\"[yd_i]2\" UNIT=\"[YD_I]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[cin_i]\" CODE=\"[CIN_I]\" isMetric=\"no\" class=\"intcust\">\n <name>cubic inch</name>\n <property>volume</property>\n <value Unit=\"[in_i]3\" UNIT=\"[IN_I]3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[cft_i]\" CODE=\"[CFT_I]\" isMetric=\"no\" class=\"intcust\">\n <name>cubic foot</name>\n <property>volume</property>\n <value Unit=\"[ft_i]3\" UNIT=\"[FT_I]3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[cyd_i]\" CODE=\"[CYD_I]\" isMetric=\"no\" class=\"intcust\">\n <name>cubic yard</name>\n <printSymbol>cu.yd</printSymbol>\n <property>volume</property>\n <value Unit=\"[yd_i]3\" UNIT=\"[YD_I]3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[bf_i]\" CODE=\"[BF_I]\" isMetric=\"no\" class=\"intcust\">\n <name>board foot</name>\n <property>volume</property>\n <value Unit=\"[in_i]3\" UNIT=\"[IN_I]3\" value=\"144\">144</value>\n </unit>\n <unit Code=\"[cr_i]\" CODE=\"[CR_I]\" isMetric=\"no\" class=\"intcust\">\n <name>cord</name>\n <property>volume</property>\n <value Unit=\"[ft_i]3\" UNIT=\"[FT_I]3\" value=\"128\">128</value>\n </unit>\n <unit Code=\"[mil_i]\" CODE=\"[MIL_I]\" isMetric=\"no\" class=\"intcust\">\n <name>mil</name>\n <printSymbol>mil</printSymbol>\n <property>length</property>\n <value Unit=\"[in_i]\" UNIT=\"[IN_I]\" value=\"1e-3\">1 &#215; 10<sup>-3</sup>\n </value>\n </unit>\n <unit Code=\"[cml_i]\" CODE=\"[CML_I]\" isMetric=\"no\" class=\"intcust\">\n <name>circular mil</name>\n <printSymbol>circ.mil</printSymbol>\n <property>area</property>\n <value Unit=\"[pi]/4.[mil_i]2\" UNIT=\"[PI]/4.[MIL_I]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[hd_i]\" CODE=\"[HD_I]\" isMetric=\"no\" class=\"intcust\">\n <name>hand</name>\n <printSymbol>hd</printSymbol>\n <property>height of horses</property>\n <value Unit=\"[in_i]\" UNIT=\"[IN_I]\" value=\"4\">4</value>\n </unit>\n <unit Code=\"[ft_us]\" CODE=\"[FT_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>foot</name>\n <printSymbol>ft<sub>us</sub>\n </printSymbol>\n <property>length</property>\n <value Unit=\"m/3937\" UNIT=\"M/3937\" value=\"1200\">1200</value>\n </unit>\n <unit Code=\"[yd_us]\" CODE=\"[YD_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>yard</name>\n <property>length</property>\n <value Unit=\"[ft_us]\" UNIT=\"[FT_US]\" value=\"3\">3</value>\n </unit>\n <unit Code=\"[in_us]\" CODE=\"[IN_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>inch</name>\n <property>length</property>\n <value Unit=\"[ft_us]/12\" UNIT=\"[FT_US]/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[rd_us]\" CODE=\"[RD_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>rod</name>\n <property>length</property>\n <value Unit=\"[ft_us]\" UNIT=\"[FT_US]\" value=\"16.5\">16.5</value>\n </unit>\n <unit Code=\"[ch_us]\" CODE=\"[CH_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>Gunter's chain</name>\n <name>Surveyor's chain</name>\n <property>length</property>\n <value Unit=\"[rd_us]\" UNIT=\"[RD_US]\" value=\"4\">4</value>\n </unit>\n <unit Code=\"[lk_us]\" CODE=\"[LK_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>link for Gunter's chain</name>\n <property>length</property>\n <value Unit=\"[ch_us]/100\" UNIT=\"[CH_US]/100\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[rch_us]\" CODE=\"[RCH_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>Ramden's chain</name>\n <name>Engineer's chain</name>\n <property>length</property>\n <value Unit=\"[ft_us]\" UNIT=\"[FT_US]\" value=\"100\">100</value>\n </unit>\n <unit Code=\"[rlk_us]\" CODE=\"[RLK_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>link for Ramden's chain</name>\n <property>length</property>\n <value Unit=\"[rch_us]/100\" UNIT=\"[RCH_US]/100\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[fth_us]\" CODE=\"[FTH_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>fathom</name>\n <property>length</property>\n <value Unit=\"[ft_us]\" UNIT=\"[FT_US]\" value=\"6\">6</value>\n </unit>\n <unit Code=\"[fur_us]\" CODE=\"[FUR_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>furlong</name>\n <property>length</property>\n <value Unit=\"[rd_us]\" UNIT=\"[RD_US]\" value=\"40\">40</value>\n </unit>\n <unit Code=\"[mi_us]\" CODE=\"[MI_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>mile</name>\n <property>length</property>\n <value Unit=\"[fur_us]\" UNIT=\"[FUR_US]\" value=\"8\">8</value>\n </unit>\n <unit Code=\"[acr_us]\" CODE=\"[ACR_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>acre</name>\n <property>area</property>\n <value Unit=\"[rd_us]2\" UNIT=\"[RD_US]2\" value=\"160\">160</value>\n </unit>\n <unit Code=\"[srd_us]\" CODE=\"[SRD_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>square rod</name>\n <property>area</property>\n <value Unit=\"[rd_us]2\" UNIT=\"[RD_US]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[smi_us]\" CODE=\"[SMI_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>square mile</name>\n <property>area</property>\n <value Unit=\"[mi_us]2\" UNIT=\"[MI_US]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[sct]\" CODE=\"[SCT]\" isMetric=\"no\" class=\"us-lengths\">\n <name>section</name>\n <property>area</property>\n <value Unit=\"[mi_us]2\" UNIT=\"[MI_US]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[twp]\" CODE=\"[TWP]\" isMetric=\"no\" class=\"us-lengths\">\n <name>township</name>\n <property>area</property>\n <value Unit=\"[sct]\" UNIT=\"[SCT]\" value=\"36\">36</value>\n </unit>\n <unit Code=\"[mil_us]\" CODE=\"[MIL_US]\" isMetric=\"no\" class=\"us-lengths\">\n <name>mil</name>\n <property>length</property>\n <value Unit=\"[in_us]\" UNIT=\"[IN_US]\" value=\"1e-3\">1 &#215; 10<sup>-3</sup>\n </value>\n </unit>\n <unit Code=\"[in_br]\" CODE=\"[IN_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>inch</name>\n <property>length</property>\n <value Unit=\"cm\" UNIT=\"CM\" value=\"2.539998\">2.539998</value>\n </unit>\n <unit Code=\"[ft_br]\" CODE=\"[FT_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>foot</name>\n <property>length</property>\n <value Unit=\"[in_br]\" UNIT=\"[IN_BR]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[rd_br]\" CODE=\"[RD_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>rod</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"16.5\">16.5</value>\n </unit>\n <unit Code=\"[ch_br]\" CODE=\"[CH_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>Gunter's chain</name>\n <property>length</property>\n <value Unit=\"[rd_br]\" UNIT=\"[RD_BR]\" value=\"4\">4</value>\n </unit>\n <unit Code=\"[lk_br]\" CODE=\"[LK_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>link for Gunter's chain</name>\n <property>length</property>\n <value Unit=\"[ch_br]/100\" UNIT=\"[CH_BR]/100\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[fth_br]\" CODE=\"[FTH_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>fathom</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"6\">6</value>\n </unit>\n <unit Code=\"[pc_br]\" CODE=\"[PC_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>pace</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"2.5\">2.5</value>\n </unit>\n <unit Code=\"[yd_br]\" CODE=\"[YD_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>yard</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"3\">3</value>\n </unit>\n <unit Code=\"[mi_br]\" CODE=\"[MI_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>mile</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"5280\">5280</value>\n </unit>\n <unit Code=\"[nmi_br]\" CODE=\"[NMI_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>nautical mile</name>\n <property>length</property>\n <value Unit=\"[ft_br]\" UNIT=\"[FT_BR]\" value=\"6080\">6080</value>\n </unit>\n <unit Code=\"[kn_br]\" CODE=\"[KN_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>knot</name>\n <property>velocity</property>\n <value Unit=\"[nmi_br]/h\" UNIT=\"[NMI_BR]/H\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[acr_br]\" CODE=\"[ACR_BR]\" isMetric=\"no\" class=\"brit-length\">\n <name>acre</name>\n <property>area</property>\n <value Unit=\"[yd_br]2\" UNIT=\"[YD_BR]2\" value=\"4840\">4840</value>\n </unit>\n <unit Code=\"[gal_us]\" CODE=\"[GAL_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>Queen&#160;Anne's wine gallon</name>\n <property>fluid volume</property>\n <value Unit=\"[in_i]3\" UNIT=\"[IN_I]3\" value=\"231\">231</value>\n </unit>\n <unit Code=\"[bbl_us]\" CODE=\"[BBL_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>barrel</name>\n <property>fluid volume</property>\n <value Unit=\"[gal_us]\" UNIT=\"[GAL_US]\" value=\"42\">42</value>\n </unit>\n <unit Code=\"[qt_us]\" CODE=\"[QT_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>quart</name>\n <property>fluid volume</property>\n <value Unit=\"[gal_us]/4\" UNIT=\"[GAL_US]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pt_us]\" CODE=\"[PT_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>pint</name>\n <property>fluid volume</property>\n <value Unit=\"[qt_us]/2\" UNIT=\"[QT_US]/2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[gil_us]\" CODE=\"[GIL_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>gill</name>\n <property>fluid volume</property>\n <value Unit=\"[pt_us]/4\" UNIT=\"[PT_US]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[foz_us]\" CODE=\"[FOZ_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>fluid ounce</name>\n <printSymbol>oz fl</printSymbol>\n <property>fluid volume</property>\n <value Unit=\"[gil_us]/4\" UNIT=\"[GIL_US]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[fdr_us]\" CODE=\"[FDR_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>fluid dram</name>\n <property>fluid volume</property>\n <value Unit=\"[foz_us]/8\" UNIT=\"[FOZ_US]/8\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[min_us]\" CODE=\"[MIN_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>minim</name>\n <property>fluid volume</property>\n <value Unit=\"[fdr_us]/60\" UNIT=\"[FDR_US]/60\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[crd_us]\" CODE=\"[CRD_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>cord</name>\n <property>fluid volume</property>\n <value Unit=\"[ft_i]3\" UNIT=\"[FT_I]3\" value=\"128\">128</value>\n </unit>\n <unit Code=\"[bu_us]\" CODE=\"[BU_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>bushel</name>\n <property>dry volume</property>\n <value Unit=\"[in_i]3\" UNIT=\"[IN_I]3\" value=\"2150.42\">2150.42</value>\n </unit>\n <unit Code=\"[gal_wi]\" CODE=\"[GAL_WI]\" isMetric=\"no\" class=\"us-volumes\">\n <name>historical winchester gallon</name>\n <property>dry volume</property>\n <value Unit=\"[bu_us]/8\" UNIT=\"[BU_US]/8\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pk_us]\" CODE=\"[PK_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>peck</name>\n <property>dry volume</property>\n <value Unit=\"[bu_us]/4\" UNIT=\"[BU_US]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[dqt_us]\" CODE=\"[DQT_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>dry quart</name>\n <property>dry volume</property>\n <value Unit=\"[pk_us]/8\" UNIT=\"[PK_US]/8\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[dpt_us]\" CODE=\"[DPT_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>dry pint</name>\n <property>dry volume</property>\n <value Unit=\"[dqt_us]/2\" UNIT=\"[DQT_US]/2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[tbs_us]\" CODE=\"[TBS_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>tablespoon</name>\n <property>volume</property>\n <value Unit=\"[foz_us]/2\" UNIT=\"[FOZ_US]/2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[tsp_us]\" CODE=\"[TSP_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>teaspoon</name>\n <property>volume</property>\n <value Unit=\"[tbs_us]/3\" UNIT=\"[TBS_US]/3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[cup_us]\" CODE=\"[CUP_US]\" isMetric=\"no\" class=\"us-volumes\">\n <name>cup</name>\n <property>volume</property>\n <value Unit=\"[tbs_us]\" UNIT=\"[TBS_US]\" value=\"16\">16</value>\n </unit>\n <unit Code=\"[foz_m]\" CODE=\"[FOZ_M]\" isMetric=\"no\" class=\"us-volumes\">\n <name>metric fluid ounce</name>\n <printSymbol>oz fl</printSymbol>\n <property>fluid volume</property>\n <value Unit=\"mL\" UNIT=\"ML\" value=\"30\">30</value>\n </unit>\n <unit Code=\"[cup_m]\" CODE=\"[CUP_M]\" isMetric=\"no\" class=\"us-volumes\">\n <name>metric cup</name>\n <property>volume</property>\n <value Unit=\"mL\" UNIT=\"ML\" value=\"240\">240</value>\n </unit>\n <unit Code=\"[tsp_m]\" CODE=\"[TSP_M]\" isMetric=\"no\" class=\"us-volumes\">\n <name>metric teaspoon</name>\n <property>volume</property>\n <value Unit=\"mL\" UNIT=\"mL\" value=\"5\">5</value>\n </unit>\n <unit Code=\"[tbs_m]\" CODE=\"[TBS_M]\" isMetric=\"no\" class=\"us-volumes\">\n <name>metric tablespoon</name>\n <property>volume</property>\n <value Unit=\"mL\" UNIT=\"mL\" value=\"15\">15</value>\n </unit>\n <unit Code=\"[gal_br]\" CODE=\"[GAL_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>gallon</name>\n <property>volume</property>\n <value Unit=\"l\" UNIT=\"L\" value=\"4.54609\">4.54609</value>\n </unit>\n <unit Code=\"[pk_br]\" CODE=\"[PK_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>peck</name>\n <property>volume</property>\n <value Unit=\"[gal_br]\" UNIT=\"[GAL_BR]\" value=\"2\">2</value>\n </unit>\n <unit Code=\"[bu_br]\" CODE=\"[BU_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>bushel</name>\n <property>volume</property>\n <value Unit=\"[pk_br]\" UNIT=\"[PK_BR]\" value=\"4\">4</value>\n </unit>\n <unit Code=\"[qt_br]\" CODE=\"[QT_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>quart</name>\n <property>volume</property>\n <value Unit=\"[gal_br]/4\" UNIT=\"[GAL_BR]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pt_br]\" CODE=\"[PT_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>pint</name>\n <property>volume</property>\n <value Unit=\"[qt_br]/2\" UNIT=\"[QT_BR]/2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[gil_br]\" CODE=\"[GIL_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>gill</name>\n <property>volume</property>\n <value Unit=\"[pt_br]/4\" UNIT=\"[PT_BR]/4\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[foz_br]\" CODE=\"[FOZ_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>fluid ounce</name>\n <property>volume</property>\n <value Unit=\"[gil_br]/5\" UNIT=\"[GIL_BR]/5\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[fdr_br]\" CODE=\"[FDR_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>fluid dram</name>\n <property>volume</property>\n <value Unit=\"[foz_br]/8\" UNIT=\"[FOZ_BR]/8\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[min_br]\" CODE=\"[MIN_BR]\" isMetric=\"no\" class=\"brit-volumes\">\n <name>minim</name>\n <property>volume</property>\n <value Unit=\"[fdr_br]/60\" UNIT=\"[FDR_BR]/60\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[gr]\" CODE=\"[GR]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>grain</name>\n <property>mass</property>\n <value Unit=\"mg\" UNIT=\"MG\" value=\"64.79891\">64.79891</value>\n </unit>\n <unit Code=\"[lb_av]\" CODE=\"[LB_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>pound</name>\n <printSymbol>lb</printSymbol>\n <property>mass</property>\n <value Unit=\"[gr]\" UNIT=\"[GR]\" value=\"7000\">7000</value>\n </unit>\n <unit Code=\"[oz_av]\" CODE=\"[OZ_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>ounce</name>\n <printSymbol>oz</printSymbol>\n <property>mass</property>\n <value Unit=\"[lb_av]/16\" UNIT=\"[LB_AV]/16\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[dr_av]\" CODE=\"[DR_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>dram</name>\n <property>mass</property>\n <value Unit=\"[oz_av]/16\" UNIT=\"[OZ_AV]/16\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[scwt_av]\" CODE=\"[SCWT_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>short hundredweight</name>\n <name>U.S. hundredweight</name>\n <property>mass</property>\n <value Unit=\"[lb_av]\" UNIT=\"[LB_AV]\" value=\"100\">100</value>\n </unit>\n <unit Code=\"[lcwt_av]\" CODE=\"[LCWT_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>long hundredweight</name>\n <name>British hundredweight</name>\n <property>mass</property>\n <value Unit=\"[lb_av]\" UNIT=\"[LB_AV]\" value=\"112\">112</value>\n </unit>\n <unit Code=\"[ston_av]\" CODE=\"[STON_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>short ton</name>\n <name>U.S. ton</name>\n <property>mass</property>\n <value Unit=\"[scwt_av]\" UNIT=\"[SCWT_AV]\" value=\"20\">20</value>\n </unit>\n <unit Code=\"[lton_av]\" CODE=\"[LTON_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>long ton</name>\n <name>British ton</name>\n <property>mass</property>\n <value Unit=\"[lcwt_av]\" UNIT=\"[LCWT_AV]\" value=\"20\">20</value>\n </unit>\n <unit Code=\"[stone_av]\" CODE=\"[STONE_AV]\" isMetric=\"no\" class=\"avoirdupois\">\n <name>stone</name>\n <name>British stone</name>\n <property>mass</property>\n <value Unit=\"[lb_av]\" UNIT=\"[LB_AV]\" value=\"14\">14</value>\n </unit>\n <unit Code=\"[pwt_tr]\" CODE=\"[PWT_TR]\" isMetric=\"no\" class=\"troy\">\n <name>pennyweight</name>\n <property>mass</property>\n <value Unit=\"[gr]\" UNIT=\"[GR]\" value=\"24\">24</value>\n </unit>\n <unit Code=\"[oz_tr]\" CODE=\"[OZ_TR]\" isMetric=\"no\" class=\"troy\">\n <name>ounce</name>\n <property>mass</property>\n <value Unit=\"[pwt_tr]\" UNIT=\"[PWT_TR]\" value=\"20\">20</value>\n </unit>\n <unit Code=\"[lb_tr]\" CODE=\"[LB_TR]\" isMetric=\"no\" class=\"troy\">\n <name>pound</name>\n <property>mass</property>\n <value Unit=\"[oz_tr]\" UNIT=\"[OZ_TR]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[sc_ap]\" CODE=\"[SC_AP]\" isMetric=\"no\" class=\"apoth\">\n <name>scruple</name>\n <property>mass</property>\n <value Unit=\"[gr]\" UNIT=\"[GR]\" value=\"20\">20</value>\n </unit>\n <unit Code=\"[dr_ap]\" CODE=\"[DR_AP]\" isMetric=\"no\" class=\"apoth\">\n <name>dram</name>\n <name>drachm</name>\n <property>mass</property>\n <value Unit=\"[sc_ap]\" UNIT=\"[SC_AP]\" value=\"3\">3</value>\n </unit>\n <unit Code=\"[oz_ap]\" CODE=\"[OZ_AP]\" isMetric=\"no\" class=\"apoth\">\n <name>ounce</name>\n <property>mass</property>\n <value Unit=\"[dr_ap]\" UNIT=\"[DR_AP]\" value=\"8\">8</value>\n </unit>\n <unit Code=\"[lb_ap]\" CODE=\"[LB_AP]\" isMetric=\"no\" class=\"apoth\">\n <name>pound</name>\n <property>mass</property>\n <value Unit=\"[oz_ap]\" UNIT=\"[OZ_AP]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[oz_m]\" CODE=\"[OZ_M]\" isMetric=\"no\" class=\"apoth\">\n <name>metric ounce</name>\n <property>mass</property>\n <value Unit=\"g\" UNIT=\"g\" value=\"28\">28</value>\n </unit>\n <unit Code=\"[lne]\" CODE=\"[LNE]\" isMetric=\"no\" class=\"typeset\">\n <name>line</name>\n <property>length</property>\n <value Unit=\"[in_i]/12\" UNIT=\"[IN_I]/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pnt]\" CODE=\"[PNT]\" isMetric=\"no\" class=\"typeset\">\n <name>point</name>\n <property>length</property>\n <value Unit=\"[lne]/6\" UNIT=\"[LNE]/6\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pca]\" CODE=\"[PCA]\" isMetric=\"no\" class=\"typeset\">\n <name>pica</name>\n <property>length</property>\n <value Unit=\"[pnt]\" UNIT=\"[PNT]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[pnt_pr]\" CODE=\"[PNT_PR]\" isMetric=\"no\" class=\"typeset\">\n <name>Printer's point</name>\n <property>length</property>\n <value Unit=\"[in_i]\" UNIT=\"[IN_I]\" value=\"0.013837\">0.013837</value>\n </unit>\n <unit Code=\"[pca_pr]\" CODE=\"[PCA_PR]\" isMetric=\"no\" class=\"typeset\">\n <name>Printer's pica</name>\n <property>length</property>\n <value Unit=\"[pnt_pr]\" UNIT=\"[PNT_PR]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[pied]\" CODE=\"[PIED]\" isMetric=\"no\" class=\"typeset\">\n <name>pied</name>\n <name>French foot</name>\n <property>length</property>\n <value Unit=\"cm\" UNIT=\"CM\" value=\"32.48\">32.48</value>\n </unit>\n <unit Code=\"[pouce]\" CODE=\"[POUCE]\" isMetric=\"no\" class=\"typeset\">\n <name>pouce</name>\n <name>French inch</name>\n <property>length</property>\n <value Unit=\"[pied]/12\" UNIT=\"[PIED]/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ligne]\" CODE=\"[LIGNE]\" isMetric=\"no\" class=\"typeset\">\n <name>ligne</name>\n <name>French line</name>\n <property>length</property>\n <value Unit=\"[pouce]/12\" UNIT=\"[POUCE]/12\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[didot]\" CODE=\"[DIDOT]\" isMetric=\"no\" class=\"typeset\">\n <name>didot</name>\n <name>Didot's point</name>\n <property>length</property>\n <value Unit=\"[ligne]/6\" UNIT=\"[LIGNE]/6\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[cicero]\" CODE=\"[CICERO]\" isMetric=\"no\" class=\"typeset\">\n <name>cicero</name>\n <name>Didot's pica</name>\n <property>length</property>\n <value Unit=\"[didot]\" UNIT=\"[DIDOT]\" value=\"12\">12</value>\n </unit>\n <unit Code=\"[degF]\" CODE=\"[DEGF]\" isMetric=\"no\" isSpecial=\"yes\" class=\"heat\">\n <name>degree Fahrenheit</name>\n <printSymbol>&#176;F</printSymbol>\n <property>temperature</property>\n <value Unit=\"degf(5 K/9)\" UNIT=\"DEGF(5 K/9)\">\n <function name=\"degF\" value=\"5\" Unit=\"K/9\"/>\n </value>\n </unit>\n <unit Code=\"[degR]\" CODE=\"[degR]\" isMetric=\"no\" class=\"heat\">\n <name>degree Rankine</name>\n <printSymbol>&#176;R</printSymbol>\n <property>temperature</property>\n <value value=\"5\" Unit=\"K/9\" UNIT=\"K/9\">5</value>\n </unit>\n <unit Code=\"[degRe]\" CODE=\"[degRe]\" isMetric=\"no\" isSpecial=\"yes\" class=\"heat\">\n <name>degree R&#233;aumur</name>\n <printSymbol>&#176;R&#233;</printSymbol>\n <property>temperature</property>\n <value Unit=\"degre(5 K/4)\" UNIT=\"DEGRE(5 K/4)\">\n <function name=\"degRe\" value=\"5\" Unit=\"K/4\"/>\n </value>\n </unit>\n <unit Code=\"cal_[15]\" CODE=\"CAL_[15]\" isMetric=\"yes\" class=\"heat\">\n <name>calorie at 15&#160;&#176;C</name>\n <printSymbol>cal<sub>15&#176;C</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"J\" UNIT=\"J\" value=\"4.18580\">4.18580</value>\n </unit>\n <unit Code=\"cal_[20]\" CODE=\"CAL_[20]\" isMetric=\"yes\" class=\"heat\">\n <name>calorie at 20&#160;&#176;C</name>\n <printSymbol>cal<sub>20&#176;C</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"J\" UNIT=\"J\" value=\"4.18190\">4.18190</value>\n </unit>\n <unit Code=\"cal_m\" CODE=\"CAL_M\" isMetric=\"yes\" class=\"heat\">\n <name>mean calorie</name>\n <printSymbol>cal<sub>m</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"J\" UNIT=\"J\" value=\"4.19002\">4.19002</value>\n </unit>\n <unit Code=\"cal_IT\" CODE=\"CAL_IT\" isMetric=\"yes\" class=\"heat\">\n <name>international table calorie</name>\n <printSymbol>cal<sub>IT</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"J\" UNIT=\"J\" value=\"4.1868\">4.1868</value>\n </unit>\n <unit Code=\"cal_th\" CODE=\"CAL_TH\" isMetric=\"yes\" class=\"heat\">\n <name>thermochemical calorie</name>\n <printSymbol>cal<sub>th</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"J\" UNIT=\"J\" value=\"4.184\">4.184</value>\n </unit>\n <unit Code=\"cal\" CODE=\"CAL\" isMetric=\"yes\" class=\"heat\">\n <name>calorie</name>\n <printSymbol>cal</printSymbol>\n <property>energy</property>\n <value Unit=\"cal_th\" UNIT=\"CAL_TH\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[Cal]\" CODE=\"[CAL]\" isMetric=\"no\" class=\"heat\">\n <name>nutrition label Calories</name>\n <printSymbol>Cal</printSymbol>\n <property>energy</property>\n <value Unit=\"kcal_th\" UNIT=\"KCAL_TH\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[Btu_39]\" CODE=\"[BTU_39]\" isMetric=\"no\" class=\"heat\">\n <name>British thermal unit at 39&#160;&#176;F</name>\n <printSymbol>Btu<sub>39&#176;F</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.05967\">1.05967</value>\n </unit>\n <unit Code=\"[Btu_59]\" CODE=\"[BTU_59]\" isMetric=\"no\" class=\"heat\">\n <name>British thermal unit at 59&#160;&#176;F</name>\n <printSymbol>Btu<sub>59&#176;F</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.05480\">1.05480</value>\n </unit>\n <unit Code=\"[Btu_60]\" CODE=\"[BTU_60]\" isMetric=\"no\" class=\"heat\">\n <name>British thermal unit at 60&#160;&#176;F</name>\n <printSymbol>Btu<sub>60&#176;F</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.05468\">1.05468</value>\n </unit>\n <unit Code=\"[Btu_m]\" CODE=\"[BTU_M]\" isMetric=\"no\" class=\"heat\">\n <name>mean British thermal unit</name>\n <printSymbol>Btu<sub>m</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.05587\">1.05587</value>\n </unit>\n <unit Code=\"[Btu_IT]\" CODE=\"[BTU_IT]\" isMetric=\"no\" class=\"heat\">\n <name>international table British thermal unit</name>\n <printSymbol>Btu<sub>IT</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.05505585262\">1.05505585262</value>\n </unit>\n <unit Code=\"[Btu_th]\" CODE=\"[BTU_TH]\" isMetric=\"no\" class=\"heat\">\n <name>thermochemical British thermal unit</name>\n <printSymbol>Btu<sub>th</sub>\n </printSymbol>\n <property>energy</property>\n <value Unit=\"kJ\" UNIT=\"kJ\" value=\"1.054350\">1.054350</value>\n </unit>\n <unit Code=\"[Btu]\" CODE=\"[BTU]\" isMetric=\"no\" class=\"heat\">\n <name>British thermal unit</name>\n <printSymbol>btu</printSymbol>\n <property>energy</property>\n <value Unit=\"[Btu_th]\" UNIT=\"[BTU_TH]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[HP]\" CODE=\"[HP]\" isMetric=\"no\" class=\"heat\">\n <name>horsepower</name>\n <property>power</property>\n <value Unit=\"[ft_i].[lbf_av]/s\" UNIT=\"[FT_I].[LBF_AV]/S\" value=\"550\">550</value>\n </unit>\n <unit Code=\"tex\" CODE=\"TEX\" isMetric=\"yes\" class=\"heat\">\n <name>tex</name>\n <printSymbol>tex</printSymbol>\n <property>linear mass density (of textile thread)</property>\n <value value=\"1\" Unit=\"g/km\" UNIT=\"G/KM\">1</value>\n </unit>\n <unit Code=\"[den]\" CODE=\"[DEN]\" isMetric=\"no\" class=\"heat\">\n <name>Denier</name>\n <printSymbol>den</printSymbol>\n <property>linear mass density (of textile thread)</property>\n <value value=\"1\" Unit=\"g/9/km\" UNIT=\"G/9/KM\">1</value>\n </unit>\n <unit Code=\"m[H2O]\" CODE=\"M[H2O]\" isMetric=\"yes\" class=\"clinical\">\n <name>meter of water column</name>\n <printSymbol>m&#160;H<sub>\n <r>2</r>\n </sub>O</printSymbol>\n <property>pressure</property>\n <value Unit=\"kPa\" UNIT=\"KPAL\" value=\"980665e-5\">9.80665</value>\n </unit>\n <unit Code=\"m[Hg]\" CODE=\"M[HG]\" isMetric=\"yes\" class=\"clinical\">\n <name>meter of mercury column</name>\n <printSymbol>m&#160;Hg</printSymbol>\n <property>pressure</property>\n <value Unit=\"kPa\" UNIT=\"KPAL\" value=\"133.3220\">133.3220</value>\n </unit>\n <unit Code=\"[in_i'H2O]\" CODE=\"[IN_I'H2O]\" isMetric=\"no\" class=\"clinical\">\n <name>inch of water column</name>\n <printSymbol>in&#160;H<sub>\n <r>2</r>\n </sub>O</printSymbol>\n <property>pressure</property>\n <value Unit=\"m[H2O].[in_i]/m\" UNIT=\"M[H2O].[IN_I]/M\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[in_i'Hg]\" CODE=\"[IN_I'HG]\" isMetric=\"no\" class=\"clinical\">\n <name>inch of mercury column</name>\n <printSymbol>in&#160;Hg</printSymbol>\n <property>pressure</property>\n <value Unit=\"m[Hg].[in_i]/m\" UNIT=\"M[HG].[IN_I]/M\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[PRU]\" CODE=\"[PRU]\" isMetric=\"no\" class=\"clinical\">\n <name>peripheral vascular resistance unit</name>\n <printSymbol>P.R.U.</printSymbol>\n <property>fluid resistance</property>\n <value Unit=\"mm[Hg].s/ml\" UNIT=\"MM[HG].S/ML\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[wood'U]\" CODE=\"[WOOD'U]\" isMetric=\"no\" class=\"clinical\">\n <name>Wood unit</name>\n <printSymbol>Wood U.</printSymbol>\n <property>fluid resistance</property>\n <value Unit=\"mm[Hg].min/L\" UNIT=\"MM[HG].MIN/L\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[diop]\" CODE=\"[DIOP]\" isMetric=\"no\" class=\"clinical\">\n <name>diopter</name>\n <printSymbol>dpt</printSymbol>\n <property>refraction of a lens</property>\n <value Unit=\"/m\" UNIT=\"/M\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[p'diop]\" CODE=\"[P'DIOP]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>prism diopter</name>\n <printSymbol>PD</printSymbol>\n <property>refraction of a prism</property>\n <value Unit=\"100tan(1 rad)\" UNIT=\"100TAN(1 RAD)\">\n <function name=\"tanTimes100\" value=\"1\" Unit=\"rad\"/>\n </value>\n </unit>\n <unit Code=\"%[slope]\" CODE=\"%[SLOPE]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>percent of slope</name>\n <printSymbol>%</printSymbol>\n <property>slope</property>\n <value Unit=\"100tan(1 rad)\" UNIT=\"100TAN(1 RAD)\">\n <function name=\"100tan\" value=\"1\" Unit=\"deg\"/>\n </value>\n </unit>\n <unit Code=\"[mesh_i]\" CODE=\"[MESH_I]\" isMetric=\"no\" class=\"clinical\">\n <name>mesh</name>\n <property>lineic number</property>\n <value Unit=\"/[in_i]\" UNIT=\"/[IN_I]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[Ch]\" CODE=\"[CH]\" isMetric=\"no\" class=\"clinical\">\n <name>Charri&#232;re</name>\n <name>french</name>\n <printSymbol>Ch</printSymbol>\n <property>gauge of catheters</property>\n <value Unit=\"mm/3\" UNIT=\"MM/3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[drp]\" CODE=\"[DRP]\" isMetric=\"no\" class=\"clinical\">\n <name>drop</name>\n <printSymbol>drp</printSymbol>\n <property>volume</property>\n <value Unit=\"ml/20\" UNIT=\"ML/20\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[hnsf'U]\" CODE=\"[HNSF'U]\" isMetric=\"no\" class=\"clinical\">\n <name>Hounsfield unit</name>\n <printSymbol>HF</printSymbol>\n <property>x-ray attenuation</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[MET]\" CODE=\"[MET]\" isMetric=\"no\" class=\"clinical\">\n <name>metabolic equivalent</name>\n <printSymbol>MET</printSymbol>\n <property>metabolic cost of physical activity</property>\n <value Unit=\"mL/min/kg\" UNIT=\"ML/MIN/KG\" value=\"3.5\">3.5</value>\n </unit>\n <unit Code=\"[hp'_X]\" CODE=\"[HP'_X]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>homeopathic potency of decimal series (retired)</name>\n <printSymbol>X</printSymbol>\n <property>homeopathic potency (retired)</property>\n <value Unit=\"hpX(1 1)\" UNIT=\"HPX(1 1)\">\n <function name=\"hpX\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"[hp'_C]\" CODE=\"[HP'_C]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>homeopathic potency of centesimal series (retired)</name>\n <printSymbol>C</printSymbol>\n <property>homeopathic potency (retired)</property>\n <value Unit=\"hpC(1 1)\" UNIT=\"HPC(1 1)\">\n <function name=\"hpC\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"[hp'_M]\" CODE=\"[HP'_M]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>homeopathic potency of millesimal series (retired)</name>\n <printSymbol>M</printSymbol>\n <property>homeopathic potency (retired)</property>\n <value Unit=\"hpM(1 1)\" UNIT=\"HPM(1 1)\">\n <function name=\"hpM\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"[hp'_Q]\" CODE=\"[HP'_Q]\" isMetric=\"no\" isSpecial=\"yes\" class=\"clinical\">\n <name>homeopathic potency of quintamillesimal series (retired)</name>\n <printSymbol>Q</printSymbol>\n <property>homeopathic potency (retired)</property>\n <value Unit=\"hpQ(1 1)\" UNIT=\"HPQ(1 1)\">\n <function name=\"hpQ\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"[hp_X]\" CODE=\"[HP_X]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of decimal hahnemannian series</name>\n <printSymbol>X</printSymbol>\n <property>homeopathic potency (Hahnemann)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[hp_C]\" CODE=\"[HP_C]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of centesimal hahnemannian series</name>\n <printSymbol>C</printSymbol>\n <property>homeopathic potency (Hahnemann)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[hp_M]\" CODE=\"[HP_M]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of millesimal hahnemannian series</name>\n <printSymbol>M</printSymbol>\n <property>homeopathic potency (Hahnemann)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[hp_Q]\" CODE=\"[HP_Q]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of quintamillesimal hahnemannian series</name>\n <printSymbol>Q</printSymbol>\n <property>homeopathic potency (Hahnemann)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[kp_X]\" CODE=\"[KP_X]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of decimal korsakovian series</name>\n <printSymbol>X</printSymbol>\n <property>homeopathic potency (Korsakov)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[kp_C]\" CODE=\"[KP_C]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of centesimal korsakovian series</name>\n <printSymbol>C</printSymbol>\n <property>homeopathic potency (Korsakov)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[kp_M]\" CODE=\"[KP_M]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of millesimal korsakovian series</name>\n <printSymbol>M</printSymbol>\n <property>homeopathic potency (Korsakov)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[kp_Q]\" CODE=\"[KP_Q]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"clinical\">\n <name>homeopathic potency of quintamillesimal korsakovian series</name>\n <printSymbol>Q</printSymbol>\n <property>homeopathic potency (Korsakov)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"eq\" CODE=\"EQ\" isMetric=\"yes\" class=\"chemical\">\n <name>equivalents</name>\n <printSymbol>eq</printSymbol>\n <property>amount of substance</property>\n <value Unit=\"mol\" UNIT=\"MOL\" value=\"1\">1</value>\n </unit>\n <unit Code=\"osm\" CODE=\"OSM\" isMetric=\"yes\" class=\"chemical\">\n <name>osmole</name>\n <printSymbol>osm</printSymbol>\n <property>amount of substance (dissolved particles)</property>\n <value Unit=\"mol\" UNIT=\"MOL\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[pH]\" CODE=\"[PH]\" isMetric=\"no\" isSpecial=\"yes\" class=\"chemical\">\n <name>pH</name>\n <printSymbol>pH</printSymbol>\n <property>acidity</property>\n <value Unit=\"pH(1 mol/l)\" UNIT=\"PH(1 MOL/L)\">\n <function name=\"pH\" value=\"1\" Unit=\"mol/l\"/>\n </value>\n </unit>\n <unit Code=\"g%\" CODE=\"G%\" isMetric=\"yes\" class=\"chemical\">\n <name>gram percent</name>\n <printSymbol>g%</printSymbol>\n <property>mass concentration</property>\n <value Unit=\"g/dl\" UNIT=\"G/DL\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[S]\" CODE=\"[S]\" isMetric=\"no\" class=\"chemical\">\n <name>Svedberg unit</name>\n <printSymbol>S</printSymbol>\n <property>sedimentation coefficient</property>\n <value Unit=\"10*-13.s\" UNIT=\"10*-13.S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[HPF]\" CODE=\"[HPF]\" isMetric=\"no\" class=\"chemical\">\n <name>high power field</name>\n <printSymbol>HPF</printSymbol>\n <property>view area in microscope</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[LPF]\" CODE=\"[LPF]\" isMetric=\"no\" class=\"chemical\">\n <name>low power field</name>\n <printSymbol>LPF</printSymbol>\n <property>view area in microscope</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"100\">100</value>\n </unit>\n <unit Code=\"kat\" CODE=\"KAT\" isMetric=\"yes\" class=\"chemical\">\n <name>katal</name>\n <printSymbol>kat</printSymbol>\n <property>catalytic activity</property>\n <value Unit=\"mol/s\" UNIT=\"MOL/S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"U\" CODE=\"U\" isMetric=\"yes\" class=\"chemical\">\n <name>Unit</name>\n <printSymbol>U</printSymbol>\n <property>catalytic activity</property>\n <value Unit=\"umol/min\" UNIT=\"UMOL/MIN\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[iU]\" CODE=\"[IU]\" isMetric=\"yes\" isArbitrary=\"yes\" class=\"chemical\">\n <name>international unit</name>\n <printSymbol>IU</printSymbol>\n <property>arbitrary</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[IU]\" CODE=\"[IU]\" isMetric=\"yes\" isArbitrary=\"yes\" class=\"chemical\">\n <name>international unit</name>\n <printSymbol>i.U.</printSymbol>\n <property>arbitrary</property>\n <value Unit=\"[iU]\" UNIT=\"[IU]\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[arb'U]\" CODE=\"[ARB'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>arbitrary unit</name>\n <printSymbol>arb. U</printSymbol>\n <property>arbitrary</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[USP'U]\" CODE=\"[USP'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>United States Pharmacopeia unit</name>\n <printSymbol>U.S.P.</printSymbol>\n <property>arbitrary</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[GPL'U]\" CODE=\"[GPL'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>GPL unit</name>\n <property>biologic activity of anticardiolipin IgG</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[MPL'U]\" CODE=\"[MPL'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>MPL unit</name>\n <property>biologic activity of anticardiolipin IgM</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[APL'U]\" CODE=\"[APL'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>APL unit</name>\n <property>biologic activity of anticardiolipin IgA</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[beth'U]\" CODE=\"[BETH'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>Bethesda unit</name>\n <property>biologic activity of factor VIII inhibitor</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[anti'Xa'U]\" CODE=\"[ANTI'XA'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>anti factor Xa unit</name>\n <property>biologic activity of factor Xa inhibitor (heparin)</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[todd'U]\" CODE=\"[TODD'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>Todd unit</name>\n <property>biologic activity antistreptolysin O</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[dye'U]\" CODE=\"[DYE'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>Dye unit</name>\n <property>biologic activity of amylase</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[smgy'U]\" CODE=\"[SMGY'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>Somogyi unit</name>\n <property>biologic activity of amylase</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[bdsk'U]\" CODE=\"[BDSK'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>Bodansky unit</name>\n <property>biologic activity of phosphatase</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ka'U]\" CODE=\"[KA'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>King-Armstrong unit</name>\n <property>biologic activity of phosphatase</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[knk'U]\" CODE=\"[KNK'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>Kunkel unit</name>\n <property>arbitrary biologic activity</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[mclg'U]\" CODE=\"[MCLG'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>Mac Lagan unit</name>\n <property>arbitrary biologic activity</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[tb'U]\" CODE=\"[TB'U]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>tuberculin unit</name>\n <property>biologic activity of tuberculin</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[CCID_50]\" CODE=\"[CCID_50]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>50% cell culture infectious dose</name>\n <printSymbol>CCID<sub>50</sub>\n </printSymbol>\n <property>biologic activity (infectivity) of an infectious agent preparation</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[TCID_50]\" CODE=\"[TCID_50]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>50% tissue culture infectious dose</name>\n <printSymbol>TCID<sub>50</sub>\n </printSymbol>\n <property>biologic activity (infectivity) of an infectious agent preparation</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[EID_50]\" CODE=\"[EID_50]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>50% embryo infectious dose</name>\n <printSymbol>EID<sub>50</sub>\n </printSymbol>\n <property>biologic activity (infectivity) of an infectious agent preparation</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[PFU]\" CODE=\"[PFU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>plaque forming units</name>\n <printSymbol>PFU</printSymbol>\n <property>amount of an infectious agent</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[FFU]\" CODE=\"[FFU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>focus forming units</name>\n <printSymbol>FFU</printSymbol>\n <property>amount of an infectious agent</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[CFU]\" CODE=\"[CFU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>colony forming units</name>\n <printSymbol>CFU</printSymbol>\n <property>amount of a proliferating organism</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[IR]\" CODE=\"[IR]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>index of reactivity</name>\n <printSymbol>IR</printSymbol>\n <property>amount of an allergen calibrated through in-vivo testing using the Stallergenes&#174; method</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[BAU]\" CODE=\"[BAU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>bioequivalent allergen unit</name>\n <printSymbol>BAU</printSymbol>\n <property>amount of an allergen calibrated through in-vivo testing based on the ID50EAL method of (intradermal dilution for 50mm sum of erythema diameters</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[AU]\" CODE=\"[AU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>allergen unit</name>\n <printSymbol>AU</printSymbol>\n <property>procedure defined amount of an allergen using some reference standard</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[Amb'a'1'U]\" CODE=\"[AMB'A'1'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>allergen unit for Ambrosia artemisiifolia</name>\n <printSymbol>Amb a 1 U</printSymbol>\n <property>procedure defined amount of the major allergen of ragweed</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[PNU]\" CODE=\"[PNU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>protein nitrogen unit</name>\n <printSymbol>PNU</printSymbol>\n <property>procedure defined amount of a protein substance</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[Lf]\" CODE=\"[LF]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>Limit of flocculation</name>\n <printSymbol>Lf</printSymbol>\n <property>procedure defined amount of an antigen substance</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[D'ag'U]\" CODE=\"[D'AG'U]\" isMetric=\"no\" isArbitrary=\"yes\"\n class=\"chemical\">\n <name>D-antigen unit</name>\n <printSymbol/>\n <property>procedure defined amount of a poliomyelitis d-antigen substance</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[FEU]\" CODE=\"[FEU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>fibrinogen equivalent unit</name>\n <printSymbol/>\n <property>amount of fibrinogen broken down into the measured d-dimers</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[ELU]\" CODE=\"[ELU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>ELISA unit</name>\n <printSymbol/>\n <property>arbitrary ELISA unit</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[EU]\" CODE=\"[EU]\" isMetric=\"no\" isArbitrary=\"yes\" class=\"chemical\">\n <name>Ehrlich unit</name>\n <printSymbol/>\n <property>Ehrlich unit</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Np\" CODE=\"NEP\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>neper</name>\n <printSymbol>Np</printSymbol>\n <property>level</property>\n <value Unit=\"ln(1 1)\" UNIT=\"LN(1 1)\">\n <function name=\"ln\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"B\" CODE=\"B\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel</name>\n <printSymbol>B</printSymbol>\n <property>level</property>\n <value Unit=\"lg(1 1)\" UNIT=\"LG(1 1)\">\n <function name=\"lg\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"B[SPL]\" CODE=\"B[SPL]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel sound pressure</name>\n <printSymbol>B(SPL)</printSymbol>\n <property>pressure level</property>\n <value Unit=\"2lg(2 10*-5.Pa)\" UNIT=\"2LG(2 10*-5.PAL)\">\n <function name=\"lgTimes2\" value=\"2\" Unit=\"10*-5.Pa\"/>\n </value>\n </unit>\n <unit Code=\"B[V]\" CODE=\"B[V]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel volt</name>\n <printSymbol>B(V)</printSymbol>\n <property>electric potential level</property>\n <value Unit=\"2lg(1 V)\" UNIT=\"2LG(1 V)\">\n <function name=\"lgTimes2\" value=\"1\" Unit=\"V\"/>\n </value>\n </unit>\n <unit Code=\"B[mV]\" CODE=\"B[MV]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel millivolt</name>\n <printSymbol>B(mV)</printSymbol>\n <property>electric potential level</property>\n <value Unit=\"2lg(1 mV)\" UNIT=\"2LG(1 MV)\">\n <function name=\"lgTimes2\" value=\"1\" Unit=\"mV\"/>\n </value>\n </unit>\n <unit Code=\"B[uV]\" CODE=\"B[UV]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel microvolt</name>\n <printSymbol>B(&#956;V)</printSymbol>\n <property>electric potential level</property>\n <value Unit=\"2lg(1 uV)\" UNIT=\"2LG(1 UV)\">\n <function name=\"lgTimes2\" value=\"1\" Unit=\"uV\"/>\n </value>\n </unit>\n <unit Code=\"B[10.nV]\" CODE=\"B[10.NV]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel 10 nanovolt</name>\n <printSymbol>B(10 nV)</printSymbol>\n <property>electric potential level</property>\n <value Unit=\"2lg(10 nV)\" UNIT=\"2LG(10 NV)\">\n <function name=\"lgTimes2\" value=\"10\" Unit=\"nV\"/>\n </value>\n </unit>\n <unit Code=\"B[W]\" CODE=\"B[W]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel watt</name>\n <printSymbol>B(W)</printSymbol>\n <property>power level</property>\n <value Unit=\"lg(1 W)\" UNIT=\"LG(1 W)\">\n <function name=\"lg\" value=\"1\" Unit=\"W\"/>\n </value>\n </unit>\n <unit Code=\"B[kW]\" CODE=\"B[KW]\" isMetric=\"yes\" isSpecial=\"yes\" class=\"levels\">\n <name>bel kilowatt</name>\n <printSymbol>B(kW)</printSymbol>\n <property>power level</property>\n <value Unit=\"lg(1 kW)\" UNIT=\"LG(1 KW)\">\n <function name=\"lg\" value=\"1\" Unit=\"kW\"/>\n </value>\n </unit>\n <unit Code=\"st\" CODE=\"STR\" isMetric=\"yes\" class=\"misc\">\n <name>stere</name>\n <printSymbol>st</printSymbol>\n <property>volume</property>\n <value Unit=\"m3\" UNIT=\"M3\" value=\"1\">1</value>\n </unit>\n <unit Code=\"Ao\" CODE=\"AO\" isMetric=\"no\" class=\"misc\">\n <name>&#197;ngstr&#246;m</name>\n <printSymbol>&#197;</printSymbol>\n <property>length</property>\n <value Unit=\"nm\" UNIT=\"NM\" value=\"0.1\">0.1</value>\n </unit>\n <unit Code=\"b\" CODE=\"BRN\" isMetric=\"no\" class=\"misc\">\n <name>barn</name>\n <printSymbol>b</printSymbol>\n <property>action area</property>\n <value Unit=\"fm2\" UNIT=\"FM2\" value=\"100\">100</value>\n </unit>\n <unit Code=\"att\" CODE=\"ATT\" isMetric=\"no\" class=\"misc\">\n <name>technical atmosphere</name>\n <printSymbol>at</printSymbol>\n <property>pressure</property>\n <value Unit=\"kgf/cm2\" UNIT=\"KGF/CM2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"mho\" CODE=\"MHO\" isMetric=\"yes\" class=\"misc\">\n <name>mho</name>\n <printSymbol>mho</printSymbol>\n <property>electric conductance</property>\n <value Unit=\"S\" UNIT=\"S\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[psi]\" CODE=\"[PSI]\" isMetric=\"no\" class=\"misc\">\n <name>pound per square inch</name>\n <printSymbol>psi</printSymbol>\n <property>pressure</property>\n <value Unit=\"[lbf_av]/[in_i]2\" UNIT=\"[LBF_AV]/[IN_I]2\" value=\"1\">1</value>\n </unit>\n <unit Code=\"circ\" CODE=\"CIRC\" isMetric=\"no\" class=\"misc\">\n <name>circle</name>\n <printSymbol>circ</printSymbol>\n <property>plane angle</property>\n <value Unit=\"[pi].rad\" UNIT=\"[PI].RAD\" value=\"2\">2</value>\n </unit>\n <unit Code=\"sph\" CODE=\"SPH\" isMetric=\"no\" class=\"misc\">\n <name>sphere</name>\n <printSymbol>sph</printSymbol>\n <property>solid angle</property>\n <value Unit=\"[pi].sr\" UNIT=\"[PI].SR\" value=\"4\">4</value>\n </unit>\n <unit Code=\"[car_m]\" CODE=\"[CAR_M]\" isMetric=\"no\" class=\"misc\">\n <name>metric carat</name>\n <printSymbol>ct<sub>m</sub>\n </printSymbol>\n <property>mass</property>\n <value Unit=\"g\" UNIT=\"G\" value=\"2e-1\">0.2</value>\n </unit>\n <unit Code=\"[car_Au]\" CODE=\"[CAR_AU]\" isMetric=\"no\" class=\"misc\">\n <name>carat of gold alloys</name>\n <printSymbol>ct<sub>\n <r>Au</r>\n </sub>\n </printSymbol>\n <property>mass fraction</property>\n <value Unit=\"/24\" UNIT=\"/24\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[smoot]\" CODE=\"[SMOOT]\" isMetric=\"no\" class=\"misc\">\n <name>Smoot</name>\n <printSymbol/>\n <property>length</property>\n <value Unit=\"[in_i]\" UNIT=\"[IN_I]\" value=\"67\">67</value>\n </unit>\n <unit Code=\"[m/s2/Hz^(1/2)]\" CODE=\"[M/S2/HZ^(1/2)]\" isMetric=\"no\" isSpecial=\"yes\"\n class=\"misc\">\n <name>meter per square seconds per square root of hertz</name>\n <printSymbol/>\n <property>amplitude spectral density</property>\n <value Unit=\"sqrt(1 m2/s4/Hz)\" UNIT=\"SQRT(1 M2/S4/HZ)\">\n <function name=\"sqrt\" value=\"1\" Unit=\"m2/s4/Hz\"/>\n </value>\n </unit>\n <unit Code=\"[NTU]\" CODE=\"[NTU]\" isMetric=\"no\" class=\"misc\">\n <name>Nephelometric Turbidity Unit</name>\n <printSymbol/>\n <property>turbidity</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"[FNU]\" CODE=\"[FNU]\" isMetric=\"no\" class=\"misc\">\n <name>Formazin Nephelometric Unit</name>\n <printSymbol/>\n <property>turbidity</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"bit_s\" CODE=\"BIT_S\" isMetric=\"no\" isSpecial=\"yes\" class=\"infotech\">\n <name>bit</name>\n <printSymbol>bit<sub>s</sub>\n </printSymbol>\n <property>amount of information</property>\n <value Unit=\"ld(1 1)\" UNIT=\"ld(1 1)\">\n <function name=\"ld\" value=\"1\" Unit=\"1\"/>\n </value>\n </unit>\n <unit Code=\"bit\" CODE=\"BIT\" isMetric=\"yes\" class=\"infotech\">\n <name>bit</name>\n <printSymbol>bit</printSymbol>\n <property>amount of information</property>\n <value Unit=\"1\" UNIT=\"1\" value=\"1\">1</value>\n </unit>\n <unit Code=\"By\" CODE=\"BY\" isMetric=\"yes\" class=\"infotech\">\n <name>byte</name>\n <printSymbol>B</printSymbol>\n <property>amount of information</property>\n <value Unit=\"bit\" UNIT=\"bit\" value=\"8\">8</value>\n </unit>\n <unit Code=\"Bd\" CODE=\"BD\" isMetric=\"yes\" class=\"infotech\">\n <name>baud</name>\n <printSymbol>Bd</printSymbol>\n <property>signal transmission rate</property>\n <value Unit=\"/s\" UNIT=\"/s\" value=\"1\">1</value>\n </unit>\n <prefix Code=\"Ki\" CODE=\"KIB\">\n <name>kibi</name>\n <printSymbol>Ki</printSymbol>\n <value value=\"1024\">1024</value>\n </prefix>\n <prefix Code=\"Mi\" CODE=\"MIB\">\n <name>mebi</name>\n <printSymbol>Mi</printSymbol>\n <value value=\"1048576\">1048576</value>\n </prefix>\n <prefix Code=\"Gi\" CODE=\"GIB\">\n <name>gibi</name>\n <printSymbol>Gi</printSymbol>\n <value value=\"1073741824\">1073741824</value>\n </prefix>\n <prefix Code=\"Ti\" CODE=\"TIB\">\n <name>tebi</name>\n <printSymbol>Ti</printSymbol>\n <value value=\"1099511627776\">1099511627776</value>\n </prefix>\n</root>`;\n","/**\n * Parse the vendored, verbatim UCUM `ucum-essence.xml` (embedded as {@link UCUM_ESSENCE_XML}) into\n * the engine's in-memory unit model — the {@link UcumEssence} table of prefixes and atoms.\n *\n * Hand-rolled, **zero-dependency** scanning of a known-well-formed document (not a general XML\n * parser): the essence file is a flat, regular list of `<prefix>` / `<base-unit>` / `<unit>`\n * elements. Parsed **once**, lazily, and cached — the engine reads no file at runtime; the table is\n * a pure in-process transform of the embedded verbatim content, never serialized or distributed. The\n * UCUM table is copyright © Regenstrief Institute, Inc. and is bundled verbatim — see\n * `vendor/ucum/NOTICE.md`, which ships with this package.\n *\n * @packageDocumentation\n */\n\nimport { UCUM_ESSENCE_XML } from \"./essence-data.generated.js\";\nimport type { UcumAtom, UcumEssence, UcumPrefix } from \"./types.js\";\n\n/** Read an XML attribute value (`name=\"value\"`) from an element's opening tag. */\nfunction attr(tag: string, name: string): string | undefined {\n const m = new RegExp(`\\\\b${name}=\"([^\"]*)\"`).exec(tag);\n return m?.[1];\n}\n\n/** The nested `<value ... value=\"…\" Unit=\"…\">` of a `<unit>` element, when present. */\nfunction readValue(block: string): { factor: number; unit: string } | undefined {\n const m = /<value\\b([^>]*)>/.exec(block);\n if (!m?.[1]) return undefined;\n const valueAttr = attr(m[1], \"value\");\n const unitAttr = attr(m[1], \"Unit\");\n if (valueAttr === undefined || unitAttr === undefined) return undefined;\n const factor = Number(valueAttr);\n if (!Number.isFinite(factor)) return undefined;\n return { factor, unit: unitAttr };\n}\n\n/**\n * Parse a UCUM essence XML document into the prefix + atom tables. Exported for the drift/robustness\n * tests (feeding it malformed rows); production code calls {@link loadUcumEssence}, which caches.\n *\n * The table it returns is **deeply frozen** — every atom, every atom's definition, every prefix and\n * both arrays — so the `readonly` on those is enforced when the code runs and not only when it\n * compiles. The two lookup maps refuse `set` / `delete` / `clear`; a `Map` cannot be made immutable\n * in place, so that is the direct route and not every route (see {@link sealLookup}).\n *\n * The three `?? \"\"` capture-group fallbacks below cannot be reached from any input, so this function\n * does not report 100% branch coverage and is not meant to. They used to carry `v8 ignore` hints,\n * which is **the wrong tool twice over**: this repo's coverage provider does not honour one (measured\n * — the hinted branches were reported uncovered either way, with and without a `--` reason and under\n * `--coverage.experimentalAstAwareRemapping`), and an ignore is an assertion about reachability that\n * the next reader inherits without a way to check it. The package's posture is that an unreachable\n * `noUncheckedIndexedAccess` artifact stays visibly uncovered under a directory floor of 90.\n *\n * @param xml - The essence XML (the vendored verbatim document, or a test fragment).\n * @returns The parsed {@link UcumEssence} model, frozen.\n * @example\n * ```ts\n * // Package-internal: `parseEssence` is not re-exported from \"@cosyte/terminology\", and the\n * // package declares no subpath export. Consumers call `loadUcumEssence()`, which parses the\n * // vendored table once and caches it.\n * import { parseEssence } from \"./essence.js\";\n *\n * const table = parseEssence('<root><base-unit Code=\"m\" dim=\"L\"><name>m</name></base-unit></root>');\n * table.atomByCode.get(\"m\")?.base; // => true\n * ```\n */\nexport function parseEssence(xml: string): UcumEssence {\n const prefixes: UcumPrefix[] = [];\n const atoms: UcumAtom[] = [];\n\n for (const m of xml.matchAll(/<prefix\\b([^>]*)>([\\s\\S]*?)<\\/prefix>/g)) {\n // `matchAll` always yields both capture groups; each `?? \"\"` is a `noUncheckedIndexedAccess`\n // fallback with no input that reaches it, so both stay uncovered (see `parseEssence`'s docblock).\n const openTag = m[1] ?? \"\";\n const body = m[2] ?? \"\";\n const code = attr(openTag, \"Code\");\n // A prefix's `<value>` carries only a `value` attribute (no `Unit`) — read it directly.\n const valueTag = /<value\\b([^>]*)>/.exec(body);\n const valueAttr = valueTag?.[1] === undefined ? undefined : attr(valueTag[1], \"value\");\n const factor = valueAttr === undefined ? NaN : Number(valueAttr);\n if (code !== undefined && Number.isFinite(factor)) prefixes.push({ code, factor });\n }\n\n for (const m of xml.matchAll(/<base-unit\\b([^>]*)>/g)) {\n // Same unreachable `noUncheckedIndexedAccess` fallback as above.\n const openTag = m[1] ?? \"\";\n const code = attr(openTag, \"Code\");\n if (code === undefined) continue;\n atoms.push({\n code,\n metric: true,\n base: true,\n dim: code,\n special: false,\n arbitrary: false,\n });\n }\n\n for (const m of xml.matchAll(/<unit\\b([^>]*)>([\\s\\S]*?)<\\/unit>/g)) {\n // Same unreachable `noUncheckedIndexedAccess` fallbacks as above.\n const openTag = m[1] ?? \"\";\n const body = m[2] ?? \"\";\n const code = attr(openTag, \"Code\");\n if (code === undefined) continue;\n const special = attr(openTag, \"isSpecial\") === \"yes\";\n const arbitrary = attr(openTag, \"isArbitrary\") === \"yes\";\n // Special units are non-linear (a `<function>`, not a scalar) — never carry a linear value.\n const value = special ? undefined : readValue(body);\n atoms.push({\n code,\n metric: attr(openTag, \"isMetric\") === \"yes\",\n base: false,\n special,\n arbitrary,\n ...(value ? { value } : {}),\n });\n }\n\n // Longest symbols first so greedy matching resolves e.g. `min` (minute) before `m` (metre) and\n // `da` (deca) before the 1-char prefixes.\n prefixes.sort((a, b) => b.code.length - a.code.length);\n atoms.sort((a, b) => b.code.length - a.code.length);\n\n const atomByCode = new Map(atoms.map((a) => [a.code, a]));\n const prefixByCode = new Map(prefixes.map((p) => [p.code, p]));\n return freezeEssence({ prefixes, atoms, atomByCode, prefixByCode });\n}\n\n/** Refuse a write to the shared unit table. Named so the throw site reads as the table's own rule. */\nfunction refuseTableWrite(): never {\n throw new TypeError(\"the UCUM unit table is immutable\");\n}\n\n/**\n * Refuse `set` / `delete` / `clear` on a lookup map, which `Object.freeze` cannot: a `Map` keeps its\n * entries in internal slots, so freezing the object leaves the prototype's mutators working.\n *\n * **This closes the direct route and not every route, and the difference is measured rather than\n * assumed.** `Map.prototype.set.call(table.atomByCode, …)` still inserts. What that reaches is\n * bounded by where the maps are read: {@link parseUcum} resolves an atom by scanning `atoms`, never\n * through `atomByCode`, so an entry forced in this way changes **no** reduction and no `ucumEqual`\n * answer — only what the caller's own `atomByCode.get` hands back. Both halves are pinned in\n * `test/ucum/essence-immutable.test.ts`.\n */\nfunction sealLookup<V>(map: Map<string, V>): ReadonlyMap<string, V> {\n return Object.defineProperties(map, {\n set: { value: refuseTableWrite },\n delete: { value: refuseTableWrite },\n clear: { value: refuseTableWrite },\n });\n}\n\n/**\n * Make the parsed table immutable **at run time**, not only to the type checker.\n *\n * Every field of {@link UcumEssence} and {@link UcumAtom} is `readonly`, which TypeScript erases:\n * until this change nothing here froze anything, so a consumer holding the table\n * {@link loadUcumEssence} handed it could write an atom's definition in place. That is not a\n * cosmetic hole. `reduce` memoizes each atom's reduction against the atom **object**, so corrupting\n * a loaded atom **before its first reduction** writes the memo, and the reading survives putting the\n * table back exactly as shipped. Measured on `bf153cb` with the litre defined as `1`:\n * `ucumEqual(\"L\", \"1\")` and `ucumEqual(\"mg/L\", \"mg\")` both answered `true` where the uncorrupted\n * control answered `false`, and `mmol/L` fell from `6.0221407599999985e+23 × m-3` to a dimensionless\n * `6.02214076e+20` — a concentration reading equal to a mass, out of an engine whose stated\n * invariant is that it never fabricates.\n *\n * **The freeze has to be deep, and a shallow one is worth nothing here**: freezing the atom alone\n * leaves `atom.value.unit = \"1\"`, which reproduces the same three readings. The `atoms` array is\n * frozen too, because that is the one {@link parseUcum} scans — replacing an element there hands the\n * parser a forged atom directly, with the same result and without touching the memo at all.\n *\n * Note that `Object.freeze` refuses a write by **throwing in strict mode and silently ignoring it in\n * sloppy mode**. The invariant this function provides is therefore *the table does not change*,\n * which holds in both; the `TypeError` a strict-mode caller sees is how that is observed, not what\n * is promised.\n */\nfunction freezeEssence(essence: UcumEssence): UcumEssence {\n for (const atom of essence.atoms) {\n if (atom.value) Object.freeze(atom.value);\n Object.freeze(atom);\n }\n for (const prefix of essence.prefixes) Object.freeze(prefix);\n Object.freeze(essence.atoms);\n Object.freeze(essence.prefixes);\n sealLookup(essence.atomByCode as Map<string, UcumAtom>);\n sealLookup(essence.prefixByCode as Map<string, UcumPrefix>);\n return Object.freeze(essence);\n}\n\nlet cached: UcumEssence | undefined;\n\n/**\n * Load the UCUM essence table, parsing the embedded verbatim XML on first call and caching it.\n *\n * One table is shared by every caller and by the engine itself, so it is handed out **frozen**: an\n * atom's definition cannot be rewritten in place, and neither can the `atoms` array the parser\n * scans. It used to be, and doing so before that atom's first reduction poisoned the\n * reduction memo for the life of the process — a fabricated unit equivalence that survived putting\n * the table back. A write is refused, which in strict mode means a `TypeError`.\n *\n * @returns The shared, frozen in-memory {@link UcumEssence} model.\n * @example\n * ```ts\n * import { loadUcumEssence } from \"@cosyte/terminology\";\n *\n * const essence = loadUcumEssence();\n * essence.atomByCode.has(\"m\"); // => true\n * ```\n */\nexport function loadUcumEssence(): UcumEssence {\n cached ??= parseEssence(UCUM_ESSENCE_XML);\n return cached;\n}\n","/**\n * The **UCUM grammar parser**: a hand-rolled, zero-dependency recursive-descent\n * parser from a unit expression string to a {@link UnitNode} AST, grounded firsthand on the UCUM\n * specification's syntax (base units, metric prefixes attached with no delimiter and resolved by\n * longest-match, `.` multiply / `/` divide, signed integer exponents, `{…}` inert annotations, and\n * the `10*` / `10^` powers-of-ten). Validation **is** parsing: an expression is valid iff it parses\n * completely over **known** atoms — an unknown atom yields no match and fails, never a guessed unit.\n *\n * @packageDocumentation\n */\n\nimport { loadUcumEssence } from \"./essence.js\";\nimport type {\n ComponentNode,\n SimpleUnitNode,\n UcumAtom,\n UcumEssence,\n UcumPrefix,\n UnitNode,\n} from \"./types.js\";\n\n/** A successful parse (the AST) or a value-free failure reason. */\nexport type ParseResult = { readonly ok: true; readonly node: UnitNode } | ParseFailure;\n\n/** A parse failure carrying a value-free structural reason. */\nexport interface ParseFailure {\n readonly ok: false;\n /** A structural description of the fault (never echoes an input *value* beyond the offending token shape). */\n readonly reason: string;\n}\n\nconst isDigitCode = (cc: number): boolean => cc >= 0x30 && cc <= 0x39;\nconst isDigitAt = (s: string, i: number): boolean => isDigitCode(s.charCodeAt(i));\n\n/** A component followed by anything but end / `.` / `/` / `)` is a juxtaposition error. */\nfunction atBoundary(s: string, pos: number): boolean {\n if (pos >= s.length) return true;\n const c = s[pos];\n return c === \".\" || c === \"/\" || c === \")\";\n}\n\n/** One candidate interpretation of a simple unit at a position: a prefix?+atom consuming `len` chars. */\ninterface SimpleMatch {\n readonly prefix?: UcumPrefix;\n readonly atom: UcumAtom;\n readonly len: number;\n}\n\n/**\n * All plausible (prefix?+atom) interpretations at `pos`, ordered by preference: longer total match\n * first, and a bare atom before a prefixed one on a tie (so `Pa` is pascal, not peta-are). The\n * caller commits to the first whose continuation lands on a component boundary.\n */\nfunction simpleMatches(essence: UcumEssence, s: string, pos: number): SimpleMatch[] {\n const out: SimpleMatch[] = [];\n for (const atom of essence.atoms) {\n if (s.startsWith(atom.code, pos)) out.push({ atom, len: atom.code.length });\n }\n for (const prefix of essence.prefixes) {\n if (!s.startsWith(prefix.code, pos)) continue;\n const rem = pos + prefix.code.length;\n for (const atom of essence.atoms) {\n if (atom.metric && s.startsWith(atom.code, rem)) {\n out.push({ prefix, atom, len: prefix.code.length + atom.code.length });\n }\n }\n }\n out.sort((a, b) => b.len - a.len || (a.prefix ? 1 : 0) - (b.prefix ? 1 : 0));\n return out;\n}\n\ninterface Cursor {\n readonly s: string;\n pos: number;\n /** Current parenthesis-nesting depth — capped to keep hostile input from overflowing the stack. */\n depth: number;\n readonly essence: UcumEssence;\n}\n\n/**\n * Maximum parenthesis nesting. Real UCUM units nest a handful of levels at most; a cap keeps a\n * hostile input (e.g. thousands of `(`) from overflowing the recursive-descent stack — it degrades\n * to a typed invalid, never a crash: the parser does not crash on hostile input.\n */\nconst MAX_PAREN_DEPTH = 100;\n\n/** Parse an optional signed-integer exponent at the cursor. Returns the value (default 1). */\nfunction parseExponent(cur: Cursor): { value: number; consumed: boolean } {\n const { s } = cur;\n let i = cur.pos;\n let sign = 1;\n if (s[i] === \"+\") i++;\n else if (s[i] === \"-\") {\n sign = -1;\n i++;\n }\n const start = i;\n while (i < s.length && isDigitAt(s, i)) i++;\n if (i === start) return { value: 1, consumed: false }; // no digits — no exponent\n cur.pos = i;\n return { value: sign * Number(s.slice(start, i)), consumed: true };\n}\n\n/** Parse and validate a `{…}` annotation, advancing past the closing brace. */\nfunction parseAnnotation(cur: Cursor): ParseFailure | undefined {\n const { s } = cur;\n let i = cur.pos + 1; // skip '{'\n for (; i < s.length; i++) {\n const code = s.charCodeAt(i);\n if (code === 0x7d /* } */) {\n cur.pos = i + 1;\n return undefined;\n }\n // Annotation text is printable ASCII (0x20–0x7E) except the curly braces — no Unicode.\n if (code < 0x20 || code > 0x7e || code === 0x7b /* { */) {\n return { ok: false, reason: \"annotation contains a non-ASCII or illegal character\" };\n }\n }\n return { ok: false, reason: \"annotation is not closed with '}'\" };\n}\n\n/** Parse a simple unit (prefix?+atom) + optional exponent, committing to the first valid boundary. */\nfunction parseSimpleUnit(cur: Cursor): { ok: true; node: SimpleUnitNode } | ParseFailure {\n const candidates = simpleMatches(cur.essence, cur.s, cur.pos);\n for (const cand of candidates) {\n const save = cur.pos;\n cur.pos = save + cand.len;\n const exp = parseExponent(cur);\n // `10*` / `10^` are the powers-of-ten — they require an explicit exponent.\n if ((cand.atom.code === \"10*\" || cand.atom.code === \"10^\") && !exp.consumed) {\n cur.pos = save;\n continue;\n }\n // An annotation may ride on the simple unit; the boundary is checked after it.\n let annotationEnd = cur.pos;\n if (cur.s.charCodeAt(cur.pos) === 0x7b /* { */) {\n const err = parseAnnotation(cur);\n if (err) {\n cur.pos = save;\n return err;\n }\n annotationEnd = cur.pos;\n }\n if (atBoundary(cur.s, annotationEnd)) {\n const node: SimpleUnitNode = cand.prefix\n ? { kind: \"simple\", prefix: cand.prefix, atom: cand.atom, exponent: exp.value }\n : { kind: \"simple\", atom: cand.atom, exponent: exp.value };\n return { ok: true, node };\n }\n cur.pos = save; // this interpretation doesn't reach a boundary — try the next\n }\n return { ok: false, reason: \"unrecognized unit atom\" };\n}\n\n/** Parse a single component: a group `( … )`, an annotation-only term, a factor, or a simple unit. */\nfunction parseComponent(cur: Cursor): { ok: true; node: ComponentNode } | ParseFailure {\n const { s } = cur;\n const cc = s.charCodeAt(cur.pos); // NaN at end-of-input — falls through to the atom parser\n\n if (cc === 0x28 /* ( */) {\n if (cur.depth >= MAX_PAREN_DEPTH) {\n return { ok: false, reason: \"parentheses nested too deeply\" };\n }\n cur.pos++;\n cur.depth++;\n const inner = parseTerm(cur, true);\n cur.depth--;\n if (!inner.ok) return inner;\n return { ok: true, node: { kind: \"group\", term: inner.node } };\n }\n\n if (cc === 0x7b /* { */) {\n const err = parseAnnotation(cur);\n if (err) return err;\n return { ok: true, node: { kind: \"annotation\" } };\n }\n\n // A bare integer factor (e.g. the `4` in `4.[pi]`) — but `10*n` / `10^n` are simple units, not factors.\n if (isDigitCode(cc) && !s.startsWith(\"10*\", cur.pos) && !s.startsWith(\"10^\", cur.pos)) {\n const start = cur.pos;\n while (cur.pos < s.length && isDigitAt(s, cur.pos)) cur.pos++;\n if (s.charCodeAt(cur.pos) === 0x7b /* { */) {\n const err = parseAnnotation(cur);\n if (err) return err;\n }\n if (!atBoundary(s, cur.pos)) {\n return { ok: false, reason: \"a numeric factor must be followed by an operator\" };\n }\n return { ok: true, node: { kind: \"factor\", value: Number(s.slice(start, cur.pos)) } };\n }\n\n return parseSimpleUnit(cur);\n}\n\n/** Parse a term: components joined by `.` / `/`, with a leading `/` meaning `1/…`. */\nfunction parseTerm(cur: Cursor, inParen: boolean): { ok: true; node: UnitNode } | ParseFailure {\n const factors: Array<{ sign: 1 | -1; node: ComponentNode }> = [];\n\n let sign: 1 | -1 = 1;\n if (cur.s[cur.pos] === \"/\") {\n sign = -1;\n cur.pos++;\n }\n const first = parseComponent(cur);\n if (!first.ok) return first;\n factors.push({ sign, node: first.node });\n\n while (cur.pos < cur.s.length) {\n const op = cur.s[cur.pos];\n if (op !== \".\" && op !== \"/\") break;\n cur.pos++;\n const comp = parseComponent(cur);\n if (!comp.ok) return comp;\n factors.push({ sign: op === \"/\" ? -1 : 1, node: comp.node });\n }\n\n if (inParen) {\n if (cur.s[cur.pos] !== \")\") return { ok: false, reason: \"unbalanced '(' — missing ')'\" };\n cur.pos++;\n }\n return { ok: true, node: { kind: \"term\", factors } };\n}\n\n/**\n * Parse a UCUM unit expression into an AST.\n *\n * @param unit - The unit expression (e.g. `\"mmol/L\"`, `\"kg.m/s2\"`, `\"10*3/ul\"`).\n * @returns The parsed {@link UnitNode}, or a typed {@link ParseFailure} with a value-free reason.\n * @example\n * ```ts\n * import { parseUcum } from \"@cosyte/terminology\";\n *\n * parseUcum(\"mmol/L\").ok; // => true\n * parseUcum(\"m/\").ok; // => false\n * ```\n */\nexport function parseUcum(unit: string): ParseResult {\n if (unit.length === 0) return { ok: false, reason: \"empty unit expression\" };\n const cur: Cursor = { s: unit, pos: 0, depth: 0, essence: loadUcumEssence() };\n const result = parseTerm(cur, false);\n if (!result.ok) return result;\n if (cur.pos !== unit.length) {\n return { ok: false, reason: \"unexpected trailing input (missing operator?)\" };\n }\n return { ok: true, node: result.node };\n}\n","/**\n * **Dimensional reduction** of a parsed UCUM unit: reduce an expression to its\n * canonical base-unit form — a scalar factor times a map of the seven UCUM base dimensions\n * (`m s g rad K C cd`), recursively substituting each atom's essence definition down to base units.\n *\n * This is **representation** canonicalization, not magnitude *conversion*: it answers \"are these two\n * expressions the same unit\" (`N` ≡ `kg.m/s2`, `mmol/L` ≡ `mmol.L-1`), never \"what is 5 mg/dL in\n * mmol/L\" (that needs an analyte's molar mass, which the engine refuses). **Special** units (`Cel`,\n * `B`, `[pH]`) are non-linear and carry no factor/dimension — they reduce to an opaque normalized\n * form and are never equated with a linear unit. **Arbitrary** units (`[IU]`, `[arb'U]`) are modeled\n * as their own dimension axis, so they cancel with themselves but convert to nothing else.\n *\n * @packageDocumentation\n */\n\nimport { parseUcum } from \"./parse.js\";\nimport type {\n ComponentNode,\n LinearReduction,\n Reduction,\n SimpleUnitNode,\n UcumAtom,\n UnitNode,\n} from \"./types.js\";\n\n/** Multiply two linear reductions (add dimension exponents, multiply factors). */\nfunction multiply(a: LinearReduction, b: LinearReduction): LinearReduction {\n const dims: Record<string, number> = { ...a.dims };\n for (const [k, v] of Object.entries(b.dims)) {\n const next = (dims[k] ?? 0) + v;\n if (next === 0) delete dims[k];\n else dims[k] = next;\n }\n return { kind: \"linear\", factor: a.factor * b.factor, dims };\n}\n\n/** Raise a linear reduction to an integer power (factor exponentiated, exponents scaled). */\nfunction power(r: LinearReduction, p: number): LinearReduction {\n if (p === 1) return r;\n const dims: Record<string, number> = {};\n for (const [k, v] of Object.entries(r.dims)) {\n const e = v * p;\n if (e !== 0) dims[k] = e;\n }\n return { kind: \"linear\", factor: Math.pow(r.factor, p), dims };\n}\n\n/**\n * The dimensionless reduction, used as an internal building block. **Frozen, and never handed to a\n * caller**: it is module-global, so a consumer able to mutate the object it received would be\n * mutating the engine. On `0.0.5` it was neither — `reduce` returned it for a term with no factors,\n * and setting `dims.m = 1` and `factor = 999` on that result made every later reduction in the\n * process start from those, so `kg.m/s2` came back as `999000 × m2.g.s-2` and\n * `ucumEqual(\"N\", \"kg.m/s2\")` answered `false`. {@link linearReduceTerm} now accumulates from a\n * fresh object, so the reductions callers receive are per-call and mutable as before, and the freeze\n * keeps a later path that returns this one from re-opening the same hole silently.\n */\nconst DIMENSIONLESS: LinearReduction = Object.freeze({\n kind: \"linear\",\n factor: 1,\n dims: Object.freeze({}),\n});\n\n/**\n * The per-atom memo of a completed reduction, and the guard against an atom whose definition leads\n * back to itself. **Both are keyed on the atom OBJECT, never on `atom.code`.**\n *\n * Keying on the code string made these tables a channel between atoms that merely share a code.\n * `reduce` is exported and takes a caller-built `UnitNode`, and nothing checks that an atom on it\n * came from the vendored table, so a forged atom wrote under a shipped atom's key and every later\n * reduction of the shipped atom in that process read what the forged one left. Measured on `0.0.5`,\n * forging `{ code: \"L\" }` with no `value` as the first touch of `L`: `ucumEqual(\"L\", \"1\")` and\n * `ucumEqual(\"mg/L\", \"mg\")` both answered `true` (control: `false`), and `mmol/L` reduced without\n * its `m-3` — a concentration reading equal to a mass, out of a never-fabricate engine.\n *\n * Identity keying makes an entry describe the atom it was computed from, and it does not cost the\n * hot path: the atoms `parseUcum` resolves are the singletons `loadUcumEssence` caches, so a parsed\n * expression still finds one entry per atom, and the lookup is a reference compare rather than a\n * string hash. Benchmarked warm against the string-keyed original two ways — separate processes,\n * and both trees alternating inside one process, best-of-n over hundreds of thousands of `reduce`\n * calls — the difference did **not** reproduce in either direction: over twelve alternating trials\n * the head/base ratio landed above 1 four times and below it eight, spread far wider than any\n * difference between the two. So the claim here is\n * only that identity keying has **no measured cost on the hot path**, and no figures are quoted,\n * because three drafts quoted three pairs and none of them was reproducible. Do not add one back.\n * An atom a caller\n * built gets its own entry, collected with it — the containers hold their keys weakly, so forged\n * atoms cannot accumulate either.\n *\n * **Identity keying closes the forged-atom route and does not reach the mutation one, so the other\n * half of the answer lives in `essence.ts`.** An entry describing the atom it was computed from is\n * still a lie if that atom was rewritten before it was computed: until this change the shared table\n * was `readonly` to TypeScript only, and defining the loaded litre as `1` before the litre's first\n * reduction made `ucumEqual(\"L\", \"1\")` answer `true` for the life of the process, even after the\n * table was put back. The table is frozen now. Neither half substitutes for the other.\n */\nconst atomMemo = new WeakMap<UcumAtom, LinearReduction>();\nconst inProgress = new WeakSet<UcumAtom>();\n\n/** Reduce a single (non-special) atom to base units, memoized per atom. */\nfunction reduceAtomLinear(atom: UcumAtom): LinearReduction {\n // Every base atom in the bundled table carries its `dim`, but this function is reachable with an\n // atom a caller assembled, so `?? atom.code` is a real arm rather than a type-narrowing fallback\n // and is covered as one. It used to sit under a `/* v8 ignore next */` asserting the table's\n // property as if it were the exported surface's — the same over-scoped claim that hid a leak one\n // function over. Answering a forged base atom on its own code changes nothing for the table's\n // atoms: it is keyed by identity like every other memo entry.\n if (atom.base) return { kind: \"linear\", factor: 1, dims: { [atom.dim ?? atom.code]: 1 } };\n // Arbitrary units are not commensurable with anything else: give each its own dimension axis.\n if (atom.arbitrary) return { kind: \"linear\", factor: 1, dims: { [`arb:${atom.code}`]: 1 } };\n\n const cached = atomMemo.get(atom);\n if (cached) return cached;\n\n // The three guards below. No expression `parseUcum` accepts reaches any of them, but **that is a\n // property of `reduce`'s own control flow, not of the unit table** — an earlier wording of this\n // comment said the table's atoms all carry a resolvable definition and that was false. Measured on\n // the bundled v2.2 table: of its 312 atoms, 28 carry no `value` at all — the 7 base units and the\n // 21 special ones (`Cel`, `[pH]`, `B`, `Np`, `[degF]`, …), 0 arbitrary. What keeps them out of\n // here is that `reduce` short-circuits a special-containing expression to the opaque `special`\n // form before any linear reduction, and base and arbitrary atoms are answered above. Of the 291\n // non-special atoms — the 7 base units, answered above, plus the 284 that carry a `value` — every\n // one reduces fully: no definition chain in the table reaches a value-less atom, an unparseable\n // definition, or a cycle. **284 is the count that carries a `value`, not the count of non-special\n // atoms**, and a draft of this comment attached it to the wrong noun; both are asserted in\n // `test/ucum/reduce-memo.test.ts` so neither can drift from the table. That file's last case is\n // the sweep this comment rests on.\n //\n // Reachability differs per guard, and this is deliberate. A caller-assembled atom reaches the two\n // below it: nothing checks an atom's provenance, and an atom **defined in terms of a special unit**\n // (`{ value: { unit: \"Cel\" } }`) lands on the table's own `Cel` in the no-linear-definition guard.\n // The cyclic guard is reached differently again, and this took three wrong descriptions to get\n // right — do not re-derive it from the shape of the code, because the shape is misleading. Naming\n // is not enough: a definition is resolved by `parseUcum` against the loaded table, so an assembled\n // atom, or one off a second table built with `parseEssence`, can name a table atom but never be\n // one; a self-referential `Pa` taken off a table copy resolves to the shipped pascal and answers\n // 1000 g.m-1.s-2. Corrupting a *loaded* atom in place used to reach it and no longer does, because\n // the table is frozen. **What reaches it is an ACCESSOR**: `UcumAtom.value` is `readonly` to\n // TypeScript only, which a getter satisfies, and `atom.value.unit` is read *below*, after\n // `inProgress.add(atom)` — so a caller's getter runs inside the recursion and can re-enter\n // `reduce` with this very atom. No mutation, no table, no cast. That is a supported public call\n // and it is pinned in `test/ucum/reduce.test.ts`, under a 100,000-byte atom code, so this guard\n // is covered rather than excluded. A definition cycle in the vendored table would reach it too,\n // and the whole-table sweep in `reduce-memo.test.ts` asserts there is not one today.\n //\n // Every message here is a literal. A caller-assembled `atom.code` is unbounded: interpolating one\n // produced a 1,000,042-byte `Error.message`, with those same bytes in `err.stack`, on `0.0.5`.\n // Do not put an atom back into a message, and do not memoize an answer for an atom none of these\n // let through. All three are pinned in `test/ucum/reduce.test.ts` by whole-message equality, a\n // length bound, and `err.stack` under a 100,000-byte caller-supplied code. Equality is the\n // load-bearing part — `toThrowError(string)` is a substring match, and a draft that used only that\n // stayed green with the atom interpolated back in.\n if (inProgress.has(atom)) {\n throw new Error(\"cyclic UCUM atom definition in the unit table\");\n }\n if (!atom.value) {\n // This atom carries no linear definition and is neither a base nor an arbitrary unit, so there\n // is nothing to reduce. Answering \"dimensionless\" here is what let a value-less assembled `L`\n // equal `1`. The message says \"no linear definition\" rather than blaming the table, because both\n // its reachable cases are real: an atom that was never in the table, and a shipped **special**\n // atom, which is in the table and legitimately has no linear form.\n throw new Error(\"UCUM atom has no linear definition\");\n }\n\n inProgress.add(atom);\n try {\n const parsed = parseUcum(atom.value.unit);\n if (!parsed.ok) {\n throw new Error(\"unparseable UCUM essence definition in the unit table\");\n }\n const reduced = linearReduceTerm(parsed.node);\n const result = multiply({ kind: \"linear\", factor: atom.value.factor, dims: {} }, reduced);\n atomMemo.set(atom, result);\n return result;\n } finally {\n // `finally`, because `linearReduceTerm` can throw while this atom is marked in progress — an\n // atom defined in terms of a special unit reaches the no-linear-definition guard from inside the\n // recursion, and one whose definition does not parse reaches the guard just above. The delete\n // used to sit on the success path only, so the entry stayed behind and every later reduction\n // touching that atom hit the cyclic guard for the rest of the process. Measured on published\n // `0.0.5`, where a forged atom coded `N` and defined as `N` did re-enter the cyclic guard,\n // because the keys were code strings: after one such call every `ucumEqual(\"N\", \"kg.m/s2\")`\n // threw. **That route is closed here** — identity keys mean an assembled atom is never the table\n // atom its definition names, and the same call now reduces cleanly. The `finally` is still\n // load-bearing, for the two throws named above rather than for that one. Do not read the message\n // literals in this file back onto `0.0.5`: it threw `cyclic UCUM atom definition for 'N'`, still\n // interpolating the atom. These literals are newer than that build.\n inProgress.delete(atom);\n }\n}\n\n/** Reduce a simple unit (prefix?+atom+exponent), assuming it is not special. */\nfunction reduceSimpleLinear(node: SimpleUnitNode): LinearReduction {\n const base = reduceAtomLinear(node.atom);\n const prefixed = node.prefix\n ? { kind: \"linear\" as const, factor: base.factor * node.prefix.factor, dims: base.dims }\n : base;\n return power(prefixed, node.exponent);\n}\n\n/** Reduce one component to a linear form (specials handled separately by the caller). */\nfunction linearReduceComponent(comp: ComponentNode): LinearReduction {\n switch (comp.kind) {\n case \"factor\":\n return { kind: \"linear\", factor: comp.value, dims: {} };\n case \"annotation\":\n return DIMENSIONLESS;\n case \"group\":\n return linearReduceTerm(comp.term);\n case \"simple\":\n return reduceSimpleLinear(comp);\n }\n}\n\n/** Reduce a whole term to a linear form (assumes no special units in the tree). */\nfunction linearReduceTerm(node: UnitNode): LinearReduction {\n // A fresh accumulator, not the shared `DIMENSIONLESS`: this value can be what `reduce` returns.\n let acc: LinearReduction = { kind: \"linear\", factor: 1, dims: {} };\n for (const { sign, node: comp } of node.factors) {\n acc = multiply(acc, power(linearReduceComponent(comp), sign));\n }\n return acc;\n}\n\n/** Whether any simple unit anywhere in the tree is a special (non-linear) unit. */\nfunction containsSpecial(node: UnitNode): boolean {\n return node.factors.some(({ node: comp }) => {\n if (comp.kind === \"simple\") return comp.atom.special;\n if (comp.kind === \"group\") return containsSpecial(comp.term);\n return false;\n });\n}\n\n/** A normalized, order-independent token string for a special-containing expression. */\nfunction serializeSpecial(node: UnitNode): string {\n const tokens: string[] = [];\n const walk = (t: UnitNode, outerSign: number): void => {\n for (const { sign, node: comp } of t.factors) {\n const s = sign * outerSign;\n if (comp.kind === \"simple\") {\n const net = comp.exponent * s;\n tokens.push(`${comp.prefix?.code ?? \"\"}${comp.atom.code}${net === 1 ? \"\" : String(net)}`);\n } else if (comp.kind === \"factor\") {\n tokens.push(`#${String(comp.value)}${s === 1 ? \"\" : `^${String(s)}`}`);\n } else if (comp.kind === \"group\") {\n walk(comp.term, s);\n }\n // annotations are inert — dropped\n }\n };\n walk(node, 1);\n return tokens.sort().join(\".\");\n}\n\n/**\n * Reduce a parsed UCUM unit to its canonical {@link Reduction} — a linear scalar×dimension form, or\n * an opaque `special` form for expressions involving a non-linear special unit.\n *\n * The reduction of one atom is cached against **that atom object**, so a `UnitNode` you assembled\n * yourself is answered from its own atoms and cannot change how a unit off {@link parseUcum} reduces,\n * in this call or any later one.\n *\n * @param node - The AST from {@link parseUcum}.\n * @returns The reduced form.\n * @throws {Error} If reducing `node` reaches an atom with no linear definition, or one whose\n * definition does not parse. **No expression {@link parseUcum} accepts reaches either**; a node\n * you assemble yourself can, including by defining an atom in terms of a special unit such as\n * `Cel`, which lands on the table's own `Cel`. A third guard catches a definition that leads back\n * to itself. Naming a table atom does not reach it — a definition is resolved against the loaded\n * table, so your atom can name one but never be one — and neither does the table itself, which is\n * frozen; what reaches it is a `value` accessor that re-enters `reduce` for the same atom while\n * that atom is still being reduced. The message names the fault, never the atom.\n * @example\n * ```ts\n * import { parseUcum, reduce } from \"@cosyte/terminology\";\n *\n * const parsed = parseUcum(\"N\");\n * if (parsed.ok) {\n * const r = reduce(parsed.node);\n * r.kind; // => \"linear\" (1000 × g·m·s⁻²)\n * }\n * ```\n */\nexport function reduce(node: UnitNode): Reduction {\n if (containsSpecial(node)) return { kind: \"special\", form: serializeSpecial(node) };\n return linearReduceTerm(node);\n}\n","/**\n * The public **UCUM** surface: {@link validateUcum} (recognition + a canonical\n * descriptor) and {@link ucumEqual} (are two expressions the *same unit*).\n *\n * Both are **recognition / validation / representation-canonicalization only** — never magnitude\n * conversion. The never-fabricate posture holds: an unparseable or unknown unit is\n * a typed {@link TERM_UCUM_INVALID} outcome carrying a value-free reason, **never** a guessed\n * \"nearest\" unit; and a special (non-linear) unit is never claimed equal to a linear one.\n *\n * @packageDocumentation\n */\n\nimport { parseUcum } from \"./parse.js\";\nimport { reduce } from \"./reduce.js\";\nimport type { Reduction, UcumValidation } from \"./types.js\";\n\n/** Round a scalar to 12 significant figures so float noise never splits two equal units. */\nfunction roundFactor(x: number): string {\n return String(Number(x.toPrecision(12)));\n}\n\n/** Serialize a reduction to a stable, comparison-ready canonical descriptor string. */\nfunction canonicalOf(r: Reduction): string {\n if (r.kind === \"special\") return `special:${r.form}`;\n const keys = Object.keys(r.dims).sort();\n const dims = keys.length === 0 ? \"1\" : keys.map((k) => `${k}${String(r.dims[k])}`).join(\".\");\n return `${roundFactor(r.factor)} ${dims}`;\n}\n\n/**\n * Validate a UCUM unit expression and, when valid, return its canonical descriptor.\n *\n * Validation **is** parsing against the UCUM grammar over the known atom table: an expression is\n * valid iff it parses completely. An invalid expression returns a typed {@link TERM_UCUM_INVALID}\n * with a value-free reason — never a coerced or guessed unit.\n *\n * @param unit - The UCUM unit expression (e.g. `\"mmol/L\"`, `\"kg.m/s2\"`, `\"Cel\"`).\n * @returns `{ valid: true, canonical }` or `{ valid: false, code: \"TERM_UCUM_INVALID\", reason }`.\n * @example\n * ```ts\n * import { validateUcum } from \"@cosyte/terminology\";\n *\n * validateUcum(\"mmol/L\").valid; // => true\n * const bad = validateUcum(\"mg/dl/\"); // trailing operator\n * bad.valid; // => false\n * ```\n */\nexport function validateUcum(unit: string): UcumValidation {\n const parsed = parseUcum(unit);\n if (!parsed.ok) return { valid: false, code: \"TERM_UCUM_INVALID\", reason: parsed.reason };\n return { valid: true, canonical: canonicalOf(reduce(parsed.node)) };\n}\n\n/**\n * Whether two UCUM expressions denote the **same unit** — i.e. they reduce to the same canonical\n * form (equal base dimensions *and* equal scale). This recognizes representational equivalences\n * (`N` ≡ `kg.m/s2`, `mmol/L` ≡ `mmol.L-1`, annotations inert) but is **not** magnitude conversion:\n * `mg` and `g` are different units and compare unequal.\n *\n * A unit is never equal to an invalid expression, and a special (non-linear) unit (`Cel`, `[pH]`) is\n * equal only to a structurally identical special unit — never to a linear unit (the never-fabricate\n * posture: the engine will not assert an equivalence it cannot prove).\n *\n * @param a - The first UCUM unit expression.\n * @param b - The second UCUM unit expression.\n * @returns `true` iff both are valid and denote the same unit.\n * @example\n * ```ts\n * import { ucumEqual } from \"@cosyte/terminology\";\n *\n * ucumEqual(\"N\", \"kg.m/s2\"); // => true\n * ucumEqual(\"mmol/L\", \"mmol.L-1\"); // => true\n * ucumEqual(\"mg\", \"g\"); // => false\n * ```\n */\nexport function ucumEqual(a: string, b: string): boolean {\n const va = validateUcum(a);\n const vb = validateUcum(b);\n return va.valid && vb.valid && va.canonical === vb.canonical;\n}\n","/**\n * The CMS **ICD-9 ↔ ICD-10 GEMs** (General Equivalence Mappings) loader + applier.\n *\n * The GEMs are **CMS/NCHS public-domain** (US-government work) reference mappings between the ICD-9-CM\n * and ICD-10-CM diagnosis classifications. CMS is emphatic about what they are — *\"GEMs are not\n * crosswalks. They are reference mappings… the raw material from which providers… derive specific\n * applied mappings\"* — so this resolver treats a GEM hit as a **candidate**, never an equivalence:\n *\n * - **Approximate by default.** Position-1 flag: most entries are approximate (source and target are\n * not identical in meaning). The flag rides through; the engine asserts nothing beyond it.\n * - **No-Map is first-class.** A source with no valid target carries the `NoDx` sentinel (and the\n * position-2 flag); {@link applyGem} returns a typed {@link CrosswalkNoMap}, never a guessed code.\n * - **1:many, never collapsed.** A source with several targets returns the **whole** candidate set.\n * - **Combination clusters.** A combination source (position-3 flag) maps to a *combination* of\n * targets grouped by scenario (position 4) and choice list (position 5); the result surfaces that\n * structure so a caller can build valid clusters, never a single fabricated target.\n * - **Directional, never inverted.** The forward (9→10) and backward (10→9) files are **separate,\n * non-inverse** artifacts; {@link invertGem} refuses to synthesize one from the other.\n *\n * The engine ships **no GEM content**: the caller supplies the public-domain GEM file (BYO).\n *\n * @packageDocumentation\n */\n\nimport { TerminologyError, FATAL_CODES } from \"../common/diagnostics.js\";\nimport { frozenMap } from \"../common/frozen-map.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport type {\n CrosswalkNoMap,\n CrosswalkUnmapped,\n GemApplyResult,\n GemChoiceList,\n GemDirection,\n GemEntry,\n GemFlags,\n GemLoadWarning,\n GemMap,\n GemMatched,\n GemScenario,\n} from \"./types.js\";\n\n/** The diagnosis GEM No-Map target sentinel — the source has no valid ICD equivalent. */\nconst NO_DX = \"NoDx\";\n/** The procedure GEM No-Map target sentinel (accepted so the reader also serves the PCS GEMs). */\nconst NO_PCS = \"NoPCS\";\n\n/** Is a target field the CMS No-Map sentinel (`NoDx` / `NoPCS`)? */\nfunction isNoMapSentinel(target: string): boolean {\n return target === NO_DX || target === NO_PCS;\n}\n\n/**\n * A raw GEM source file, plus the direction it maps and its release version. BYO — the caller\n * supplies the public-domain CMS GEM file content.\n */\nexport interface GemSource {\n /** The raw GEM file content (whitespace-delimited: `source target flags`, one entry per line). */\n readonly content: string;\n /** Which direction this file maps (`\"9-to-10\"` for `…_I9gem.txt`, `\"10-to-9\"` for `…_I10gem.txt`). */\n readonly direction: GemDirection;\n /** The GEM release/version (e.g. `\"2018\"`), when known — mappings are release-scoped. */\n readonly version?: string;\n}\n\n/**\n * Decode a GEM 5-position flag field into typed {@link GemFlags}. The layout (CMS Dx GEM User's\n * Guide) is `approximate | no-map | combination | scenario | choice-list`, one digit each.\n */\nfunction decodeFlags(raw: string): GemFlags | undefined {\n if (!/^[0-9]{5}$/.test(raw)) return undefined;\n return Object.freeze({\n approximate: raw[0] === \"1\",\n noMap: raw[1] === \"1\",\n combination: raw[2] === \"1\",\n scenario: Number(raw[3]),\n choiceList: Number(raw[4]),\n raw,\n });\n}\n\n/**\n * Load a CMS GEM file into an immutable {@link GemMap}, keyed by source code.\n *\n * Liberal on load: a structurally unusable *line* (not three whitespace-delimited fields, or a\n * malformed 5-digit flag) is **skipped and surfaced** as a {@link GemLoadWarning}, never a\n * partially-parsed entry. An unusable *source* is not possible here (an all-malformed file loads to an\n * empty map with warnings) — there is no fatal for GEM load. Ships **no** GEM content: the entries are\n * the caller's public-domain file.\n *\n * @param source - The {@link GemSource} (raw content + direction + version).\n * @returns The immutable {@link GemMap}.\n * @example\n * ```ts\n * import { loadGems, applyGem } from \"@cosyte/terminology\";\n *\n * // Synthetic rows in the CMS GEM format (source target flags): an exact map and a No-Map.\n * const gems = loadGems({\n * direction: \"9-to-10\",\n * version: \"2018\",\n * content: \"0010 A000 00000\\nV290 NoDx 11000\\n\",\n * });\n * applyGem(gems, \"0010\").mapped; // => true\n * ```\n */\nexport function loadGems(source: GemSource): GemMap {\n const entries = new Map<string, GemEntry[]>();\n const warnings: GemLoadWarning[] = [];\n let count = 0;\n const lines = source.content.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i++) {\n const raw = lines[i];\n if (raw === undefined) continue;\n const trimmed = raw.trim();\n if (trimmed === \"\") continue;\n const fields = trimmed.split(/\\s+/);\n if (fields.length !== 3) {\n warnings.push(\n Object.freeze({\n code: \"TERM_GEM_MALFORMED_ROW\",\n line: i + 1,\n detail: `expected 3 whitespace-delimited fields, found ${String(fields.length)}`,\n }),\n );\n continue;\n }\n const [src, tgt, flagStr] = fields as [string, string, string];\n const flags = decodeFlags(flagStr);\n if (flags === undefined) {\n warnings.push(\n Object.freeze({\n code: \"TERM_GEM_MALFORMED_ROW\",\n line: i + 1,\n detail: \"flag field is not a 5-digit code\",\n }),\n );\n continue;\n }\n const entry: Writable<GemEntry> = { source: src, flags };\n // A No-Map row carries the sentinel target and no real code — never surface it as a target.\n if (!isNoMapSentinel(tgt)) entry.target = tgt;\n const frozen = Object.freeze(entry);\n const list = entries.get(src);\n if (list) list.push(frozen);\n else entries.set(src, [frozen]);\n count++;\n }\n // Freeze each source's candidate list, then hand out the index as a read-only view rather than the\n // map itself. `Object.freeze` below reaches neither: a `Map`'s entries live in an internal slot,\n // and the lists were only `readonly` to TypeScript. Without both, a holder could delete an\n // ICD-9 → ICD-10 mapping, or push a target the steward's file never authored into one, and\n // {@link applyGem} would answer from it.\n for (const list of entries.values()) Object.freeze(list);\n return Object.freeze({\n direction: source.direction,\n ...(source.version !== undefined ? { version: source.version } : {}),\n count,\n entries: frozenMap(entries, \"a loaded GEM map's entries\"),\n warnings: Object.freeze(warnings),\n });\n}\n\n/** Build the scenario→choice-list combination structure from a source's combination entries. */\nfunction buildCombinations(entries: readonly GemEntry[]): readonly GemScenario[] | undefined {\n const combo = entries.filter((e) => e.flags.combination && e.target !== undefined);\n if (combo.length === 0) return undefined;\n // Group by scenario, then by choice list, preserving file order within each choice list.\n const scenarioNums: number[] = [];\n const byScenario = new Map<number, Map<number, string[]>>();\n for (const e of combo) {\n const s = e.flags.scenario;\n let lists = byScenario.get(s);\n if (!lists) {\n lists = new Map<number, string[]>();\n byScenario.set(s, lists);\n scenarioNums.push(s);\n }\n const cl = e.flags.choiceList;\n const targets = lists.get(cl);\n if (targets) targets.push(e.target as string);\n else lists.set(cl, [e.target as string]);\n }\n const scenarios: GemScenario[] = [];\n for (const s of scenarioNums.sort((a, b) => a - b)) {\n const lists = byScenario.get(s) as Map<number, string[]>;\n const choiceLists: GemChoiceList[] = [];\n for (const cl of [...lists.keys()].sort((a, b) => a - b)) {\n choiceLists.push(\n Object.freeze({ choiceList: cl, targets: Object.freeze(lists.get(cl) as string[]) }),\n );\n }\n scenarios.push(Object.freeze({ scenario: s, choiceLists: Object.freeze(choiceLists) }));\n }\n return Object.freeze(scenarios);\n}\n\n/**\n * Apply a loaded GEM map to a source code, in the map's authored direction only.\n *\n * Returns the **full** candidate set (never collapsed to one), with each entry's steward flags; a\n * combination source additionally surfaces its scenario/choice-list structure. A source the steward\n * marked No-Map (`NoDx` sentinel) is a typed {@link CrosswalkNoMap}; a source **absent** from the map\n * is a typed {@link CrosswalkUnmapped} — the two are distinct, and neither is ever a fabricated code.\n *\n * @param map - A {@link GemMap} from {@link loadGems}.\n * @param source - The source code (in the map's source classification).\n * @returns A {@link GemApplyResult}.\n * @example\n * ```ts\n * import { loadGems, applyGem } from \"@cosyte/terminology\";\n *\n * const gems = loadGems({ direction: \"9-to-10\", content: \"V290 NoDx 11000\\n\" });\n * const r = applyGem(gems, \"V290\");\n * r.mapped; // => false\n * ```\n */\nexport function applyGem(map: GemMap, source: string): GemApplyResult {\n const all = map.entries.get(source);\n if (all === undefined || all.length === 0) {\n const unmapped: CrosswalkUnmapped = Object.freeze({\n mapped: false,\n noMap: false,\n code: \"TERM_CROSSWALK_UNMAPPED\",\n source,\n });\n return unmapped;\n }\n\n // Target presence (the `NoDx`/`NoPCS` sentinel is dropped at load) is authoritative for No-Map —\n // the ground truth for \"is there a code to return\", decoupled from the flag digit (which is\n // carried on `flags.noMap` for fidelity but, in real CMS data, always agrees with the sentinel).\n const realTargets = all.filter((e) => e.target !== undefined);\n if (realTargets.length === 0) {\n // Every entry for this source is a No-Map — the steward says it cannot be classified.\n const noMap: CrosswalkNoMap = Object.freeze({\n mapped: false,\n noMap: true,\n code: \"TERM_CROSSWALK_NO_MAP\",\n source,\n entries: Object.freeze([...all]),\n });\n return noMap;\n }\n\n const combinations = buildCombinations(realTargets);\n const matched: Writable<GemMatched> = {\n mapped: true,\n source,\n direction: map.direction,\n entries: Object.freeze([...realTargets]),\n };\n if (combinations !== undefined) matched.combinations = combinations;\n return Object.freeze(matched);\n}\n\n/**\n * The frozen fatal message per authored direction, and the fallback for anything else. A **closed-set\n * lookup, not an interpolation**: `GemSource.direction` is typed `GemDirection`, but a JavaScript\n * caller can put any string there, and interpolating it would put an unbounded caller-supplied value\n * into `TerminologyError.message` and `err.stack`. Naming the direction is worth keeping because it\n * tells the caller which file to load instead — so it is kept, from a table the engine owns.\n */\nconst NOT_INVERTIBLE_MESSAGE: ReadonlyMap<string, string> = new Map([\n [\"9-to-10\", \"GEM map (direction 9-to-10) cannot be inverted — load the 10-to-9 GEM file instead\"],\n [\"10-to-9\", \"GEM map (direction 10-to-9) cannot be inverted — load the 9-to-10 GEM file instead\"],\n]);\n\n/** The message for a map whose `direction` is not one of the two authored GEM directions. */\nconst NOT_INVERTIBLE_UNKNOWN_DIRECTION =\n \"GEM map cannot be inverted — load the reverse GEM file instead\";\n\n/**\n * Refuse to invert a directional GEM map. **Always throws** {@link FATAL_CODES.TERM_MAP_NOT_INVERTIBLE}.\n *\n * The never-invert invariant made explicit and discoverable: a forward GEM (9→10) is **not** the\n * inverse of the backward GEM (10→9) — CMS ships them as separate artifacts and *\"forward and\n * backward mappings are not simply the reverse\"*. To resolve the other direction, load\n * the other file with {@link loadGems}; the engine never synthesizes an inverse.\n *\n * @param map - The map an inversion was (incorrectly) requested for.\n * @returns Never — always throws.\n * @throws {TerminologyError} `TERM_MAP_NOT_INVERTIBLE`, always.\n * @example\n * ```ts runnable throws\n * import { loadGems, invertGem } from \"@cosyte/terminology\";\n *\n * const gems = loadGems({ direction: \"9-to-10\", content: \"0010 A000 00000\\n\" });\n * invertGem(gems); // throws TERM_MAP_NOT_INVERTIBLE\n * ```\n */\nexport function invertGem(map: GemMap): never {\n throw new TerminologyError(\n FATAL_CODES.TERM_MAP_NOT_INVERTIBLE,\n NOT_INVERTIBLE_MESSAGE.get(map.direction) ?? NOT_INVERTIBLE_UNKNOWN_DIRECTION,\n );\n}\n","/**\n * Steward-defined **map category** and **map-relationship** identifiers the crosswalk resolvers carry\n * through verbatim — the SNOMED CT complex-map `mapCategoryId` concepts and the map-correlation\n * concepts. These are SNOMED CT metadata concepts, and **they are bundled**: the four ids below and\n * their steward descriptions ship inside this package. SNOMED CT is copyright © International Health\n * Terminology Standards Development Organisation. **No SNOMED CT refset or release is bundled** — a\n * caller still supplies the map refset itself under their own SNOMED CT licence (the BYO posture).\n *\n * The category on a resolved SNOMED→ICD-10-CM map row is the steward telling the caller *how much to\n * trust the target*: a `447638001` \"cannot be classified\" row is a **No-Map**, a `447640006`\n * \"ambiguous\" row must surface its candidates rather than pick one, and a `447639009`\n * \"context-dependent\" row needs runtime patient context. The resolver never collapses these to a\n * single confident target.\n *\n * @packageDocumentation\n */\n\n/**\n * The SNOMED CT complex-map **map category** concept ids — the `mapCategoryId` column of the\n * SNOMED→ICD-10-CM extended-map refset. These four SNOMED CT concepts — id and steward description —\n * are **bundled** in this package (SNOMED CT is copyright © International Health Terminology\n * Standards Development Organisation); carried through a resolution verbatim so a caller sees the\n * steward's own trust signal.\n *\n * @example\n * ```ts\n * import { MAP_CATEGORIES } from \"@cosyte/terminology\";\n *\n * MAP_CATEGORIES.NO_MAP; // => \"447638001\"\n * ```\n */\nexport const MAP_CATEGORIES = {\n /** `447637006` — \"Map source concept is properly classified\" (a normal, usable target). */\n PROPERLY_CLASSIFIED: \"447637006\",\n /** `447638001` — \"Map source concept cannot be classified with available data\" — a **No-Map**. */\n NO_MAP: \"447638001\",\n /** `447639009` — \"Map of source concept is context dependent\" (needs runtime patient context). */\n CONTEXT_DEPENDENT: \"447639009\",\n /** `447640006` — \"Source concept is ambiguous\" — surface candidates, never pick one. */\n AMBIGUOUS: \"447640006\",\n} as const;\n\n/** A value from {@link MAP_CATEGORIES} — the SNOMED map-category id carried on a resolution. */\nexport type MapCategoryId = (typeof MAP_CATEGORIES)[keyof typeof MAP_CATEGORIES];\n\n/**\n * The set of {@link MAP_CATEGORIES} ids the resolver treats as a **No-Map** (a typed, surfaced\n * \"cannot be classified\", never a fabricated target).\n */\nexport const NO_MAP_CATEGORIES: ReadonlySet<string> = new Set([MAP_CATEGORIES.NO_MAP]);\n\n/**\n * The canonical code-system URI for **ICD-10-CM** — the target system of both crosswalks. A published\n * identity fact (mirrors {@link ../systems/registry.SYSTEM_IDENTITIES}); attached to a resolved\n * target {@link ../common/coding.Coding} so a translation is self-describing.\n */\nexport const ICD10CM_SYSTEM = \"http://hl7.org/fhir/sid/icd-10-cm\";\n\n/**\n * The canonical code-system URI for **ICD-9-CM** (the legacy diagnosis classification the GEMs bridge\n * to/from). A published identity fact; attached to a GEM target/source coding.\n */\nexport const ICD9CM_SYSTEM = \"http://hl7.org/fhir/sid/icd-9-cm\";\n\n/**\n * The canonical code-system URI for **SNOMED CT** — the source system of the SNOMED→ICD-10-CM complex\n * map. Recognised by URI only; **no SNOMED CT refset or release is bundled**.\n */\nexport const SNOMEDCT_SYSTEM = \"http://snomed.info/sct\";\n","/**\n * The **SNOMED CT → ICD-10-CM complex-map** resolver — a rule-based, **BYO**\n * resolver over the caller-supplied complex/extended-map refset. **No SNOMED CT refset or release is\n * bundled**: the engine ships the rule machinery; the caller supplies the map rows from their own\n * SNOMED CT release. (Individual SNOMED CT concepts this resolver *names* are bundled: the\n * map-category concepts a row's `mapCategoryId` refers to — see\n * {@link ../crosswalk/categories.MAP_CATEGORIES} — and the two gender findings a gender `IFA` rule\n * is written against.)\n *\n * The map is *\"semi-automated\"* by the steward's own statement — 1:many, context-dependent, with\n * first-class No-Map states. The resolver honours that:\n *\n * - **Map groups are an AND.** A source needing a manifestation *and* an etiology code has two groups;\n * {@link applyComplexMap} resolves each independently and returns one result per group.\n * - **Priorities are an if-then-else.** Within a group, rules run in ascending priority; the first\n * whose `IFA` predicate the caller's context satisfies wins.\n * - **Context it wasn't given, it never guesses.** If deciding a group requires an `IFA` predicate\n * (an age band, a gender) the caller left unspecified, the group is a typed\n * {@link ComplexMapContextRequired} carrying the candidate rules + advice — never a silently-picked\n * branch.\n * - **No-Map is typed.** A `447638001` \"cannot be classified\" row (or an empty target) is a typed\n * No-Map, never a fabricated code.\n * - **Advice rides through verbatim.** `CONSIDER LATERALITY`, `EPISODE OF CARE INFORMATION NEEDED`,\n * manifestation-code advice — carried untouched to the caller.\n * - **Never inverted.** The map is applied SNOMED→ICD-10-CM only; the reverse is a separate artifact.\n *\n * @packageDocumentation\n */\n\nimport { coding } from \"../common/coding.js\";\nimport { TerminologyError, FATAL_CODES } from \"../common/diagnostics.js\";\nimport { frozenMap } from \"../common/frozen-map.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { ICD10CM_SYSTEM, MAP_CATEGORIES, SNOMEDCT_SYSTEM } from \"./categories.js\";\nimport type {\n ComplexMap,\n ComplexMapApplyResult,\n ComplexMapEntry,\n ComplexMapGroupResult,\n ComplexMapLoadWarning,\n ComplexMapMatched,\n CrosswalkUnmapped,\n PatientContext,\n} from \"./types.js\";\n\n/** SNOMED concept id for the \"Female (finding)\" clinical-finding used in gender `IFA` rules. */\nconst SNOMED_FEMALE = \"248152002\";\n/** SNOMED concept id for the \"Male (finding)\" clinical-finding used in gender `IFA` rules. */\nconst SNOMED_MALE = \"248153007\";\n\n/**\n * The discriminated input {@link loadComplexMap} accepts — already-structured refset rows, or a raw\n * RF2 tab-delimited extended-map refset the caller exported from their SNOMED release.\n */\nexport type ComplexMapInput =\n | {\n readonly format: \"rows\";\n readonly rows: readonly ComplexMapEntry[];\n readonly version?: string;\n }\n | { readonly format: \"rf2\"; readonly content: string; readonly version?: string };\n\n/** Freeze a {@link ComplexMapEntry}, dropping absent optional fields (no `undefined` keys). */\nfunction freezeEntry(e: ComplexMapEntry): ComplexMapEntry {\n const out: Writable<ComplexMapEntry> = {\n source: e.source,\n group: e.group,\n priority: e.priority,\n rule: e.rule,\n advice: e.advice,\n };\n if (e.target !== undefined && e.target !== \"\") out.target = e.target;\n if (e.category !== undefined && e.category !== \"\") out.category = e.category;\n if (e.correlation !== undefined && e.correlation !== \"\") out.correlation = e.correlation;\n return Object.freeze(out);\n}\n\n/** Parse an RF2 extended-map refset (tab-delimited, header row) into structured rows + warnings. */\nfunction parseRf2(content: string): {\n rows: ComplexMapEntry[];\n warnings: ComplexMapLoadWarning[];\n} {\n const rows: ComplexMapEntry[] = [];\n const warnings: ComplexMapLoadWarning[] = [];\n const lines = content.split(/\\r?\\n/);\n if (lines.length === 0 || lines[0] === undefined || lines[0].trim() === \"\") {\n throw new TerminologyError(\n FATAL_CODES.TERM_CROSSWALK_MALFORMED,\n \"complex-map RF2: empty content (no header row)\",\n );\n }\n const header = lines[0].split(\"\\t\").map((h) => h.trim());\n const col = (name: string): number => header.indexOf(name);\n const iActive = col(\"active\");\n const iSource = col(\"referencedComponentId\");\n const iGroup = col(\"mapGroup\");\n const iPriority = col(\"mapPriority\");\n const iRule = col(\"mapRule\");\n const iAdvice = col(\"mapAdvice\");\n const iTarget = col(\"mapTarget\");\n const iCorr = col(\"correlationId\");\n const iCat = col(\"mapCategoryId\");\n if (iSource < 0 || iGroup < 0 || iPriority < 0) {\n throw new TerminologyError(\n FATAL_CODES.TERM_CROSSWALK_MALFORMED,\n \"complex-map RF2: header is missing a required column (referencedComponentId/mapGroup/mapPriority)\",\n );\n }\n const at = (fields: readonly string[], i: number): string =>\n i >= 0 && i < fields.length ? (fields[i] ?? \"\") : \"\";\n for (let i = 1; i < lines.length; i++) {\n const raw = lines[i];\n if (raw === undefined || raw === \"\") continue;\n const f = raw.split(\"\\t\");\n // Skip inactive refset members (RF2 active flag \"0\"), liberal-on-load.\n if (iActive >= 0 && at(f, iActive) === \"0\") continue;\n const source = at(f, iSource);\n const groupN = Number(at(f, iGroup));\n const priorityN = Number(at(f, iPriority));\n if (source === \"\" || !Number.isFinite(groupN) || !Number.isFinite(priorityN)) {\n warnings.push(\n Object.freeze({\n code: \"TERM_COMPLEX_MAP_MALFORMED_ROW\",\n line: i + 1,\n detail: \"row is missing referencedComponentId / mapGroup / mapPriority\",\n }),\n );\n continue;\n }\n rows.push({\n source,\n group: groupN,\n priority: priorityN,\n rule: at(f, iRule),\n advice: at(f, iAdvice),\n target: at(f, iTarget),\n category: at(f, iCat),\n correlation: at(f, iCorr),\n });\n }\n return { rows, warnings };\n}\n\n/**\n * Load a SNOMED→ICD-10-CM complex map from **caller-supplied** rows or a raw RF2 refset into an\n * immutable {@link ComplexMap}, keyed by source concept and ordered by (group, priority).\n *\n * Liberal on load: a structurally unusable RF2 *row* is skipped and surfaced as a warning; only an\n * unusable *source* (empty content, header missing required columns) is a fatal\n * {@link FATAL_CODES.TERM_CROSSWALK_MALFORMED}. Ships **no** SNOMED CT release or refset — the rows\n * are the caller's, under their own licence.\n *\n * @param input - Structured `rows`, or a raw RF2 extended-map refset `content`.\n * @returns The immutable {@link ComplexMap}.\n * @throws {TerminologyError} `TERM_CROSSWALK_MALFORMED` when the source is structurally unusable.\n * @example\n * ```ts\n * import { loadComplexMap } from \"@cosyte/terminology\";\n *\n * const map = loadComplexMap({\n * format: \"rows\",\n * rows: [\n * { source: \"195967001\", group: 1, priority: 1, rule: \"TRUE\", advice: \"ALWAYS J45.909\", target: \"J45.909\", category: \"447637006\" },\n * ],\n * });\n * map.count; // => 1\n * ```\n */\nexport function loadComplexMap(input: ComplexMapInput): ComplexMap {\n let rawRows: readonly ComplexMapEntry[];\n let warnings: readonly ComplexMapLoadWarning[];\n if (input.format === \"rf2\") {\n const parsed = parseRf2(input.content);\n rawRows = parsed.rows;\n warnings = Object.freeze(parsed.warnings);\n } else {\n rawRows = input.rows;\n warnings = Object.freeze([]);\n }\n\n const bySource = new Map<string, ComplexMapEntry[]>();\n for (const r of rawRows) {\n const e = freezeEntry(r);\n const list = bySource.get(e.source);\n if (list) list.push(e);\n else bySource.set(e.source, [e]);\n }\n // Order each source's rows by (group, priority) so evaluation is deterministic regardless of input.\n const entries = new Map<string, readonly ComplexMapEntry[]>();\n let count = 0;\n for (const [src, list] of bySource) {\n const sorted = [...list].sort((a, b) => a.group - b.group || a.priority - b.priority);\n entries.set(src, Object.freeze(sorted));\n count += sorted.length;\n }\n\n // Hand out the index as a read-only view rather than the map itself: `Object.freeze` below cannot\n // reach a `Map`'s entries, so without this a holder could delete a source concept's rules, or add\n // a rule the caller's refset never carried, and {@link applyComplexMap} would resolve from it.\n const out: Writable<ComplexMap> = {\n count,\n entries: frozenMap(entries, \"a loaded complex map's entries\"),\n warnings,\n };\n if (input.version !== undefined) out.version = input.version;\n return Object.freeze(out);\n}\n\n/** How a single map rule evaluates against the caller's context. */\ntype RuleMatch = \"match\" | \"no-match\" | \"unknown\";\n\n/**\n * Evaluate a **single** `IFA` conjunct (one predicate, no `AND`) against the context. A gender or\n * age predicate whose context the caller did not supply is `unknown` (never assumed); an `IFA`\n * predicate we cannot interpret is `unknown` (never assumed true or false).\n */\nfunction evaluateConjunct(clause: string, context: PatientContext): RuleMatch {\n const trimmed = clause.trim();\n if (!/^IFA\\b/i.test(trimmed)) return \"unknown\";\n\n // Gender predicate: `IFA 248152002 | Female (finding) |` (no comparator part).\n if (trimmed.includes(SNOMED_FEMALE)) {\n if (context.gender === undefined) return \"unknown\";\n return context.gender === \"female\" ? \"match\" : \"no-match\";\n }\n if (trimmed.includes(SNOMED_MALE)) {\n if (context.gender === undefined) return \"unknown\";\n return context.gender === \"male\" ? \"match\" : \"no-match\";\n }\n\n // Age predicate: `IFA <ageObservable> | … | <op> <value> year(s)`. Comparator + numeric + \"year\".\n const ageMatch = /(<=|>=|<|>|=)\\s*([0-9]+(?:\\.[0-9]+)?)\\s*year/i.exec(trimmed);\n if (ageMatch) {\n const op = ageMatch[1];\n const bound = Number(ageMatch[2]);\n if (context.ageYears === undefined || !Number.isFinite(bound)) return \"unknown\";\n const age = context.ageYears;\n const ok =\n op === \"<=\"\n ? age <= bound\n : op === \">=\"\n ? age >= bound\n : op === \"<\"\n ? age < bound\n : op === \">\"\n ? age > bound\n : op === \"=\"\n ? age === bound\n : undefined;\n if (ok === undefined) return \"unknown\";\n return ok ? \"match\" : \"no-match\";\n }\n // An `IFA` predicate we cannot interpret — never assume it true or false.\n return \"unknown\";\n}\n\n/**\n * Evaluate a `mapRule` against the caller's {@link PatientContext}.\n *\n * A SNOMED→ICD-10-CM map rule can be a **conjunction** of `IFA` predicates joined by `AND` — the map\n * uses this for bounded age intervals (`… >= 15 years AND … < 55 years`) and gender+age combinations\n * (`IFA … | Female (finding) | AND IFA … age … < 55 years`). Each conjunct is evaluated and the\n * results combined **fail-safe**: `no-match` if *any* conjunct is a no-match; `unknown` (→\n * context-required) if any needed conjunct is `unknown` and none is a no-match; `match` **only** when\n * *every* conjunct matches. A conjunct is never dropped, so a rule is never confidently applied while\n * one of its conditions is undecided (context is never guessed).\n *\n * The split is on an uppercase `AND` that begins a new `IFA` clause, so a lowercase `and` (or an\n * uppercase `AND`) inside a concept's term description never falsely splits the rule.\n */\nfunction evaluateRule(rule: string, context: PatientContext): RuleMatch {\n const trimmed = rule.trim();\n // Unconditional fall-through — always the default branch.\n if (/^(OTHERWISE\\s+)?TRUE$/.test(trimmed)) return \"match\";\n\n const conjuncts = trimmed.split(/\\s+AND\\s+(?=IFA\\b)/);\n let sawUnknown = false;\n for (const c of conjuncts) {\n const m = evaluateConjunct(c, context);\n if (m === \"no-match\") return \"no-match\"; // any failed condition ⇒ the whole rule is false\n if (m === \"unknown\") sawUnknown = true; // an undecided condition blocks a confident match\n }\n return sawUnknown ? \"unknown\" : \"match\";\n}\n\n/** Is this entry a No-Map (steward category `447638001`, or an empty target)? */\nfunction isNoMap(e: ComplexMapEntry): boolean {\n return e.category === MAP_CATEGORIES.NO_MAP || e.target === undefined;\n}\n\n/** Resolve one map group's ordered rules against the context into a {@link ComplexMapGroupResult}. */\nfunction resolveGroup(\n group: number,\n rules: readonly ComplexMapEntry[],\n context: PatientContext,\n): ComplexMapGroupResult {\n for (const entry of rules) {\n const m = evaluateRule(entry.rule, context);\n if (m === \"no-match\") continue;\n if (m === \"unknown\") {\n // We cannot decide this branch without context the caller did not supply — surface, never pick.\n return Object.freeze({\n outcome: \"context-required\",\n code: \"TERM_CROSSWALK_CONTEXT_REQUIRED\",\n group,\n rules,\n });\n }\n // m === \"match\": this rule wins the group.\n if (isNoMap(entry)) {\n const noMap: Writable<Extract<ComplexMapGroupResult, { outcome: \"no-map\" }>> = {\n outcome: \"no-map\",\n code: \"TERM_CROSSWALK_NO_MAP\",\n group,\n advice: entry.advice,\n };\n if (entry.category !== undefined) noMap.category = entry.category;\n return Object.freeze(noMap);\n }\n const target = coding({ system: ICD10CM_SYSTEM, code: entry.target as string });\n const resolved: Writable<Extract<ComplexMapGroupResult, { outcome: \"resolved\" }>> = {\n outcome: \"resolved\",\n group,\n target,\n advice: entry.advice,\n rule: entry.rule,\n };\n if (entry.category !== undefined) resolved.category = entry.category;\n return Object.freeze(resolved);\n }\n // No rule matched and none was unknown (a map with no TRUE fallback) — refuse to guess.\n return Object.freeze({\n outcome: \"context-required\",\n code: \"TERM_CROSSWALK_CONTEXT_REQUIRED\",\n group,\n rules,\n });\n}\n\n/**\n * Apply a loaded SNOMED→ICD-10-CM complex map to a source concept and patient context.\n *\n * Resolves **each map group** independently (groups are an AND — a source needing multiple ICD-10-CM\n * codes has multiple groups) by running its rules in priority order against `context`. A group whose\n * decision needs `IFA` context the caller did not supply is a typed\n * {@link ComplexMapContextRequired}; a `447638001` row is a typed No-Map; every result carries the\n * steward's advice verbatim. **Never** fabricates a target, **never** inverts the map.\n *\n * @param map - A {@link ComplexMap} from {@link loadComplexMap}.\n * @param source - The SNOMED CT source concept id.\n * @param context - The caller-supplied {@link PatientContext} (age / gender). Optional; a missing\n * field that a rule needs yields a `context-required` group, never a guessed branch.\n * @returns A {@link ComplexMapApplyResult} — per-group resolutions, or a typed absence.\n * @example\n * ```ts\n * import { loadComplexMap, applyComplexMap } from \"@cosyte/terminology\";\n *\n * const map = loadComplexMap({\n * format: \"rows\",\n * rows: [\n * { source: \"72098002\", group: 1, priority: 1, rule: \"IFA 248152002 | Female (finding) |\", advice: \"MAP IS CONTEXT DEPENDENT FOR GENDER\", target: \"O00.9\", category: \"447639009\" },\n * { source: \"72098002\", group: 1, priority: 2, rule: \"OTHERWISE TRUE\", advice: \"CANNOT BE CLASSIFIED\", category: \"447638001\" },\n * ],\n * });\n * const r = applyComplexMap(map, \"72098002\", { gender: \"female\" });\n * r.mapped; // => true\n * ```\n */\nexport function applyComplexMap(\n map: ComplexMap,\n source: string,\n context: PatientContext = {},\n): ComplexMapApplyResult {\n const rows = map.entries.get(source);\n if (rows === undefined || rows.length === 0) {\n const unmapped: CrosswalkUnmapped = Object.freeze({\n mapped: false,\n noMap: false,\n code: \"TERM_CROSSWALK_UNMAPPED\",\n source,\n });\n return unmapped;\n }\n\n // Partition the source's ordered rows into map groups (already sorted by group, then priority).\n const groupNumbers: number[] = [];\n const byGroup = new Map<number, ComplexMapEntry[]>();\n for (const r of rows) {\n const list = byGroup.get(r.group);\n if (list) list.push(r);\n else {\n byGroup.set(r.group, [r]);\n groupNumbers.push(r.group);\n }\n }\n\n const groups: ComplexMapGroupResult[] = [];\n for (const g of groupNumbers) {\n const rules = Object.freeze(byGroup.get(g) as ComplexMapEntry[]);\n groups.push(resolveGroup(g, rules, context));\n }\n\n const matched: ComplexMapMatched = Object.freeze({\n mapped: true,\n source,\n groups: Object.freeze(groups),\n });\n return matched;\n}\n\n/** The SNOMED CT source-system URI a complex-map source concept is drawn from (re-exported for docs). */\nexport const COMPLEX_MAP_SOURCE_SYSTEM = SNOMEDCT_SYSTEM;\n","/**\n * The RxNorm **term-type (`TTY`) vocabulary** relevant to the drug graph — the normal-form ladder and\n * the cross-link kinds — encoded as published identity facts (grounded firsthand on the NLM RxNorm\n * Technical Documentation, Appendix 5). **No RxNorm release is bundled**: what ships is these\n * *labels*, not the drug list.\n *\n * The RxNorm normal-form graph runs `IN → SCDC → SCD → SBD` (ingredient → clinical-drug component →\n * semantic clinical drug → semantic branded drug), with `BN` (brand name) and `DF` (dose form) as\n * cross-links.\n *\n * **Appendix 5 splits these into two kinds, and the split is load-bearing.** A **defining** term type\n * (its \"Normalized Names\" table, `IN` … `DFG`) says what an `RXCUI` *is*. A **synonym** term type\n * (its \"Synonyms\" table, `PSN` / `SY` / `TMSY`) is Appendix 5's own word for an atom that is a\n * *\"synonym of another TTY\"*: it types a **name**, not a concept, so it can never be a concept's term\n * type. `ET` is in neither table; the appendix describes it only in prose, as \"a small number of\n * concepts with TTY=ET, a term type reserved for entry terms for dose forms\". Those are concepts in\n * their own right rather than synonyms carried on another, so `ET` counts as defining here. See\n * {@link isSynonymTermType} and {@link ../rxnorm/load.loadRxNormGraph}.\n *\n * @packageDocumentation\n */\n\nimport type { TermType } from \"./types.js\";\n\n/**\n * The drug-graph term types (`RXNCONSO.TTY`), each mapped to its **verbatim Appendix 5 name** (`ET`\n * excepted: the appendix publishes no Name for it, so the UMLS expansion \"Entry Term\" is used).\n * Encoded as an identity fact; a concept's `TTY` is carried verbatim on its\n * {@link ../rxnorm/types.RxNormConcept}, never re-labeled.\n *\n * The keys are the full Appendix 5 vocabulary, defining and synonym alike. Only the **defining** ones\n * can appear on a loaded concept (see {@link isSynonymTermType}).\n *\n * @example\n * ```ts\n * import { TERM_TYPES } from \"@cosyte/terminology\";\n *\n * TERM_TYPES.SCD; // => \"Semantic Clinical Drug\"\n * TERM_TYPES.SCDF; // => \"Semantic Clinical Drug Form\"\n * ```\n */\nexport const TERM_TYPES: Readonly<Record<TermType, string>> = Object.freeze({\n IN: \"Ingredient\",\n PIN: \"Precise Ingredient\",\n MIN: \"Multiple Ingredients\",\n BN: \"Brand Name\",\n SCDC: \"Semantic Clinical Drug Component\",\n SBDC: \"Semantic Branded Drug Component\",\n SCDF: \"Semantic Clinical Drug Form\",\n SBDF: \"Semantic Branded Drug Form\",\n SCDFP: \"Semantic Clinical Drug Form Precise\",\n SBDFP: \"Semantic Branded Drug Form Precise\",\n SCD: \"Semantic Clinical Drug\",\n SBD: \"Semantic Branded Drug\",\n SCDG: \"Semantic Clinical Drug Group\",\n SBDG: \"Semantic Branded Drug Group\",\n SCDGP: \"Semantic Clinical Drug Form Group Precise\",\n GPCK: \"Generic Pack\",\n BPCK: \"Brand Name Pack\",\n DF: \"Dose Form\",\n DFG: \"Dose Form Group\",\n PSN: \"Prescribable Name\",\n SY: \"Synonym\",\n TMSY: \"Tall Man Lettering Synonym\",\n ET: \"Entry Term\",\n});\n\n/** The set of {@link TERM_TYPES} keys, for fast recognition of a `TTY` string as a known term type. */\nconst KNOWN: ReadonlySet<string> = new Set(Object.keys(TERM_TYPES));\n\n/**\n * The **synonym-class** term types, verbatim from Appendix 5's \"Synonyms\" table. Each types a *name*\n * carried on some other concept, not a concept of its own.\n */\nconst SYNONYM: ReadonlySet<string> = new Set([\"PSN\", \"SY\", \"TMSY\"]);\n\n/**\n * Narrow a raw `RXNCONSO.TTY` string to a known {@link TermType}, or `undefined` when it is not a\n * drug-graph term type this engine models (the atom is then skipped at load, liberal-on-load, never\n * coerced to a wrong type).\n *\n * @param tty - The raw `TTY` value from an `RXNCONSO` row.\n * @returns The narrowed {@link TermType}, or `undefined` when unrecognized.\n * @example\n * ```ts\n * import { asTermType } from \"@cosyte/terminology\";\n *\n * asTermType(\"SCD\"); // => \"SCD\"\n * asTermType(\"ZZZ\"); // => undefined\n * ```\n */\nexport function asTermType(tty: string): TermType | undefined {\n return KNOWN.has(tty) ? (tty as TermType) : undefined;\n}\n\n/**\n * Is this term type a **synonym-class** one (`PSN` / `SY` / `TMSY`)?\n *\n * Appendix 5 defines each as a *\"synonym of another TTY\"*: it labels an alternate **name** for a\n * concept, never the concept's own kind. So a synonym atom can never establish an `RXCUI`'s term\n * type, and {@link ../rxnorm/load.loadRxNormGraph} will not let one: an `RXCUI` whose release\n * supplies only synonym atoms is skipped and surfaced, never typed `\"TMSY\"`.\n *\n * @param tty - A {@link TermType}.\n * @returns `true` for `PSN` / `SY` / `TMSY`; `false` for every defining term type.\n * @example\n * ```ts\n * import { isSynonymTermType } from \"@cosyte/terminology\";\n *\n * isSynonymTermType(\"TMSY\"); // => true\n * isSynonymTermType(\"SCDF\"); // => false\n * ```\n */\nexport function isSynonymTermType(tty: TermType): boolean {\n return SYNONYM.has(tty);\n}\n","/**\n * The **RxNorm drug graph loader** — build an immutable {@link RxNormGraph} from a\n * **caller-supplied** RxNorm RRF release (`RXNCONSO.RRF` + `RXNREL.RRF`, and optionally `RXNSAT.RRF`\n * for NDC attributes). Reuses the shared, zero-dep {@link ../codesystem/rrf.parseRrfLine} (pipe split,\n * reserved trailing pipe) — the same RRF reader the CodeSystem layer uses.\n *\n * **Column layouts, grounded firsthand** on the NLM RxNorm Technical Documentation (§ file\n * descriptions):\n * - `RXNCONSO.RRF` (18 cols): `RXCUI`(0) `LAT`(1) `TS`(2) `LUI`(3) `STT`(4) `SUI`(5) `ISPREF`(6)\n * `RXAUI`(7) `SAUI`(8) `SCUI`(9) `SDUI`(10) `SAB`(11) `TTY`(12) `CODE`(13) `STR`(14) `SRL`(15)\n * `SUPPRESS`(16) `CVF`(17). Only the **normalized** atoms (`SAB=RXNORM`) become graph concepts, and\n * only through a **defining** `TTY` (see \"Typing a concept\" below).\n * - `RXNREL.RRF` (16 cols): `RXCUI1`(0) `RXAUI1`(1) `STYPE1`(2) `REL`(3) `RXCUI2`(4) `RXAUI2`(5)\n * `STYPE2`(6) `RELA`(7) `RUI`(8) `SRUI`(9) `SAB`(10) `SL`(11) `RG`(12) `DIR`(13) `SUPPRESS`(14)\n * `CVF`(15). Read `subject = RXCUI2`, `predicate = RELA`, `object = RXCUI1` (the direction\n * convention — see {@link ../rxnorm/rela}). Only concept-level rows (both `RXCUI`s present) with a\n * non-empty `RELA` become edges; atom-level (`RXAUI`) rows are not part of the concept graph.\n * - `RXNSAT.RRF` (13 cols): `RXCUI`(0) … `ATN`(8) `SAB`(9) `ATV`(10) `SUPPRESS`(11) `CVF`(12). Rows\n * with `ATN=NDC` index `ATV`(the NDC) → `RXCUI`, marked `active` **as of** the loaded release.\n *\n * **Typing a concept (`RXNCONSO`).** An `RXCUI` carries one **defining** atom (its normalized\n * name, a `TTY` from Appendix 5's \"Normalized Names\" table) plus any number of **synonym** atoms, whose\n * `TTY` (`PSN`/`SY`/`TMSY`) Appendix 5 defines as a *\"synonym of another TTY\"*: it types a **name**,\n * not a concept. RxNorm documents no ordering between an `RXCUI`'s atoms, so the loader takes the\n * **defining** atom wherever it sits in the file (first-wins among defining atoms) and **never** falls\n * back to a synonym atom. An `RXCUI` that no defining atom could type, because every atom is\n * synonym-class or carries a `TTY` this engine does not model, is **skipped and surfaced** as a\n * `TERM_RXNORM_UNTYPED_CONCEPT` warning naming the line. Skipping is the deliberate choice: an absent\n * concept is already a first-class typed outcome (`TERM_RXNORM_UNKNOWN_RXCUI`), whereas a concept\n * whose `tty` reads `\"TMSY\"` is a fabricated claim about what the drug *is*, indistinguishable from a\n * real one.\n *\n * **Liberal on load**: a structurally unusable *row* (too few columns, missing a required\n * value) is **skipped and surfaced** as a `TERM_RXNORM_MALFORMED_ROW` warning, never a partial\n * concept/edge, never a crash. Rows that are simply *not of interest* (a non-`RXNORM` atom, an\n * atom-level relationship, a non-`NDC` attribute) are skipped **silently** — they are expected, not\n * faults. Ships **no** RxNorm release: every concept/edge is the caller's.\n *\n * @packageDocumentation\n */\n\nimport { parseRrfLine } from \"../codesystem/rrf.js\";\nimport { frozenMap } from \"../common/frozen-map.js\";\nimport type { Writable } from \"../common/writable.js\";\nimport { asTermType, isSynonymTermType } from \"./tty.js\";\nimport type {\n NdcStatus,\n RxNormConcept,\n RxNormEdge,\n RxNormGraph,\n RxNormLoadWarning,\n} from \"./types.js\";\n\n/** The normalized-content source-abbreviation whose atoms define RxNorm's own concepts. */\nconst SAB_RXNORM = \"RXNORM\";\n/** `RXNSAT.ATN` value marking an NDC attribute. */\nconst ATN_NDC = \"NDC\";\n\n// ── Column indices (grounded firsthand on the RxNorm Technical Documentation — see the module doc) ──\nconst CONSO = { RXCUI: 0, SAB: 11, TTY: 12, STR: 14, SUPPRESS: 16 } as const;\nconst REL = { RXCUI1: 0, RXCUI2: 4, RELA: 7 } as const;\nconst SAT = { RXCUI: 0, ATN: 8, ATV: 10 } as const;\n\n/**\n * A raw RxNorm RRF release, BYO. The caller supplies the public-domain Current Prescribable Content\n * subset or the full (licensed) release; the engine bundles **no** RxNorm release.\n */\nexport interface RxNormGraphSource {\n /** The raw `RXNCONSO.RRF` content (pipe-delimited concept/atom names). */\n readonly conso: string;\n /** The raw `RXNREL.RRF` content (pipe-delimited relationships). */\n readonly rel: string;\n /** The raw `RXNSAT.RRF` content (pipe-delimited attributes) — supply to resolve NDCs. Optional. */\n readonly sat?: string;\n /** The release version (e.g. `\"RXNORM_2026AA\"`), when known — mappings are release-scoped. */\n readonly version?: string;\n}\n\n/** Read a cell by index, trimmed; `undefined` when out of range. */\nfunction cell(cells: readonly string[], index: number): string | undefined {\n const v = cells[index];\n return v === undefined ? undefined : v.trim();\n}\n\n/**\n * Parse `RXNCONSO.RRF` into the `RXCUI → concept` map.\n *\n * **A concept is typed by a DEFINING atom, never by file order.** An `RXCUI` carries one defining\n * atom (its normalized name: `IN`/`SCD`/`SCDF`/`BN`/…) plus any number of synonym atoms, and RxNorm\n * documents no ordering between them within an `RXCUI`. So the defining atom wins wherever it sits\n * in the file, and the first defining atom wins among defining atoms. An `RXCUI` no defining atom\n * could type is **skipped and surfaced** (`TERM_RXNORM_UNTYPED_CONCEPT`), never typed from a synonym.\n */\nfunction parseConso(content: string, warnings: RxNormLoadWarning[]): Map<string, RxNormConcept> {\n const concepts = new Map<string, RxNormConcept>();\n const conso: RxNormLoadWarning[] = [];\n /** `RXCUI` → the first line whose atom could not type it. Cleared once a defining atom arrives. */\n const untyped = new Map<string, number>();\n\n for (const [i, raw] of content.split(/\\r?\\n/).entries()) {\n if (raw === \"\") continue;\n const cells = parseRrfLine(raw);\n // Need at least through STR(14) to be a usable concept row.\n if (cells.length <= CONSO.STR) {\n conso.push(\n Object.freeze({\n code: \"TERM_RXNORM_MALFORMED_ROW\",\n file: \"RXNCONSO\",\n line: i + 1,\n detail: `row has ${String(cells.length)} columns, need at least ${String(CONSO.STR + 1)}`,\n }),\n );\n continue;\n }\n // Only RxNorm-normalized atoms define concepts; other sources are expected, skip silently.\n if (cell(cells, CONSO.SAB) !== SAB_RXNORM) continue;\n\n const rxcui = cell(cells, CONSO.RXCUI);\n if (rxcui === undefined || rxcui === \"\") {\n conso.push(\n Object.freeze({\n code: \"TERM_RXNORM_MALFORMED_ROW\",\n file: \"RXNCONSO\",\n line: i + 1,\n detail: \"row is missing its RXCUI\",\n }),\n );\n continue;\n }\n\n // A TTY this engine does not model, or a synonym-class one (which types a NAME, not a concept),\n // cannot establish the concept's type. Remember the RXCUI so an atom-less-defining one is\n // surfaced rather than lost, and never fall back to it.\n const tty = asTermType(cell(cells, CONSO.TTY) ?? \"\");\n if (tty === undefined || isSynonymTermType(tty)) {\n if (!concepts.has(rxcui) && !untyped.has(rxcui)) untyped.set(rxcui, i + 1);\n continue;\n }\n\n if (concepts.has(rxcui)) continue; // first DEFINING atom per RXCUI wins\n untyped.delete(rxcui);\n\n const name = cell(cells, CONSO.STR) ?? \"\";\n const suppress = cell(cells, CONSO.SUPPRESS) ?? \"N\";\n concepts.set(\n rxcui,\n Object.freeze({ rxcui, tty, name, suppressed: suppress !== \"\" && suppress !== \"N\" }),\n );\n }\n\n for (const line of untyped.values()) {\n conso.push(\n Object.freeze({\n code: \"TERM_RXNORM_UNTYPED_CONCEPT\",\n file: \"RXNCONSO\",\n line,\n detail:\n \"no RXNORM atom established this RXCUI's term type (every atom was synonym-class or an unmodelled TTY); skipped rather than typed from a synonym\",\n }),\n );\n }\n // Keep the file's warnings in line order regardless of when each was decided. Appended one at a\n // time on purpose: a spread would pass every warning as an argument, and a large enough malformed\n // release (RRF files run to millions of rows) exceeds the argument limit and throws. This path\n // must never crash.\n conso.sort((a, b) => a.line - b.line);\n for (const w of conso) warnings.push(w);\n\n return concepts;\n}\n\n/** Parse `RXNREL.RRF` into `subject → edges`, normalizing each row to the documented direction. */\nfunction parseRel(\n content: string,\n warnings: RxNormLoadWarning[],\n): { edges: Map<string, RxNormEdge[]>; edgeCount: number } {\n const edges = new Map<string, RxNormEdge[]>();\n let edgeCount = 0;\n for (const [i, raw] of content.split(/\\r?\\n/).entries()) {\n if (raw === \"\") continue;\n const cells = parseRrfLine(raw);\n if (cells.length <= REL.RELA) {\n warnings.push(\n Object.freeze({\n code: \"TERM_RXNORM_MALFORMED_ROW\",\n file: \"RXNREL\",\n line: i + 1,\n detail: `row has ${String(cells.length)} columns, need at least ${String(REL.RELA + 1)}`,\n }),\n );\n continue;\n }\n const rela = cell(cells, REL.RELA);\n const rxcui1 = cell(cells, REL.RXCUI1);\n const rxcui2 = cell(cells, REL.RXCUI2);\n // No navigable predicate, or an atom-level (RXAUI) row with a blank RXCUI — not a concept edge.\n if (rela === undefined || rela === \"\") continue;\n if (rxcui1 === undefined || rxcui1 === \"\" || rxcui2 === undefined || rxcui2 === \"\") continue;\n\n // Direction convention (RxNorm techdoc §12.7): RELA is the relationship RXCUI2 HAS TO RXCUI1,\n // so subject = RXCUI2, object = RXCUI1.\n const edge: RxNormEdge = Object.freeze({ subject: rxcui2, predicate: rela, object: rxcui1 });\n const list = edges.get(rxcui2);\n if (list) list.push(edge);\n else edges.set(rxcui2, [edge]);\n edgeCount++;\n }\n return { edges, edgeCount };\n}\n\n/** Parse `RXNSAT.RRF` NDC attributes into `NDC → { rxcui, status }` (active as of the release). */\nfunction parseNdcs(\n content: string,\n warnings: RxNormLoadWarning[],\n): Map<string, { rxcui: string; status: NdcStatus }> {\n const ndcs = new Map<string, { rxcui: string; status: NdcStatus }>();\n for (const [i, raw] of content.split(/\\r?\\n/).entries()) {\n if (raw === \"\") continue;\n const cells = parseRrfLine(raw);\n if (cells.length <= SAT.ATV) {\n warnings.push(\n Object.freeze({\n code: \"TERM_RXNORM_MALFORMED_ROW\",\n file: \"RXNSAT\",\n line: i + 1,\n detail: `row has ${String(cells.length)} columns, need at least ${String(SAT.ATV + 1)}`,\n }),\n );\n continue;\n }\n if (cell(cells, SAT.ATN) !== ATN_NDC) continue; // not an NDC attribute — expected, skip silently\n const ndc = cell(cells, SAT.ATV);\n const rxcui = cell(cells, SAT.RXCUI);\n if (ndc === undefined || ndc === \"\" || rxcui === undefined || rxcui === \"\") {\n warnings.push(\n Object.freeze({\n code: \"TERM_RXNORM_MALFORMED_ROW\",\n file: \"RXNSAT\",\n line: i + 1,\n detail: \"NDC attribute row is missing its RXCUI or NDC value\",\n }),\n );\n continue;\n }\n // A first mapping per NDC wins; an NDC present in the release is active as of that release.\n if (!ndcs.has(ndc)) ndcs.set(ndc, Object.freeze({ rxcui, status: \"active\" }));\n }\n return ndcs;\n}\n\n/**\n * Load a **caller-supplied** RxNorm RRF release into an immutable {@link RxNormGraph}.\n *\n * Parses `RXNCONSO` (concepts), `RXNREL` (directed edges, normalized to the documented direction), and\n * — when supplied — `RXNSAT` (NDC attributes). Liberal on load: a structurally unusable row is a\n * skipped, surfaced {@link RxNormLoadWarning}, never partial. Ships **no** RxNorm release — the graph\n * is entirely the caller's release.\n *\n * A concept is typed only by a **defining** atom, never by a synonym-class one and never by file\n * order; an `RXCUI` no defining atom could type is skipped and surfaced as\n * `TERM_RXNORM_UNTYPED_CONCEPT`. See the module documentation.\n *\n * @param source - The {@link RxNormGraphSource} (RRF file contents + optional version).\n * @returns The immutable {@link RxNormGraph}.\n * @example\n * ```ts\n * import { loadRxNormGraph } from \"@cosyte/terminology\";\n *\n * // Synthetic rows in the RxNorm RRF wire format (no RxNorm release is bundled).\n * const graph = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|IN||lisinopril||N||\\n2|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||\",\n * // \"SCDC(2) has_ingredient IN(1)\": subject=RXCUI2=2, object=RXCUI1=1.\n * rel: \"1|||RN|2|||has_ingredient|||RXNORM||||||\",\n * });\n * graph.conceptCount; // => 2\n * ```\n */\nexport function loadRxNormGraph(source: RxNormGraphSource): RxNormGraph {\n const warnings: RxNormLoadWarning[] = [];\n const concepts = parseConso(source.conso, warnings);\n const { edges, edgeCount } = parseRel(source.rel, warnings);\n const ndcs =\n source.sat !== undefined ? parseNdcs(source.sat, warnings) : new Map<string, never>();\n\n // Freeze each edge list, then hand out the three indexes as read-only views rather than the maps\n // themselves. `Object.freeze(out)` below cannot reach a `Map`, so without this a holder could\n // clear the edges of a medication graph, delete a concept, or add one the release never\n // authored — and `conceptCount` / `edgeCount` would go on reporting the loaded figures.\n for (const list of edges.values()) Object.freeze(list);\n\n const out: Writable<RxNormGraph> = {\n concepts: frozenMap(concepts, \"a loaded RxNorm graph's concepts\"),\n edges: frozenMap(edges, \"a loaded RxNorm graph's edges\"),\n ndcs: frozenMap(ndcs, \"a loaded RxNorm graph's NDC index\"),\n conceptCount: concepts.size,\n edgeCount,\n warnings: Object.freeze(warnings),\n };\n if (source.version !== undefined) out.version = source.version;\n return Object.freeze(out);\n}\n","/**\n * The RxNorm **relationship (`RELA`) vocabulary** and the **direction convention** the drug graph is\n * built on — encoded here as published identity facts (like the code-system OID↔URI facts in\n * {@link ../systems/registry}), grounded firsthand on the NLM RxNorm Technical Documentation and the\n * UMLS Reference Manual. **No RxNorm release is bundled** — what ships is the relationship *names*\n * and the *rule* for reading a row's direction.\n *\n * **The direction rule (a documented medication-safety trap).** From the\n * RxNorm Technical Documentation (§12.7) and the UMLS Reference Manual, verbatim: *\"the direction of\n * REL — the relationship which the SECOND concept or atom (with … RXCUI2 …) HAS TO the FIRST concept\n * or atom (with … RXCUI1 …).\"* The doc's worked example — a row with `RXCUI1=1155862`, `RELA=isa`,\n * `RXCUI2=197589` — reads *\"197589 **isa** 1155862\"* (the second concept is-a the first).\n *\n * So an `RXNREL.RRF` row is read **`RXCUI2 ⟶RELA⟶ RXCUI1`**, and {@link ../rxnorm/load.loadRxNormGraph}\n * normalizes every row to `subject = RXCUI2`, `predicate = RELA`, `object = RXCUI1`. Concretely, a\n * `has_ingredient` row places the **having** concept in `RXCUI2` and what it *has* in `RXCUI1`; a\n * `tradename_of` row places the **branded** concept in `RXCUI2` and the **generic** in `RXCUI1` (the\n * brand *is a tradename of* the generic). Getting this backwards is a wrong-medication bug, so the\n * fixtures pin it against the doc's convention.\n *\n * **Direction is not topology, and the topology is not the obvious one.** Knowing how to read a row\n * does not tell you which rows exist. RxNorm authors `has_ingredient` from the **clinical** side\n * (`SCDC`/`SCDF`/`SCDG`) to an `IN`, and from the **branded** side (`SBD`/`SBDC`/`SBDF`/`SBDG`) to a\n * `BN` rather than to the active ingredient; it authors **no** `SCD ⟶ IN` ingredient edge at all, so\n * a clinical drug reaches its ingredient only through `consists_of`. The **precise** forms\n * (`SCDFP`/`SBDFP`/`SCDGP`) carry no `has_ingredient` row either: an `SCDFP` instead reaches its\n * basis-of-strength substances by `has_boss` (one-to-many, and its targets can be a `PIN` or a plain\n * `IN`), and the other two author no ingredient-bearing edge at all. Treat those pairings as the\n * ones RxNorm authors, not as a closed set, and read the `TTY` of what a traversal returns. See\n * {@link ../rxnorm/navigate.ingredientsOf}.\n *\n * @packageDocumentation\n */\n\n/**\n * The drug-graph `RELA` relationship names, grounded on the NLM RxNorm Technical Documentation\n * (Appendix 1). Each is directional and read `subject ⟶RELA⟶ object` after normalization (see the\n * module doc). RxNorm ships both members of an inverse pair as **separate rows**, so the graph\n * traverses the authored predicate for the direction it wants — it **never synthesizes an inverse**.\n *\n * @example\n * ```ts\n * import { RELA } from \"@cosyte/terminology\";\n *\n * RELA.HAS_INGREDIENT; // => \"has_ingredient\"\n * ```\n */\nexport const RELA = {\n /**\n * `has_ingredient`: subject *has ingredient* object. Authored from the clinical side\n * (`SCDC`/`SCDF`/`SCDG`) to an `IN` and from the branded side (`SBD`/`SBDC`/`SBDF`/`SBDG`) to a\n * `BN`; RxNorm authors no `SCD ⟶ IN` row.\n */\n HAS_INGREDIENT: \"has_ingredient\",\n /**\n * `ingredient_of`: subject *is an ingredient of* object. The authored inverse, so an `IN` reaches\n * clinical components and dose forms and a `BN` reaches branded concepts (the `SBD` included).\n * Neither reaches an `SCD`.\n */\n INGREDIENT_OF: \"ingredient_of\",\n /** `has_precise_ingredient` — subject *has precise ingredient* object (a `PIN`). */\n HAS_PRECISE_INGREDIENT: \"has_precise_ingredient\",\n /** `precise_ingredient_of` — inverse of `has_precise_ingredient`. */\n PRECISE_INGREDIENT_OF: \"precise_ingredient_of\",\n /** `tradename_of` — subject (a branded concept) *is a tradename of* object (its generic). */\n TRADENAME_OF: \"tradename_of\",\n /** `has_tradename` — subject (a generic concept) *has tradename* object (a branded concept). */\n HAS_TRADENAME: \"has_tradename\",\n /** `has_dose_form` — subject (a drug) *has dose form* object (a `DF`). */\n HAS_DOSE_FORM: \"has_dose_form\",\n /** `dose_form_of` — subject (a `DF`) *is the dose form of* object (a drug). */\n DOSE_FORM_OF: \"dose_form_of\",\n /** `has_doseformgroup` — subject *has dose-form group* object (a `DFG`). */\n HAS_DOSE_FORM_GROUP: \"has_doseformgroup\",\n /** `doseformgroup_of` — inverse of `has_doseformgroup`. */\n DOSE_FORM_GROUP_OF: \"doseformgroup_of\",\n /** `consists_of` — subject (an `SCD`/`SBD`) *consists of* object (its `SCDC`/`SBDC` component(s)). */\n CONSISTS_OF: \"consists_of\",\n /** `constitutes` — subject (a component) *constitutes* object (the drug). Inverse of `consists_of`. */\n CONSTITUTES: \"constitutes\",\n /** `contains` — subject (a pack) *contains* object (a member drug). */\n CONTAINS: \"contains\",\n /** `contained_in` — subject (a drug) *is contained in* object (a pack). Inverse of `contains`. */\n CONTAINED_IN: \"contained_in\",\n /** `has_quantified_form` — subject *has quantified form* object. */\n HAS_QUANTIFIED_FORM: \"has_quantified_form\",\n /** `quantified_form_of` — inverse of `has_quantified_form`. */\n QUANTIFIED_FORM_OF: \"quantified_form_of\",\n /** `isa` — subject *is a* object (hierarchical, e.g. `SCD isa SCDG`). */\n ISA: \"isa\",\n /** `inverse_isa` — subject *is a parent of* object. Inverse of `isa`. */\n INVERSE_ISA: \"inverse_isa\",\n} as const;\n\n/** A value from {@link RELA} — a drug-graph relationship name. */\nexport type RelaName = (typeof RELA)[keyof typeof RELA];\n\n/**\n * The authored **inverse pairs** of the drug-graph `RELA`s — a published fact (RxNorm Appendix 1),\n * used only to *document* and *validate* that a caller is traversing a real relationship. The graph\n * **never** uses this to synthesize a missing edge: RxNorm ships both directions, so\n * {@link ../rxnorm/navigate} follows whichever authored predicate points the way it wants to go.\n *\n * @example\n * ```ts\n * import { RELA_INVERSE, RELA } from \"@cosyte/terminology\";\n *\n * RELA_INVERSE[RELA.HAS_INGREDIENT]; // => \"ingredient_of\"\n * ```\n */\nexport const RELA_INVERSE: Readonly<Record<string, string>> = Object.freeze({\n [RELA.HAS_INGREDIENT]: RELA.INGREDIENT_OF,\n [RELA.INGREDIENT_OF]: RELA.HAS_INGREDIENT,\n [RELA.HAS_PRECISE_INGREDIENT]: RELA.PRECISE_INGREDIENT_OF,\n [RELA.PRECISE_INGREDIENT_OF]: RELA.HAS_PRECISE_INGREDIENT,\n [RELA.TRADENAME_OF]: RELA.HAS_TRADENAME,\n [RELA.HAS_TRADENAME]: RELA.TRADENAME_OF,\n [RELA.HAS_DOSE_FORM]: RELA.DOSE_FORM_OF,\n [RELA.DOSE_FORM_OF]: RELA.HAS_DOSE_FORM,\n [RELA.HAS_DOSE_FORM_GROUP]: RELA.DOSE_FORM_GROUP_OF,\n [RELA.DOSE_FORM_GROUP_OF]: RELA.HAS_DOSE_FORM_GROUP,\n [RELA.CONSISTS_OF]: RELA.CONSTITUTES,\n [RELA.CONSTITUTES]: RELA.CONSISTS_OF,\n [RELA.CONTAINS]: RELA.CONTAINED_IN,\n [RELA.CONTAINED_IN]: RELA.CONTAINS,\n [RELA.HAS_QUANTIFIED_FORM]: RELA.QUANTIFIED_FORM_OF,\n [RELA.QUANTIFIED_FORM_OF]: RELA.HAS_QUANTIFIED_FORM,\n [RELA.ISA]: RELA.INVERSE_ISA,\n [RELA.INVERSE_ISA]: RELA.ISA,\n});\n\n/** The canonical code-system URI for **RxNorm** — a published identity fact, attached to graph codings. */\nexport const RXNORM_SYSTEM = \"http://www.nlm.nih.gov/research/umls/rxnorm\";\n","/**\n * **RxNorm drug-graph navigation**: resolve a drug to its components and its\n * ingredient, a branded drug to its generic, a drug to its dose form, and an NDC to its `RXCUI`, over\n * a loaded {@link RxNormGraph}. Every query is **fail-safe and never-fabricate**:\n *\n * - a queried `RXCUI` absent from the graph is a typed {@link RxNormUnknown}, never a guessed concept;\n * - a present concept with no such relationship is a {@link RxNormRelated} with **empty** `targets` —\n * an honest, data-grounded \"no such edge\", distinct from \"unknown concept\";\n * - navigation follows only **authored** edges by their predicate; the engine **never synthesizes an\n * inverse** (RxNorm ships both directions as separate rows, so brand→generic follows the authored\n * `tradename_of` and generic→brand follows the authored `has_tradename`);\n * - an NDC not in the loaded release is a typed {@link NdcUnmapped}, and a resolution carries the\n * **as-of release** and temporal {@link ../rxnorm/types.NdcStatus} (never a timeless assertion);\n * - approximate matching is an **opt-in, explicitly labeled** path ({@link approximateMatch}), never\n * the default and never presented as an exact code resolution.\n *\n * @packageDocumentation\n */\n\nimport { RELA } from \"./rela.js\";\nimport type {\n NdcResult,\n RxNormApproximateMatch,\n RxNormConcept,\n RxNormGraph,\n RxNormNavResult,\n} from \"./types.js\";\n\n/**\n * Look up a single concept by `RXCUI`.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The concept unique identifier.\n * @returns The {@link RxNormConcept}, or `undefined` when the `RXCUI` is not in the release.\n * @example\n * ```ts\n * import { loadRxNormGraph, getConcept } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({ conso: \"1|ENG||||||||||RXNORM|IN||aspirin||N||\", rel: \"\" });\n * getConcept(g, \"1\")?.tty; // => \"IN\"\n * ```\n */\nexport function getConcept(graph: RxNormGraph, rxcui: string): RxNormConcept | undefined {\n return graph.concepts.get(rxcui);\n}\n\n/** Resolve the object `RXCUI`s of a source's edges (matching `predicates`) to loaded concepts. */\nfunction follow(\n graph: RxNormGraph,\n rxcui: string,\n predicates: ReadonlySet<string>,\n): RxNormNavResult {\n if (!graph.concepts.has(rxcui)) {\n return Object.freeze({ found: false, code: \"TERM_RXNORM_UNKNOWN_RXCUI\", rxcui });\n }\n const out: RxNormConcept[] = [];\n const seen = new Set<string>();\n for (const edge of graph.edges.get(rxcui) ?? []) {\n if (!predicates.has(edge.predicate)) continue;\n if (seen.has(edge.object)) continue;\n const target = graph.concepts.get(edge.object);\n // Only surface a target we actually loaded — an edge to an unloaded concept is a load-completeness\n // gap (the caller's release omitted that atom), never fabricated into a placeholder concept.\n if (target !== undefined) {\n out.push(target);\n seen.add(edge.object);\n }\n }\n return Object.freeze({\n found: true,\n rxcui,\n predicates: Object.freeze([...predicates]),\n targets: Object.freeze(out),\n });\n}\n\n/**\n * Follow one or more `RELA` predicates out of a concept (the generic navigation primitive). Direction\n * is the **authored** edge direction (`subject ⟶predicate⟶ object`); the engine never inverts.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The source concept.\n * @param predicate - A `RELA` name, or an array of them (any-of).\n * @returns A {@link RxNormNavResult}: the related concepts (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, relatedByRela, RELA } from \"@cosyte/terminology\";\n *\n * // \"SCDC(2) has_ingredient IN(1)\": subject=RXCUI2=2, object=RXCUI1=1.\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|IN||lisinopril||N||\\n2|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||\",\n * rel: \"1|||RN|2|||has_ingredient|||RXNORM||||||\",\n * });\n * const r = relatedByRela(g, \"2\", RELA.HAS_INGREDIENT);\n * r.found && r.targets[0]?.name; // => \"lisinopril\"\n * ```\n */\nexport function relatedByRela(\n graph: RxNormGraph,\n rxcui: string,\n predicate: string | readonly string[],\n): RxNormNavResult {\n const set = new Set(typeof predicate === \"string\" ? [predicate] : predicate);\n return follow(graph, rxcui, set);\n}\n\n/**\n * The **ingredients** of a concept — the concepts it links to by a **direct** `has_ingredient` /\n * `has_precise_ingredient` edge in the loaded release.\n *\n * This follows the *authored, direct* edge only (never-fabricate, never a synthesized path), and\n * **RxNorm's ingredient topology is not the obvious one**. Always read the `TTY` of what comes back:\n *\n * - concepts on the **clinical** side (`SCDC`, `SCDF`, `SCDG`) link to the ingredient itself, an\n * `IN`;\n * - concepts on the **branded** side (`SBD`, `SBDC`, `SBDF`, `SBDG`) link to their **brand name**, a\n * `BN`. That is what the release says and what is echoed back, term type included. It is *not* the\n * active ingredient. (`has_precise_ingredient`, which this function also follows, likewise reaches\n * a `PIN`.)\n * - a **clinical drug** (`SCD`) carries **no** `has_ingredient` edge at all. RxNorm authors none, in\n * any release, so this honestly returns found-with-empty-targets rather than walking a path on the\n * caller's behalf.\n * - the **precise** forms (`SCDFP`, `SBDFP`, `SCDGP`) carry **neither** edge, so this returns\n * found-with-empty-targets for them too. They do **not** behave like their non-precise siblings:\n * an `SCDFP` reaches its basis-of-strength substance(s) by `has_boss`, a one-to-many relation with\n * a different meaning whose targets can be a `PIN` or a plain `IN`, and which this function\n * deliberately does not follow; an `SBDFP` and an\n * `SCDGP` author no ingredient-bearing edge at all and are reached instead through `form_of` /\n * `tradename_of` / `isa`.\n *\n * Those pairings are the ones RxNorm authors, not a closed set a caller may rely on: check the\n * returned `TTY` rather than assuming it from the one you queried.\n *\n * **To reach an active ingredient, walk to the CLINICAL component and take its edge.** From an `SCD`\n * that is `SCD ⟶consists_of⟶ SCDC ⟶has_ingredient⟶ IN`, i.e. {@link consistsOf} then\n * `ingredientsOf`. From an `SBD` it needs one more decision, because `consists_of` returns **both**\n * its branded component (`SBDC`, whose own ingredient edge is the `BN` again) and the clinical\n * `SCDC`: it is the `SCDC` that leads to the `IN`. The engine never invents the transitive edge and\n * never picks that branch for you.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The concept (a drug or a clinical/branded component).\n * @returns The directly-linked ingredient concepts (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, ingredientsOf } from \"@cosyte/terminology\";\n *\n * // The ingredient edge is authored on the COMPONENT, not on the clinical drug.\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|IN||lisinopril||N||\\n2|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||\",\n * rel: \"1|||RN|2|||has_ingredient|||RXNORM||||||\",\n * });\n * ingredientsOf(g, \"2\").found; // => true\n * ```\n */\nexport function ingredientsOf(graph: RxNormGraph, rxcui: string): RxNormNavResult {\n return follow(graph, rxcui, new Set([RELA.HAS_INGREDIENT, RELA.HAS_PRECISE_INGREDIENT]));\n}\n\n/**\n * The **generic** form(s) of a branded concept — an `SBD`/`BN`/`BPCK` `tradename_of` its generic. The\n * authored forward edge; the engine never inverts a `has_tradename` edge to synthesize this.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The branded concept.\n * @returns The generic concept(s) (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, genericFor } from \"@cosyte/terminology\";\n *\n * // \"SBD(2) tradename_of SCD(1)\": subject=RXCUI2=2, object=RXCUI1=1.\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\\n2|ENG||||||||||RXNORM|SBD||lisinopril 10 MG Oral Tablet [Zestril]||N||\",\n * rel: \"1|||RN|2|||tradename_of|||RXNORM||||||\",\n * });\n * genericFor(g, \"2\").found; // => true\n * ```\n */\nexport function genericFor(graph: RxNormGraph, rxcui: string): RxNormNavResult {\n return follow(graph, rxcui, new Set([RELA.TRADENAME_OF]));\n}\n\n/**\n * The **branded** form(s) of a generic concept — an `SCD`/`IN`/`GPCK` that `has_tradename` a brand.\n * The authored forward edge; not a synthesized inverse of `tradename_of`.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The generic concept.\n * @returns The branded concept(s) (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, brandsFor } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\\n2|ENG||||||||||RXNORM|SBD||lisinopril 10 MG Oral Tablet [Zestril]||N||\",\n * rel: \"2|||RN|1|||has_tradename|||RXNORM||||||\",\n * });\n * brandsFor(g, \"1\").found; // => true\n * ```\n */\nexport function brandsFor(graph: RxNormGraph, rxcui: string): RxNormNavResult {\n return follow(graph, rxcui, new Set([RELA.HAS_TRADENAME]));\n}\n\n/**\n * The **dose form(s)** of a drug — the `DF`/`DFG` concepts it `has_dose_form` / `has_doseformgroup`.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The drug concept.\n * @returns The dose-form concept(s) (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, doseFormsOf } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\\n9|ENG||||||||||RXNORM|DF||Oral Tablet||N||\",\n * rel: \"9|||RN|1|||has_dose_form|||RXNORM||||||\",\n * });\n * doseFormsOf(g, \"1\").found; // => true\n * ```\n */\nexport function doseFormsOf(graph: RxNormGraph, rxcui: string): RxNormNavResult {\n return follow(graph, rxcui, new Set([RELA.HAS_DOSE_FORM, RELA.HAS_DOSE_FORM_GROUP]));\n}\n\n/**\n * The **components** a drug `consists_of` — an `SCD`/`SBD` → its `SCDC`/`SBDC` dose-form components.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param rxcui - The drug concept.\n * @returns The component concept(s) (possibly empty), or a typed unknown source.\n * @example\n * ```ts\n * import { loadRxNormGraph, consistsOf } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({\n * conso: \"2|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\\n3|ENG||||||||||RXNORM|SCDC||lisinopril 10 MG||N||\",\n * rel: \"3|||RN|2|||consists_of|||RXNORM||||||\",\n * });\n * consistsOf(g, \"2\").found; // => true\n * ```\n */\nexport function consistsOf(graph: RxNormGraph, rxcui: string): RxNormNavResult {\n return follow(graph, rxcui, new Set([RELA.CONSISTS_OF]));\n}\n\n/**\n * Resolve an **NDC** (National Drug Code) to its `RXCUI` in the loaded release, carrying the temporal\n * status and the as-of release. NDC↔RXCUI is many:1 and changes across releases, so an\n * NDC present in the release is `active` **as of that release**; an absent NDC is a typed\n * {@link NdcUnmapped}, never a guessed `RXCUI`.\n *\n * @param graph - A loaded {@link RxNormGraph} (load with `sat` supplied to populate NDC attributes).\n * @param ndc - The NDC (as it appears in the release, e.g. 11-digit).\n * @returns An {@link NdcResult} — a resolution with status + `asOf`, or a typed absence.\n * @example\n * ```ts\n * import { loadRxNormGraph, resolveNdc } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({\n * conso: \"2|ENG||||||||||RXNORM|SCD||lisinopril 10 MG Oral Tablet||N||\",\n * rel: \"\",\n * sat: \"2||||||||NDC|RXNORM|00000000000|N||\",\n * version: \"RXNORM_2026AA\",\n * });\n * const r = resolveNdc(g, \"00000000000\");\n * r.resolved && r.status; // => \"active\"\n * ```\n */\nexport function resolveNdc(graph: RxNormGraph, ndc: string): NdcResult {\n const hit = graph.ndcs.get(ndc);\n if (hit === undefined) {\n return Object.freeze({ resolved: false, code: \"TERM_RXNORM_NDC_UNMAPPED\", ndc });\n }\n const out = {\n resolved: true as const,\n ndc,\n rxcui: hit.rxcui,\n status: hit.status,\n ...(graph.version !== undefined ? { asOf: graph.version } : {}),\n };\n return Object.freeze(out);\n}\n\n/** Tokenize a drug name into a set of lowercased alphanumeric tokens (for similarity only). */\nfunction tokenize(name: string): Set<string> {\n return new Set(\n name\n .toLowerCase()\n .split(/[^a-z0-9]+/)\n .filter((t) => t !== \"\"),\n );\n}\n\n/** Jaccard similarity of two token sets in `[0, 1]` — a derived, labeled score, not a clinical claim. */\nfunction jaccard(a: ReadonlySet<string>, b: ReadonlySet<string>): number {\n if (a.size === 0 || b.size === 0) return 0;\n let inter = 0;\n for (const t of a) if (b.has(t)) inter++;\n const union = a.size + b.size - inter;\n return union === 0 ? 0 : inter / union;\n}\n\n/** Options for {@link approximateMatch}. */\nexport interface ApproximateMatchOptions {\n /** Minimum similarity (`0`–`1`) for a candidate to be returned. Default `0.34`. */\n readonly minScore?: number;\n /** Maximum number of candidates to return, best-first. Default `20`. */\n readonly limit?: number;\n}\n\n/**\n * **Opt-in, explicitly labeled** approximate name matching — find loaded concepts whose\n * names are token-similar to `query`. This is **never** the default resolution path and its results\n * are **never** an exact code assertion: every candidate is marked `approximate: true` with a derived\n * {@link RxNormApproximateMatch.score}. A caller opts in by calling this function explicitly.\n *\n * Coverage is not correctness: a \"no match\" is an **empty** array (typed, honest),\n * distinct from a fabricated nearest guess. The engine never promotes an approximate hit to an exact\n * one.\n *\n * @param graph - A loaded {@link RxNormGraph}.\n * @param query - A free-text drug name to match against loaded concept names.\n * @param options - {@link ApproximateMatchOptions} (min score, limit).\n * @returns The labeled approximate candidates, best-first (possibly empty). Never an exact resolution.\n * @example\n * ```ts\n * import { loadRxNormGraph, approximateMatch } from \"@cosyte/terminology\";\n *\n * const g = loadRxNormGraph({\n * conso: \"1|ENG||||||||||RXNORM|IN||lisinopril||N||\",\n * rel: \"\",\n * });\n * approximateMatch(g, \"lisinopril\")[0]?.approximate; // => true\n * ```\n */\nexport function approximateMatch(\n graph: RxNormGraph,\n query: string,\n options: ApproximateMatchOptions = {},\n): readonly RxNormApproximateMatch[] {\n const minScore = options.minScore ?? 0.34;\n const limit = options.limit ?? 20;\n const q = tokenize(query);\n if (q.size === 0) return Object.freeze([]);\n\n const scored: RxNormApproximateMatch[] = [];\n for (const concept of graph.concepts.values()) {\n const score = jaccard(q, tokenize(concept.name));\n if (score >= minScore) scored.push(Object.freeze({ approximate: true, concept, score }));\n }\n // Best-first; ties keep a stable order by RXCUI so the result is deterministic.\n scored.sort((a, b) => b.score - a.score || a.concept.rxcui.localeCompare(b.concept.rxcui));\n return Object.freeze(scored.slice(0, limit));\n}\n","/**\n * Public entry point for **`@cosyte/terminology`** — a zero-dependency, developer-focused\n * **terminology engine** for US healthcare code systems.\n *\n * Unlike its sibling `@cosyte/*` packages, this is **not a wire-format parser**: it mirrors the\n * **FHIR Terminology Module** (`$translate`, `$lookup`, `$validate-code`, `$expand`, …), operating\n * over **consumer-supplied** FHIR resources. It ships the *engine* and **no code-system release**\n * (SNOMED CT / CPT / LOINC / UMLS / RxNorm are strictly BYO). It is not content-free: see\n * **What is bundled** at the end of this note, which includes the UCUM unit table, the code-system\n * *identities* (OID ↔ URI), the SNOMED CT concepts the crosswalk resolver names and RxNorm's\n * relationship and term-type names, each with its copyright.\n *\n * **Code-system identity and ConceptMap translation:**\n *\n * - {@link resolveSystem} — the code-system identity / canonical-URI resolver (mnemonic | OID → URI).\n * - {@link loadConceptMap} + {@link translate} — the ConceptMap `$translate` engine, with the\n * **never-fabricate / never-invert** invariants: an unmapped source is a typed\n * {@link TranslateUnmapped}, never a guessed target; a directional map is never run backwards.\n *\n * **The CodeSystem load layer**, with the FHIR `$lookup` / `$validate-code` operations:\n *\n * - {@link loadCodeSystem} — load a **consumer-supplied** release (RRF / CSV / fixed-width / FHIR\n * `CodeSystem` JSON) into an immutable model. Ships the loader; **no code-system release**.\n * - {@link lookup} — code → display + properties, carrying status (deprecated / header-not-billable).\n * - {@link validateCode} — is a code a valid member of the system, with its status flags.\n *\n * The never-fabricate invariant holds here too: an unknown code is a typed `unknown` / `valid: false`,\n * never a fabricated display or a guessed `valid: true`.\n *\n * **The ValueSet binding layer** — FHIR `$expand` / `$validate-code` over a `compose`:\n *\n * - {@link loadValueSet} — load a **consumer-supplied** FHIR `ValueSet` (intensional `compose` and/or\n * a pre-computed `expansion`) into an immutable model.\n * - {@link expand} — flatten membership over the supplied {@link CodeSystem}s (`include`/`exclude`,\n * explicit `concept` lists, `is-a`/property `filter`s, referenced value sets), with an honest\n * `complete` flag: an unresolvable part is a typed `TERM_VALUESET_CANNOT_EXPAND`, never a guess.\n * - {@link validateCodeInValueSet} — binding membership, returning a **decided** `result` only when\n * proven and a typed `undetermined` otherwise (a truncated expansion never reads as complete).\n *\n * **The UCUM unit layer** — a hand-rolled UCUM grammar parser + validation + representation\n * canonicalization (recognition only, **no** magnitude conversion):\n *\n * - {@link validateUcum} — is a string a valid UCUM unit; if so, its canonical descriptor. An\n * invalid unit is a typed `TERM_UCUM_INVALID`, never a guessed \"nearest\" unit.\n * - {@link ucumEqual} — do two expressions denote the *same unit* (`N` ≡ `kg.m/s2`), by reducing\n * both to base dimensions. Not magnitude conversion (`mg/dL` → `mmol/L` is refused).\n * - {@link parseUcum} / {@link reduce} / {@link loadUcumEssence} — the underlying grammar parser,\n * dimensional reducer, and the in-memory model of the vendored, verbatim UCUM table.\n *\n * **The crosswalk resolvers** — the never-fabricate/never-invert invariant applied to the\n * published, directional reference maps:\n *\n * - {@link loadGems} + {@link applyGem} — the CMS **ICD-9↔ICD-10 GEMs** (public-domain reference\n * mappings), honoring the steward's Approximate / No-Map / Combination (scenario→choice-list) flags.\n * A No-Map source is a typed {@link CrosswalkNoMap}; a 1:many source returns the full candidate set.\n * - {@link loadComplexMap} + {@link applyComplexMap} — the NLM **SNOMED CT → ICD-10-CM complex map**\n * (BYO — **no SNOMED CT refset bundled**), evaluating Map Group / Priority / `IFA` Rule /\n * Advice / Category against caller-supplied {@link PatientContext}; a rule needing context the\n * caller lacks is a typed {@link ComplexMapContextRequired}, never a guessed branch.\n * - {@link invertGem} — the never-invert refusal made a first-class, thrown contract\n * ({@link FATAL_CODES.TERM_MAP_NOT_INVERTIBLE}).\n *\n * **The RxNorm drug relationship graph** — ingredient / brand / clinical-drug / dose-form\n * navigation over a **caller-supplied** RxNorm RRF release:\n *\n * - {@link loadRxNormGraph} — load `RXNCONSO` (concepts, typed by `TTY`), `RXNREL` (directed `RELA`\n * edges, normalized to the documented `RXCUI2 ⟶RELA⟶ RXCUI1` direction), and optionally `RXNSAT`\n * (NDC attributes) into an immutable graph. Ships **no** RxNorm release — BYO.\n * - {@link ingredientsOf} / {@link genericFor} / {@link brandsFor} / {@link doseFormsOf} /\n * {@link consistsOf} / {@link relatedByRela} — graph navigation following **authored** edges only\n * (the engine never synthesizes an inverse). An absent `RXCUI` is a typed {@link RxNormUnknown}.\n * - {@link resolveNdc} — NDC → `RXCUI` carrying the temporal status and the as-of release; an absent\n * NDC is a typed {@link NdcUnmapped}, never a guess.\n * - {@link approximateMatch} — the **opt-in, explicitly labeled** similarity path (never the default,\n * never an exact code assertion).\n *\n * **What is bundled.** No code-system release is. What is bundled includes the following, named with\n * its copyright:\n *\n * - the **UCUM unit table** (`ucum-essence.xml`, version 2.2, revision-date 2024-06-17) — copyright\n * ©1999–2024 Regenstrief Institute, Inc., all rights reserved, reproduced **verbatim** under the\n * UCUM Copyright Notice and License (https://ucum.org/license), embedded byte-for-byte in the\n * published build and parsed at runtime; no modified or derivative copy is distributed. The UCUM\n * Specification is provided \"as is\" **without warranty of any kind** — see the License for the\n * full disclaimer. The complete notice ships with this package at `vendor/ucum/NOTICE.md`.\n * - the **code-system identity facts** ({@link SYSTEM_IDENTITIES}) — OID ↔ canonical-URI pairings,\n * which identify the systems rather than listing any system's codes.\n * - the **SNOMED CT concepts the crosswalk resolver names**, each with its description: the four\n * map-category concepts ({@link MAP_CATEGORIES}) a complex-map row's `mapCategoryId` refers to, and\n * the two gender findings (`248152002` Female, `248153007` Male) a gender `IFA` rule is written\n * against. Further SNOMED CT identifiers, and ICD-10-CM codes, appear in the API documentation\n * examples, which are distributed in the compiled declaration files and in the build's\n * sourcemaps. SNOMED CT is copyright © International Health Terminology Standards\n * Development Organisation.\n * - the **RxNorm relationship and term-type names** the drug-graph API is written against: the\n * relationship names in {@link RELA} / {@link RELA_INVERSE} (`has_ingredient`, `tradename_of`, …),\n * and the term-type codes in {@link TERM_TYPES}, each with its name as published by the U.S.\n * National Library of Medicine (`SCD` reads \"Semantic Clinical Drug\"). Individual RxNorm\n * identifiers also appear in the API documentation examples, with their RxNorm names and term\n * types (for instance `RXCUI` `316151`, \"lisinopril 10 MG\"), and in `README.md` as well as the\n * places named above. RxNorm is produced by the National Library of Medicine; no RxNorm release\n * is bundled.\n *\n * The `LICENSE` file that ships with this package carries the MIT text for the package's own code\n * and a third-party notices section naming each of the above.\n *\n * The content packs that would change this (the CMS GEM files, the RxNorm Current Prescribable\n * subset) are not bundled; a caller supplies them, as they do a SNOMED CT, CPT, LOINC, UMLS or VSAC\n * release, under whatever terms its steward sets. This states what is distributed and under whose\n * copyright; it is not legal advice, and makes no claim about whether a particular use is permitted\n * to you.\n *\n * @packageDocumentation\n */\n\n/**\n * Library version string, kept in lockstep with `package.json#version`.\n *\n * Changesets owns the bump and rewrites `package.json` only, so the release `version` script runs\n * `scripts/sync-version.mjs` to rewrite this declaration in the same commit, and\n * `test/sanity.test.ts` compares the two so a skipped sync goes red instead of shipping a version\n * string that lies. That is not hypothetical: `0.0.1` went to the registry exporting `\"0.0.0\"`.\n *\n * @example\n * ```ts\n * import { VERSION } from \"@cosyte/terminology\";\n * typeof VERSION; // => \"string\"\n * ```\n */\nexport const VERSION: string = \"0.0.8\";\n\n// ── Value types ──────────────────────────────────────────────────────────────────────────────\nexport { coding, codeableConcept, type Coding, type CodeableConcept } from \"./common/coding.js\";\n\n// ── Diagnostics (value-free stable codes + typed error) ──────────────────────────────────────\nexport {\n DIAGNOSTIC_CODES,\n FATAL_CODES,\n TerminologyError,\n type DiagnosticCode,\n type FatalCode,\n} from \"./common/diagnostics.js\";\n\n// ── FHIR JSON navigation helpers (for consumers reading untrusted resources) ───────────────────\nexport { isJsonObject, getString, getArray, getBoolean, getNumber } from \"./common/fhir-json.js\";\n\n// ── Code-system identity / canonical-URI resolver ──────────────────────────────────────────────\nexport {\n resolveSystem,\n isUnknownSystem,\n type ResolveSystemResult,\n type UnknownSystem,\n} from \"./systems/resolve.js\";\nexport {\n SYSTEM_IDENTITIES,\n HL7_V2_OID_ROOT,\n HL7_V2_URL_PREFIX,\n type SystemIdentity,\n} from \"./systems/registry.js\";\n\n// ── ConceptMap $translate engine ──────────────────────────────────────────────────────────────\nexport { loadConceptMap } from \"./conceptmap/load.js\";\nexport { translate } from \"./conceptmap/translate.js\";\nexport type {\n ConceptMap,\n ConceptMapGroup,\n ConceptMapElement,\n ConceptMapTarget,\n ConceptMapUnmapped,\n MapProvenance,\n R4Equivalence,\n Relationship,\n TranslateMatch,\n TranslateMatched,\n TranslateResult,\n TranslateUnmapped,\n UnmappedMode,\n} from \"./conceptmap/types.js\";\n\n// ── CodeSystem load layer + $lookup / $validate-code ────────────────────────────────────────────\nexport { loadCodeSystem } from \"./codesystem/load.js\";\nexport { lookup, validateCode } from \"./codesystem/lookup.js\";\nexport { parseRrf, parseRrfLine } from \"./codesystem/rrf.js\";\nexport { parseCsv, parseCsvSource } from \"./codesystem/csv.js\";\nexport {\n parseFixedWidth,\n sliceField,\n ICD10CM_ORDER_FILE_FIELDS,\n} from \"./codesystem/fixed-width.js\";\nexport { parseFhirCodeSystem } from \"./codesystem/fhir.js\";\nexport { defaultStatusMapper, makeStatus } from \"./codesystem/status.js\";\nexport type {\n CodeSystem,\n CodeSystemSource,\n Concept,\n ConceptActivity,\n ConceptStatus,\n Property,\n LoadWarning,\n LookupOutcome,\n LookupResult,\n LookupUnknown,\n ValidateCodeResult,\n StatusMapper,\n FieldSlice,\n RrfSource,\n RrfColumnMap,\n RrfPropertyColumn,\n CsvSource,\n CsvColumnMap,\n FixedWidthSource,\n FixedWidthFieldMap,\n FixedWidthPropertyField,\n BillableFlag,\n FhirCodeSystemSource,\n} from \"./codesystem/types.js\";\n\n// ── ValueSet binding: compose / $expand / $validate-code ─────────────────────────────────────────\nexport { loadValueSet } from \"./valueset/load.js\";\nexport { expand } from \"./valueset/expand.js\";\nexport { validateCodeInValueSet } from \"./valueset/validate.js\";\nexport { buildSubsumption, isA, matchesFilter, unsupportedOps } from \"./valueset/filters.js\";\nexport type { Subsumption, FilterMatch } from \"./valueset/filters.js\";\nexport type {\n ValueSet,\n ValueSetCompose,\n ConceptSetComponent,\n ConceptSetFilter,\n ConceptRef,\n FilterOperator,\n ExpansionContains,\n ValueSetExpansion,\n ExpansionContext,\n ExpansionDiagnostic,\n ExpandResult,\n ValueSetMembership,\n ValueSetMemberDecided,\n ValueSetMemberUndetermined,\n} from \"./valueset/types.js\";\n\n// ── UCUM: unit grammar validation + representation canonicalization (recognition only) ────────────\nexport { validateUcum, ucumEqual } from \"./ucum/validate.js\";\nexport { parseUcum, type ParseResult, type ParseFailure } from \"./ucum/parse.js\";\nexport { reduce } from \"./ucum/reduce.js\";\nexport { loadUcumEssence } from \"./ucum/essence.js\";\nexport type {\n UcumValidation,\n UcumEssence,\n UcumPrefix,\n UcumAtom,\n UnitNode,\n ComponentNode,\n SimpleUnitNode,\n FactorNode,\n GroupNode,\n AnnotationNode,\n Reduction,\n LinearReduction,\n SpecialReduction,\n} from \"./ucum/types.js\";\n\n// ── Crosswalk resolvers: ICD-9↔ICD-10 GEMs + SNOMED→ICD-10-CM complex map (never-fabricate) ───────\nexport { loadGems, applyGem, invertGem, type GemSource } from \"./crosswalk/gems.js\";\nexport {\n loadComplexMap,\n applyComplexMap,\n COMPLEX_MAP_SOURCE_SYSTEM,\n type ComplexMapInput,\n} from \"./crosswalk/complex-map.js\";\nexport {\n MAP_CATEGORIES,\n NO_MAP_CATEGORIES,\n ICD10CM_SYSTEM,\n ICD9CM_SYSTEM,\n SNOMEDCT_SYSTEM,\n type MapCategoryId,\n} from \"./crosswalk/categories.js\";\nexport type {\n GemDirection,\n GemFlags,\n GemEntry,\n GemMap,\n GemLoadWarning,\n GemChoiceList,\n GemScenario,\n GemMatched,\n GemApplyResult,\n ComplexMapEntry,\n ComplexMap,\n ComplexMapLoadWarning,\n PatientContext,\n ComplexMapGroupResult,\n ComplexMapGroupResolved,\n ComplexMapGroupNoMap,\n ComplexMapContextRequired,\n ComplexMapMatched,\n ComplexMapApplyResult,\n CrosswalkNoMap,\n CrosswalkUnmapped,\n} from \"./crosswalk/types.js\";\n\n// ── RxNorm drug graph: ingredient / brand / clinical-drug / dose-form navigation (never-fabricate) ──\nexport { loadRxNormGraph, type RxNormGraphSource } from \"./rxnorm/load.js\";\nexport {\n getConcept,\n relatedByRela,\n ingredientsOf,\n genericFor,\n brandsFor,\n doseFormsOf,\n consistsOf,\n resolveNdc,\n approximateMatch,\n type ApproximateMatchOptions,\n} from \"./rxnorm/navigate.js\";\nexport { RELA, RELA_INVERSE, RXNORM_SYSTEM, type RelaName } from \"./rxnorm/rela.js\";\nexport { TERM_TYPES, asTermType, isSynonymTermType } from \"./rxnorm/tty.js\";\nexport type {\n TermType,\n RxNormConcept,\n RxNormEdge,\n RxNormGraph,\n RxNormLoadWarning,\n RxNormNavResult,\n RxNormRelated,\n RxNormUnknown,\n RxNormApproximateMatch,\n NdcStatus,\n NdcResolution,\n NdcUnmapped,\n NdcResult,\n} from \"./rxnorm/types.js\";\n"]}