@cosyte/astm 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -175,6 +175,28 @@ var WARNING_CODES = {
175
175
  * this warning flags the anomaly. Positional context only; no field value.
176
176
  */
177
177
  ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND: "ASTM_RECORD_AMBIGUOUS_MESSAGE_KIND",
178
+ /**
179
+ * A later `H` (header) record declared a **different** delimiter set from the one in force, and the
180
+ * parser **followed it**: that header and every record after it are read with the newly-declared
181
+ * delimiters, until the next `H`. Records already read keep the set that was in force when they were
182
+ * read — a redeclaration never reinterprets bytes that have already been consumed.
183
+ *
184
+ * A stream carrying several messages back to back is ordinary, and a header that simply **repeats**
185
+ * the delimiters already in force is a no-op that warns nothing. This code fires only when the set
186
+ * actually changes, because that is the point at which a reader still using the old set would begin
187
+ * merging fields together.
188
+ */
189
+ ASTM_RECORD_DELIMITERS_REDECLARED: "ASTM_RECORD_DELIMITERS_REDECLARED",
190
+ /**
191
+ * A later `H` (header) record could not declare a usable delimiter set — it was too short, or the
192
+ * field separator it named also appeared among the other three, leaving the four roles
193
+ * indistinguishable. The delimiters **already in force are kept** and every record is still surfaced;
194
+ * a set is never guessed and no record is dropped.
195
+ *
196
+ * The same condition on the *first* header is unrecoverable and remains the
197
+ * `ASTM_RECORD_UNDECLARED_DELIMITERS` fatal — there is no earlier set to fall back to.
198
+ */
199
+ ASTM_RECORD_UNREADABLE_REDECLARATION: "ASTM_RECORD_UNREADABLE_REDECLARATION",
178
200
  /**
179
201
  * The downgraded form an active vendor {@link AstmProfile} produces from a deviation it *expects*
180
202
  * (see `src/profiles/`). The original warning is **never dropped**: its code moves to
@@ -201,6 +223,20 @@ function nonStandardDelimiters(position) {
201
223
  position
202
224
  };
203
225
  }
226
+ function delimitersRedeclared(position) {
227
+ return {
228
+ code: WARNING_CODES.ASTM_RECORD_DELIMITERS_REDECLARED,
229
+ message: "A later header declared different delimiters \u2014 honored from that header onward; earlier records keep the set they were read with.",
230
+ position
231
+ };
232
+ }
233
+ function unreadableRedeclaration(position) {
234
+ return {
235
+ code: WARNING_CODES.ASTM_RECORD_UNREADABLE_REDECLARATION,
236
+ message: "A later header could not declare a usable delimiter set \u2014 the delimiters already in force were kept.",
237
+ position
238
+ };
239
+ }
204
240
  function unknownEscapeSequence(position) {
205
241
  return {
206
242
  code: WARNING_CODES.ASTM_UNKNOWN_ESCAPE_SEQUENCE,
@@ -897,6 +933,17 @@ function tokenizeRecord(record, d, onUnknownEscape) {
897
933
  const rawFields = splitEscapeAware(record, d.field, d.escape);
898
934
  return rawFields.map((raw, fieldIndex) => toField(raw, d, () => onUnknownEscape?.(fieldIndex)));
899
935
  }
936
+ function tokenizeHeader(record, d, onUnknownEscape) {
937
+ const defEnd = record.indexOf(d.field, 2);
938
+ const definition = defEnd === -1 ? record.slice(2) : record.slice(2, defEnd);
939
+ const head = [opaqueField(record.slice(0, Math.min(1, record.length))), opaqueField(definition)];
940
+ if (defEnd === -1) return head;
941
+ const data = tokenizeRecord(record.slice(defEnd + 1), d, (i) => onUnknownEscape?.(i + 2));
942
+ return [...head, ...data];
943
+ }
944
+ function opaqueField(raw) {
945
+ return { raw, components: [raw], repeats: [[raw]] };
946
+ }
900
947
  function toField(raw, d, onUnknownEscape) {
901
948
  const rawRepeats = splitEscapeAware(raw, d.repeat, d.escape);
902
949
  const repeats = rawRepeats.map(
@@ -950,9 +997,13 @@ function parseAstmRecords(raw, options = {}) {
950
997
  if (isNonStandard(delimiters)) {
951
998
  warnings.push(nonStandardDelimiters({ recordIndex: 0, recordType: "H" }));
952
999
  }
953
- const built = lines.map(
954
- (line2, recordIndex) => buildRecord(line2, recordIndex, delimiters, warnings)
955
- );
1000
+ let active = delimiters;
1001
+ const built = lines.map((line2, recordIndex) => {
1002
+ if (recordIndex > 0 && line2.charAt(0) === "H") {
1003
+ active = adoptRedeclaredDelimiters(line2, active, recordIndex, warnings);
1004
+ }
1005
+ return buildRecord(line2, recordIndex, active, warnings);
1006
+ });
956
1007
  const records = attachComments(built, warnings);
957
1008
  const classification = classifyMessage(records);
958
1009
  if (classification.hasQuery && classification.hasResults) {
@@ -982,6 +1033,21 @@ function resolveProfile(options) {
982
1033
  if (options.profile !== void 0) return options.profile;
983
1034
  return getDefaultAstmProfile();
984
1035
  }
1036
+ function adoptRedeclaredDelimiters(line2, active, recordIndex, warnings) {
1037
+ const position = { recordIndex, recordType: "H" };
1038
+ const declared = readDelimiters(line2);
1039
+ if (declared === void 0) {
1040
+ warnings.push(unreadableRedeclaration(position));
1041
+ return active;
1042
+ }
1043
+ if (sameDelimiters(declared, active)) return active;
1044
+ warnings.push(delimitersRedeclared(position));
1045
+ if (isNonStandard(declared)) warnings.push(nonStandardDelimiters(position));
1046
+ return declared;
1047
+ }
1048
+ function sameDelimiters(a, b) {
1049
+ return a.field === b.field && a.repeat === b.repeat && a.component === b.component && a.escape === b.escape;
1050
+ }
985
1051
  function decodeBytes(bytes) {
986
1052
  let out = "";
987
1053
  for (const b of bytes) out += String.fromCharCode(b);
@@ -992,11 +1058,12 @@ function astmField(fields, n) {
992
1058
  }
993
1059
  function buildRecord(line2, recordIndex, d, warnings) {
994
1060
  const rawType = line2.charAt(0);
995
- const fields = tokenizeRecord(line2, d, (fieldIndex) => {
1061
+ const onUnknownEscape = (fieldIndex) => {
996
1062
  warnings.push(
997
1063
  unknownEscapeSequence({ recordIndex, recordType: rawType, fieldIndex: fieldIndex + 1 })
998
1064
  );
999
- });
1065
+ };
1066
+ const fields = rawType === "H" ? tokenizeHeader(line2, d, onUnknownEscape) : tokenizeRecord(line2, d, onUnknownEscape);
1000
1067
  switch (rawType) {
1001
1068
  case "H":
1002
1069
  return {
@@ -1218,19 +1285,57 @@ function definedString(key, value) {
1218
1285
 
1219
1286
  // src/records/serialize.ts
1220
1287
  var AstmSerializeError = class extends Error {
1221
- /** Stable discriminant; `ASTM_EMIT_UNENCODABLE_VALUE` for a `CR`/`LF` in a value. */
1288
+ /**
1289
+ * Stable discriminant. `ASTM_EMIT_UNENCODABLE_VALUE` for a `CR`/`LF` in a value;
1290
+ * `ASTM_EMIT_INVALID_DELIMITERS` for a delimiter set that cannot be emitted
1291
+ * reversibly.
1292
+ */
1222
1293
  code;
1223
1294
  /** 0-based ordinal of the record within the message, when known. */
1224
1295
  recordIndex;
1225
1296
  /** @internal */
1226
- constructor(message, recordIndex) {
1297
+ constructor(message, recordIndex, code = "ASTM_EMIT_UNENCODABLE_VALUE") {
1227
1298
  super(message);
1228
1299
  this.name = "AstmSerializeError";
1229
- this.code = "ASTM_EMIT_UNENCODABLE_VALUE";
1300
+ this.code = code;
1230
1301
  if (recordIndex !== void 0) this.recordIndex = recordIndex;
1231
1302
  }
1232
1303
  };
1304
+ var DELIMITER_ROLES = ["field", "repeat", "component", "escape"];
1305
+ var CONTROL_CHARACTER = /[\u0000-\u001f\u007f]/;
1306
+ function assertEmittableDelimiters(d, recordIndex) {
1307
+ const invalid = (reason) => {
1308
+ throw new AstmSerializeError(
1309
+ `Cannot emit against these delimiters: ${reason}.`,
1310
+ recordIndex,
1311
+ "ASTM_EMIT_INVALID_DELIMITERS"
1312
+ );
1313
+ };
1314
+ if (typeof d !== "object" || d === null) {
1315
+ invalid("a delimiter set is required");
1316
+ }
1317
+ for (const role of DELIMITER_ROLES) {
1318
+ const char = d[role];
1319
+ if (typeof char !== "string" || char.length !== 1) {
1320
+ invalid(`the ${role} delimiter must be exactly one character`);
1321
+ }
1322
+ if (char === "\r" || char === "\n") {
1323
+ invalid(`the ${role} delimiter must not be a record terminator (CR/LF)`);
1324
+ }
1325
+ }
1326
+ DELIMITER_ROLES.forEach((a, i) => {
1327
+ for (const b of DELIMITER_ROLES.slice(i + 1)) {
1328
+ if (d[a] === d[b]) {
1329
+ invalid(`the ${a} and ${b} delimiters must not be the same character`);
1330
+ }
1331
+ }
1332
+ });
1333
+ }
1233
1334
  function encodeComponent(leaf, d, recordIndex) {
1335
+ assertEmittableDelimiters(d, recordIndex);
1336
+ return encodeLeaf(leaf, d, recordIndex);
1337
+ }
1338
+ function encodeLeaf(leaf, d, recordIndex) {
1234
1339
  if (leaf.includes("\r") || leaf.includes("\n")) {
1235
1340
  throw new AstmSerializeError(
1236
1341
  "A value contains a record terminator (CR/LF), which cannot be escaped without breaking framing.",
@@ -1240,28 +1345,58 @@ function encodeComponent(leaf, d, recordIndex) {
1240
1345
  return leaf.split(d.escape).join(d.escape + "E" + d.escape).split(d.field).join(d.escape + "F" + d.escape).split(d.component).join(d.escape + "S" + d.escape).split(d.repeat).join(d.escape + "R" + d.escape);
1241
1346
  }
1242
1347
  function encodeField(repeats, d, recordIndex) {
1243
- return repeats.map((rep) => rep.map((c) => encodeComponent(c, d, recordIndex)).join(d.component)).join(d.repeat);
1348
+ return repeats.map((rep) => rep.map((c) => encodeLeaf(c, d, recordIndex)).join(d.component)).join(d.repeat);
1244
1349
  }
1245
1350
  function serializeAstmRecord(record, d = CANONICAL_DELIMITERS) {
1246
- if (record.type === "M" || record.type === "S") return record.rawLine;
1351
+ assertEmittableDelimiters(d, record.recordIndex);
1352
+ return serializeRecordChecked(record, d);
1353
+ }
1354
+ function serializeRecordChecked(record, d) {
1355
+ if (record.type === "M" || record.type === "S") return serializeVerbatimRecord(record, d);
1247
1356
  if (record.type === "H") return serializeHeader(record, d);
1248
1357
  return record.fields.map((f) => encodeField(f.repeats, d, record.recordIndex)).join(d.field);
1249
1358
  }
1359
+ function serializeVerbatimRecord(record, d) {
1360
+ if (recoversVerbatim(record, d)) return record.rawLine;
1361
+ return record.fields.map((f) => encodeField(f.repeats, d, record.recordIndex)).join(d.field);
1362
+ }
1363
+ function recoversVerbatim(record, d) {
1364
+ return sameFieldTree(tokenizeRecord(record.rawLine, d), record.fields);
1365
+ }
1366
+ function sameFieldTree(a, b) {
1367
+ if (a.length !== b.length) return false;
1368
+ return a.every((fieldA, i) => {
1369
+ const fieldB = b[i];
1370
+ if (fieldB === void 0) return false;
1371
+ if (fieldA.repeats.length !== fieldB.repeats.length) return false;
1372
+ return fieldA.repeats.every((repA, r) => {
1373
+ const repB = fieldB.repeats[r];
1374
+ if (repB === void 0 || repA.length !== repB.length) return false;
1375
+ return repA.every((comp, c) => comp === repB[c]);
1376
+ });
1377
+ });
1378
+ }
1250
1379
  function serializeHeader(header, d) {
1251
- const head = "H" + d.field + d.repeat + d.component + d.escape;
1252
- const src = header.delimiters;
1253
- const defEnd = header.rawLine.indexOf(src.field, 2);
1254
- if (defEnd === -1) return head;
1255
- const dataPortion = header.rawLine.slice(defEnd + 1);
1256
- const dataFields = tokenizeRecord(dataPortion, src);
1380
+ const head = "H" + d.field + d.repeat + d.component + d.escape + declarationResidual(header, d);
1381
+ const dataFields = header.fields.slice(2);
1257
1382
  const rest = dataFields.map((f) => d.field + encodeField(f.repeats, d, header.recordIndex)).join("");
1258
1383
  return head + rest;
1259
1384
  }
1385
+ function declarationResidual(header, d) {
1386
+ const declaration = header.fields[1]?.raw ?? "";
1387
+ const roles = d.repeat + d.component + d.escape;
1388
+ if (!declaration.startsWith(roles)) return "";
1389
+ const residual = declaration.slice(roles.length);
1390
+ if (residual.includes(d.field) || CONTROL_CHARACTER.test(residual)) return "";
1391
+ return residual;
1392
+ }
1260
1393
  function serializeAstmRecords(input, d = CANONICAL_DELIMITERS) {
1394
+ assertEmittableDelimiters(d);
1261
1395
  const records = Array.isArray(input) ? input : input.records;
1262
- return records.map((r) => serializeAstmRecord(r, d) + "\r").join("");
1396
+ return records.map((r) => serializeRecordChecked(r, d) + "\r").join("");
1263
1397
  }
1264
1398
  function serializeField(field, d = CANONICAL_DELIMITERS) {
1399
+ assertEmittableDelimiters(d);
1265
1400
  return encodeField(field.repeats, d);
1266
1401
  }
1267
1402
 
@@ -1396,17 +1531,108 @@ function buildAstmMessage(input) {
1396
1531
  return lines.map((l) => l + "\r").join("");
1397
1532
  }
1398
1533
 
1534
+ // src/records/messages.ts
1535
+ var AMBIGUOUS_CODES = {
1536
+ /** The stream carries more than one `H` … `L` message, so a stream-wide answer spans patients. */
1537
+ ASTM_AMBIGUOUS_MULTI_MESSAGE: "ASTM_AMBIGUOUS_MULTI_MESSAGE",
1538
+ /** The one message in the stream carries more than one `P`, so "the patient" is not determined. */
1539
+ ASTM_AMBIGUOUS_MULTI_PATIENT: "ASTM_AMBIGUOUS_MULTI_PATIENT"
1540
+ };
1541
+ var AstmAmbiguousStreamError = class extends Error {
1542
+ /** The stable discriminant — see {@link AMBIGUOUS_CODES}. */
1543
+ code;
1544
+ /** Where the ambiguity became visible: the second header, or the second `P`. Value-free. */
1545
+ position;
1546
+ /** How many `H` … `L` messages the stream carries. */
1547
+ messageCount;
1548
+ /** How many `P` records the message in question carries. */
1549
+ patientCount;
1550
+ /** @internal */
1551
+ constructor(code, message, position, counts) {
1552
+ super(message);
1553
+ this.name = "AstmAmbiguousStreamError";
1554
+ this.code = code;
1555
+ this.position = position;
1556
+ this.messageCount = counts.messageCount;
1557
+ this.patientCount = counts.patientCount;
1558
+ }
1559
+ };
1560
+ function messages(msg) {
1561
+ const groups = [];
1562
+ let current;
1563
+ for (const record of msg.records) {
1564
+ if (record.type === "H" || current === void 0) {
1565
+ current = [];
1566
+ groups.push(current);
1567
+ }
1568
+ current.push(record);
1569
+ }
1570
+ return Object.freeze(
1571
+ groups.map((records, index) => {
1572
+ const header = records.find((r) => r.type === "H") ?? msg.header;
1573
+ const patients = records.filter((r) => r.type === "P");
1574
+ return Object.freeze({
1575
+ index,
1576
+ header,
1577
+ delimiters: header.delimiters,
1578
+ records: Object.freeze(records),
1579
+ patient: patients.length === 1 ? patients[0] : void 0,
1580
+ patients: Object.freeze(patients),
1581
+ results: Object.freeze(records.filter((r) => r.type === "R")),
1582
+ orders: Object.freeze(records.filter((r) => r.type === "O")),
1583
+ comments: Object.freeze(records.filter((r) => r.type === "C")),
1584
+ queries: Object.freeze(records.filter((r) => r.type === "Q"))
1585
+ });
1586
+ })
1587
+ );
1588
+ }
1589
+ function surveyMessages(msg) {
1590
+ let count = 0;
1591
+ let secondHeader;
1592
+ for (const record of msg.records) {
1593
+ if (record.type !== "H") continue;
1594
+ count += 1;
1595
+ if (count === 2) secondHeader = record;
1596
+ }
1597
+ return { count, secondHeader };
1598
+ }
1599
+ function assertSingleMessage(msg, accessor) {
1600
+ const { count, secondHeader } = surveyMessages(msg);
1601
+ if (count <= 1) return;
1602
+ throw new AstmAmbiguousStreamError(
1603
+ AMBIGUOUS_CODES.ASTM_AMBIGUOUS_MULTI_MESSAGE,
1604
+ `${accessor} is scoped to the whole stream, and this stream carries ${String(count)} messages, so its answer would span patients. Use messages() and read each message's own records.`,
1605
+ { recordIndex: secondHeader?.recordIndex ?? 0, recordType: "H" },
1606
+ { messageCount: count, patientCount: 0 }
1607
+ );
1608
+ }
1609
+ function assertSinglePatient(msg, accessor) {
1610
+ const patients = msg.records.filter((r) => r.type === "P");
1611
+ if (patients.length <= 1) return;
1612
+ throw new AstmAmbiguousStreamError(
1613
+ AMBIGUOUS_CODES.ASTM_AMBIGUOUS_MULTI_PATIENT,
1614
+ `${accessor} cannot name one patient: this message carries ${String(patients.length)} P records. Read them from messages()[n].patients and pair each with the records it owns.`,
1615
+ { recordIndex: patients[1]?.recordIndex ?? 0, recordType: "P" },
1616
+ { messageCount: 1, patientCount: patients.length }
1617
+ );
1618
+ }
1619
+
1399
1620
  // src/records/extractors.ts
1400
1621
  function results(msg) {
1622
+ assertSingleMessage(msg, "results()");
1401
1623
  return msg.records.filter((r) => r.type === "R");
1402
1624
  }
1403
1625
  function patient(msg) {
1626
+ assertSingleMessage(msg, "patient()");
1627
+ assertSinglePatient(msg, "patient()");
1404
1628
  return msg.records.find((r) => r.type === "P");
1405
1629
  }
1406
1630
  function orders(msg) {
1631
+ assertSingleMessage(msg, "orders()");
1407
1632
  return msg.records.filter((r) => r.type === "O");
1408
1633
  }
1409
1634
  function comments(msg) {
1635
+ assertSingleMessage(msg, "comments()");
1410
1636
  return msg.records.filter((r) => r.type === "C");
1411
1637
  }
1412
1638
  function commentsFor(msg, parent) {
@@ -1415,6 +1641,7 @@ function commentsFor(msg, parent) {
1415
1641
  );
1416
1642
  }
1417
1643
  function query(msg) {
1644
+ assertSingleMessage(msg, "query()");
1418
1645
  return msg.records.filter((r) => r.type === "Q");
1419
1646
  }
1420
1647
 
@@ -1970,8 +2197,8 @@ function concatBytes3(chunks) {
1970
2197
  }
1971
2198
 
1972
2199
  // src/index.ts
1973
- var VERSION = "0.0.3";
2200
+ var VERSION = "0.0.4";
1974
2201
 
1975
- export { ALL_ASTM_WARNING_CODES, ACK as ASTM_ACK, ENQ as ASTM_ENQ, EOT as ASTM_EOT, NAK as ASTM_NAK, AstmFrameEncodeError, AstmFrameStrictError, AstmParseError, AstmProfileDefinitionError, AstmSerializeError, AstmStrictError, CANONICAL_DELIMITERS, FATAL_CODES, FRAME_WARNING_CODES, LIVD_WARNING_CODES, LTP_WARNING_CODES, SAFETY_CRITICAL_CODES, TOLERABLE_CODES, VERSION, WARNING_CODES, ambiguousMessageKind, ambiguousValueSplit, applyAstmProfile, applyAstmProfileToWarnings, applyLivd, astmDateToLocalISO, astmProfiles, attachComments, buildAstmMessage, classifyMessage, comments, commentsFor, composeAstmFrames, computeChecksum, decodeAstmFrames, decodeEscapes, deepFreeze, defineAstmProfile, defineLivdCatalog, detectFraming, encodeComponent, fieldScalar, frameBadChecksum, frameOversize, frameSequenceGap, frameUnterminated, getAstmProfile, getDefaultAstmProfile, interpretAbnormalFlag, interpretResultStatus, isNonStandard, isSafetyCriticalCode, listAstmProfiles, livdAmbiguousMapping, livdUnmappedCode, lookupLivdForRecord, ltpAmbiguousTransport, ltpFrameRejected, ltpInitialState, ltpReduce, ltpUnexpectedEvent, nonStandardDelimiters, orders, orphanComment, parseAstmDate, parseAstmRecords, parseChecksumHex, parseFramedAstm, parseReferenceRange, partialTimestamp, patient, primaryCode, profileQuirkApplied, query, readDelimiters, recognizeUniversalTestId, resolveProfileTransport, results, serializeAstmRecord, serializeAstmRecords, serializeField, serializeFramedAstm, setDefaultAstmProfile, splitEscapeAware, toChecksumHex, tokenizeRecord, undefinedAbnormalFlag, undefinedResultStatus, uninterpretedQueryStatus, unitsAbsent, unknownEscapeSequence, unknownRecordType, unparseableReferenceRange };
2202
+ export { ALL_ASTM_WARNING_CODES, AMBIGUOUS_CODES, ACK as ASTM_ACK, ENQ as ASTM_ENQ, EOT as ASTM_EOT, NAK as ASTM_NAK, AstmAmbiguousStreamError, AstmFrameEncodeError, AstmFrameStrictError, AstmParseError, AstmProfileDefinitionError, AstmSerializeError, AstmStrictError, CANONICAL_DELIMITERS, FATAL_CODES, FRAME_WARNING_CODES, LIVD_WARNING_CODES, LTP_WARNING_CODES, SAFETY_CRITICAL_CODES, TOLERABLE_CODES, VERSION, WARNING_CODES, ambiguousMessageKind, ambiguousValueSplit, applyAstmProfile, applyAstmProfileToWarnings, applyLivd, astmDateToLocalISO, astmProfiles, attachComments, buildAstmMessage, classifyMessage, comments, commentsFor, composeAstmFrames, computeChecksum, decodeAstmFrames, decodeEscapes, deepFreeze, defineAstmProfile, defineLivdCatalog, delimitersRedeclared, detectFraming, encodeComponent, fieldScalar, frameBadChecksum, frameOversize, frameSequenceGap, frameUnterminated, getAstmProfile, getDefaultAstmProfile, interpretAbnormalFlag, interpretResultStatus, isNonStandard, isSafetyCriticalCode, listAstmProfiles, livdAmbiguousMapping, livdUnmappedCode, lookupLivdForRecord, ltpAmbiguousTransport, ltpFrameRejected, ltpInitialState, ltpReduce, ltpUnexpectedEvent, messages, nonStandardDelimiters, orders, orphanComment, parseAstmDate, parseAstmRecords, parseChecksumHex, parseFramedAstm, parseReferenceRange, partialTimestamp, patient, primaryCode, profileQuirkApplied, query, readDelimiters, recognizeUniversalTestId, resolveProfileTransport, results, serializeAstmRecord, serializeAstmRecords, serializeField, serializeFramedAstm, setDefaultAstmProfile, splitEscapeAware, toChecksumHex, tokenizeHeader, tokenizeRecord, undefinedAbnormalFlag, undefinedResultStatus, uninterpretedQueryStatus, unitsAbsent, unknownEscapeSequence, unknownRecordType, unparseableReferenceRange, unreadableRedeclaration };
1976
2203
  //# sourceMappingURL=index.mjs.map
1977
2204
  //# sourceMappingURL=index.mjs.map