@cosyte/x12 0.0.8 → 0.0.10

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
@@ -138,7 +138,10 @@ var WARNING_CODES = {
138
138
  X12_837_UNKNOWN_VARIANT: "X12_837_UNKNOWN_VARIANT",
139
139
  X12_UNKNOWN_CLAIM_STATUS_CATEGORY: "X12_UNKNOWN_CLAIM_STATUS_CATEGORY",
140
140
  X12_UNKNOWN_CLAIM_STATUS: "X12_UNKNOWN_CLAIM_STATUS",
141
- X12_834_UNKNOWN_MAINTENANCE_TYPE: "X12_834_UNKNOWN_MAINTENANCE_TYPE"
141
+ X12_834_UNKNOWN_MAINTENANCE_TYPE: "X12_834_UNKNOWN_MAINTENANCE_TYPE",
142
+ X12_UNPARSEABLE_DECIMAL: "X12_UNPARSEABLE_DECIMAL",
143
+ X12_837_SERVICE_LINE_NOT_DECODED: "X12_837_SERVICE_LINE_NOT_DECODED",
144
+ X12_837_SERVICE_LINE_DROPPED: "X12_837_SERVICE_LINE_DROPPED"
142
145
  };
143
146
  var CONTROL_NUMBER_PAIRS = {
144
147
  /** ISA-13 against IEA-02. */
@@ -211,7 +214,10 @@ var WARNING_MESSAGES = {
211
214
  X12_837_UNKNOWN_VARIANT: `837 variant could not be resolved: ST-03's implementation convention reference is not one of "005010X222A2" / "005010X223A3" / "005010X224A2", and no SVx service-line segment was present to fall back on. The verbatim reference is preserved on the model.`,
212
215
  X12_UNKNOWN_CLAIM_STATUS_CATEGORY: "Unknown claim status category (CSCC): the STC composite's first component is outside the bundled snapshot. The verbatim code is preserved on the status; only its description is unavailable.",
213
216
  X12_UNKNOWN_CLAIM_STATUS: "Unknown claim status code (CSC): the STC composite's second component is outside the bundled snapshot. The verbatim code is preserved on the status; only its description is unavailable.",
214
- X12_834_UNKNOWN_MAINTENANCE_TYPE: "Unknown 834 maintenance type: the INS-03/HD-01 code is outside the bundled snapshot. The verbatim code is preserved on the enrollment and the action is NEVER inferred."
217
+ X12_834_UNKNOWN_MAINTENANCE_TYPE: "Unknown 834 maintenance type: the INS-03/HD-01 code is outside the bundled snapshot. The verbatim code is preserved on the enrollment and the action is NEVER inferred.",
218
+ X12_UNPARSEABLE_DECIMAL: "Unparseable decimal: the element at `position.elementIndex` held bytes this library could not decode as a decimal, so NO value was decoded from it. Whatever occupies that slot on the model, including 0 and undefined, is a stand-in and is NOT a value the sender supplied. The verbatim bytes are preserved on the segment; read them there before acting on the amount, quantity or percent.",
219
+ X12_837_SERVICE_LINE_NOT_DECODED: "837 service line with no decoded service segment: the Loop 2400 line opened at `position.segmentIndex` is followed by no SV1 / SV2 / SV3 matching the variant this submission resolved to, so NOTHING carried by the service segment was read. The line's `charge` and `units` hold 0 as a stand-in and are NOT values the sender supplied; its procedure code, modifiers, unit of measure and place of service are equally undecoded. Two common causes: the line carries no SVx at all, or it carries one for a different 837 variant than ST-03 (or the caller's `type` option) named. Which side is wrong is NOT decided here, because a caller-supplied `type` can disagree with a perfectly conformant document. The verbatim segments are preserved on the transaction set; read them there before acting on the charge or the quantity.",
220
+ X12_837_SERVICE_LINE_DROPPED: "837 service line dropped from the typed model: the LX at `position.segmentIndex` opened no Loop 2400, so no line appears on any claim's `serviceLines` for it and the SV1 / SV2 / SV3 that followed - its charge, units, procedure code and modifiers - was read into nothing. Compare `X12_837_SERVICE_LINE_NOT_DECODED`, where the line IS on the model and only its service segment went unread. Two causes: no Loop 2300 (CLM) is open at this LX, so there is no claim to attach a line to; or the submission's variant is not one of P / I / D, so no variant-specific line shape could be built. Read `submission.variant` and `submission.claims` to tell them apart; do NOT expect `X12_837_UNKNOWN_VARIANT` alongside this code, because a caller-supplied `type` outside P / I / D reaches the second cause without it. Nothing is fabricated to stand in for the missing line and no claim is synthesized. What becomes of a DTP / AMT / NTE / REF that follows the dropped LX depends on the route and this message does not say; see KNOWN-LIMITATIONS.md. The verbatim segments are preserved on the transaction set; read them there before concluding the claim had no service lines."
215
221
  };
216
222
  var ALL_WARNING_MESSAGES = new Set(
217
223
  Object.values(WARNING_MESSAGES)
@@ -372,6 +378,20 @@ function unknown837Variant(position) {
372
378
  position
373
379
  };
374
380
  }
381
+ function serviceLineNotDecoded(position) {
382
+ return {
383
+ code: WARNING_CODES.X12_837_SERVICE_LINE_NOT_DECODED,
384
+ message: WARNING_MESSAGES.X12_837_SERVICE_LINE_NOT_DECODED,
385
+ position
386
+ };
387
+ }
388
+ function serviceLineDropped(position) {
389
+ return {
390
+ code: WARNING_CODES.X12_837_SERVICE_LINE_DROPPED,
391
+ message: WARNING_MESSAGES.X12_837_SERVICE_LINE_DROPPED,
392
+ position
393
+ };
394
+ }
375
395
  function unknownClaimStatusCategory(position) {
376
396
  return {
377
397
  code: WARNING_CODES.X12_UNKNOWN_CLAIM_STATUS_CATEGORY,
@@ -393,6 +413,13 @@ function unknownMaintenanceType(position) {
393
413
  position
394
414
  };
395
415
  }
416
+ function unparseableDecimal(position) {
417
+ return {
418
+ code: WARNING_CODES.X12_UNPARSEABLE_DECIMAL,
419
+ message: WARNING_MESSAGES.X12_UNPARSEABLE_DECIMAL,
420
+ position
421
+ };
422
+ }
396
423
 
397
424
  // src/parser/release.ts
398
425
  var RELEASE_CHAR = "?";
@@ -424,6 +451,9 @@ function unescapeRelease(input, delimiters, emit, position) {
424
451
  return out;
425
452
  }
426
453
  function escapeRelease(value, delimiters) {
454
+ if (typeof value !== "string") {
455
+ throw new TypeError(`escapeRelease: value must be a string, received ${typeof value}.`);
456
+ }
427
457
  if (value.length === 0) return value;
428
458
  let out = "";
429
459
  for (let i = 0; i < value.length; i++) {
@@ -903,13 +933,26 @@ function componentOptional(seg, n, p, delimiters) {
903
933
  const v = getSegmentValue(seg, `${String(n).padStart(2, "0")}-${String(p)}`, delimiters);
904
934
  return v === void 0 || v === "" ? void 0 : v;
905
935
  }
906
- function elementDecimal(seg, n, delimiters) {
936
+ function readElementDecimal(seg, n, delimiters) {
907
937
  const raw = elementOptional(seg, n, delimiters);
908
- if (raw === void 0) return void 0;
909
- return X12Decimal.fromString(raw);
938
+ if (raw === void 0) return { value: void 0, status: "absent" };
939
+ const value = X12Decimal.fromString(raw);
940
+ if (value === void 0) return { value: void 0, status: "unparseable" };
941
+ return { value, status: "decoded" };
942
+ }
943
+ function elementDecimal(seg, n, delimiters, sink) {
944
+ const read = readElementDecimal(seg, n, delimiters);
945
+ if (read.status === "unparseable" && sink !== void 0) {
946
+ sink.warnings.push(unparseableDecimal({ ...sink.position, elementIndex: n }));
947
+ }
948
+ return read.value;
910
949
  }
911
- function elementDecimalOrZero(seg, n, delimiters) {
912
- return elementDecimal(seg, n, delimiters) ?? X12Decimal.ZERO;
950
+ function elementDecimalOrZero(seg, n, delimiters, sink) {
951
+ const read = readElementDecimal(seg, n, delimiters);
952
+ if (read.status === "unparseable" && sink !== void 0) {
953
+ sink.warnings.push(unparseableDecimal({ ...sink.position, elementIndex: n }));
954
+ }
955
+ return read.value ?? X12Decimal.ZERO;
913
956
  }
914
957
  function collectElementValues(seg, start, end, delimiters) {
915
958
  const out = [];
@@ -1415,6 +1458,7 @@ function defineLoopSpec(input) {
1415
1458
  // src/code-lists/meta.ts
1416
1459
  function makeLookup(snapshot) {
1417
1460
  return (code) => {
1461
+ if (!Object.hasOwn(snapshot.codes, code)) return void 0;
1418
1462
  const description = snapshot.codes[code];
1419
1463
  if (description === void 0) return void 0;
1420
1464
  return Object.freeze({ code, description });
@@ -1663,7 +1707,7 @@ var CLAIM_ADJUSTMENT_GROUP_CODES = {
1663
1707
  PI: "PI"
1664
1708
  };
1665
1709
  function isClaimAdjustmentGroupCode(value) {
1666
- return value in CLAIM_ADJUSTMENT_GROUP_CODES;
1710
+ return Object.hasOwn(CLAIM_ADJUSTMENT_GROUP_CODES, value);
1667
1711
  }
1668
1712
 
1669
1713
  // src/code-lists/rarc.ts
@@ -1803,6 +1847,7 @@ var HI_QUALIFIERS = {
1803
1847
  }
1804
1848
  };
1805
1849
  function resolveHiQualifier(qualifier) {
1850
+ if (!Object.hasOwn(HI_QUALIFIERS, qualifier)) return void 0;
1806
1851
  return HI_QUALIFIERS[qualifier];
1807
1852
  }
1808
1853
  function isDiagnosisQualifier(qualifier) {
@@ -1912,9 +1957,10 @@ function get835(delimiters, tx) {
1912
1957
  const seg = body[i];
1913
1958
  if (seg === void 0) continue;
1914
1959
  const position = { segmentIndex: i + 1, transactionIndex: 0 };
1960
+ const sink = { warnings, position };
1915
1961
  switch (seg.id) {
1916
1962
  case "BPR": {
1917
- payment = decodeBpr(seg, delimiters);
1963
+ payment = decodeBpr(seg, delimiters, sink);
1918
1964
  bprSegmentIndex = position.segmentIndex;
1919
1965
  break;
1920
1966
  }
@@ -1989,7 +2035,7 @@ function get835(delimiters, tx) {
1989
2035
  case "CLP": {
1990
2036
  flushClaim();
1991
2037
  lastParty = void 0;
1992
- currentClaim = openClaim(seg, delimiters, position.segmentIndex);
2038
+ currentClaim = openClaim(seg, delimiters, position.segmentIndex, sink);
1993
2039
  break;
1994
2040
  }
1995
2041
  case "CAS": {
@@ -2041,7 +2087,7 @@ function get835(delimiters, tx) {
2041
2087
  break;
2042
2088
  }
2043
2089
  case "AMT": {
2044
- const amount = decodeAmt(seg, delimiters);
2090
+ const amount = decodeAmt(seg, delimiters, sink);
2045
2091
  if (amount === void 0) break;
2046
2092
  if (currentServiceLine !== void 0) currentServiceLine.amounts.push(amount);
2047
2093
  else if (currentClaim !== void 0) currentClaim.amounts.push(amount);
@@ -2060,12 +2106,12 @@ function get835(delimiters, tx) {
2060
2106
  }
2061
2107
  case "SVC": {
2062
2108
  flushServiceLine();
2063
- currentServiceLine = openServiceLine(seg, delimiters);
2109
+ currentServiceLine = openServiceLine(seg, delimiters, sink);
2064
2110
  break;
2065
2111
  }
2066
2112
  case "PLB": {
2067
2113
  flushClaim();
2068
- for (const p of decodePlb(seg, delimiters)) providerAdjustments.push(p);
2114
+ for (const p of decodePlb(seg, delimiters, sink)) providerAdjustments.push(p);
2069
2115
  break;
2070
2116
  }
2071
2117
  }
@@ -2096,10 +2142,10 @@ function get835(delimiters, tx) {
2096
2142
  warnings: Object.freeze(warnings.slice())
2097
2143
  });
2098
2144
  }
2099
- function decodeBpr(seg, delimiters) {
2145
+ function decodeBpr(seg, delimiters, sink) {
2100
2146
  return Object.freeze({
2101
2147
  transactionHandlingCode: elementValue(seg, 1, delimiters),
2102
- totalActualPayment: elementDecimalOrZero(seg, 2, delimiters),
2148
+ totalActualPayment: elementDecimalOrZero(seg, 2, delimiters, sink),
2103
2149
  creditDebitFlag: elementValue(seg, 3, delimiters),
2104
2150
  method: elementValue(seg, 4, delimiters),
2105
2151
  paymentFormatCode: elementOptional(seg, 5, delimiters),
@@ -2158,8 +2204,8 @@ function decodePer(seg, delimiters) {
2158
2204
  communications: Object.freeze(comms)
2159
2205
  });
2160
2206
  }
2161
- function decodeAmt(seg, delimiters) {
2162
- const amount = elementDecimal(seg, 2, delimiters);
2207
+ function decodeAmt(seg, delimiters, sink) {
2208
+ const amount = elementDecimal(seg, 2, delimiters, sink);
2163
2209
  if (amount === void 0) return void 0;
2164
2210
  return Object.freeze({
2165
2211
  qualifier: elementValue(seg, 1, delimiters),
@@ -2195,13 +2241,14 @@ function collectMoaRemarks(seg, delimiters) {
2195
2241
  return out;
2196
2242
  }
2197
2243
  function decodeCasAdjustments(seg, delimiters, warnings, position) {
2244
+ const sink = { warnings, position };
2198
2245
  const groupCode = elementValue(seg, 1, delimiters);
2199
2246
  const out = [];
2200
2247
  for (let triple = 0; triple < 6; triple += 1) {
2201
2248
  const base = 2 + triple * 3;
2202
2249
  const reasonCode = elementOptional(seg, base, delimiters);
2203
- const amount = elementDecimal(seg, base + 1, delimiters);
2204
- const quantity = elementDecimal(seg, base + 2, delimiters);
2250
+ const amount = elementDecimal(seg, base + 1, delimiters, sink);
2251
+ const quantity = elementDecimal(seg, base + 2, delimiters, sink);
2205
2252
  if (reasonCode === void 0 && amount === void 0) continue;
2206
2253
  const code = reasonCode ?? "";
2207
2254
  const entry = code === "" ? void 0 : lookupCarc(code);
@@ -2245,7 +2292,7 @@ function decodeNm1(seg, delimiters) {
2245
2292
  })
2246
2293
  };
2247
2294
  }
2248
- function openClaim(seg, delimiters, clpSegmentIndex) {
2295
+ function openClaim(seg, delimiters, clpSegmentIndex, sink) {
2249
2296
  const claimStatusCode = elementValue(seg, 2, delimiters);
2250
2297
  const claimStatusDescription = lookupClpStatus(claimStatusCode)?.description;
2251
2298
  const facilityTypeCode = componentOptional(seg, 8, 1, delimiters) ?? elementOptional(seg, 8, delimiters);
@@ -2255,9 +2302,9 @@ function openClaim(seg, delimiters, clpSegmentIndex) {
2255
2302
  patientControlNumber: elementValue(seg, 1, delimiters),
2256
2303
  claimStatusCode,
2257
2304
  claimStatusDescription,
2258
- totalChargeAmount: elementDecimalOrZero(seg, 3, delimiters),
2259
- totalPaymentAmount: elementDecimalOrZero(seg, 4, delimiters),
2260
- patientResponsibilityAmount: elementDecimalOrZero(seg, 5, delimiters),
2305
+ totalChargeAmount: elementDecimalOrZero(seg, 3, delimiters, sink),
2306
+ totalPaymentAmount: elementDecimalOrZero(seg, 4, delimiters, sink),
2307
+ patientResponsibilityAmount: elementDecimalOrZero(seg, 5, delimiters, sink),
2261
2308
  claimFilingIndicatorCode: elementOptional(seg, 6, delimiters),
2262
2309
  payerClaimControlNumber: elementOptional(seg, 7, delimiters),
2263
2310
  facilityTypeCode,
@@ -2276,7 +2323,7 @@ function openClaim(seg, delimiters, clpSegmentIndex) {
2276
2323
  serviceLines: []
2277
2324
  };
2278
2325
  }
2279
- function openServiceLine(seg, delimiters) {
2326
+ function openServiceLine(seg, delimiters, sink) {
2280
2327
  const productServiceIdQualifier = componentOptional(seg, 1, 1, delimiters) ?? "";
2281
2328
  const productServiceId = componentOptional(seg, 1, 2, delimiters) ?? "";
2282
2329
  const modifiers = [];
@@ -2284,18 +2331,20 @@ function openServiceLine(seg, delimiters) {
2284
2331
  const m = componentOptional(seg, 1, comp, delimiters);
2285
2332
  if (m !== void 0) modifiers.push(m);
2286
2333
  }
2287
- const revenueCode = elementOptional(seg, 5, delimiters);
2288
- const paidUnitsOfService = elementDecimal(seg, 7, delimiters);
2334
+ const revenueCode = elementOptional(seg, 4, delimiters);
2335
+ const paidUnitsOfService = elementDecimal(seg, 5, delimiters, sink);
2336
+ const originalUnitsOfService = elementDecimal(seg, 7, delimiters, sink);
2289
2337
  const originalServiceIdQualifier = componentOptional(seg, 6, 1, delimiters);
2290
2338
  const originalServiceId = componentOptional(seg, 6, 2, delimiters);
2291
2339
  return {
2292
2340
  productServiceIdQualifier,
2293
2341
  productServiceId,
2294
2342
  modifiers,
2295
- chargeAmount: elementDecimalOrZero(seg, 2, delimiters),
2296
- paymentAmount: elementDecimalOrZero(seg, 3, delimiters),
2343
+ chargeAmount: elementDecimalOrZero(seg, 2, delimiters, sink),
2344
+ paymentAmount: elementDecimalOrZero(seg, 3, delimiters, sink),
2297
2345
  revenueCode,
2298
2346
  paidUnitsOfService,
2347
+ originalUnitsOfService,
2299
2348
  originalServiceId,
2300
2349
  originalServiceIdQualifier,
2301
2350
  serviceDateStart: void 0,
@@ -2321,13 +2370,13 @@ function attachServiceLineDtm(line, seg, delimiters) {
2321
2370
  if (qualifier === "472" || qualifier === "150") line.serviceDateStart = date;
2322
2371
  if (qualifier === "472" || qualifier === "151") line.serviceDateEnd = date;
2323
2372
  }
2324
- function decodePlb(seg, delimiters) {
2373
+ function decodePlb(seg, delimiters, sink) {
2325
2374
  const providerId = elementValue(seg, 1, delimiters);
2326
2375
  const fiscalPeriodDate = elementValue(seg, 2, delimiters);
2327
2376
  const out = [];
2328
2377
  for (let pair = 0; pair < 6; pair += 1) {
2329
2378
  const composite = 3 + pair * 2;
2330
- const amount = elementDecimal(seg, composite + 1, delimiters);
2379
+ const amount = elementDecimal(seg, composite + 1, delimiters, sink);
2331
2380
  const reasonCode = componentOptional(seg, composite, 1, delimiters);
2332
2381
  const subCode = componentOptional(seg, composite, 2, delimiters);
2333
2382
  if (amount === void 0 && reasonCode === void 0) continue;
@@ -2391,6 +2440,7 @@ function freezeServiceLine(acc) {
2391
2440
  paymentAmount: acc.paymentAmount,
2392
2441
  revenueCode: acc.revenueCode,
2393
2442
  paidUnitsOfService: acc.paidUnitsOfService,
2443
+ originalUnitsOfService: acc.originalUnitsOfService,
2394
2444
  originalServiceId: acc.originalServiceId,
2395
2445
  originalServiceIdQualifier: acc.originalServiceIdQualifier,
2396
2446
  serviceDateStart: acc.serviceDateStart,
@@ -2506,10 +2556,75 @@ function isRealArray(value) {
2506
2556
  return Array.isArray(value);
2507
2557
  }
2508
2558
 
2559
+ // src/builder/caller-decimal.ts
2560
+ function describeCallerDecimal(value) {
2561
+ if (value === null) return "null";
2562
+ if (value === void 0) return "undefined";
2563
+ const type = typeof value;
2564
+ if (type === "object") return Array.isArray(value) ? "an array" : "an object";
2565
+ if (type === "function") return "a function";
2566
+ return `a ${type} (${renderCallerValue(value)})`;
2567
+ }
2568
+ function requireCallerDecimal(value, at, refuse) {
2569
+ if (value instanceof X12Decimal) return value;
2570
+ refuse(
2571
+ `${at}: every numeric element value must be an X12Decimal, but received ${describeCallerDecimal(value)}. Values are never coerced - a JavaScript number has no X12 lexical form (0.1 + 0.2 renders as "0.30000000000000004", 1e21 as "1e+21", NaN as "NaN"), and rounding one here would guess a scale the caller never stated. Build it with X12Decimal.fromString() at the call site.`
2572
+ );
2573
+ }
2574
+
2575
+ // src/builder/caller-segment.ts
2576
+ function describeSegmentValue(value) {
2577
+ if (value === null) return "null";
2578
+ if (value === void 0) return "undefined";
2579
+ const type = typeof value;
2580
+ if (type === "object") return Array.isArray(value) ? "an array" : "an object";
2581
+ if (type === "function") return "a function";
2582
+ return `a ${type} (${renderCallerValue(value)})`;
2583
+ }
2584
+ function locateSlot(parts, index) {
2585
+ const id = parts[0];
2586
+ const position = String(index).padStart(2, "0");
2587
+ if (typeof id !== "string" || id.length === 0) return `element ${String(index)}`;
2588
+ return `${renderCallerValue(id)}-${position}`;
2589
+ }
2590
+ function requireCallerSegment(parts, at, refuse) {
2591
+ let index = 0;
2592
+ for (const part of parts) {
2593
+ if (typeof part !== "string") {
2594
+ refuse(
2595
+ `${at}: ${locateSlot(parts, index)} must be a string, but received ${describeSegmentValue(part)}. Values are never coerced - a JavaScript number cannot carry a leading-zero identifier, so converting here could emit a different value than the caller sent. Convert at the call site.`
2596
+ );
2597
+ }
2598
+ index += 1;
2599
+ }
2600
+ }
2601
+
2602
+ // src/builder/caller-string.ts
2603
+ function describeCallerValue(value) {
2604
+ if (value === null) return "null";
2605
+ if (value === void 0) return "undefined";
2606
+ const type = typeof value;
2607
+ if (type === "object") return Array.isArray(value) ? "an array" : "an object";
2608
+ if (type === "function") return "a function";
2609
+ return `a ${type} (${renderCallerValue(value)})`;
2610
+ }
2611
+ function requireCallerString(value, at, refuse) {
2612
+ if (typeof value === "string") return value;
2613
+ refuse(
2614
+ `${at}: every element value must be a string, but received ${describeCallerValue(value)}. Values are never coerced - a JavaScript number cannot carry a leading-zero identifier, so converting here could emit a different value than the caller sent. Convert at the call site.`
2615
+ );
2616
+ }
2617
+ function makeCallerEscaper(delimiters, at, refuse) {
2618
+ return (value) => escapeRelease(requireCallerString(value, at, refuse), delimiters);
2619
+ }
2620
+
2509
2621
  // src/transactions/remit/build-835.ts
2510
2622
  function refuseSpec(message) {
2511
2623
  throw new Remit835BuildError(REMIT_835_BUILD_ERROR_CODES.X12_835_BUILD_INVALID_SPEC, message);
2512
2624
  }
2625
+ function escDec(value, esc) {
2626
+ return esc(requireCallerDecimal(value, "build835", refuseSpec).toString());
2627
+ }
2513
2628
  var X221A1_VERSION_RELEASE = "005010X221A1";
2514
2629
  var X12_835_FUNCTIONAL_ID = "HP";
2515
2630
  var X12_AGENCY_CODE = "X";
@@ -2531,8 +2646,9 @@ function build835(spec) {
2531
2646
  component: componentSeparator,
2532
2647
  segment: segmentTerminator
2533
2648
  };
2534
- const esc = (value) => escapeRelease(value, delimiters);
2649
+ const esc = makeCallerEscaper(delimiters, "build835", refuseSpec);
2535
2650
  const seg = (parts) => {
2651
+ requireCallerSegment(parts, "build835", refuseSpec);
2536
2652
  let end = parts.length;
2537
2653
  while (end > 1 && parts[end - 1] === "") end -= 1;
2538
2654
  return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
@@ -2594,9 +2710,9 @@ function build835(spec) {
2594
2710
  // GS-02
2595
2711
  esc(applicationReceiverCode),
2596
2712
  // GS-03
2597
- groupDate,
2713
+ esc(groupDate),
2598
2714
  // GS-04 - CCYYMMDD
2599
- groupTime,
2715
+ esc(groupTime),
2600
2716
  // GS-05 - HHMM
2601
2717
  esc(envelope.groupControlNumber),
2602
2718
  // GS-06
@@ -2612,7 +2728,7 @@ function build835(spec) {
2612
2728
  seg([
2613
2729
  "BPR",
2614
2730
  esc(spec.payment.transactionHandlingCode),
2615
- esc(spec.payment.totalActualPayment.toString()),
2731
+ escDec(spec.payment.totalActualPayment, esc),
2616
2732
  esc(spec.payment.creditDebitFlag),
2617
2733
  esc(spec.payment.method),
2618
2734
  esc(spec.payment.paymentFormatCode ?? ""),
@@ -2747,6 +2863,7 @@ function materializeServiceLine(spec) {
2747
2863
  paymentAmount: spec.paymentAmount,
2748
2864
  revenueCode: spec.revenueCode,
2749
2865
  paidUnitsOfService: spec.paidUnitsOfService,
2866
+ originalUnitsOfService: spec.originalUnitsOfService,
2750
2867
  originalServiceId: spec.originalServiceId,
2751
2868
  originalServiceIdQualifier: spec.originalServiceIdQualifier,
2752
2869
  serviceDateStart: spec.serviceDateStart,
@@ -2842,9 +2959,9 @@ function emitClaim(claim, body, seg, esc, comp) {
2842
2959
  "CLP",
2843
2960
  esc(claim.patientControlNumber),
2844
2961
  esc(claim.claimStatusCode),
2845
- esc(claim.totalChargeAmount.toString()),
2846
- esc(claim.totalPaymentAmount.toString()),
2847
- esc(claim.patientResponsibilityAmount.toString()),
2962
+ escDec(claim.totalChargeAmount, esc),
2963
+ escDec(claim.totalPaymentAmount, esc),
2964
+ escDec(claim.patientResponsibilityAmount, esc),
2848
2965
  esc(claim.claimFilingIndicatorCode ?? ""),
2849
2966
  esc(claim.payerClaimControlNumber ?? ""),
2850
2967
  comp([claim.facilityTypeCode ?? "", "", claim.claimFrequencyCode ?? ""])
@@ -2866,7 +2983,7 @@ function emitClaim(claim, body, seg, esc, comp) {
2866
2983
  }
2867
2984
  for (const ref of claim.references ?? []) body.push(emitRef(ref, seg, esc));
2868
2985
  for (const amt of claim.amounts ?? []) {
2869
- body.push(seg(["AMT", esc(amt.qualifier), esc(amt.amount.toString())]));
2986
+ body.push(seg(["AMT", esc(amt.qualifier), escDec(amt.amount, esc)]));
2870
2987
  }
2871
2988
  for (const remark of claim.remarks ?? []) {
2872
2989
  body.push(seg(["LQ", esc(remark.system), esc(remark.code)]));
@@ -2886,20 +3003,24 @@ function emitServiceLine(line, body, seg, esc, comp) {
2886
3003
  seg([
2887
3004
  "SVC",
2888
3005
  svc01,
2889
- esc(line.chargeAmount.toString()),
2890
- esc(line.paymentAmount.toString()),
2891
- "",
2892
- // SVC-04 - revenue code is SVC-05 in X221A1; SVC-04 unused
3006
+ escDec(line.chargeAmount, esc),
3007
+ escDec(line.paymentAmount, esc),
3008
+ // SVC-04 is the NUBC revenue code (element 234, Product/Service ID) and
3009
+ // SVC-05 is the Units of Service PAID Count (element 380, Quantity).
3010
+ // SVC-07 is the ORIGINAL (submitted) units, a different quantity from
3011
+ // SVC-05 - so the two never share a field. See the SVC note in
3012
+ // KNOWN-LIMITATIONS.md for the sources.
2893
3013
  esc(line.revenueCode ?? ""),
3014
+ line.paidUnitsOfService === void 0 ? "" : escDec(line.paidUnitsOfService, esc),
2894
3015
  svc06,
2895
- line.paidUnitsOfService === void 0 ? "" : esc(line.paidUnitsOfService.toString())
3016
+ line.originalUnitsOfService === void 0 ? "" : escDec(line.originalUnitsOfService, esc)
2896
3017
  ])
2897
3018
  );
2898
3019
  emitServiceLineDtm(line, body, seg, esc);
2899
3020
  emitCasGroup(line.adjustments, "build835: serviceLine.adjustments", body, seg, esc);
2900
3021
  for (const ref of line.references ?? []) body.push(emitRef(ref, seg, esc));
2901
3022
  for (const amt of line.amounts ?? []) {
2902
- body.push(seg(["AMT", esc(amt.qualifier), esc(amt.amount.toString())]));
3023
+ body.push(seg(["AMT", esc(amt.qualifier), escDec(amt.amount, esc)]));
2903
3024
  }
2904
3025
  for (const remark of line.remarks ?? []) {
2905
3026
  body.push(seg(["LQ", esc(remark.system), esc(remark.code)]));
@@ -2931,8 +3052,8 @@ function emitCasGroup(raw, at, body, seg, esc) {
2931
3052
  if (adj === void 0 || adj.groupCode !== groupCode) break;
2932
3053
  parts.push(
2933
3054
  esc(adj.reasonCode),
2934
- esc(adj.amount.toString()),
2935
- adj.quantity === void 0 ? "" : esc(adj.quantity.toString())
3055
+ escDec(adj.amount, esc),
3056
+ adj.quantity === void 0 ? "" : escDec(adj.quantity, esc)
2936
3057
  );
2937
3058
  triples += 1;
2938
3059
  i += 1;
@@ -2990,7 +3111,7 @@ function emitProviderAdjustments(raw, at, body, seg, esc, comp) {
2990
3111
  if (adj === void 0 || adj.providerId !== providerId || adj.fiscalPeriodDate !== fiscalPeriodDate) {
2991
3112
  break;
2992
3113
  }
2993
- parts.push(comp([adj.reasonCode, adj.subCode ?? ""]), esc(adj.amount.toString()));
3114
+ parts.push(comp([adj.reasonCode, adj.subCode ?? ""]), escDec(adj.amount, esc));
2994
3115
  pairs += 1;
2995
3116
  i += 1;
2996
3117
  }
@@ -3088,13 +3209,22 @@ var REMIT_835_LOOP_1000B = defineLoopSpec({
3088
3209
  ]
3089
3210
  });
3090
3211
 
3212
+ // src/parser/lookup.ts
3213
+ function wireLookup(entries) {
3214
+ const table = /* @__PURE__ */ Object.create(null);
3215
+ for (const [key, value] of Object.entries(entries)) {
3216
+ table[key] = value;
3217
+ }
3218
+ return Object.freeze(table);
3219
+ }
3220
+
3091
3221
  // src/transactions/claim/get-837.ts
3092
- var VARIANT_BY_ICR = Object.freeze({
3222
+ var VARIANT_BY_ICR = wireLookup({
3093
3223
  "005010X222A2": "P",
3094
3224
  "005010X223A3": "I",
3095
3225
  "005010X224A2": "D"
3096
3226
  });
3097
- var VARIANT_BY_SV_SEGMENT = Object.freeze({
3227
+ var VARIANT_BY_SV_SEGMENT = wireLookup({
3098
3228
  SV1: "P",
3099
3229
  SV2: "I",
3100
3230
  SV3: "D"
@@ -3115,7 +3245,7 @@ var NM1_QUALIFIERS = Object.freeze({
3115
3245
  PAYER: "PR",
3116
3246
  PATIENT: "QC"
3117
3247
  });
3118
- var EXPECTED_PARENT_LEVEL = Object.freeze({
3248
+ var EXPECTED_PARENT_LEVEL = wireLookup({
3119
3249
  [HL_LEVEL_CODES.INFORMATION_SOURCE]: void 0,
3120
3250
  [HL_LEVEL_CODES.SUBSCRIBER]: HL_LEVEL_CODES.INFORMATION_SOURCE,
3121
3251
  [HL_LEVEL_CODES.DEPENDENT]: HL_LEVEL_CODES.SUBSCRIBER
@@ -3170,6 +3300,9 @@ function get837Claims(delimiters, tx, opts) {
3170
3300
  const flushServiceLine = () => {
3171
3301
  flushAdjudication();
3172
3302
  if (currentServiceLine !== void 0 && currentClaim !== void 0) {
3303
+ if (!currentServiceLine.serviceSegmentDecoded) {
3304
+ warnings.push(serviceLineNotDecoded(currentServiceLine.position));
3305
+ }
3173
3306
  currentClaim.serviceLines.push(freezeServiceLine2(currentServiceLine));
3174
3307
  }
3175
3308
  currentServiceLine = void 0;
@@ -3243,6 +3376,7 @@ function get837Claims(delimiters, tx, opts) {
3243
3376
  const seg = body[i];
3244
3377
  if (seg === void 0) continue;
3245
3378
  const position = { segmentIndex: i + 1, transactionIndex: 0 };
3379
+ const sink = { warnings, position };
3246
3380
  switch (seg.id) {
3247
3381
  case "HL": {
3248
3382
  flushClaim();
@@ -3390,16 +3524,21 @@ function get837Claims(delimiters, tx, opts) {
3390
3524
  warnings.push(missingRequiredLoop(position, REQUIRED_LOOPS.PAYER_NAME_2010BB));
3391
3525
  }
3392
3526
  }
3393
- currentClaim = openClaim2(seg, delimiters, {
3394
- variant,
3395
- hierarchy: currentPatientHl ?? currentSubscriberHl,
3396
- billingProvider,
3397
- payToAddress,
3398
- payToPlan,
3399
- subscriber: currentSubscriberMember,
3400
- payer: currentPayer,
3401
- patient: currentPatientMember
3402
- });
3527
+ currentClaim = openClaim2(
3528
+ seg,
3529
+ delimiters,
3530
+ {
3531
+ variant,
3532
+ hierarchy: currentPatientHl ?? currentSubscriberHl,
3533
+ billingProvider,
3534
+ payToAddress,
3535
+ payToPlan,
3536
+ subscriber: currentSubscriberMember,
3537
+ payer: currentPayer,
3538
+ patient: currentPatientMember
3539
+ },
3540
+ sink
3541
+ );
3403
3542
  activeEntity = void 0;
3404
3543
  context = { kind: "loop2300" };
3405
3544
  break;
@@ -3438,7 +3577,7 @@ function get837Claims(delimiters, tx, opts) {
3438
3577
  break;
3439
3578
  }
3440
3579
  case "AMT": {
3441
- const amount = decodeAmt2(seg, delimiters);
3580
+ const amount = decodeAmt2(seg, delimiters, sink);
3442
3581
  if (amount === void 0) break;
3443
3582
  if (currentAdjudication !== void 0) break;
3444
3583
  if (currentServiceLine !== void 0) currentServiceLine.amounts.push(amount);
@@ -3447,22 +3586,26 @@ function get837Claims(delimiters, tx, opts) {
3447
3586
  }
3448
3587
  case "LX": {
3449
3588
  flushServiceLine();
3450
- if (currentClaim === void 0) break;
3451
- currentServiceLine = openServiceLine2(seg, delimiters, currentClaim.variant);
3589
+ if (currentClaim === void 0) {
3590
+ warnings.push(serviceLineDropped(position));
3591
+ break;
3592
+ }
3593
+ currentServiceLine = openServiceLine2(seg, delimiters, currentClaim.variant, position);
3594
+ if (currentServiceLine === void 0) warnings.push(serviceLineDropped(position));
3452
3595
  activeEntity = void 0;
3453
3596
  context = { kind: "loop2400" };
3454
3597
  break;
3455
3598
  }
3456
3599
  case "SV1": {
3457
- if (currentServiceLine !== void 0) decodeSv1(currentServiceLine, seg, delimiters);
3600
+ if (currentServiceLine !== void 0) decodeSv1(currentServiceLine, seg, delimiters, sink);
3458
3601
  break;
3459
3602
  }
3460
3603
  case "SV2": {
3461
- if (currentServiceLine !== void 0) decodeSv2(currentServiceLine, seg, delimiters);
3604
+ if (currentServiceLine !== void 0) decodeSv2(currentServiceLine, seg, delimiters, sink);
3462
3605
  break;
3463
3606
  }
3464
3607
  case "SV3": {
3465
- if (currentServiceLine !== void 0) decodeSv3(currentServiceLine, seg, delimiters);
3608
+ if (currentServiceLine !== void 0) decodeSv3(currentServiceLine, seg, delimiters, sink);
3466
3609
  break;
3467
3610
  }
3468
3611
  case "TOO": {
@@ -3488,7 +3631,7 @@ function get837Claims(delimiters, tx, opts) {
3488
3631
  }
3489
3632
  currentServiceLine.drug = {
3490
3633
  ...currentServiceLine.drug,
3491
- quantity: elementDecimal(seg, 4, delimiters),
3634
+ quantity: elementDecimal(seg, 4, delimiters, sink),
3492
3635
  unitOfMeasure: componentOptional(seg, 5, 1, delimiters)
3493
3636
  };
3494
3637
  break;
@@ -3496,7 +3639,7 @@ function get837Claims(delimiters, tx, opts) {
3496
3639
  case "SVD": {
3497
3640
  flushAdjudication();
3498
3641
  if (currentServiceLine === void 0) break;
3499
- currentAdjudication = openAdjudication(seg, delimiters);
3642
+ currentAdjudication = openAdjudication(seg, delimiters, sink);
3500
3643
  break;
3501
3644
  }
3502
3645
  case "CAS": {
@@ -3674,19 +3817,20 @@ function decodeNte(seg, delimiters) {
3674
3817
  description: note
3675
3818
  });
3676
3819
  }
3677
- function decodeAmt2(seg, delimiters) {
3678
- const amount = elementDecimal(seg, 2, delimiters);
3820
+ function decodeAmt2(seg, delimiters, sink) {
3821
+ const amount = elementDecimal(seg, 2, delimiters, sink);
3679
3822
  if (amount === void 0) return void 0;
3680
3823
  return Object.freeze({ qualifier: elementValue(seg, 1, delimiters), amount });
3681
3824
  }
3682
3825
  function decodeCas(seg, delimiters, warnings, position) {
3826
+ const sink = { warnings, position };
3683
3827
  const groupCode = elementValue(seg, 1, delimiters);
3684
3828
  const out = [];
3685
3829
  for (let triple = 0; triple < 6; triple += 1) {
3686
3830
  const base = 2 + triple * 3;
3687
3831
  const reasonCode = elementOptional(seg, base, delimiters);
3688
- const amount = elementDecimal(seg, base + 1, delimiters);
3689
- const quantity = elementDecimal(seg, base + 2, delimiters);
3832
+ const amount = elementDecimal(seg, base + 1, delimiters, sink);
3833
+ const quantity = elementDecimal(seg, base + 2, delimiters, sink);
3690
3834
  if (reasonCode === void 0 && amount === void 0) continue;
3691
3835
  const code = reasonCode ?? "";
3692
3836
  const entry = code === "" ? void 0 : lookupCarc(code);
@@ -3721,7 +3865,7 @@ var EMPTY_SUBSCRIBER_INFO = Object.freeze({
3721
3865
  groupName: void 0,
3722
3866
  claimFilingIndicator: void 0
3723
3867
  });
3724
- function openClaim2(seg, delimiters, ctx) {
3868
+ function openClaim2(seg, delimiters, ctx, sink) {
3725
3869
  const {
3726
3870
  variant,
3727
3871
  hierarchy,
@@ -3742,7 +3886,7 @@ function openClaim2(seg, delimiters, ctx) {
3742
3886
  payer,
3743
3887
  patient,
3744
3888
  claimId: elementValue(seg, 1, delimiters),
3745
- totalCharge: elementDecimalOrZero(seg, 2, delimiters),
3889
+ totalCharge: elementDecimalOrZero(seg, 2, delimiters, sink),
3746
3890
  placeOfServiceCode: componentOptional(seg, 5, 1, delimiters),
3747
3891
  facilityCodeQualifier: componentOptional(seg, 5, 2, delimiters),
3748
3892
  claimFrequencyCode: componentOptional(seg, 5, 3, delimiters),
@@ -3762,10 +3906,12 @@ function openClaim2(seg, delimiters, ctx) {
3762
3906
  serviceLines: []
3763
3907
  };
3764
3908
  }
3765
- function openServiceLine2(seg, delimiters, variant) {
3909
+ function openServiceLine2(seg, delimiters, variant, position) {
3766
3910
  const lineNumber = elementValue(seg, 1, delimiters);
3767
3911
  const base = {
3768
3912
  lineNumber,
3913
+ position,
3914
+ serviceSegmentDecoded: false,
3769
3915
  charge: X12Decimal.ZERO,
3770
3916
  units: X12Decimal.ZERO,
3771
3917
  unitOfMeasure: void 0,
@@ -3817,8 +3963,9 @@ function openServiceLine2(seg, delimiters, variant) {
3817
3963
  }
3818
3964
  return void 0;
3819
3965
  }
3820
- function decodeSv1(acc, seg, delimiters) {
3966
+ function decodeSv1(acc, seg, delimiters, sink) {
3821
3967
  if (acc.variant !== "P") return;
3968
+ acc.serviceSegmentDecoded = true;
3822
3969
  acc.procedureQualifier = componentOptional(seg, 1, 1, delimiters) ?? "";
3823
3970
  acc.procedureCode = componentOptional(seg, 1, 2, delimiters) ?? "";
3824
3971
  const mods = [];
@@ -3827,9 +3974,9 @@ function decodeSv1(acc, seg, delimiters) {
3827
3974
  if (m !== void 0) mods.push(m);
3828
3975
  }
3829
3976
  acc.modifiers = mods;
3830
- acc.charge = elementDecimalOrZero(seg, 2, delimiters);
3977
+ acc.charge = elementDecimalOrZero(seg, 2, delimiters, sink);
3831
3978
  acc.unitOfMeasure = elementOptional(seg, 3, delimiters);
3832
- acc.units = elementDecimalOrZero(seg, 4, delimiters);
3979
+ acc.units = elementDecimalOrZero(seg, 4, delimiters, sink);
3833
3980
  acc.placeOfServiceCode = elementOptional(seg, 5, delimiters);
3834
3981
  const pointers = [];
3835
3982
  for (let p = 1; p <= 4; p += 1) {
@@ -3841,8 +3988,9 @@ function decodeSv1(acc, seg, delimiters) {
3841
3988
  acc.epsdtIndicator = elementOptional(seg, 11, delimiters);
3842
3989
  acc.familyPlanningIndicator = elementOptional(seg, 12, delimiters);
3843
3990
  }
3844
- function decodeSv2(acc, seg, delimiters) {
3991
+ function decodeSv2(acc, seg, delimiters, sink) {
3845
3992
  if (acc.variant !== "I") return;
3993
+ acc.serviceSegmentDecoded = true;
3846
3994
  acc.revenueCode = elementValue(seg, 1, delimiters);
3847
3995
  acc.procedureQualifier = componentOptional(seg, 2, 1, delimiters);
3848
3996
  acc.procedureCode = componentOptional(seg, 2, 2, delimiters);
@@ -3852,14 +4000,15 @@ function decodeSv2(acc, seg, delimiters) {
3852
4000
  if (m !== void 0) mods.push(m);
3853
4001
  }
3854
4002
  acc.modifiers = mods;
3855
- acc.charge = elementDecimalOrZero(seg, 3, delimiters);
4003
+ acc.charge = elementDecimalOrZero(seg, 3, delimiters, sink);
3856
4004
  acc.unitOfMeasure = elementOptional(seg, 4, delimiters);
3857
- acc.units = elementDecimalOrZero(seg, 5, delimiters);
3858
- acc.serviceLineRate = elementDecimal(seg, 6, delimiters);
3859
- acc.nonCoveredCharge = elementDecimal(seg, 7, delimiters);
4005
+ acc.units = elementDecimalOrZero(seg, 5, delimiters, sink);
4006
+ acc.serviceLineRate = elementDecimal(seg, 6, delimiters, sink);
4007
+ acc.nonCoveredCharge = elementDecimal(seg, 7, delimiters, sink);
3860
4008
  }
3861
- function decodeSv3(acc, seg, delimiters) {
4009
+ function decodeSv3(acc, seg, delimiters, sink) {
3862
4010
  if (acc.variant !== "D") return;
4011
+ acc.serviceSegmentDecoded = true;
3863
4012
  acc.procedureQualifier = componentOptional(seg, 1, 1, delimiters) ?? "";
3864
4013
  acc.procedureCode = componentOptional(seg, 1, 2, delimiters) ?? "";
3865
4014
  const mods = [];
@@ -3868,7 +4017,7 @@ function decodeSv3(acc, seg, delimiters) {
3868
4017
  if (m !== void 0) mods.push(m);
3869
4018
  }
3870
4019
  acc.modifiers = mods;
3871
- acc.charge = elementDecimalOrZero(seg, 2, delimiters);
4020
+ acc.charge = elementDecimalOrZero(seg, 2, delimiters, sink);
3872
4021
  acc.placeOfServiceCode = elementOptional(seg, 3, delimiters);
3873
4022
  const cavities = [];
3874
4023
  for (let p = 1; p <= 5; p += 1) {
@@ -3877,15 +4026,15 @@ function decodeSv3(acc, seg, delimiters) {
3877
4026
  }
3878
4027
  acc.oralCavityArea = cavities;
3879
4028
  acc.prosthesisCrownInlayCode = elementOptional(seg, 5, delimiters);
3880
- acc.units = elementDecimalOrZero(seg, 6, delimiters);
4029
+ acc.units = elementDecimalOrZero(seg, 6, delimiters, sink);
3881
4030
  }
3882
- function openAdjudication(seg, delimiters) {
4031
+ function openAdjudication(seg, delimiters, sink) {
3883
4032
  return {
3884
4033
  otherPayerId: elementValue(seg, 1, delimiters),
3885
- amountPaid: elementDecimalOrZero(seg, 2, delimiters),
4034
+ amountPaid: elementDecimalOrZero(seg, 2, delimiters, sink),
3886
4035
  procedureQualifier: componentOptional(seg, 3, 1, delimiters),
3887
4036
  procedureCode: componentOptional(seg, 3, 2, delimiters),
3888
- paidUnits: elementDecimal(seg, 5, delimiters),
4037
+ paidUnits: elementDecimal(seg, 5, delimiters, sink),
3889
4038
  adjustments: [],
3890
4039
  dateAdjudicated: void 0
3891
4040
  };
@@ -4177,6 +4326,12 @@ function refuseHierarchy(message) {
4177
4326
  function refuseSpec2(message) {
4178
4327
  throw new Claim837BuildError(CLAIM_837_BUILD_ERROR_CODES.X12_837_BUILD_INVALID_SPEC, message);
4179
4328
  }
4329
+ function decStr(value) {
4330
+ return requireCallerDecimal(value, "build837", refuseSpec2).toString();
4331
+ }
4332
+ function escDec2(value, esc) {
4333
+ return esc(decStr(value));
4334
+ }
4180
4335
  var VERSION_BY_VARIANT = {
4181
4336
  P: "005010X222A2",
4182
4337
  I: "005010X223A3",
@@ -4208,8 +4363,9 @@ function buildClaim837(variant, spec) {
4208
4363
  component: componentSeparator,
4209
4364
  segment: segmentTerminator
4210
4365
  };
4211
- const esc = (value) => escapeRelease(value, delimiters);
4366
+ const esc = makeCallerEscaper(delimiters, "build837", refuseSpec2);
4212
4367
  const seg = (parts) => {
4368
+ requireCallerSegment(parts, "build837", refuseSpec2);
4213
4369
  let end = parts.length;
4214
4370
  while (end > 1 && parts[end - 1] === "") end -= 1;
4215
4371
  return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
@@ -4253,8 +4409,8 @@ function buildClaim837(variant, spec) {
4253
4409
  X12_837_FUNCTIONAL_ID,
4254
4410
  esc(applicationSenderCode),
4255
4411
  esc(applicationReceiverCode),
4256
- groupDate,
4257
- groupTime,
4412
+ esc(groupDate),
4413
+ esc(groupTime),
4258
4414
  esc(envelope.groupControlNumber),
4259
4415
  X12_AGENCY_CODE2,
4260
4416
  versionRelease
@@ -4469,7 +4625,7 @@ function emitClaim2(variant, claim, body, ctx) {
4469
4625
  ctx.seg([
4470
4626
  "CLM",
4471
4627
  ctx.esc(claim.claimId),
4472
- ctx.esc(claim.totalCharge.toString()),
4628
+ escDec2(claim.totalCharge, ctx.esc),
4473
4629
  "",
4474
4630
  "",
4475
4631
  ctx.comp([
@@ -4517,8 +4673,8 @@ function emitOtherSubscriber(other, body, ctx) {
4517
4673
  if (other.otherPayer !== void 0) emitEntity(other.otherPayer, body, ctx);
4518
4674
  }
4519
4675
  function emitServiceLine2(variant, line, lineNumber, body, ctx) {
4520
- body.push(ctx.seg(["LX", line.lineNumber ?? String(lineNumber)]));
4521
- const units = line.units === void 0 ? "0" : line.units.toString();
4676
+ body.push(ctx.seg(["LX", ctx.esc(line.lineNumber ?? String(lineNumber))]));
4677
+ const units = line.units === void 0 ? "0" : decStr(line.units);
4522
4678
  if (line.variant === "P") {
4523
4679
  const proc = ctx.comp([line.procedureQualifier, line.procedureCode, ...line.modifiers ?? []]);
4524
4680
  const pointers = ctx.comp(line.diagnosisPointers ?? []);
@@ -4526,7 +4682,7 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
4526
4682
  ctx.seg([
4527
4683
  "SV1",
4528
4684
  proc,
4529
- ctx.esc(line.charge.toString()),
4685
+ escDec2(line.charge, ctx.esc),
4530
4686
  ctx.esc(line.unitOfMeasure ?? ""),
4531
4687
  ctx.esc(units),
4532
4688
  ctx.esc(line.placeOfServiceCode ?? ""),
@@ -4550,11 +4706,11 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
4550
4706
  "SV2",
4551
4707
  ctx.esc(line.revenueCode),
4552
4708
  proc,
4553
- ctx.esc(line.charge.toString()),
4709
+ escDec2(line.charge, ctx.esc),
4554
4710
  ctx.esc(line.unitOfMeasure ?? ""),
4555
4711
  ctx.esc(units),
4556
- line.serviceLineRate === void 0 ? "" : ctx.esc(line.serviceLineRate.toString()),
4557
- line.nonCoveredCharge === void 0 ? "" : ctx.esc(line.nonCoveredCharge.toString())
4712
+ line.serviceLineRate === void 0 ? "" : escDec2(line.serviceLineRate, ctx.esc),
4713
+ line.nonCoveredCharge === void 0 ? "" : escDec2(line.nonCoveredCharge, ctx.esc)
4558
4714
  ])
4559
4715
  );
4560
4716
  } else {
@@ -4564,7 +4720,7 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
4564
4720
  ctx.seg([
4565
4721
  "SV3",
4566
4722
  proc,
4567
- ctx.esc(line.charge.toString()),
4723
+ escDec2(line.charge, ctx.esc),
4568
4724
  ctx.esc(line.placeOfServiceCode ?? ""),
4569
4725
  cavity,
4570
4726
  ctx.esc(line.prosthesisCrownInlayCode ?? ""),
@@ -4583,7 +4739,7 @@ function emitServiceLine2(variant, line, lineNumber, body, ctx) {
4583
4739
  "",
4584
4740
  "",
4585
4741
  "",
4586
- drug.quantity === void 0 ? "" : ctx.esc(drug.quantity.toString()),
4742
+ drug.quantity === void 0 ? "" : escDec2(drug.quantity, ctx.esc),
4587
4743
  ctx.esc(drug.unitOfMeasure ?? "")
4588
4744
  ])
4589
4745
  );
@@ -4613,10 +4769,10 @@ function emitAdjudication(adj, body, ctx) {
4613
4769
  ctx.seg([
4614
4770
  "SVD",
4615
4771
  ctx.esc(adj.otherPayerId),
4616
- ctx.esc(adj.amountPaid.toString()),
4772
+ escDec2(adj.amountPaid, ctx.esc),
4617
4773
  proc,
4618
4774
  "",
4619
- adj.paidUnits === void 0 ? "" : ctx.esc(adj.paidUnits.toString())
4775
+ adj.paidUnits === void 0 ? "" : escDec2(adj.paidUnits, ctx.esc)
4620
4776
  ])
4621
4777
  );
4622
4778
  emitCasGroup2(adj.adjustments, "build837: adjudication.adjustments", body, ctx);
@@ -4641,8 +4797,8 @@ function emitCasGroup2(raw, at, body, ctx) {
4641
4797
  if (adj === void 0 || adj.groupCode !== groupCode) break;
4642
4798
  parts.push(
4643
4799
  ctx.esc(adj.reasonCode),
4644
- ctx.esc(adj.amount.toString()),
4645
- adj.quantity === void 0 ? "" : ctx.esc(adj.quantity.toString())
4800
+ escDec2(adj.amount, ctx.esc),
4801
+ adj.quantity === void 0 ? "" : escDec2(adj.quantity, ctx.esc)
4646
4802
  );
4647
4803
  triples += 1;
4648
4804
  i += 1;
@@ -4713,7 +4869,7 @@ function emitNote(note, body, ctx) {
4713
4869
  body.push(ctx.seg(["NTE", ctx.esc(note.noteReferenceCode), ctx.esc(note.description)]));
4714
4870
  }
4715
4871
  function emitAmount(amt, body, ctx) {
4716
- body.push(ctx.seg(["AMT", ctx.esc(amt.qualifier), ctx.esc(amt.amount.toString())]));
4872
+ body.push(ctx.seg(["AMT", ctx.esc(amt.qualifier), escDec2(amt.amount, ctx.esc)]));
4717
4873
  }
4718
4874
  function emitHi(hi, body, ctx) {
4719
4875
  const composite = ctx.comp([
@@ -4721,8 +4877,10 @@ function emitHi(hi, body, ctx) {
4721
4877
  hi.code,
4722
4878
  hi.dateQualifier ?? "",
4723
4879
  hi.date ?? "",
4724
- hi.monetaryAmount === void 0 ? "" : hi.monetaryAmount.toString(),
4725
- hi.quantity === void 0 ? "" : hi.quantity.toString(),
4880
+ // `decStr`, not `escDec`: `ctx.comp` maps `esc` over every component, so
4881
+ // escaping here would double-release an active delimiter.
4882
+ hi.monetaryAmount === void 0 ? "" : decStr(hi.monetaryAmount),
4883
+ hi.quantity === void 0 ? "" : decStr(hi.quantity),
4726
4884
  hi.versionId ?? "",
4727
4885
  "",
4728
4886
  hi.poaIndicator ?? ""
@@ -5034,6 +5192,7 @@ function get271Eligibility(delimiters, tx) {
5034
5192
  const seg = body[i];
5035
5193
  if (seg === void 0) continue;
5036
5194
  const position = { segmentIndex: i + 1, transactionIndex: 0 };
5195
+ const sink = { warnings, position };
5037
5196
  switch (seg.id) {
5038
5197
  case "HL": {
5039
5198
  const hl = decodeHl2(seg, delimiters);
@@ -5137,7 +5296,7 @@ function get271Eligibility(delimiters, tx) {
5137
5296
  case "EB": {
5138
5297
  flushBenefit();
5139
5298
  if (currentSubscriber === void 0 && currentDependent === void 0) break;
5140
- currentBenefit = openBenefit(seg, delimiters);
5299
+ currentBenefit = openBenefit(seg, delimiters, sink);
5141
5300
  break;
5142
5301
  }
5143
5302
  case "MSG": {
@@ -5234,7 +5393,7 @@ function decodeDtp2(seg, delimiters) {
5234
5393
  value
5235
5394
  });
5236
5395
  }
5237
- function openBenefit(seg, delimiters) {
5396
+ function openBenefit(seg, delimiters, sink) {
5238
5397
  const serviceTypeCodes = [];
5239
5398
  for (const code of getAllSegmentValues(seg, "03", delimiters)) {
5240
5399
  if (code === "") continue;
@@ -5249,10 +5408,10 @@ function openBenefit(seg, delimiters) {
5249
5408
  insuranceTypeCode: elementOptional(seg, 4, delimiters),
5250
5409
  planCoverageDescription: elementOptional(seg, 5, delimiters),
5251
5410
  timePeriodQualifier: elementOptional(seg, 6, delimiters),
5252
- monetaryAmount: elementDecimal(seg, 7, delimiters),
5253
- percent: elementDecimal(seg, 8, delimiters),
5411
+ monetaryAmount: elementDecimal(seg, 7, delimiters, sink),
5412
+ percent: elementDecimal(seg, 8, delimiters, sink),
5254
5413
  quantityQualifier: elementOptional(seg, 9, delimiters),
5255
- quantity: elementDecimal(seg, 10, delimiters),
5414
+ quantity: elementDecimal(seg, 10, delimiters, sink),
5256
5415
  authorizationRequired: elementOptional(seg, 11, delimiters),
5257
5416
  inPlanNetwork: elementOptional(seg, 12, delimiters),
5258
5417
  references: [],
@@ -5349,6 +5508,15 @@ function refuseHierarchy2(message) {
5349
5508
  message
5350
5509
  );
5351
5510
  }
5511
+ function refuseSpec3(message) {
5512
+ throw new Eligibility271BuildError(
5513
+ ELIGIBILITY_271_BUILD_ERROR_CODES.X12_271_BUILD_INVALID_SPEC,
5514
+ message
5515
+ );
5516
+ }
5517
+ function escDec3(value, esc) {
5518
+ return esc(requireCallerDecimal(value, "build271", refuseSpec3).toString());
5519
+ }
5352
5520
  var X279A1_VERSION_RELEASE = "005010X279A1";
5353
5521
  var X12_271_FUNCTIONAL_ID = "HB";
5354
5522
  var X12_AGENCY_CODE3 = "X";
@@ -5366,8 +5534,9 @@ function build271(spec) {
5366
5534
  component: componentSeparator,
5367
5535
  segment: segmentTerminator
5368
5536
  };
5369
- const esc = (value) => escapeRelease(value, delimiters);
5537
+ const esc = makeCallerEscaper(delimiters, "build271", refuseSpec3);
5370
5538
  const seg = (parts) => {
5539
+ requireCallerSegment(parts, "build271", refuseSpec3);
5371
5540
  let end = parts.length;
5372
5541
  while (end > 1 && parts[end - 1] === "") end -= 1;
5373
5542
  return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
@@ -5405,8 +5574,8 @@ function build271(spec) {
5405
5574
  X12_271_FUNCTIONAL_ID,
5406
5575
  esc(applicationSenderCode),
5407
5576
  esc(applicationReceiverCode),
5408
- groupDate,
5409
- groupTime,
5577
+ esc(groupDate),
5578
+ esc(groupTime),
5410
5579
  esc(envelope.groupControlNumber),
5411
5580
  X12_AGENCY_CODE3,
5412
5581
  X279A1_VERSION_RELEASE
@@ -5576,10 +5745,10 @@ function emitBenefit(benefit, body, ctx) {
5576
5745
  ctx.esc(benefit.insuranceTypeCode ?? ""),
5577
5746
  ctx.esc(benefit.planCoverageDescription ?? ""),
5578
5747
  ctx.esc(benefit.timePeriodQualifier ?? ""),
5579
- benefit.monetaryAmount === void 0 ? "" : ctx.esc(benefit.monetaryAmount.toString()),
5580
- benefit.percent === void 0 ? "" : ctx.esc(benefit.percent.toString()),
5748
+ benefit.monetaryAmount === void 0 ? "" : escDec3(benefit.monetaryAmount, ctx.esc),
5749
+ benefit.percent === void 0 ? "" : escDec3(benefit.percent, ctx.esc),
5581
5750
  ctx.esc(benefit.quantityQualifier ?? ""),
5582
- benefit.quantity === void 0 ? "" : ctx.esc(benefit.quantity.toString()),
5751
+ benefit.quantity === void 0 ? "" : escDec3(benefit.quantity, ctx.esc),
5583
5752
  ctx.esc(benefit.authorizationRequired ?? ""),
5584
5753
  ctx.esc(benefit.inPlanNetwork ?? "")
5585
5754
  ])
@@ -5786,6 +5955,7 @@ function walk277(delimiters, tx) {
5786
5955
  const seg = body[i];
5787
5956
  if (seg === void 0) continue;
5788
5957
  const position = { segmentIndex: i + 1, transactionIndex: 0 };
5958
+ const sink = { warnings, position };
5789
5959
  switch (seg.id) {
5790
5960
  case "HL": {
5791
5961
  flushClaim();
@@ -5863,7 +6033,7 @@ function walk277(delimiters, tx) {
5863
6033
  case "SVC": {
5864
6034
  flushServiceLine();
5865
6035
  if (currentClaim === void 0) currentClaim = openClaim3();
5866
- currentServiceLine = openServiceLine3(seg, delimiters);
6036
+ currentServiceLine = openServiceLine3(seg, delimiters, sink);
5867
6037
  break;
5868
6038
  }
5869
6039
  case "REF": {
@@ -5937,6 +6107,7 @@ function decodeDtp3(seg, delimiters) {
5937
6107
  });
5938
6108
  }
5939
6109
  function decodeStc(seg, delimiters, warnings, position) {
6110
+ const sink = { warnings, position };
5940
6111
  const statuses = [];
5941
6112
  for (const elementIndex of [1, 10, 11]) {
5942
6113
  const code = decodeStatusComposite(seg, elementIndex, delimiters, warnings, position);
@@ -5945,8 +6116,8 @@ function decodeStc(seg, delimiters, warnings, position) {
5945
6116
  return Object.freeze({
5946
6117
  statusEffectiveDate: elementOptional(seg, 2, delimiters),
5947
6118
  actionCode: elementOptional(seg, 3, delimiters),
5948
- totalChargeAmount: elementDecimal(seg, 4, delimiters),
5949
- paymentAmount: elementDecimal(seg, 5, delimiters),
6119
+ totalChargeAmount: elementDecimal(seg, 4, delimiters, sink),
6120
+ paymentAmount: elementDecimal(seg, 5, delimiters, sink),
5950
6121
  adjudicationDate: elementOptional(seg, 6, delimiters),
5951
6122
  message: elementOptional(seg, 12, delimiters),
5952
6123
  statuses: Object.freeze(statuses)
@@ -5973,7 +6144,7 @@ function decodeStatusComposite(seg, n, delimiters, warnings, position) {
5973
6144
  entityCode
5974
6145
  });
5975
6146
  }
5976
- function openServiceLine3(seg, delimiters) {
6147
+ function openServiceLine3(seg, delimiters, sink) {
5977
6148
  const modifiers = [];
5978
6149
  for (let comp = 3; comp <= 6; comp += 1) {
5979
6150
  const m = componentOptional(seg, 1, comp, delimiters);
@@ -5983,9 +6154,13 @@ function openServiceLine3(seg, delimiters) {
5983
6154
  serviceIdQualifier: componentOptional(seg, 1, 1, delimiters),
5984
6155
  procedureCode: componentOptional(seg, 1, 2, delimiters),
5985
6156
  modifiers,
5986
- lineChargeAmount: elementDecimal(seg, 2, delimiters),
5987
- linePaymentAmount: elementDecimal(seg, 3, delimiters),
6157
+ lineChargeAmount: elementDecimal(seg, 2, delimiters, sink),
6158
+ linePaymentAmount: elementDecimal(seg, 3, delimiters, sink),
5988
6159
  revenueCode: elementOptional(seg, 4, delimiters),
6160
+ // SVC-07. SVC-05 (Quantity) and SVC-06 (a second composite) are NOT USED
6161
+ // in both X212 and X214, so they are deliberately left unread rather than
6162
+ // decoded "for symmetry" with the 835, whose SVC-05 IS the paid count.
6163
+ unitsOfService: elementDecimal(seg, 7, delimiters, sink),
5989
6164
  statuses: [],
5990
6165
  references: [],
5991
6166
  dates: []
@@ -5999,6 +6174,7 @@ function freezeServiceLine3(acc) {
5999
6174
  lineChargeAmount: acc.lineChargeAmount,
6000
6175
  linePaymentAmount: acc.linePaymentAmount,
6001
6176
  revenueCode: acc.revenueCode,
6177
+ unitsOfService: acc.unitsOfService,
6002
6178
  statuses: Object.freeze(acc.statuses.slice()),
6003
6179
  references: Object.freeze(acc.references.slice()),
6004
6180
  dates: Object.freeze(acc.dates.slice())
@@ -6041,12 +6217,15 @@ function refuseHierarchy3(message) {
6041
6217
  message
6042
6218
  );
6043
6219
  }
6044
- function refuseSpec3(message) {
6220
+ function refuseSpec4(message) {
6045
6221
  throw new ClaimStatus277BuildError(
6046
6222
  CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
6047
6223
  message
6048
6224
  );
6049
6225
  }
6226
+ function escDec4(value, esc) {
6227
+ return esc(requireCallerDecimal(value, "build277", refuseSpec4).toString());
6228
+ }
6050
6229
  var X12_277_FUNCTIONAL_ID = "HN";
6051
6230
  var X12_AGENCY_CODE4 = "X";
6052
6231
  var HL_LEVEL3 = {
@@ -6064,7 +6243,7 @@ function build277CA(spec) {
6064
6243
  }
6065
6244
  function buildClaimStatus(version, spec) {
6066
6245
  const { envelope } = spec;
6067
- enforceStructuralSpec4(spec);
6246
+ enforceStructuralSpec4(version, spec);
6068
6247
  const elementSeparator = envelope.elementSeparator ?? "*";
6069
6248
  const repetitionSeparator = envelope.repetitionSeparator ?? "^";
6070
6249
  const componentSeparator = envelope.componentSeparator ?? ":";
@@ -6075,8 +6254,9 @@ function buildClaimStatus(version, spec) {
6075
6254
  component: componentSeparator,
6076
6255
  segment: segmentTerminator
6077
6256
  };
6078
- const esc = (value) => escapeRelease(value, delimiters);
6257
+ const esc = makeCallerEscaper(delimiters, "build277", refuseSpec4);
6079
6258
  const seg = (parts) => {
6259
+ requireCallerSegment(parts, "build277", refuseSpec4);
6080
6260
  let end = parts.length;
6081
6261
  while (end > 1 && parts[end - 1] === "") end -= 1;
6082
6262
  return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
@@ -6120,8 +6300,8 @@ function buildClaimStatus(version, spec) {
6120
6300
  X12_277_FUNCTIONAL_ID,
6121
6301
  esc(applicationSenderCode),
6122
6302
  esc(applicationReceiverCode),
6123
- groupDate,
6124
- groupTime,
6303
+ esc(groupDate),
6304
+ esc(groupTime),
6125
6305
  esc(envelope.groupControlNumber),
6126
6306
  X12_AGENCY_CODE4,
6127
6307
  version
@@ -6140,7 +6320,7 @@ function buildClaimStatus(version, spec) {
6140
6320
  const raw = isa + gs + st + body.join("") + se + ge + iea;
6141
6321
  return parseX12(raw);
6142
6322
  }
6143
- function enforceStructuralSpec4(spec) {
6323
+ function enforceStructuralSpec4(version, spec) {
6144
6324
  const sources = requireCallerArray(
6145
6325
  spec.informationSources,
6146
6326
  "build277: spec.informationSources",
@@ -6198,13 +6378,13 @@ function enforceStructuralSpec4(spec) {
6198
6378
  for (let u = 0; u < subscribers.length; u += 1) {
6199
6379
  const subscriber = subscribers[u];
6200
6380
  if (subscriber === void 0) continue;
6201
- enforceSubscriber(subscriber, `${locator}.subscriber[${String(u)}]`);
6381
+ enforceSubscriber(version, subscriber, `${locator}.subscriber[${String(u)}]`);
6202
6382
  }
6203
6383
  }
6204
6384
  }
6205
6385
  }
6206
6386
  }
6207
- function enforceSubscriber(subscriber, locator) {
6387
+ function enforceSubscriber(version, subscriber, locator) {
6208
6388
  const claims = requireCallerArray(
6209
6389
  subscriber.claims,
6210
6390
  `build277: subscriber at ${locator}: claims`,
@@ -6223,7 +6403,8 @@ function enforceSubscriber(subscriber, locator) {
6223
6403
  }
6224
6404
  for (let c = 0; c < claims.length; c += 1) {
6225
6405
  const claim = claims[c];
6226
- if (claim !== void 0) enforceClaim2(claim, `${locator}.claim[${String(c)}]`, c === 0);
6406
+ if (claim !== void 0)
6407
+ enforceClaim2(version, claim, `${locator}.claim[${String(c)}]`, c === 0);
6227
6408
  }
6228
6409
  for (let d = 0; d < dependents.length; d += 1) {
6229
6410
  const dependent = dependents[d];
@@ -6242,20 +6423,21 @@ function enforceSubscriber(subscriber, locator) {
6242
6423
  }
6243
6424
  for (let c = 0; c < depClaims.length; c += 1) {
6244
6425
  const claim = depClaims[c];
6245
- if (claim !== void 0) enforceClaim2(claim, `${depLocator}.claim[${String(c)}]`, c === 0);
6426
+ if (claim !== void 0)
6427
+ enforceClaim2(version, claim, `${depLocator}.claim[${String(c)}]`, c === 0);
6246
6428
  }
6247
6429
  }
6248
6430
  }
6249
- function enforceClaim2(claim, locator, isFirst) {
6431
+ function enforceClaim2(version, claim, locator, isFirst) {
6250
6432
  const statuses = requireCallerArray(
6251
6433
  claim.statuses,
6252
6434
  `build277: claim at ${locator}: statuses`,
6253
- refuseSpec3
6435
+ refuseSpec4
6254
6436
  );
6255
6437
  const serviceLines = requireCallerArray(
6256
6438
  claim.serviceLines,
6257
6439
  `build277: claim at ${locator}: serviceLines`,
6258
- refuseSpec3
6440
+ refuseSpec4
6259
6441
  );
6260
6442
  if (claim.trace === void 0 && statuses.length === 0 && serviceLines.length === 0) {
6261
6443
  throw new ClaimStatus277BuildError(
@@ -6275,10 +6457,16 @@ function enforceClaim2(claim, locator, isFirst) {
6275
6457
  for (let l = 0; l < serviceLines.length; l += 1) {
6276
6458
  const line = serviceLines[l];
6277
6459
  if (line === void 0) continue;
6460
+ if (version === "005010X212" && line.unitsOfService === void 0) {
6461
+ throw new ClaimStatus277BuildError(
6462
+ CLAIM_STATUS_277_BUILD_ERROR_CODES.X12_277_BUILD_INVALID_SPEC,
6463
+ `build277: service line at ${locator}.line[${String(l)}] has no unitsOfService, and SVC-07 is a required element in 005010X212. Supply the submitted count; it is never defaulted. In 005010X214 it is situational, so build277CA accepts the same line.`
6464
+ );
6465
+ }
6278
6466
  const lineStatuses = requireCallerArray(
6279
6467
  line.statuses,
6280
6468
  `build277: claim at ${locator}.line[${String(l)}]: statuses`,
6281
- refuseSpec3
6469
+ refuseSpec4
6282
6470
  );
6283
6471
  for (let i = 0; i < lineStatuses.length; i += 1) {
6284
6472
  enforceStatus(lineStatuses[i], `${locator}.line[${String(l)}].status[${String(i)}]`);
@@ -6368,9 +6556,12 @@ function emitServiceLine3(line, body, ctx) {
6368
6556
  ctx.seg([
6369
6557
  "SVC",
6370
6558
  svc01,
6371
- line.lineChargeAmount === void 0 ? "" : ctx.esc(line.lineChargeAmount.toString()),
6372
- line.linePaymentAmount === void 0 ? "" : ctx.esc(line.linePaymentAmount.toString()),
6373
- ctx.esc(line.revenueCode ?? "")
6559
+ line.lineChargeAmount === void 0 ? "" : escDec4(line.lineChargeAmount, ctx.esc),
6560
+ line.linePaymentAmount === void 0 ? "" : escDec4(line.linePaymentAmount, ctx.esc),
6561
+ ctx.esc(line.revenueCode ?? ""),
6562
+ "",
6563
+ "",
6564
+ line.unitsOfService === void 0 ? "" : escDec4(line.unitsOfService, ctx.esc)
6374
6565
  ])
6375
6566
  );
6376
6567
  for (const status of line.statuses ?? []) emitStatus(status, body, ctx);
@@ -6389,8 +6580,8 @@ function emitStatus(status, body, ctx) {
6389
6580
  composite(0),
6390
6581
  ctx.esc(status.statusEffectiveDate ?? ""),
6391
6582
  ctx.esc(status.actionCode ?? ""),
6392
- status.totalChargeAmount === void 0 ? "" : ctx.esc(status.totalChargeAmount.toString()),
6393
- status.paymentAmount === void 0 ? "" : ctx.esc(status.paymentAmount.toString()),
6583
+ status.totalChargeAmount === void 0 ? "" : escDec4(status.totalChargeAmount, ctx.esc),
6584
+ status.paymentAmount === void 0 ? "" : escDec4(status.paymentAmount, ctx.esc),
6394
6585
  ctx.esc(status.adjudicationDate ?? ""),
6395
6586
  "",
6396
6587
  "",
@@ -6560,9 +6751,11 @@ function get820Payments(delimiters, tx) {
6560
6751
  for (let i = 0; i < body.length; i += 1) {
6561
6752
  const seg = body[i];
6562
6753
  if (seg === void 0) continue;
6754
+ const position = { segmentIndex: i + 1, transactionIndex: 0 };
6755
+ const sink = { warnings, position };
6563
6756
  switch (seg.id) {
6564
6757
  case "BPR": {
6565
- payment = decodeBpr2(seg, delimiters);
6758
+ payment = decodeBpr2(seg, delimiters, sink);
6566
6759
  break;
6567
6760
  }
6568
6761
  case "TRN": {
@@ -6629,13 +6822,13 @@ function get820Payments(delimiters, tx) {
6629
6822
  }
6630
6823
  case "RMR": {
6631
6824
  if (current === void 0) break;
6632
- const item = decodeRmr(seg, delimiters);
6825
+ const item = decodeRmr(seg, delimiters, sink);
6633
6826
  if (item !== void 0) current.openItems.push(item);
6634
6827
  break;
6635
6828
  }
6636
6829
  case "ADX": {
6637
6830
  if (current === void 0) break;
6638
- const adjustment = decodeAdx(seg, delimiters);
6831
+ const adjustment = decodeAdx(seg, delimiters, sink);
6639
6832
  if (adjustment !== void 0) current.adjustments.push(adjustment);
6640
6833
  break;
6641
6834
  }
@@ -6687,10 +6880,10 @@ function freezeRemittance(acc) {
6687
6880
  adjustments: Object.freeze(acc.adjustments.slice())
6688
6881
  });
6689
6882
  }
6690
- function decodeBpr2(seg, delimiters) {
6883
+ function decodeBpr2(seg, delimiters, sink) {
6691
6884
  return Object.freeze({
6692
6885
  transactionHandlingCode: elementValue(seg, 1, delimiters),
6693
- totalPremiumAmount: elementDecimalOrZero(seg, 2, delimiters),
6886
+ totalPremiumAmount: elementDecimalOrZero(seg, 2, delimiters, sink),
6694
6887
  creditDebitFlag: elementValue(seg, 3, delimiters),
6695
6888
  method: elementValue(seg, 4, delimiters),
6696
6889
  paymentFormatCode: elementOptional(seg, 5, delimiters),
@@ -6758,7 +6951,7 @@ function decodeNm13(seg, delimiters) {
6758
6951
  idCode: elementOptional(seg, 9, delimiters)
6759
6952
  });
6760
6953
  }
6761
- function decodeRmr(seg, delimiters) {
6954
+ function decodeRmr(seg, delimiters, sink) {
6762
6955
  const qualifier = elementValue(seg, 1, delimiters);
6763
6956
  const referenceId = elementValue(seg, 2, delimiters);
6764
6957
  if (qualifier === "" && referenceId === "") return void 0;
@@ -6766,12 +6959,12 @@ function decodeRmr(seg, delimiters) {
6766
6959
  qualifier,
6767
6960
  referenceId,
6768
6961
  paymentActionCode: elementOptional(seg, 3, delimiters),
6769
- amountPaid: elementDecimalOrZero(seg, 4, delimiters),
6770
- amountDue: elementDecimal(seg, 5, delimiters)
6962
+ amountPaid: elementDecimalOrZero(seg, 4, delimiters, sink),
6963
+ amountDue: elementDecimal(seg, 5, delimiters, sink)
6771
6964
  });
6772
6965
  }
6773
- function decodeAdx(seg, delimiters) {
6774
- const amount = elementDecimal(seg, 1, delimiters);
6966
+ function decodeAdx(seg, delimiters, sink) {
6967
+ const amount = elementDecimal(seg, 1, delimiters, sink);
6775
6968
  if (amount === void 0) return void 0;
6776
6969
  return Object.freeze({
6777
6970
  amount,
@@ -6829,9 +7022,12 @@ var Premium820BuildError = class extends Error {
6829
7022
  };
6830
7023
 
6831
7024
  // src/transactions/premium/build-820.ts
6832
- function refuseSpec4(message) {
7025
+ function refuseSpec5(message) {
6833
7026
  throw new Premium820BuildError(PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC, message);
6834
7027
  }
7028
+ function escDec5(value, esc) {
7029
+ return esc(requireCallerDecimal(value, "build820", refuseSpec5).toString());
7030
+ }
6835
7031
  var X218_VERSION_RELEASE = "005010X218";
6836
7032
  var X12_820_FUNCTIONAL_ID = "RA";
6837
7033
  var X12_AGENCY_CODE5 = "X";
@@ -6848,8 +7044,9 @@ function build820(spec) {
6848
7044
  component: componentSeparator,
6849
7045
  segment: segmentTerminator
6850
7046
  };
6851
- const esc = (value) => escapeRelease(value, delimiters);
7047
+ const esc = makeCallerEscaper(delimiters, "build820", refuseSpec5);
6852
7048
  const seg = (parts) => {
7049
+ requireCallerSegment(parts, "build820", refuseSpec5);
6853
7050
  let end = parts.length;
6854
7051
  while (end > 1 && parts[end - 1] === "") end -= 1;
6855
7052
  return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
@@ -6905,9 +7102,9 @@ function build820(spec) {
6905
7102
  // GS-02
6906
7103
  esc(applicationReceiverCode),
6907
7104
  // GS-03
6908
- groupDate,
7105
+ esc(groupDate),
6909
7106
  // GS-04 - CCYYMMDD
6910
- groupTime,
7107
+ esc(groupTime),
6911
7108
  // GS-05 - HHMM
6912
7109
  esc(envelope.groupControlNumber),
6913
7110
  // GS-06
@@ -6923,7 +7120,7 @@ function build820(spec) {
6923
7120
  seg([
6924
7121
  "BPR",
6925
7122
  esc(spec.payment.transactionHandlingCode),
6926
- esc(spec.payment.totalPremiumAmount.toString()),
7123
+ escDec5(spec.payment.totalPremiumAmount, esc),
6927
7124
  esc(spec.payment.creditDebitFlag),
6928
7125
  esc(spec.payment.method),
6929
7126
  esc(spec.payment.paymentFormatCode ?? ""),
@@ -6975,7 +7172,7 @@ function build820(spec) {
6975
7172
  return parseX12(raw);
6976
7173
  }
6977
7174
  function enforceStructuralSpec5(spec) {
6978
- const traces = requireCallerArray(spec.traces, "build820: spec.traces", refuseSpec4);
7175
+ const traces = requireCallerArray(spec.traces, "build820: spec.traces", refuseSpec5);
6979
7176
  if (traces.length === 0) {
6980
7177
  throw new Premium820BuildError(
6981
7178
  PREMIUM_820_BUILD_ERROR_CODES.X12_820_BUILD_INVALID_SPEC,
@@ -6985,7 +7182,7 @@ function enforceStructuralSpec5(spec) {
6985
7182
  const remittances = requireCallerArray(
6986
7183
  spec.remittances,
6987
7184
  "build820: spec.remittances",
6988
- refuseSpec4
7185
+ refuseSpec5
6989
7186
  );
6990
7187
  if (remittances.length === 0) {
6991
7188
  throw new Premium820BuildError(
@@ -7005,7 +7202,7 @@ function enforceStructuralSpec5(spec) {
7005
7202
  const openItems = requireCallerArray(
7006
7203
  remittance.openItems,
7007
7204
  `build820: spec.remittances[${String(r)}].openItems`,
7008
- refuseSpec4
7205
+ refuseSpec5
7009
7206
  );
7010
7207
  if (openItems.length === 0) {
7011
7208
  throw new Premium820BuildError(
@@ -7080,7 +7277,7 @@ function emitRemittance(remittance, body, seg, esc) {
7080
7277
  body.push(
7081
7278
  seg([
7082
7279
  "ADX",
7083
- esc(adjustment.amount.toString()),
7280
+ escDec5(adjustment.amount, esc),
7084
7281
  esc(adjustment.reasonCode),
7085
7282
  esc(adjustment.referenceQualifier ?? ""),
7086
7283
  esc(adjustment.referenceId ?? "")
@@ -7110,8 +7307,8 @@ function emitOpenItem(item, seg, esc) {
7110
7307
  esc(item.qualifier),
7111
7308
  esc(item.referenceId),
7112
7309
  esc(item.paymentActionCode ?? ""),
7113
- esc(item.amountPaid.toString()),
7114
- item.amountDue === void 0 ? "" : esc(item.amountDue.toString())
7310
+ escDec5(item.amountPaid, esc),
7311
+ item.amountDue === void 0 ? "" : escDec5(item.amountDue, esc)
7115
7312
  ]);
7116
7313
  }
7117
7314
  function emitRef5(ref, seg, esc) {
@@ -7342,7 +7539,8 @@ async function* get834Enrollments(delimiters, tx) {
7342
7539
  }
7343
7540
  case "AMT": {
7344
7541
  if (currentCoverage === void 0) break;
7345
- const amount = decodeAmt3(seg, delimiters);
7542
+ const sink = { warnings: current.warnings, position };
7543
+ const amount = decodeAmt3(seg, delimiters, sink);
7346
7544
  if (amount !== void 0) currentCoverage.amounts.push(amount);
7347
7545
  break;
7348
7546
  }
@@ -7468,8 +7666,8 @@ function decodeDtp4(seg, delimiters) {
7468
7666
  value
7469
7667
  });
7470
7668
  }
7471
- function decodeAmt3(seg, delimiters) {
7472
- const amount = elementDecimal(seg, 2, delimiters);
7669
+ function decodeAmt3(seg, delimiters, sink) {
7670
+ const amount = elementDecimal(seg, 2, delimiters, sink);
7473
7671
  if (amount === void 0) return void 0;
7474
7672
  return Object.freeze({
7475
7673
  qualifier: elementValue(seg, 1, delimiters),
@@ -7525,12 +7723,15 @@ var Enrollment834BuildError = class extends Error {
7525
7723
  };
7526
7724
 
7527
7725
  // src/transactions/enrollment/build-834.ts
7528
- function refuseSpec5(message) {
7726
+ function refuseSpec6(message) {
7529
7727
  throw new Enrollment834BuildError(
7530
7728
  ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_INVALID_SPEC,
7531
7729
  message
7532
7730
  );
7533
7731
  }
7732
+ function escDec6(value, esc) {
7733
+ return esc(requireCallerDecimal(value, "build834", refuseSpec6).toString());
7734
+ }
7534
7735
  var X220A1_VERSION_RELEASE = "005010X220A1";
7535
7736
  var X12_834_FUNCTIONAL_ID = "BE";
7536
7737
  var X12_AGENCY_CODE6 = "X";
@@ -7549,8 +7750,9 @@ function build834(spec) {
7549
7750
  component: componentSeparator,
7550
7751
  segment: segmentTerminator
7551
7752
  };
7552
- const esc = (value) => escapeRelease(value, delimiters);
7753
+ const esc = makeCallerEscaper(delimiters, "build834", refuseSpec6);
7553
7754
  const seg = (parts) => {
7755
+ requireCallerSegment(parts, "build834", refuseSpec6);
7554
7756
  let end = parts.length;
7555
7757
  while (end > 1 && parts[end - 1] === "") end -= 1;
7556
7758
  return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
@@ -7606,9 +7808,9 @@ function build834(spec) {
7606
7808
  // GS-02
7607
7809
  esc(applicationReceiverCode),
7608
7810
  // GS-03
7609
- groupDate,
7811
+ esc(groupDate),
7610
7812
  // GS-04 - CCYYMMDD
7611
- groupTime,
7813
+ esc(groupTime),
7612
7814
  // GS-05 - HHMM
7613
7815
  esc(envelope.groupControlNumber),
7614
7816
  // GS-06
@@ -7630,7 +7832,7 @@ function build834(spec) {
7630
7832
  return parseX12(raw);
7631
7833
  }
7632
7834
  function enforceStructuralSpec6(spec) {
7633
- const members = requireCallerArray(spec.members, "build834: spec.members", refuseSpec5);
7835
+ const members = requireCallerArray(spec.members, "build834: spec.members", refuseSpec6);
7634
7836
  if (members.length === 0) {
7635
7837
  throw new Enrollment834BuildError(
7636
7838
  ENROLLMENT_834_BUILD_ERROR_CODES.X12_834_BUILD_INVALID_SPEC,
@@ -7655,7 +7857,7 @@ function enforceStructuralSpec6(spec) {
7655
7857
  const coverages = requireCallerArray(
7656
7858
  member.healthCoverages,
7657
7859
  `build834: spec.members[${String(m)}].healthCoverages`,
7658
- refuseSpec5
7860
+ refuseSpec6
7659
7861
  );
7660
7862
  for (let c = 0; c < coverages.length; c += 1) {
7661
7863
  const coverage = coverages[c];
@@ -7789,7 +7991,7 @@ function emitCoverage(coverage, body, seg, esc) {
7789
7991
  );
7790
7992
  for (const date of coverage.dates ?? []) body.push(emitDate4(date, seg, esc));
7791
7993
  for (const amount of coverage.amounts ?? []) {
7792
- body.push(seg(["AMT", esc(amount.qualifier), esc(amount.amount.toString())]));
7994
+ body.push(seg(["AMT", esc(amount.qualifier), escDec6(amount.amount, esc)]));
7793
7995
  }
7794
7996
  }
7795
7997
  function emitRef6(ref, seg, esc) {
@@ -8182,6 +8384,12 @@ function refuseHierarchy4(message) {
8182
8384
  message
8183
8385
  );
8184
8386
  }
8387
+ function refuseSpec7(message) {
8388
+ throw new ServicesReview278BuildError(
8389
+ AUTH_278_BUILD_ERROR_CODES.X12_278_BUILD_INVALID_SPEC,
8390
+ message
8391
+ );
8392
+ }
8185
8393
  var X12_278_FUNCTIONAL_ID = "HI";
8186
8394
  var X12_AGENCY_CODE7 = "X";
8187
8395
  var HL_LEVEL4 = {
@@ -8210,8 +8418,9 @@ function buildServicesReview(version, direction, spec) {
8210
8418
  component: componentSeparator,
8211
8419
  segment: segmentTerminator
8212
8420
  };
8213
- const esc = (value) => escapeRelease(value, delimiters);
8421
+ const esc = makeCallerEscaper(delimiters, "build278", refuseSpec7);
8214
8422
  const seg = (parts) => {
8423
+ requireCallerSegment(parts, "build278", refuseSpec7);
8215
8424
  let end = parts.length;
8216
8425
  while (end > 1 && parts[end - 1] === "") end -= 1;
8217
8426
  return parts.slice(0, end).join(elementSeparator) + segmentTerminator;
@@ -8255,8 +8464,8 @@ function buildServicesReview(version, direction, spec) {
8255
8464
  X12_278_FUNCTIONAL_ID,
8256
8465
  esc(applicationSenderCode),
8257
8466
  esc(applicationReceiverCode),
8258
- groupDate,
8259
- groupTime,
8467
+ esc(groupDate),
8468
+ esc(groupTime),
8260
8469
  esc(envelope.groupControlNumber),
8261
8470
  X12_AGENCY_CODE7,
8262
8471
  version
@@ -8385,7 +8594,7 @@ function emitReview(review, parentHlId, direction, body, ctx, counter) {
8385
8594
  const nested = review.reviews ?? [];
8386
8595
  const hasChild = nested.length > 0 ? "1" : "0";
8387
8596
  const levelCode = review.levelCode ?? DEFAULT_REVIEW_LEVEL;
8388
- body.push(ctx.seg(["HL", hlId, parentHlId, levelCode, hasChild]));
8597
+ body.push(ctx.seg(["HL", hlId, parentHlId, ctx.esc(levelCode), hasChild]));
8389
8598
  for (const trace of review.traces ?? []) {
8390
8599
  body.push(
8391
8600
  ctx.seg([
@@ -8961,6 +9170,9 @@ function narrowNoteCode(value) {
8961
9170
  }
8962
9171
 
8963
9172
  // src/transactions/ack/build-999.ts
9173
+ function refuseSpec8(message) {
9174
+ throw new AckBuildError(ACK_BUILD_ERROR_CODES.X12_ACK_INVALID_SPEC, message);
9175
+ }
8964
9176
  var X231A1_VERSION_RELEASE = "005010X231A1";
8965
9177
  var X12_AGENCY_CODE8 = "X";
8966
9178
  function build999(spec) {
@@ -8977,7 +9189,7 @@ function build999(spec) {
8977
9189
  component: componentSeparator,
8978
9190
  segment: segmentTerminator
8979
9191
  };
8980
- const esc = (value) => escapeRelease(value, delimiters);
9192
+ const esc = makeCallerEscaper(delimiters, "build999", refuseSpec8);
8981
9193
  const senderQualifier = envelope.senderQualifier ?? "ZZ";
8982
9194
  const receiverQualifier = envelope.receiverQualifier ?? "ZZ";
8983
9195
  const usageIndicator = envelope.usageIndicator ?? "P";
@@ -9029,13 +9241,13 @@ function build999(spec) {
9029
9241
  // GS-02
9030
9242
  esc(envelope.receiverId),
9031
9243
  // GS-03
9032
- groupDate,
9244
+ esc(groupDate),
9033
9245
  // GS-04 - CCYYMMDD
9034
- groupTime,
9246
+ esc(groupTime),
9035
9247
  // GS-05 - HHMM
9036
- envelope.groupControlNumber,
9248
+ esc(envelope.groupControlNumber),
9037
9249
  // GS-06
9038
- groupResponsibleAgency,
9250
+ esc(groupResponsibleAgency),
9039
9251
  // GS-07
9040
9252
  X231A1_VERSION_RELEASE
9041
9253
  // GS-08 - the 999 TR3
@@ -9045,7 +9257,7 @@ function build999(spec) {
9045
9257
  );
9046
9258
  const stControlNumber = envelope.transactionSetControlNumber;
9047
9259
  const st = joinSeg(
9048
- ["ST", "999", stControlNumber, X231A1_VERSION_RELEASE],
9260
+ ["ST", "999", esc(stControlNumber), X231A1_VERSION_RELEASE],
9049
9261
  elementSeparator,
9050
9262
  segmentTerminator
9051
9263
  );
@@ -9078,8 +9290,16 @@ function build999(spec) {
9078
9290
  const ak9 = buildAk9(functionalGroup, esc, elementSeparator, segmentTerminator);
9079
9291
  const bodySegments = [st, ak1, ...responseSegments, ak9];
9080
9292
  const seCount = bodySegments.length + 1;
9081
- const se = joinSeg(["SE", String(seCount), stControlNumber], elementSeparator, segmentTerminator);
9082
- const ge = joinSeg(["GE", "1", envelope.groupControlNumber], elementSeparator, segmentTerminator);
9293
+ const se = joinSeg(
9294
+ ["SE", String(seCount), esc(stControlNumber)],
9295
+ elementSeparator,
9296
+ segmentTerminator
9297
+ );
9298
+ const ge = joinSeg(
9299
+ ["GE", "1", esc(envelope.groupControlNumber)],
9300
+ elementSeparator,
9301
+ segmentTerminator
9302
+ );
9083
9303
  const iea = joinSeg(["IEA", "1", interchangeControlNumber], elementSeparator, segmentTerminator);
9084
9304
  const raw = isa + gs + bodySegments.join("") + se + ge + iea;
9085
9305
  return parseX12(raw);
@@ -9201,7 +9421,7 @@ function buildIk4(elemError, esc, componentSeparator, elementSeparator, segmentT
9201
9421
  return joinSeg(parts, elementSeparator, segmentTerminator);
9202
9422
  }
9203
9423
  function buildIk5(response, esc, elementSeparator, segmentTerminator) {
9204
- const parts = ["IK5", response.disposition];
9424
+ const parts = ["IK5", esc(response.disposition)];
9205
9425
  const codes = response.syntaxErrorCodes ?? [];
9206
9426
  if (codes.length > 5) {
9207
9427
  throw new AckBuildError(
@@ -9215,7 +9435,7 @@ function buildIk5(response, esc, elementSeparator, segmentTerminator) {
9215
9435
  function buildAk9(group, esc, elementSeparator, segmentTerminator) {
9216
9436
  const parts = [
9217
9437
  "AK9",
9218
- group.disposition,
9438
+ esc(group.disposition),
9219
9439
  String(group.numberOfTransactionSets),
9220
9440
  String(group.numberOfReceivedTransactionSets),
9221
9441
  String(group.numberOfAcceptedTransactionSets)
@@ -9231,6 +9451,7 @@ function buildAk9(group, esc, elementSeparator, segmentTerminator) {
9231
9451
  return joinSeg(parts, elementSeparator, segmentTerminator);
9232
9452
  }
9233
9453
  function joinSeg(parts, elementSeparator, segmentTerminator) {
9454
+ requireCallerSegment(parts, "build999", refuseSpec8);
9234
9455
  return parts.join(elementSeparator) + segmentTerminator;
9235
9456
  }
9236
9457
  function pad8(value, width) {
@@ -9457,6 +9678,9 @@ var X12BuildError = class extends Error {
9457
9678
  };
9458
9679
 
9459
9680
  // src/builder/build-interchange.ts
9681
+ function refuseSpec9(message) {
9682
+ throw new X12BuildError(X12_BUILD_ERROR_CODES.X12_BUILD_INVALID_SPEC, message);
9683
+ }
9460
9684
  function buildInterchange(spec) {
9461
9685
  const elementSeparator = spec.elementSeparator ?? "*";
9462
9686
  const repetitionSeparator = spec.repetitionSeparator ?? "^";
@@ -9468,7 +9692,7 @@ function buildInterchange(spec) {
9468
9692
  component: componentSeparator,
9469
9693
  segment: segmentTerminator
9470
9694
  };
9471
- const esc = (value) => escapeRelease(value, delimiters);
9695
+ const esc = makeCallerEscaper(delimiters, "buildInterchange", refuseSpec9);
9472
9696
  const senderQualifier = spec.senderQualifier ?? "ZZ";
9473
9697
  const receiverQualifier = spec.receiverQualifier ?? "ZZ";
9474
9698
  const usageIndicator = spec.usageIndicator ?? "P";
@@ -9582,6 +9806,7 @@ function buildTransaction(tx, esc, elementSeparator, segmentTerminator) {
9582
9806
  return st + bodySegments + se;
9583
9807
  }
9584
9808
  function joinSeg2(parts, elementSeparator, segmentTerminator) {
9809
+ requireCallerSegment(parts, "buildInterchange", refuseSpec9);
9585
9810
  return parts.join(elementSeparator) + segmentTerminator;
9586
9811
  }
9587
9812
  function pad9(value, width) {
@@ -9890,8 +10115,8 @@ var profiles = Object.freeze({
9890
10115
  });
9891
10116
 
9892
10117
  // src/index.ts
9893
- var VERSION = "0.0.8";
10118
+ var VERSION = "0.0.10";
9894
10119
 
9895
- export { ACK_BUILD_ERROR_CODES, ALL_WARNING_MESSAGES, AUTH_278_BUILD_ERROR_CODES, AUTH_278_LOOP_2000A, AUTH_278_LOOP_2000B, AUTH_278_LOOP_2000C, AUTH_278_LOOP_2000D, AUTH_278_LOOP_2000E, AUTH_278_LOOP_2000F, AckBuildError, BALANCE_INVARIANTS, BUILD_REFUSAL_VALUE_MAX_LENGTH, BUILD_REFUSAL_VALUE_MAX_RENDERED, CARC, CLAIM_837D_LOOP_2000A, CLAIM_837D_LOOP_2300, CLAIM_837D_LOOP_2400, CLAIM_837I_LOOP_2000A, CLAIM_837I_LOOP_2300, CLAIM_837I_LOOP_2400, CLAIM_837P_LOOP_2000A, CLAIM_837P_LOOP_2300, CLAIM_837P_LOOP_2400, CLAIM_837P_LOOP_2410, CLAIM_837_BUILD_ERROR_CODES, CLAIM_837_LOOP_1000A, CLAIM_837_LOOP_1000B, CLAIM_837_LOOP_2010AA, CLAIM_837_LOOP_2010BA, CLAIM_837_LOOP_2010BB, CLAIM_837_LOOP_2010CA, CLAIM_837_LOOP_2430, CLAIM_ADJUSTMENT_GROUP_CODES, CLAIM_STATUS_277_BUILD_ERROR_CODES, CLAIM_STATUS_CATEGORY_CODES, CLAIM_STATUS_CODES, CLP_STATUS, CONTROL_NUMBER_PAIRS, Claim837BuildError, ClaimStatus277BuildError, DELIMITER_POSITIONS, ELIGIBILITY_271_BUILD_ERROR_CODES, ELIGIBILITY_271_LOOP_2000A, ELIGIBILITY_271_LOOP_2000B, ELIGIBILITY_271_LOOP_2000C, ELIGIBILITY_271_LOOP_2000D, ELIGIBILITY_271_LOOP_2100C, ELIGIBILITY_271_LOOP_2100D, ELIGIBILITY_271_LOOP_2110, ENROLLMENT_834_BUILD_ERROR_CODES, ENROLLMENT_834_LOOP_1000A, ENROLLMENT_834_LOOP_1000B, ENROLLMENT_834_LOOP_2000, ENROLLMENT_834_LOOP_2100A, ENROLLMENT_834_LOOP_2300, ENROLLMENT_834_LOOP_2320, Eligibility271BuildError, Enrollment834BuildError, FATAL_CODES, HI_QUALIFIERS, HL_LEVEL_CODES, IK3_SYNTAX_ERROR_CODES, IK4_SYNTAX_ERROR_CODES, ISA_MIN_LENGTH, LoopSpecDefinitionError, MAINTENANCE_TYPE_CODES, NM1_QUALIFIERS, NON_SPEC_SEGMENT_ID, PREMIUM_820_BUILD_ERROR_CODES, PREMIUM_820_LOOP_1000A, PREMIUM_820_LOOP_1000B, PREMIUM_820_LOOP_2000A, PREMIUM_820_LOOP_2100A, PREMIUM_820_LOOP_2300A, PREMIUM_820_LOOP_2310A, Premium820BuildError, RARC, RELEASE_CHAR, REMIT_835_BUILD_ERROR_CODES, REMIT_835_LOOP_1000A, REMIT_835_LOOP_1000B, REMIT_835_LOOP_2000, REMIT_835_LOOP_2100, REMIT_835_LOOP_2110, REQUIRED_LOOPS, Remit835BuildError, SERVICE_TYPE_CODES, STATUS_277_LOOP_2000A, STATUS_277_LOOP_2000B, STATUS_277_LOOP_2000C, STATUS_277_LOOP_2000D, STATUS_277_LOOP_2000E, STATUS_277_LOOP_2200, STATUS_277_LOOP_2220, ServicesReview278BuildError, TA1_ACK_CODES, TA1_NOTE_CODES, UNEXPECTED_SEGMENT_CONTEXTS, VERSION, WARNING_CODES, X12BuildError, X12Decimal, X12ParseError, X12ProfileError, X12_ACK_DISPOSITION_CODES, X12_BUILD_ERROR_CODES, build271, build277, build277CA, build278Request, build278Response, build820, build834, build835, build837D, build837I, build837P, build999, buildInterchange, buildTA1, checkClaimBalance, checkRemitTotalBalance, checkServiceLineBalance, collectElementValues, componentOptional, controlNumberMismatch, danglingReleaseChar, decodeSegment, defineLoopSpec, defineProfile, detectDelimiters, elementDecimal, elementDecimalOrZero, elementOptional, elementValue, escapeRelease, get271Eligibility, get277CADisposition, get277Status, get278Request, get278Response, get820Payments, get834Enrollments, get834Header, get835, get837Claims, getAllSegmentValues, getDefaultProfile, getSegmentValue, groupCountMismatch, hlParentLevelInvalid, hlParentMismatch, isAcceptDisposition, isClaimAdjustmentGroupCode, isDiagnosisQualifier, isProcedureQualifier, lookupCarc, lookupClaimStatus, lookupClaimStatusCategory, lookupClpStatus, lookupMaintenanceType, lookupRarc, lookupServiceType, missingGe, missingIea, missingRequiredLoop, missingSe, parse999, parseTA1, parseX12, partitionWarnings, pre005010, profiles, remitBalanceMismatch, renderCallerValue, resolveHiQualifier, segmentCountMismatch, serializeX12, setDefaultProfile, trailingGarbage, transactionCountMismatch, unescapeRelease, unexpectedSegment, unknown837Variant, unknownCarc, unknownClaimStatus, unknownClaimStatusCategory, unknownHiQualifier, unknownMaintenanceType, unknownRarc };
10120
+ export { ACK_BUILD_ERROR_CODES, ALL_WARNING_MESSAGES, AUTH_278_BUILD_ERROR_CODES, AUTH_278_LOOP_2000A, AUTH_278_LOOP_2000B, AUTH_278_LOOP_2000C, AUTH_278_LOOP_2000D, AUTH_278_LOOP_2000E, AUTH_278_LOOP_2000F, AckBuildError, BALANCE_INVARIANTS, BUILD_REFUSAL_VALUE_MAX_LENGTH, BUILD_REFUSAL_VALUE_MAX_RENDERED, CARC, CLAIM_837D_LOOP_2000A, CLAIM_837D_LOOP_2300, CLAIM_837D_LOOP_2400, CLAIM_837I_LOOP_2000A, CLAIM_837I_LOOP_2300, CLAIM_837I_LOOP_2400, CLAIM_837P_LOOP_2000A, CLAIM_837P_LOOP_2300, CLAIM_837P_LOOP_2400, CLAIM_837P_LOOP_2410, CLAIM_837_BUILD_ERROR_CODES, CLAIM_837_LOOP_1000A, CLAIM_837_LOOP_1000B, CLAIM_837_LOOP_2010AA, CLAIM_837_LOOP_2010BA, CLAIM_837_LOOP_2010BB, CLAIM_837_LOOP_2010CA, CLAIM_837_LOOP_2430, CLAIM_ADJUSTMENT_GROUP_CODES, CLAIM_STATUS_277_BUILD_ERROR_CODES, CLAIM_STATUS_CATEGORY_CODES, CLAIM_STATUS_CODES, CLP_STATUS, CONTROL_NUMBER_PAIRS, Claim837BuildError, ClaimStatus277BuildError, DELIMITER_POSITIONS, ELIGIBILITY_271_BUILD_ERROR_CODES, ELIGIBILITY_271_LOOP_2000A, ELIGIBILITY_271_LOOP_2000B, ELIGIBILITY_271_LOOP_2000C, ELIGIBILITY_271_LOOP_2000D, ELIGIBILITY_271_LOOP_2100C, ELIGIBILITY_271_LOOP_2100D, ELIGIBILITY_271_LOOP_2110, ENROLLMENT_834_BUILD_ERROR_CODES, ENROLLMENT_834_LOOP_1000A, ENROLLMENT_834_LOOP_1000B, ENROLLMENT_834_LOOP_2000, ENROLLMENT_834_LOOP_2100A, ENROLLMENT_834_LOOP_2300, ENROLLMENT_834_LOOP_2320, Eligibility271BuildError, Enrollment834BuildError, FATAL_CODES, HI_QUALIFIERS, HL_LEVEL_CODES, IK3_SYNTAX_ERROR_CODES, IK4_SYNTAX_ERROR_CODES, ISA_MIN_LENGTH, LoopSpecDefinitionError, MAINTENANCE_TYPE_CODES, NM1_QUALIFIERS, NON_SPEC_SEGMENT_ID, PREMIUM_820_BUILD_ERROR_CODES, PREMIUM_820_LOOP_1000A, PREMIUM_820_LOOP_1000B, PREMIUM_820_LOOP_2000A, PREMIUM_820_LOOP_2100A, PREMIUM_820_LOOP_2300A, PREMIUM_820_LOOP_2310A, Premium820BuildError, RARC, RELEASE_CHAR, REMIT_835_BUILD_ERROR_CODES, REMIT_835_LOOP_1000A, REMIT_835_LOOP_1000B, REMIT_835_LOOP_2000, REMIT_835_LOOP_2100, REMIT_835_LOOP_2110, REQUIRED_LOOPS, Remit835BuildError, SERVICE_TYPE_CODES, STATUS_277_LOOP_2000A, STATUS_277_LOOP_2000B, STATUS_277_LOOP_2000C, STATUS_277_LOOP_2000D, STATUS_277_LOOP_2000E, STATUS_277_LOOP_2200, STATUS_277_LOOP_2220, ServicesReview278BuildError, TA1_ACK_CODES, TA1_NOTE_CODES, UNEXPECTED_SEGMENT_CONTEXTS, VERSION, WARNING_CODES, X12BuildError, X12Decimal, X12ParseError, X12ProfileError, X12_ACK_DISPOSITION_CODES, X12_BUILD_ERROR_CODES, build271, build277, build277CA, build278Request, build278Response, build820, build834, build835, build837D, build837I, build837P, build999, buildInterchange, buildTA1, checkClaimBalance, checkRemitTotalBalance, checkServiceLineBalance, collectElementValues, componentOptional, controlNumberMismatch, danglingReleaseChar, decodeSegment, defineLoopSpec, defineProfile, detectDelimiters, elementDecimal, elementDecimalOrZero, elementOptional, elementValue, escapeRelease, get271Eligibility, get277CADisposition, get277Status, get278Request, get278Response, get820Payments, get834Enrollments, get834Header, get835, get837Claims, getAllSegmentValues, getDefaultProfile, getSegmentValue, groupCountMismatch, hlParentLevelInvalid, hlParentMismatch, isAcceptDisposition, isClaimAdjustmentGroupCode, isDiagnosisQualifier, isProcedureQualifier, lookupCarc, lookupClaimStatus, lookupClaimStatusCategory, lookupClpStatus, lookupMaintenanceType, lookupRarc, lookupServiceType, missingGe, missingIea, missingRequiredLoop, missingSe, parse999, parseTA1, parseX12, partitionWarnings, pre005010, profiles, readElementDecimal, remitBalanceMismatch, renderCallerValue, resolveHiQualifier, segmentCountMismatch, serializeX12, serviceLineDropped, serviceLineNotDecoded, setDefaultProfile, trailingGarbage, transactionCountMismatch, unescapeRelease, unexpectedSegment, unknown837Variant, unknownCarc, unknownClaimStatus, unknownClaimStatusCategory, unknownHiQualifier, unknownMaintenanceType, unknownRarc, unparseableDecimal };
9896
10121
  //# sourceMappingURL=index.mjs.map
9897
10122
  //# sourceMappingURL=index.mjs.map