@cosyte/x12 0.0.13 → 0.0.14

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/CHANGELOG.md CHANGED
@@ -9,6 +9,96 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ### Added
11
11
 
12
+ - **🩺 `X12_837_SERVICE_SEGMENT_REPEATED`, the 33rd Tier-2 warning code, plus the public factory
13
+ `serviceSegmentRepeated(position)`** (`X12-837-SV1-OVERWRITE`). A **second** `SV1` / `SV2` / `SV3`
14
+ arriving inside an **already-open** Loop 2400 now says so, at that repeated segment. Through
15
+ `0.0.13` it said nothing at all.
16
+
17
+ **🩺 What that cost, and it is money and a procedure code.** A service line carries **one** service
18
+ segment's worth of slots, and every decoder writes **all** of the slots its kind writes. Under an
19
+ `ST-03` of `005010X222A2`, `SV1*HC:99213*8500*UN*4***1~` followed by `SV1*HC:99999*12*UN*1***1~`
20
+ inside one `LX` left ONE line reading `charge` **`12`** and `procedureCode` **`99999`**, with
21
+ `warnings: []`. `8500` became `12`, CPT `99213` became `99999`, and nothing was raised on any
22
+ channel. **The worst corner is a repeat whose own charge element is ABSENT:** it writes `undefined`
23
+ over the amount the first one stated, and `X12_837_SERVICE_LINE_NOT_DECODED` does **not** fire
24
+ there, because a service segment did decode.
25
+
26
+ **🛑 THIS CLOSES ONLY THE SILENCE, AND THE RESTRAINT IS THE POINT.** The decode is **not** narrowed:
27
+ last-wins is unchanged, element for element, so which values a document decodes to are byte-for-byte
28
+ what they were at `0.0.13`. This reader cannot tell a stray service segment from a conformant one,
29
+ so choosing the first would be inventing; and changing which occurrence wins changes how
30
+ **already-published documents decode**. That is the same call made for the `SVx` variant fallback.
31
+
32
+ **It fires on a repeat of ANY kind, decoded or not.** One whose kind does not match the resolved
33
+ variant is read into nothing and overwrites nothing - what it carries reaches no part of the typed
34
+ model - and it is reported the same way, before or after the matching one.
35
+
36
+ **Anchored at the repeated service segment**, with **no `elementIndex`**: what is reported is a
37
+ second occurrence of the segment, not a defect in an element of it. **Once per repeat**, and the
38
+ count is scoped to the LINE and never latched, so a first service segment under a later `LX` is a
39
+ first. It can never name the same segment as `X12_837_SERVICE_SEGMENT_WITHOUT_LX`, which requires
40
+ that no Loop 2400 be open.
41
+
42
+ **It is additive and nothing moved onto it**, pinned by committed tests asserting the whole warning
43
+ channel with the new code filtered out. **No consumer predicate written against any existing code
44
+ changes meaning.** Read that as invariance, not as a list of what else you will see.
45
+
46
+ **🛑 The package's own documentation was a consumer, and it was blind.** The cookbook's "gate before
47
+ you post a line amount" recipe named four codes and **none** of them fires on the overwrite
48
+ document, so a consumer following it posted `12` for a line the sender also sent as `8500`. The
49
+ cookbook, the troubleshooting table and `KNOWN-LIMITATIONS.md` now name this code beside the other
50
+ four, and a committed test pins that the four-code gate misses what the five-code gate catches.
51
+ **The recipe was not the only page:** `spec-notes-money` named `X12_837_SERVICE_LINE_NOT_DECODED`
52
+ as "the known instance" of an 837 charge reading `undefined` from a slot no reader read, and the
53
+ repeat corner is a second instance by a different route on which that code does not fire. It now
54
+ says so.
55
+
56
+ - **🩺 `X12_837_AMBIGUOUS_VARIANT`, the 32nd Tier-2 warning code, plus the public factory
57
+ `ambiguous837Variant(position)`** (`X12-837-RESIDUALS`). An 837 whose variant was decided by the
58
+ `SVx` fallback, in a transaction body that carries service segments for **more than one variant**,
59
+ now says so at the `ST`. Through `0.0.13` it said nothing at all about that resolution.
60
+
61
+ **What that cost.** Variant resolution runs before the walk as
62
+ `explicitType ?? variantFromIcr ?? variantFromSegment`. Absent a caller `type` option, and where
63
+ `ST-03` names no implementation convention this reader recognises, the reader falls back to the
64
+ **first** `SV1` / `SV2` / `SV3` in the body, orphans included. One stray `SV2` ahead of a conformant
65
+ Professional claim therefore re-types the whole submission Institutional: `submission.variant` reads
66
+ `"I"`, and a consumer routing on that field sends a Professional claim down an Institutional path.
67
+ The line-level consequences were reported; **the submission-level typing that produced them was on
68
+ no channel**, so `submission.variant` carried a confident value with nothing to contradict it.
69
+
70
+ **🛑 THIS CLOSES ONLY THE SILENCE, AND THE RESTRAINT IS THE POINT.** The fallback is **not**
71
+ narrowed and first-wins is unchanged, so on every document that reaches the fallback the variant
72
+ resolved and the lines decoded are byte-for-byte what they were at `0.0.13`, and this code is added
73
+ beside whatever the walk already raised. (`X12-VARIANT-ICR-UNGROUNDED`, in this same release,
74
+ changed WHICH documents reach the fallback; read its entry for what decodes differently.) Excluding orphans from
75
+ the fallback would change how already-published documents decode and is its own slice.
76
+
77
+ **🩺 Which service segment is the stray one is NOT decided.** This reader cannot tell a stray
78
+ service segment from a conformant one, and the fallback takes the first whether or not a Loop 2400
79
+ was open at it. Reporting the conflict is honest; picking a winner would be inventing. Re-read with
80
+ `get837Claims(delimiters, tx, { type })` to decode against a variant you trust.
81
+
82
+ **It reports the RESOLUTION, never the document.** A caller `type`, or an `ST-03` naming a known
83
+ convention, means no guess was made and this code is **not** raised however mixed the body is.
84
+
85
+ **Anchored at the `ST`** (`tx.segments[0]`, which carries `ST-03`), with **no `elementIndex`**: the
86
+ conflict is a property of the body rather than of an element, and one route into it is an `ST-03`
87
+ that is absent altogether. Raised **once per transaction**, because there is one resolution per
88
+ transaction, and it can never travel with `X12_837_UNKNOWN_VARIANT`, which is the other outcome of
89
+ that same resolution.
90
+
91
+ **🩺 It is additive, and nothing moved onto it.** `X12_837_SERVICE_LINE_NOT_DECODED`,
92
+ `X12_837_SERVICE_SEGMENT_WITHOUT_LX` and `X12_837_SERVICE_LINE_DROPPED` fire on exactly the
93
+ documents they fired on before **this code was added**, in the same positions, pinned by committed
94
+ tests that assert the whole warning channel with the new code filtered out. **No consumer predicate
95
+ changes meaning because of this code.** (`X12-VARIANT-ICR-UNGROUNDED`, in this same release, DID
96
+ change which documents reach the `SVx` fallback; read its entry above.) Read that as **invariance and not as a list of what else you will
97
+ see** on a contested document: it does not promise that any particular loss on one is reported at
98
+ all, and one that is not was not reported before this code existed either. A stray `LX` that opened
99
+ no line, for one, already suppressed `X12_837_SERVICE_SEGMENT_WITHOUT_LX` for the service segments
100
+ inside it, and still does.
101
+
12
102
  - **🩺 `X12_STATED_AMOUNT_DISCARDED`, the 31st Tier-2 warning code, plus the public factory
13
103
  `statedAmountDiscarded(position)`** (`X12-STATED-AMOUNT-DISCARDED`). The entry below reports a row
14
104
  whose amount this library could not read. This one is the opposite case: **the reader discarded
@@ -270,6 +360,74 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
270
360
 
271
361
  ### Changed
272
362
 
363
+ - **🩺 `get837Claims` now recognises every published `ST-03` implementation-convention reference for
364
+ the three 837 guides, and some already-published files therefore decode differently**
365
+ (`X12-VARIANT-ICR-UNGROUNDED`). This is a grounding unit: the table `VARIANT_BY_ICR` had three keys
366
+ and they were grounded against nothing.
367
+
368
+ **🩺 What that cost, measured at `668afea`, which is `main` at published `0.0.13`.** The table held exactly
369
+ `005010X222A2`, `005010X223A3` and `005010X224A2`. **It contained none of the identifiers HIPAA
370
+ adopts at 45 CFR 162.1102** (`005010X222`; `005010X223` with its `005010X223A1` Type 1 errata;
371
+ `005010X224` with `005010X224A1`), **and it was missing `005010X222A1` and `005010X223A2`**, which
372
+ CMS and state Medicaid companion guides require in ST-03 and GS-08 on production professional and
373
+ institutional claims. So a conformant, HIPAA-mandated 837P declaring `005010X222A1` resolved to no
374
+ variant at all, fell through to the `SVx` scan, and one stray `SV2` anywhere in the body re-typed
375
+ the whole submission Institutional. **The `SVx` fallback was the NORMAL path on production
376
+ professional and institutional traffic rather than the exception**, and `X12_837_UNKNOWN_VARIANT`
377
+ on such a file was a fabricated non-conformance claim about a document that was not
378
+ non-conformant. The sources for every key are named beside the table and in
379
+ `documentation/agent-notes/x12-variant-icr-ungrounded.md`; the three later published errata guides
380
+ are the weakest leg and say so in place.
381
+
382
+ **🛑 This IS a behaviour change on already-published decoding, and it is disclosed rather than
383
+ buried.** On a file whose `ST-03` is now recognised: `submission.variant` can differ from what
384
+ `0.0.13` read, wherever the first `SVx` in the body disagreed with the declaration; and
385
+ **`X12_837_AMBIGUOUS_VARIANT` and `X12_837_UNKNOWN_VARIANT` no longer fire on it at all**, because
386
+ no guess was made. **A predicate written against either code goes quiet on such a file.**
387
+
388
+ **🩺 And a service line whose `SVx` kind disagrees with the declaration is no longer DECODED, so a
389
+ code STARTS firing on a document that may have carried `warnings: []`.** Under an `ST-03` of
390
+ `005010X222A1` with a body whose only service segment is an `SV2`, `0.0.13` read `variant` `"I"`,
391
+ `charge` `7300`, `units` `2` and `warnings: []`; this release reads `variant` `"P"`, `charge` and
392
+ `units` `undefined` with the rest of the service segment undecoded, and
393
+ `X12_837_SERVICE_LINE_NOT_DECODED` at that line's `LX`. **Read only the decimal slots as
394
+ `undefined`:** an undecoded line SEEDS its identity fields, so `procedureCode` is `""` on a P or D
395
+ line and `revenueCode` is `""` on an I one. A predicate of `procedureCode === undefined` does NOT
396
+ detect this.
397
+ A mis-stamped envelope is an ordinary vendor variant and this reader can no more tell one from a
398
+ conformant document than it can tell a stray `SVx` from a conformant one, so the loss is **warned
399
+ rather than silent**, and the cookbook's post-a-line-amount gate already names that code first.
400
+
401
+ **🛑 Read all of that as ONE property and never as a closed list of consequences:** where `ST-03`
402
+ is now recognised, **the document's own declaration decides the variant instead of its first
403
+ service segment**, and everything downstream follows from that single substitution. A first draft
404
+ of this entry published a census of three and a refuter measured it false by finding a fourth.
405
+
406
+ That is
407
+ the hazard a widening onto a new code carries, taken here in the opposite direction from the two
408
+ slices before it: they refused to narrow a fallback because the reader had no evidence beyond the
409
+ segments, and here the reader had the evidence in ST-03 and was ignoring it. Re-check any routing
410
+ driven off `submission.variant` for 837s you read on `0.0.13` or earlier.
411
+
412
+ **🛑 The `SVx` fallback is NOT narrowed.** First-wins still takes the first `SV1` / `SV2` / `SV3` in
413
+ the body, orphans included, on every document that still reaches it, and precedence is unchanged:
414
+ a caller `type` still wins ahead of ST-03, and ST-03 ahead of the segments. What changed is which
415
+ documents reach the fallback.
416
+
417
+ **It is a LIST of cited identifiers, never a pattern.** A reference outside the set, in a different
418
+ case, or carrying leading whitespace still falls through exactly as before. The set is **not
419
+ claimed exhaustive and no count of it is published**: both variant-resolution messages named the
420
+ three old keys literally, so both were wrong the moment the table was corrected, and neither
421
+ enumerates the set any more. A committed tripwire reds if any registry message quotes a TR3
422
+ identifier again.
423
+
424
+ **🩺 OPEN, and deliberately not fixed here: the EMIT side still stamps the old three.** `build837P`
425
+ / `build837I` / `build837D` write `005010X222A2` / `005010X223A3` / `005010X224A2` and a caller
426
+ cannot override them, so **a partner that requires `005010X222A1` or `005010X223A2` will reject an
427
+ 837 this builder emits.** Which published guide identifier a partner accepts is a partner fact
428
+ rather than a spec fact, and changing bytes this library already emitted would break the partners
429
+ it works with today. `KNOWN-LIMITATIONS.md` carries it as an open residual.
430
+
273
431
  - **🩺 BREAKING (read model): every monetary, percent and quantity slot the readers used to fill with
274
432
  a fabricated `X12Decimal.ZERO` is now `X12Decimal | undefined`** (`X12-837-SV-UNDEFINED-DECIMAL`).
275
433
  Through `0.0.12` an **absent** `SV1-02` - a monetary field on an 837 claim service line - read back
@@ -871,8 +1029,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
871
1029
  are both the line charge, so reading a service segment into a line the walker never opened
872
1030
  mis-reads money. Refusing to read is the safe half; doing it silently was the defect. **This says
873
1031
  nothing about how the variant resolved**, and `KNOWN-LIMITATIONS.md` now discloses why: a caller's
874
- `type` option wins first, and absent one, where `ST-03` names none of the three known
875
- implementation conventions, the reader falls back to the first `SVx` in the transaction body,
1032
+ `type` option wins first, and absent one, where `ST-03` names no implementation convention this
1033
+ reader recognises, the reader falls back to the first `SVx` in the transaction body,
876
1034
  orphans included, so a stray `SV2` re-types the whole submission. That is pre-existing behaviour, measured identical at `0.0.10`, and is deliberately
877
1035
  not narrowed here.
878
1036
 
@@ -16,6 +16,52 @@ model.
16
16
 
17
17
  ## Data / decode boundaries
18
18
 
19
+ - **🩺 Which `ST-03` implementation-convention references resolve to an 837 variant CHANGED in this
20
+ release, and some already-published files therefore decode differently** (`X12-VARIANT-ICR-UNGROUNDED`).
21
+ Through `0.0.13` `get837Claims` recognised exactly three references: `005010X222A2`, `005010X223A3`
22
+ and `005010X224A2`. **That set contained none of the identifiers HIPAA adopts at 45 CFR 162.1102**
23
+ (`005010X222`, `005010X223` + `005010X223A1`, `005010X224` + `005010X224A1`), **and it was missing
24
+ `005010X222A1` and `005010X223A2`**, which CMS and state Medicaid companion guides require in ST-03
25
+ and GS-08 on production professional and institutional claims. A conformant 837P declaring
26
+ `005010X222A1` therefore resolved to no variant at all and fell through to the `SVx` scan, where a
27
+ single stray `SV2` anywhere in the body re-typed the whole submission, and
28
+ `X12_837_UNKNOWN_VARIANT` accused a document that was not non-conformant. The reader now recognises
29
+ each base guide and each of its published errata. Sources for every key are named beside the table
30
+ in `src/transactions/claim/get-837.ts` and in
31
+ `documentation/agent-notes/x12-variant-icr-ungrounded.md`.
32
+ - **🛑 What this changes for a consumer, and it is a behaviour change on already-published
33
+ decoding.** On a file whose `ST-03` is now recognised: `submission.variant` can differ from what
34
+ `0.0.13` read, where the first `SVx` in the body disagreed with the declaration; and
35
+ **`X12_837_AMBIGUOUS_VARIANT` and `X12_837_UNKNOWN_VARIANT` no longer fire at all**, because no
36
+ guess was made. A predicate written against either code goes quiet on such a file. **🩺 And a
37
+ service line whose `SVx` kind disagrees with the declaration is no longer DECODED, so a code
38
+ STARTS firing on a document that may have carried `warnings: []`**: under `005010X222A1` with a
39
+ body whose only service segment is an `SV2`, `0.0.13` read `variant` `"I"` and `charge` `7300`
40
+ with no warnings, and this release reads `variant` `"P"`, `charge` `undefined`, and
41
+ `X12_837_SERVICE_LINE_NOT_DECODED` at that line's `LX`. A mis-stamped envelope is an ordinary
42
+ vendor variant and this reader cannot tell one from a conformant document; the loss is warned
43
+ rather than silent. **Read all of this as ONE property and never as a closed list: where `ST-03`
44
+ is now recognised the document's own declaration decides the variant instead of its first
45
+ service segment, and everything downstream follows from that.** Re-check any routing driven off
46
+ `submission.variant` for 837s read on `0.0.13` or earlier.
47
+ - **🛑 The `SVx` fallback is NOT narrowed.** First-wins still takes the first service segment in the
48
+ body, orphans included, on every document that still reaches it. What changed is which documents
49
+ reach it.
50
+ - **It is a LIST of cited identifiers, never a pattern.** A reference outside the set, in a
51
+ different case, or carrying leading whitespace, still falls through exactly as before. Nothing
52
+ trims, lower-cases or prefix-matches `ST-03`, because no source says to.
53
+ - **The set is not claimed exhaustive and no count of it is published**, here or in any warning
54
+ message. Both variant messages named the three old keys literally and were wrong the moment the
55
+ table was corrected, so neither enumerates the set any more.
56
+ - **🩺 OPEN, and NOT fixed here: the EMIT side still stamps the old three.** `build837P` /
57
+ `build837I` / `build837D` write `005010X222A2` / `005010X223A3` / `005010X224A2` into ST-03 and
58
+ GS-08, and **a caller cannot override the value**. Two of those are not what the companion guides
59
+ above require, so **a trading partner that requires `005010X222A1` or `005010X223A2` will reject
60
+ an 837 this builder emits.** Deliberately not re-stamped: which published guide identifier a
61
+ partner accepts is a partner fact rather than a spec fact, and changing bytes this library
62
+ already emitted would break the partners it works with today. The remedy is a caller-supplied
63
+ override, which is a public-surface addition and its own slice.
64
+
19
65
  - **🩺 BREAKING for `build277` callers: a 277 service line now REQUIRES `unitsOfService`, because
20
66
  SVC-07 is a required element in `005010X212` and this library was not emitting it at all**
21
67
  (`X12-277-SVC07-NOT-DECODED`). Through the release before this one `get277Status` read SVC-01
@@ -321,9 +367,9 @@ model.
321
367
  confident `0` through `0.0.12`, and this code has nothing to do with either.
322
368
  - **🩺 IT SAYS NOTHING ABOUT THE VARIANT, AND A FIRST DRAFT OF THIS BOUND CLAIMED IT DID.** Variant
323
369
  resolution runs before the walk. A caller-supplied `type` option wins first; absent one, and
324
- where `ST-03` names none of the three known implementation conventions, it **falls back to the
370
+ where `ST-03` names no implementation convention this reader recognises, it **falls back to the
325
371
  first `SVx` segment id anywhere in the transaction body - orphans included**. So a stray `SV2`
326
- under an `ST-03` of `005010X222A1` re-types the whole submission as Institutional, and every
372
+ under an unrecognised `ST-03` re-types the whole submission as Institutional, and every
327
373
  conformant `SV1` line in it then reads `charge` `undefined`, `units` `undefined` (both a
328
374
  fabricated `0` through `0.0.12`) and an `undefined` procedure
329
375
  code - `undefined`, not `""`, which on such a line is the `revenueCode`. Passing
@@ -331,7 +377,88 @@ model.
331
377
  identical at `0.0.10`, **not** introduced or changed by this code, and **not** narrowed here - excluding
332
378
  orphans from the fallback would change how existing documents decode and is its own slice. It
333
379
  is warned rather than silent (`X12_837_SERVICE_LINE_NOT_DECODED` at each `LX`), and
334
- `submission.variant` is the field that tells you.
380
+ `submission.variant` is the field that tells you. **The resolution itself is now reported too
381
+ wherever it was contested**, which is the entry below; the fallback is still not narrowed.
382
+
383
+ - **🩺 An 837 variant the `SVx` fallback resolved in a body that names more than one variant raises
384
+ `X12_837_AMBIGUOUS_VARIANT`, anchored at the `ST`.** The fallback is unchanged and is deliberately
385
+ NOT narrowed: it still takes the **first** `SV1` / `SV2` / `SV3` in the body, orphans included, so on
386
+ every document that reaches it the variant resolved is byte-for-byte what it was through `0.0.13`.
387
+ **WHICH documents reach it changed in this release** - see the ST-03 entry at the top of this list. What this code
388
+ adds is that the resolution said so. Through `0.0.13` a stray `SV2` re-typed a whole Professional
389
+ submission Institutional and **only the line-level consequences were on any channel** - a consumer
390
+ routing on `submission.variant` saw a confident `"I"` with nothing to contradict it. Four bounds,
391
+ each a committed test:
392
+ - **It reports the RESOLUTION, never the document.** A caller-supplied `type` wins ahead of the
393
+ fallback, and so does an `ST-03` this reader turns into a variant; in
394
+ either case no guess was made and this code is not raised **however mixed the body is**. Never
395
+ restate it as "the file carries more than one kind of service segment".
396
+ - **🩺 Which service segment is the stray one is NOT decided, and nothing here should ever start
397
+ deciding it.** This reader cannot tell a stray service segment from a conformant one, and the
398
+ fallback takes the first whether or not a Loop 2400 was open at it, so an orphan decides the
399
+ variant like any other. Reporting the conflict is honest; picking a winner would be inventing.
400
+ - **It is ADDITIVE and nothing moved onto it.** `X12_837_SERVICE_LINE_NOT_DECODED`,
401
+ `X12_837_SERVICE_SEGMENT_WITHOUT_LX` and `X12_837_SERVICE_LINE_DROPPED` fire on exactly the
402
+ documents they fired on before **this code was added**, in the same positions, and no predicate
403
+ changes meaning because of this code. **That is a claim about this code and NOT about the
404
+ release:** the ST-03 entry at the top of this list changed which documents reach the fallback at
405
+ all, and a line whose `SVx` kind disagrees with a now-recognised `ST-03` stops decoding and
406
+ starts raising `X12_837_SERVICE_LINE_NOT_DECODED`. Read that entry beside this bound.
407
+ - **It can never travel with `X12_837_UNKNOWN_VARIANT`**, which is the other outcome of the same
408
+ resolution: a body with conflicting service segments has, by construction, at least one to fall
409
+ back on. It fires **once per transaction**, because there is one resolution per transaction.
410
+ - **What it does NOT close:** narrowing the fallback, which is deliberately left alone. It no
411
+ longer leaves a second `SVx` inside an already-open Loop 2400 unreported: that was its own
412
+ slice, and it is the entry below. **Read the earlier wording as withdrawn** - it said such a
413
+ segment is "read into nothing", which was true only of one whose kind does not match the
414
+ resolved variant; a DUPLICATE of the matching kind is read into the line and REPLACES what the
415
+ first one wrote.
416
+
417
+ - **🩺 A second `SV1` / `SV2` / `SV3` inside an ALREADY-OPEN Loop 2400 raises
418
+ `X12_837_SERVICE_SEGMENT_REPEATED`, anchored at the repeated service segment itself.** A service
419
+ line carries **one** service segment's worth of slots, and every decoder writes **all** of the
420
+ slots its kind writes, so the model holds what the **last** service segment matching the
421
+ submission's resolved variant wrote and nothing of any earlier one. **Through `0.0.13` that
422
+ happened in complete silence, and it is money and a procedure code:** under an `ST-03` of
423
+ `005010X222A2`, `SV1*HC:99213*8500*UN*4***1~` followed by `SV1*HC:99999*12*UN*1***1~` inside one
424
+ `LX` left ONE line reading `charge` `12` and `procedureCode` `99999`, with `warnings: []`. `8500`
425
+ became `12`, CPT `99213` became `99999`, and nothing was raised on any channel. Six bounds, each a
426
+ committed test:
427
+ - **🛑 The decode is NOT narrowed, and that is deliberate.** Last-wins is unchanged, element for
428
+ element, so which values a document decodes to are byte-for-byte what they were at `0.0.13`.
429
+ This reader cannot tell a stray service segment from a conformant one, so choosing the first
430
+ instead would be inventing; and changing which occurrence wins changes how **already-published
431
+ documents decode**, the same call made about the variant fallback in the entry above. **This
432
+ closes only the silence.**
433
+ - **🩺 The worst corner is a repeat whose own charge element is ABSENT.** It writes `undefined`
434
+ over the amount the first one stated, and `X12_837_SERVICE_LINE_NOT_DECODED` does **not** fire
435
+ on that line, because a service segment _did_ decode. This code is then the only thing on the
436
+ channel that says why the charge is empty.
437
+ - **It fires on a repeat of ANY kind, decoded or not.** A service segment whose kind does not
438
+ match the resolved variant is read into nothing and overwrites nothing - the loss there is that
439
+ what it carries reaches no part of the typed model - and it is reported the same way, whether it
440
+ arrives before or after the matching one. That case was silent at the segment through `0.0.13`
441
+ too, and the entry above recorded it as a deferred residual.
442
+ - **Once per repeat, and the count is scoped to the LINE, never latched.** Three service segments
443
+ in one Loop 2400 are two warnings at two positions; a first service segment under a later `LX`,
444
+ or in a later claim, is a first and never a repeat. A latching flag would report a conformant
445
+ second line.
446
+ - **It can never name the same segment as `X12_837_SERVICE_SEGMENT_WITHOUT_LX`**, which requires
447
+ that NO Loop 2400 be open where this one requires that one is. It can travel with
448
+ `X12_837_SERVICE_LINE_NOT_DECODED` (at the `LX`), with `X12_837_AMBIGUOUS_VARIANT` (at the
449
+ `ST`), and with `X12_UNPARSEABLE_DECIMAL` raised by the repeat's own amount bytes. **That last
450
+ pair sits at the SAME `position.segmentIndex`, separated only by the decimal code's own
451
+ `position.elementIndex`** - measured, and pinned by a committed test. Never read a co-occurring
452
+ pair here as two segments.
453
+ - **It is ADDITIVE and nothing moved onto it.** Every code this reader raised on a document of
454
+ this shape before **this code was added**, it still raises, at the same position, and no
455
+ predicate changes meaning because of this code. Read that as invariance and **not** as a list of
456
+ what else you will see, and **not** as a claim about the release: the ST-03 entry at the top of
457
+ this list changed which documents reach the variant fallback.
458
+ **The package's own documentation was a consumer that needed updating**: the cookbook's
459
+ "gate before you post a line amount" recipe named four codes, none of which fires on the
460
+ overwrite document, so it was blind to it - it now names this one too, and a committed test
461
+ pins that the four-code gate misses what the five-code gate catches.
335
462
 
336
463
  - **🩺 An `N3` / `N4` / `PER` / `REF` discarded after a stray `LX` raises
337
464
  `X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX`, anchored at the discarded segment itself.** This is
package/dist/index.cjs CHANGED
@@ -138,6 +138,7 @@ var WARNING_CODES = {
138
138
  X12_UNKNOWN_HI_QUALIFIER: "X12_UNKNOWN_HI_QUALIFIER",
139
139
  X12_MISSING_REQUIRED_LOOP: "X12_MISSING_REQUIRED_LOOP",
140
140
  X12_837_UNKNOWN_VARIANT: "X12_837_UNKNOWN_VARIANT",
141
+ X12_837_AMBIGUOUS_VARIANT: "X12_837_AMBIGUOUS_VARIANT",
141
142
  X12_UNKNOWN_CLAIM_STATUS_CATEGORY: "X12_UNKNOWN_CLAIM_STATUS_CATEGORY",
142
143
  X12_UNKNOWN_CLAIM_STATUS: "X12_UNKNOWN_CLAIM_STATUS",
143
144
  X12_834_UNKNOWN_MAINTENANCE_TYPE: "X12_834_UNKNOWN_MAINTENANCE_TYPE",
@@ -145,6 +146,7 @@ var WARNING_CODES = {
145
146
  X12_837_SERVICE_LINE_NOT_DECODED: "X12_837_SERVICE_LINE_NOT_DECODED",
146
147
  X12_837_SERVICE_LINE_DROPPED: "X12_837_SERVICE_LINE_DROPPED",
147
148
  X12_837_SERVICE_SEGMENT_WITHOUT_LX: "X12_837_SERVICE_SEGMENT_WITHOUT_LX",
149
+ X12_837_SERVICE_SEGMENT_REPEATED: "X12_837_SERVICE_SEGMENT_REPEATED",
148
150
  X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX: "X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX",
149
151
  X12_837_PAY_TO_ADDRESS_REPEATED: "X12_837_PAY_TO_ADDRESS_REPEATED",
150
152
  X12_835_BALANCE_NOT_EVALUABLE: "X12_835_BALANCE_NOT_EVALUABLE",
@@ -222,7 +224,8 @@ var WARNING_MESSAGES = {
222
224
  X12_MISSING_REQUIRED_LOOP_2000B: 'Missing required loop "2000B" (Subscriber HL): no Subscriber HL precedes the CLM.',
223
225
  X12_MISSING_REQUIRED_LOOP_2010BA: 'Missing required loop "2010BA" (Subscriber Name): no Subscriber Name follows the Subscriber HL.',
224
226
  X12_MISSING_REQUIRED_LOOP_2010BB: 'Missing required loop "2010BB" (Payer Name): no Payer Name follows the Subscriber HL.',
225
- 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.`,
227
+ X12_837_UNKNOWN_VARIANT: "837 variant could not be resolved: ST-03's implementation convention reference is absent, empty, or not an 837 Technical Report Type 3 identifier this reader recognises, and no SVx service-line segment was present to fall back on. The set of references it recognises covers the professional, institutional and dental 837 guides HIPAA adopts at 45 CFR 162.1102 together with their published errata; it is NOT claimed to be exhaustive, and this message deliberately does not enumerate it, because a list here goes stale the moment a guide is added. A reference outside that set is not asserted to be invalid - all this code reports is that this reader could not turn it into a variant and had nothing to fall back on. The verbatim reference is preserved on the model; read it there rather than inferring what the sender meant.",
228
+ X12_837_AMBIGUOUS_VARIANT: "837 variant resolved from a service segment while the transaction body carries service segments of more than one variant: no caller `type` option was supplied and ST-03's implementation convention reference is absent, empty, or not an 837 Technical Report Type 3 identifier this reader recognises, so this reader fell back to the FIRST SV1 / SV2 / SV3 in the body, and a later one names a different variant. `submission.variant` is therefore a guess between contradictory evidence, and every claim and service line in the submission was read against it. Which service segment is the stray one is NOT decided here and is not derivable from the TR3s: this reader cannot tell a stray service segment from a conformant one, and the fallback takes the first regardless of whether any Loop 2400 was open at it, so an orphan segment decides the variant like any other. Read the bound literally, as a property of the RESOLUTION rather than of the document: this reports the fallback's own ambiguity, so a caller-supplied `type`, or an ST-03 this reader does turn into a variant, means no guess was made and this code is NOT raised however mixed the body is. Whatever else this reader raised on a document that reaches this code, it still raises, at the same position, and this one is added beside them. It is NOT a list of what else you will see, and it does not promise that any particular loss on such a document is reported at all. Re-read with the `type` option to decode the document against a variant you trust. The verbatim segments are preserved on the transaction set; read them there before acting on the submission's type.",
226
229
  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.",
227
230
  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.",
228
231
  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.",
@@ -230,6 +233,7 @@ var WARNING_MESSAGES = {
230
233
  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` are `undefined`, which is what this library puts on a decimal slot it decoded no value into; 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.",
231
234
  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.",
232
235
  X12_837_SERVICE_SEGMENT_WITHOUT_LX: "837 service segment with no Loop 2400 to read it into: no service line was open at the SV1 / SV2 / SV3 at `position.segmentIndex`, so NOTHING it carries - its charge, units, procedure code, modifiers, unit of measure and place of service - was read. Read that literally: an LX may well appear earlier in the transaction, and what this reports is that none of them had opened a Loop 2400 still current at this segment. No line appears on any claim's `serviceLines` for it and nothing is fabricated to stand in. Compare the two codes anchored at an LX: `X12_837_SERVICE_LINE_DROPPED`, where an LX IS present and opened no line, and `X12_837_SERVICE_LINE_NOT_DECODED`, where the line is on the model and only its service segment went unread. Neither of those can report the SAME service segment as this code, because both are raised at an LX and this one only where no Loop 2400 is open; a document with several claims can still carry all three. This says NOTHING about how the submission's variant resolved: absent a caller-supplied `type` option, and where ST-03 names no known implementation convention, the reader falls back to the first SV1 / SV2 / SV3 in the transaction, and a segment reported here is eligible for that fallback like any other, so a stray one can decide the variant every line is read against. Read `submission.variant`. The verbatim segments are preserved on the transaction set; read them there before concluding the claim had no service lines.",
236
+ X12_837_SERVICE_SEGMENT_REPEATED: "837 service segment repeated inside one Loop 2400: the SV1 / SV2 / SV3 at `position.segmentIndex` is not the first service segment to arrive in the service line the LX before it opened. This reader's line carries ONE service segment's worth of slots, so it cannot hold both, and this code is the only thing that tells you the document sent more than one. It asserts nothing about what usage the TR3s give the segment; what it reports is that this reader has one set of those slots per line. What the line carries is what the LAST service segment MATCHING the submission's resolved variant wrote onto it, and only that. Such a segment writes every slot its kind writes - the charge, the units and the procedure code among them - so a matching one arriving second leaves NOTHING an earlier matching one wrote, including where the later one's charge or units element is ABSENT: there the line is left with undefined, which is what this library puts on a decimal slot it decoded no value into, over an amount the earlier one stated. A service segment of a kind that does NOT match the resolved variant is read into nothing at all - it overwrites no slot, and what it carries reaches no part of the typed model. Which of them the sender meant is NOT decided here and is not derivable from the TR3s: this reader cannot tell a stray service segment from a conformant one, and picking a winner would be inventing. Nothing is fabricated to stand in, no second line is synthesized - an LX is what opens a line and there is none here - and no earlier value is kept in a second slot. Read the bound literally, as a property of the READ: this reports a second service segment arriving while a Loop 2400 IS open, whether or not it decoded. It is disjoint from `X12_837_SERVICE_SEGMENT_WITHOUT_LX`, which requires that NO Loop 2400 be open where this one requires that one is, so the two can never name the same segment; read that as disjointness and NOT as a promise that a service segment outside an open Loop 2400 is always named by that code, because a service segment FOLLOWING an LX that opened no line at all is named by neither of them, the loss having already been reported at that LX by `X12_837_SERVICE_LINE_DROPPED`. `X12_837_SERVICE_LINE_NOT_DECODED`, anchored at the LX, reports that no service segment matching the variant decoded onto the line at all, so a document can carry both codes on different segments. It fires once per repeat, so three service segments in one Loop 2400 are two warnings, and the count resets with the line: a first service segment under a later LX is a first and never a repeat. It says nothing about how the submission's variant resolved; where the fallback decided that and the body names more than one, `X12_837_AMBIGUOUS_VARIANT` reports it separately. The verbatim segments are preserved on the transaction set; read them there before acting on the charge, the quantity or the procedure code.",
233
237
  X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX: "837 entity segment read into nothing after a dropped LX: the N3 / N4 / PER / REF at `position.segmentIndex` arrived while no entity loop was open, because an earlier LX in this transaction opened no Loop 2400 (no CLM was open at it) and closed the entity loop that was current there. NOTHING this segment carries reached the model: no party's `address`, `contacts` or `references` was written from it, and no party, claim or line was synthesized to hold it. This is the code that names THAT loss; `X12_837_SERVICE_LINE_DROPPED` is raised at the LX itself and names the SERVICE LINE's loss, never an entity segment, so the two report different things about the same stretch of the document. Read the bound literally, because this code does NOT report every unattached entity segment: it reports one discarded after such an LX and only while nothing since has opened a new loop, so an N3 / N4 / PER / REF that reaches no party by any other route is still silent, and one arriving after a later NM1 is outside this code's scope, whether or not this reader surfaces that segment kind on that party. It reports that the segment reached NO party; it does not claim it would have reached one had the LX been absent, because this reader does not surface every one of these segment kinds on every party (a PER on a patient or a pay-to address, for one). Which party a segment following a stray LX belongs to is not derivable from the TR3s in either direction, so it is discarded rather than attributed: see KNOWN-LIMITATIONS.md. The verbatim segments are preserved on the transaction set; read them there before concluding a party had no address, no secondary identifier or no contact.",
234
238
  X12_837_PAY_TO_ADDRESS_REPEATED: "837 pay-to address named more than once in one Loop 2000A: the NM1*87 at `position.segmentIndex` is not the first in this Loop 2000A, and the TR3s allow Loop 2010AB at most once there. The model has ONE pay-to address slot, so it cannot carry both, and this code is the only thing that tells you the document named more than one. The reader NEVER merges them: an N3 or N4 after this segment can no longer add a street line to, or fill a blank in, the address an earlier NM1*87 named, which is what this library did through 0.0.12 - it returned a fused address no sender sent, silently. What the slot carries instead is the LAST occurrence that stated an address of its own; an occurrence that states none - one carrying no N3 or N4 at all, or only a valueless N3 or N4 whose elements are empty - does NOT replace one that did, so nothing an earlier occurrence stated is blanked either. Where no occurrence states an address, the slot holds what the FIRST N3 or N4 to arrive under any of them produced, which may be an address with no elements at all, and which is not necessarily the first occurrence's: an occurrence that carries no N3 or N4 writes nothing, so a later one's valueless N3 is the first write and takes a slot still empty. Read that as the corner it is, and never restate it as the first OCCURRENCE winning. Which occurrence the sender meant is NOT decided here and is not derivable from the TR3s, and the losing occurrence's address is NOT on the model in any form. Read the bound literally: this reports repetition within one Loop 2000A, which is where the pay-to route lives, and an NM1*87 arriving while a CLM is open never reaches that route. The verbatim segments are preserved on the transaction set; read them there before acting on where a payment is to be sent.",
235
239
  X12_AMOUNT_ROW_DROPPED: "Amount row dropped from the typed model: the AMT or ADX at `position.segmentIndex` carried no decodable amount (AMT-02, ADX-01), so NO row was built for it and the rest of the segment went with it - its qualifier or adjustment reason code, and any reference qualifier and id. Nothing is fabricated to stand in: a row is not built around a zero this library did not read, which is why the loss is reported rather than papered over. Two routes reach it and this code does not say which: the amount element was ABSENT, or it was present and held bytes that do not decode as a decimal. On this segment only the second route also raises `X12_UNPARSEABLE_DECIMAL`, carrying the failing element in its own `position.elementIndex`, so whether one is present at this `position.segmentIndex` is what separates them - and that code is unchanged by this one, which is raised alongside it rather than in place of it. Read the bound literally: this reports a row whose AMOUNT was read and decoded no value, and it is NOT a general report that an amount segment reached no model. A segment a reader discards before reading its amount is not on this channel, and neither is one whose amount decoded and then found no claim, service line, coverage or remittance open to attach the row to. An 820 RMR is not on it either, for its own reason: that row is dropped on open-item IDENTITY, RMR-01 and RMR-02 both empty, before the amount is read at all, so an RMR that states an open item and no amount keeps its row with amountPaid undefined while one that states an amount and no open item is dropped whole. That second case is a separate loss, and so is an 837 AMT that decoded while a Loop 2430 adjudication was open; `X12_STATED_AMOUNT_DISCARDED` reports both, and this code reports neither. The two can never name the same segment, because this one requires an amount element that decoded no value and that one requires the opposite. The verbatim segments are preserved on the transaction set; read them there before concluding the document stated no such amount.",
@@ -406,6 +410,13 @@ function unknown837Variant(position) {
406
410
  position
407
411
  };
408
412
  }
413
+ function ambiguous837Variant(position) {
414
+ return {
415
+ code: WARNING_CODES.X12_837_AMBIGUOUS_VARIANT,
416
+ message: WARNING_MESSAGES.X12_837_AMBIGUOUS_VARIANT,
417
+ position
418
+ };
419
+ }
409
420
  function serviceLineNotDecoded(position) {
410
421
  return {
411
422
  code: WARNING_CODES.X12_837_SERVICE_LINE_NOT_DECODED,
@@ -427,6 +438,13 @@ function serviceSegmentWithoutLx(position) {
427
438
  position
428
439
  };
429
440
  }
441
+ function serviceSegmentRepeated(position) {
442
+ return {
443
+ code: WARNING_CODES.X12_837_SERVICE_SEGMENT_REPEATED,
444
+ message: WARNING_MESSAGES.X12_837_SERVICE_SEGMENT_REPEATED,
445
+ position
446
+ };
447
+ }
430
448
  function entitySegmentDiscardedAfterLx(position) {
431
449
  return {
432
450
  code: WARNING_CODES.X12_837_ENTITY_SEGMENT_DISCARDED_AFTER_LX,
@@ -3323,9 +3341,20 @@ function statesAnAddress(address) {
3323
3341
 
3324
3342
  // src/transactions/claim/get-837.ts
3325
3343
  var VARIANT_BY_ICR = wireLookup({
3344
+ // Health Care Claim: Professional (837).
3345
+ "005010X222": "P",
3346
+ "005010X222A1": "P",
3326
3347
  "005010X222A2": "P",
3348
+ // Health Care Claim: Institutional (837).
3349
+ "005010X223": "I",
3350
+ "005010X223A1": "I",
3351
+ "005010X223A2": "I",
3327
3352
  "005010X223A3": "I",
3328
- "005010X224A2": "D"
3353
+ // Health Care Claim: Dental (837).
3354
+ "005010X224": "D",
3355
+ "005010X224A1": "D",
3356
+ "005010X224A2": "D",
3357
+ "005010X224A3": "D"
3329
3358
  });
3330
3359
  var VARIANT_BY_SV_SEGMENT = wireLookup({
3331
3360
  SV1: "P",
@@ -3361,16 +3390,24 @@ function get837Claims(delimiters, tx, opts) {
3361
3390
  const explicitType = opts?.type;
3362
3391
  const variantFromIcr = implementationConventionReference !== void 0 && implementationConventionReference !== "" ? VARIANT_BY_ICR[implementationConventionReference] : void 0;
3363
3392
  let variantFromSegment;
3364
- for (const seg of body) {
3365
- const fromSv = VARIANT_BY_SV_SEGMENT[seg.id];
3366
- if (fromSv !== void 0) {
3367
- variantFromSegment = fromSv;
3368
- break;
3393
+ let serviceSegmentVariantsConflict = false;
3394
+ if (explicitType === void 0 && variantFromIcr === void 0) {
3395
+ for (const seg of body) {
3396
+ const fromSv = VARIANT_BY_SV_SEGMENT[seg.id];
3397
+ if (fromSv === void 0) continue;
3398
+ if (variantFromSegment === void 0) {
3399
+ variantFromSegment = fromSv;
3400
+ } else if (fromSv !== variantFromSegment) {
3401
+ serviceSegmentVariantsConflict = true;
3402
+ break;
3403
+ }
3369
3404
  }
3370
3405
  }
3371
3406
  const variant = explicitType ?? variantFromIcr ?? variantFromSegment ?? "unknown";
3372
3407
  if (variant === "unknown") {
3373
3408
  warnings.push(unknown837Variant({ segmentIndex: 0, transactionIndex: 0 }));
3409
+ } else if (serviceSegmentVariantsConflict) {
3410
+ warnings.push(ambiguous837Variant({ segmentIndex: 0, transactionIndex: 0 }));
3374
3411
  }
3375
3412
  const hierarchies = [];
3376
3413
  const hlIndex = /* @__PURE__ */ new Map();
@@ -3419,6 +3456,10 @@ function get837Claims(delimiters, tx, opts) {
3419
3456
  if (droppedLineReported) return;
3420
3457
  warnings.push(serviceSegmentWithoutLx(position));
3421
3458
  };
3459
+ const noteServiceSegment = (acc, position) => {
3460
+ if (acc.serviceSegmentSeen) warnings.push(serviceSegmentRepeated(position));
3461
+ acc.serviceSegmentSeen = true;
3462
+ };
3422
3463
  const reportDiscardedEntitySegment = (position) => {
3423
3464
  if (!entityLoopClosedByStrayLx) return;
3424
3465
  warnings.push(entitySegmentDiscardedAfterLx(position));
@@ -3761,19 +3802,41 @@ function get837Claims(delimiters, tx, opts) {
3761
3802
  // before the walk and scans every SVx in the body: an orphan segment
3762
3803
  // is eligible for that fallback like any other, which is pre-existing
3763
3804
  // and disclosed in KNOWN-LIMITATIONS.md rather than changed here.
3805
+ //
3806
+ // A SECOND service segment inside an already-open Loop 2400 is the
3807
+ // other silence on this segment, and it is a worse one: the line IS
3808
+ // open, so the repeat decodes, and every decoder writes all of the
3809
+ // slots its kind writes. `SV1*HC:99213*8500*…` followed by
3810
+ // `SV1*HC:99999*12*…` left ONE line reading `charge` 12 and
3811
+ // `procedureCode` 99999 through `0.0.13`, with `warnings: []` - money
3812
+ // and a CPT code replaced on the model, on no channel at all.
3813
+ // `noteServiceSegment` reports that, at the repeat itself, and changes
3814
+ // NOTHING about which segment wins.
3764
3815
  case "SV1": {
3765
- if (currentServiceLine !== void 0) decodeSv1(currentServiceLine, seg, delimiters, sink);
3766
- else reportOrphanServiceSegment(position);
3816
+ if (currentServiceLine === void 0) {
3817
+ reportOrphanServiceSegment(position);
3818
+ break;
3819
+ }
3820
+ noteServiceSegment(currentServiceLine, position);
3821
+ decodeSv1(currentServiceLine, seg, delimiters, sink);
3767
3822
  break;
3768
3823
  }
3769
3824
  case "SV2": {
3770
- if (currentServiceLine !== void 0) decodeSv2(currentServiceLine, seg, delimiters, sink);
3771
- else reportOrphanServiceSegment(position);
3825
+ if (currentServiceLine === void 0) {
3826
+ reportOrphanServiceSegment(position);
3827
+ break;
3828
+ }
3829
+ noteServiceSegment(currentServiceLine, position);
3830
+ decodeSv2(currentServiceLine, seg, delimiters, sink);
3772
3831
  break;
3773
3832
  }
3774
3833
  case "SV3": {
3775
- if (currentServiceLine !== void 0) decodeSv3(currentServiceLine, seg, delimiters, sink);
3776
- else reportOrphanServiceSegment(position);
3834
+ if (currentServiceLine === void 0) {
3835
+ reportOrphanServiceSegment(position);
3836
+ break;
3837
+ }
3838
+ noteServiceSegment(currentServiceLine, position);
3839
+ decodeSv3(currentServiceLine, seg, delimiters, sink);
3777
3840
  break;
3778
3841
  }
3779
3842
  case "TOO": {
@@ -4080,6 +4143,7 @@ function openServiceLine2(seg, delimiters, variant, position) {
4080
4143
  lineNumber,
4081
4144
  position,
4082
4145
  serviceSegmentDecoded: false,
4146
+ serviceSegmentSeen: false,
4083
4147
  charge: void 0,
4084
4148
  units: void 0,
4085
4149
  unitOfMeasure: void 0,
@@ -10306,7 +10370,7 @@ var profiles = Object.freeze({
10306
10370
  });
10307
10371
 
10308
10372
  // src/index.ts
10309
- var VERSION = "0.0.13";
10373
+ var VERSION = "0.0.14";
10310
10374
 
10311
10375
  exports.ACK_BUILD_ERROR_CODES = ACK_BUILD_ERROR_CODES;
10312
10376
  exports.ALL_WARNING_MESSAGES = ALL_WARNING_MESSAGES;
@@ -10414,6 +10478,7 @@ exports.X12ParseError = X12ParseError;
10414
10478
  exports.X12ProfileError = X12ProfileError;
10415
10479
  exports.X12_ACK_DISPOSITION_CODES = X12_ACK_DISPOSITION_CODES;
10416
10480
  exports.X12_BUILD_ERROR_CODES = X12_BUILD_ERROR_CODES;
10481
+ exports.ambiguous837Variant = ambiguous837Variant;
10417
10482
  exports.amountRowDropped = amountRowDropped;
10418
10483
  exports.balanceNotEvaluable = balanceNotEvaluable;
10419
10484
  exports.build271 = build271;
@@ -10493,6 +10558,7 @@ exports.segmentCountMismatch = segmentCountMismatch;
10493
10558
  exports.serializeX12 = serializeX12;
10494
10559
  exports.serviceLineDropped = serviceLineDropped;
10495
10560
  exports.serviceLineNotDecoded = serviceLineNotDecoded;
10561
+ exports.serviceSegmentRepeated = serviceSegmentRepeated;
10496
10562
  exports.serviceSegmentWithoutLx = serviceSegmentWithoutLx;
10497
10563
  exports.setDefaultProfile = setDefaultProfile;
10498
10564
  exports.statedAmountDiscarded = statedAmountDiscarded;