@ekwo-ai/peppol-ubl 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,35 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to
5
+ [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Added
10
+ - **The first version.** A sales invoice or credit note as Peppol BIS Billing
11
+ 3.0 (UBL 2.1), from a posted document as three row shapes — header, lines,
12
+ VAT breakdown — with the figures written as they were posted and never
13
+ recomputed, on exact decimals.
14
+ - **112 published rules re-read and named by their identifier**, EN 16931 and
15
+ Peppol, as `violations` beside a file that is always valid UBL 2.1.
16
+ - **Code lists generated** from the EN 16931 Schematron Peppol ships
17
+ (`scripts/build-codelists.mjs`) and compared with it code for code.
18
+ - **Proof against the sources**: the OASIS schemas in the test suite, and the
19
+ published Schematron played out of tree against 100 committed files
20
+ (`scripts/play-schematron.mjs`), its verdicts recorded and held to on every
21
+ run. The README says what that proves and what it does not.
22
+
23
+ ### Changed
24
+ - **The electronic addresses are read from the header** —
25
+ `seller_peppol_scheme`, `seller_peppol_identifier`, `buyer_peppol_scheme`,
26
+ `buyer_peppol_identifier` — where `sellerEndpoint` and `buyerEndpoint` are not
27
+ given. They are still never derived from another identifier.
28
+ - **A line is no longer joined to its tax by `tax_id`.** The category and the
29
+ rate of a line are the line's: Ekwo OS now writes them when the document is
30
+ posted, and a join read the tax of today into an invoice already sent. A line
31
+ that says neither is reported (BR-CO-04, UBL-SR-48). `tax_id` is no longer a
32
+ declared column of the rows.
33
+ - No field of the rows is marked *not in the view today* but the net price of a
34
+ line keyed with its tax in it. Same input, same file: the 100 fixtures and
35
+ their recorded verdicts are unchanged.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ekwo AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,247 @@
1
+ # `@ekwo-ai/peppol-ubl`
2
+
3
+ A sales **invoice or credit note as the Peppol network carries it** — UBL 2.1
4
+ in the profile Peppol BIS Billing 3.0 of the European standard EN 16931 — in
5
+ TypeScript, with no dependencies.
6
+
7
+ Give it a posted document as the books hold it and it gives you the file, a
8
+ name for it, and every published rule the file breaks — named by the identifier
9
+ the rule is published under.
10
+
11
+ ```ts
12
+ import { generatePeppolUbl } from '@ekwo-ai/peppol-ubl';
13
+
14
+ const { file, filename, violations } = generatePeppolUbl({ header, lines, taxes });
15
+ ```
16
+
17
+ `header`, `lines` and `taxes` are one row of `document_header`, the rows of
18
+ `document_line_items` and the rows of `document_tax_summary` in
19
+ [Ekwo OS](https://github.com/Ekwo-ai/ekwo-os): a document, its lines, and its
20
+ VAT rounded once per tax. They are declared in this package's own types, so
21
+ any invoicing system that can produce the same three things can use it. It
22
+ reads no database and knows no accounting.
23
+
24
+ Writing the file is all it does. **Sending it takes a certified access point**,
25
+ a certificate and somebody on call, and this package has none of the three: you
26
+ get the same UBL anybody gets, and you send it through the access point you
27
+ chose.
28
+
29
+ ## The figures are the books' figures
30
+
31
+ Nothing is recomputed. A total, a base and a tax are written as they were
32
+ posted, and where they do not add up the rule they break is named rather than
33
+ the figure corrected. An invoice is an accounting document before it is an XML
34
+ one: a file that disagrees with the ledger it came from by a cent is worse than
35
+ a file that is refused, because the first is found by whoever files the VAT
36
+ return.
37
+
38
+ For the same reason no figure passes through a `number`. Amounts arrive as the
39
+ text Postgres prints a `numeric` as, are compared as exact decimals on
40
+ `bigint`, and leave as the same digits. The rules of EN 16931 compare with `=`
41
+ and not with a tolerance; a sum a binary float gets wrong in its last bit is a
42
+ rule reported broken on an invoice that is right.
43
+
44
+ Two things are derived, because the standard has a place for them and the books
45
+ hold them in another shape:
46
+
47
+ - **The VAT breakdown.** The books keep one row per tax; the standard wants one
48
+ group per category and rate (BG-23). Two taxes at one rate — goods and
49
+ services at the standard rate — are one group: their bases added, their taxes
50
+ added, nothing rounded again.
51
+ - **The net price of a discounted line.** The books hold the price as keyed and
52
+ a discount in percent; the standard wants the net price (BT-146), and has room
53
+ for the gross one and the discount beside it (BT-148, BT-147). All three are
54
+ written, exact to the last digit — `27.7778` less 10 % is `25.00002` — so
55
+ that the quantity times the net price is still the line the books rounded.
56
+
57
+ A line's category and rate are read from the line and from nowhere else. In
58
+ Ekwo OS a line keeps the category and the rate it was posted with, so that a
59
+ rate that changes later restates no invoice already sent; a line that says
60
+ neither has neither, and BR-CO-04 says so.
61
+
62
+ ## Nothing is made up
63
+
64
+ There is no default currency, country, language, unit, payment means or
65
+ identifier scheme. An absent value is an absent element — never an empty one,
66
+ which is a rule broken in its own right (PEPPOL-EN16931-R008) — and the rule
67
+ that wanted it is reported. In particular:
68
+
69
+ - **The electronic addresses** (BT-34, BT-49) are read from the header —
70
+ `seller_peppol_scheme` and `seller_peppol_identifier`, and the same two for
71
+ the buyer — or given as `sellerEndpoint` and `buyerEndpoint`, which win. They
72
+ are never derived: which identifier a participant is registered under is a
73
+ fact of its registration, not of its VAT number.
74
+ - **The scheme of a registration number** (BT-30-1, BT-47-1) is given or left
75
+ out. It is *not* what Ekwo OS calls `party_scheme`: that is the scheme a party
76
+ is addressed by, and in more than one country it is not a scheme a
77
+ registration number can be written in at all.
78
+ - **An IBAN without a payment means code** is not written. The format files the
79
+ account under the code (UNTDID 4461) and there is no code that means "probably
80
+ a transfer". It comes back as `payment-means-missing`.
81
+ - **A price keyed with its tax in it** has no net price here. That one is the
82
+ line's base divided by its quantity — a rounding decision, and so the books'
83
+ to make: pass it as `net_unit_price`, or read BR-26.
84
+ - **A `Date` object is refused.** A driver hands a `date` column back as an
85
+ instant, at a midnight that is UTC for one driver and local for the next.
86
+ Select it `::text`.
87
+
88
+ ## What is refused, and what comes back as a violation
89
+
90
+ What would make the file absurd throws a `PeppolUblError`: a document that is
91
+ not a sales invoice or a sales credit note, that has no number, no date, no
92
+ currency or no line, an amount or a date that is not one. These are also what
93
+ the UBL schema requires, so **every file that comes back is a valid UBL 2.1
94
+ document** — the wrong ones too.
95
+
96
+ Everything else comes back in `violations`, beside a file that says what it was
97
+ given:
98
+
99
+ ```ts
100
+ { code: 'BR-CO-15', message: '1450.00 without VAT and 267.00 of VAT are not the 1717.01 the document totals.' }
101
+ { code: 'PEPPOL-EN16931-R120', message: '…', line: '10' }
102
+ ```
103
+
104
+ `code` is the identifier of the published rule — what a validator on the
105
+ network will say of the same file, and the only name worth branching on.
106
+ `message` is this package's sentence, not the rule's text. Two codes are
107
+ lower-case because they are this package's own — things it could not write, and
108
+ which no validator reports because it never sees them: `payment-means-missing`,
109
+ and `exemption-reason-ambiguous` for a VAT group whose lines carry several
110
+ exemption codes where the group has room for one.
111
+
112
+ An empty `violations` is the only state to send a file in.
113
+
114
+ The rules re-read here, 112 of them:
115
+
116
+ | | |
117
+ |---|---|
118
+ | the parties | BR-06 to BR-11, BR-57, BR-62, BR-63, BR-CO-09, BR-CO-26, PEPPOL-EN16931-R010, R020 |
119
+ | the reference Peppol requires | PEPPOL-EN16931-R003 |
120
+ | payment | BR-61, BR-CO-25 |
121
+ | the lines | BR-22, BR-23, BR-25 to BR-28, BR-CO-04, UBL-SR-48, PEPPOL-EN16931-R120 |
122
+ | the VAT breakdown | BR-47, BR-48, BR-CO-17, BR-CO-18, PEPPOL-EN16931-R053, R054 |
123
+ | the categories S, Z, E, AE, K, G and O | BR-*-01, -02, -05, -08, -09, -10 for each, BR-IC-11, BR-IC-12, BR-O-11, BR-O-12, PEPPOL-EN16931-P0104 to P0111 |
124
+ | the totals | BR-CO-10, BR-CO-14, BR-CO-15, BR-CO-16 |
125
+ | decimals | BR-DEC-09, -12, -14, -16, -18, -19, -20, -23, UBL-DT-01 |
126
+ | check digits | PEPPOL-COMMON-R040 (GLN), R043 (Belgian enterprise number) |
127
+ | code lists | BR-CL-03, -04, -11, -14, -16, -17, -18, -22, -23, -25, PEPPOL-EN16931-CL007, CL008 |
128
+
129
+ ## What is verified, and what is not
130
+
131
+ **Against the UBL 2.1 schema: verified, in the test suite.** Every file the
132
+ tests produce — 100 cases, invoices and credit notes, right and wrong — is
133
+ validated against the schemas OASIS publishes, unmodified under `test/xsd/`
134
+ (`xmllint-wasm`, a development dependency: no network, no system tool). The
135
+ test also mutates a file three ways and watches validation fail, so a validator
136
+ that resolved no import would not pass for one that checks.
137
+
138
+ **The code lists: generated, and compared code for code.** `src/codelists.ts`
139
+ is written by `scripts/build-codelists.mjs` from the `BR-CL-*` assertions of the
140
+ EN 16931 Schematron as Peppol BIS Billing 3.0 ships it (`test/codelist/`), and
141
+ the tests parse that file again, with other code, and compare every list with
142
+ it in order.
143
+
144
+ **Against the Schematron of EN 16931 and of Peppol: played, but not by the test
145
+ suite.** Both rule sets are Schematron with an XSLT 2.0 query binding. Nothing
146
+ in a JavaScript runtime executes XSLT 2.0 except SaxonJS, which this repository
147
+ does not depend on for a test and whose licence is not an open-source one. So:
148
+
149
+ - the Schematron was **played by hand**, from outside the repository, on
150
+ 18 September 2026: release **3.0.20** of Peppol BIS Billing (which ships the
151
+ EN 16931 rules at version 1.3.15), compiled with SchXslt 1.10.1, run with
152
+ SaxonJS. `scripts/play-schematron.mjs` is the whole procedure and checks the
153
+ SHA-256 of everything it downloads;
154
+ - it was played against the 100 files under `test/fixtures/`, and what it said
155
+ is committed as `test/fixtures/verdicts.json`;
156
+ - the test suite holds the package to that record on every run: the generator
157
+ must still write those files **byte for byte**, and for every one of them the
158
+ rules this package reports must be **exactly** the fatal rules the Schematron
159
+ reported — no more, no fewer. The 16 files meant to be right are right for
160
+ both, without a warning;
161
+ - every one of the 112 rules named above was reported by the published
162
+ Schematron on at least one of those files, and the Schematron reported
163
+ nothing on them that this package does not name. A rule added to
164
+ `src/rules.ts` and never played fails the tests.
165
+
166
+ What that proves: on those 100 documents, this package and the network agree.
167
+ What it does not: that they agree on a document that is not one of them. The
168
+ re-reading is code written from the rules, not the rules themselves. **Before
169
+ relying on an empty `violations` for a kind of invoice these cases do not
170
+ cover, validate one through your access point** — most offer a test endpoint —
171
+ or play the script.
172
+
173
+ **Not re-read at all**, so never reported here, and a validator may:
174
+
175
+ - the **national rules** Peppol adds for a seller in Denmark, Germany, Greece,
176
+ Iceland, Italy, the Netherlands, Norway and Sweden (`DK-R-*`, `DE-R-*`,
177
+ `GR-R-*`, `IS-R-*`, `IT-R-*`, `NL-R-*`, `NO-R-*`, `SE-R-*`);
178
+ - the check digits of identifier schemes other than `0088` and `0208`
179
+ (PEPPOL-COMMON-R041, R042, R044 to R050);
180
+ - every rule about something this package does not write — see below;
181
+ - the **warnings**. Only fatal rules are named.
182
+
183
+ ## What it does not write
184
+
185
+ Document-level allowances and charges (BG-20, BG-21), line-level ones (BG-27,
186
+ BG-28), the invoicing period (BG-14, BG-26), a VAT accounting currency (BT-6,
187
+ BT-111), a payee other than the seller (BG-10), a tax representative (BG-11),
188
+ attachments (BG-24), item attributes and classifications, card and direct-debit
189
+ payments, prepayment and self-billed invoices — the type is `380` or `381`.
190
+ Ekwo OS has no column for any of them today. A document that needs one is a
191
+ document this package cannot write yet, and it does not pretend to.
192
+
193
+ Neighbouring profiles — XRechnung, a PINT, Factur-X in UBL — are other formats
194
+ and would be other packages. Reading an incoming invoice is another job
195
+ altogether.
196
+
197
+ ## What the source refuted
198
+
199
+ The first draft was written from the specification. Playing the Schematron
200
+ against it found what reading had not:
201
+
202
+ - **`0999999999` is not a Belgian enterprise number.** The number every test in
203
+ the surrounding repository uses fails the check digits Peppol verifies
204
+ (PEPPOL-COMMON-R043). The fixtures use `0999999922`, in a range no number was
205
+ issued in.
206
+ - **The two rule sets do not share a list of electronic address schemes.**
207
+ EN 16931 lists seven that Peppol refuses — e-mail and telephone among them. A
208
+ scheme can break one rule and not the other (`SCHEMES_NOT_ON_PEPPOL`).
209
+ - **BR-DEC-13 never fires.** The rule that the total VAT has two decimals looks
210
+ for the currency code underneath the amount, where it is not. UBL-DT-01
211
+ catches the same digits and is what is reported.
212
+ - **BR-CO-16 rounds in one branch and not the other**, which shows on an amount
213
+ with a third decimal; **an absent price fails the rule against a negative
214
+ one** (BR-27); **a group without a rate fails the rule on its tax** (BR-S-09);
215
+ **a total VAT with no breakdown under it** breaks two Peppol rules and not
216
+ one (R053, R054); and **the UBL binding has rules of its own** beside the
217
+ standard's, so three decimals are UBL-DT-01 as well as BR-DEC-*, and a line
218
+ without a category UBL-SR-48 as well as BR-CO-04.
219
+ - **A line of the books did not say its VAT category.** The end-to-end test
220
+ found `document_line_items.vat_category` empty on every line of every pack,
221
+ and the first version joined a silent line to its tax by `tax_id`. The books
222
+ now write the line when it is posted, and the join is gone: it read the tax
223
+ of today into an invoice of last year.
224
+ - **A reason is a code *or a text*.** The same test reported BR-E-10, BR-G-10
225
+ and BR-AE-10 on a pack that codes no exemption, and called the code missing.
226
+ The rules accept a sentence, the pack had one, and the breakdown did not
227
+ carry it. It does now, as `exemption_reason`.
228
+ - **`party_scheme` is not the scheme of a registration number.** The same test
229
+ found it to be an address scheme, which for two of the four countries that
230
+ declare this profile is not an ISO 6523 identifier scheme at all (BR-CL-11).
231
+
232
+ ## Sources
233
+
234
+ - OASIS, *Universal Business Language 2.1*, schemas of 4 November 2013:
235
+ <https://docs.oasis-open.org/ubl/os-UBL-2.1/>.
236
+ - OpenPeppol, *Peppol BIS Billing 3.0*: <https://docs.peppol.eu/poacc/billing/3.0/>
237
+ — the syntax bindings of the invoice and the credit note, the rules, the code
238
+ lists. Rules as released: <https://github.com/OpenPEPPOL/peppol-bis-invoice-3>,
239
+ tag `v3.0.20`.
240
+ - CEN/TC 434, the validation artefacts of EN 16931:
241
+ <https://github.com/ConnectingEurope/eInvoicing-EN16931>.
242
+
243
+ ## Licence
244
+
245
+ MIT. The files under `test/` that come from OASIS and from the European
246
+ Commission keep their own notices and licences, are fixtures of the tests, and
247
+ are not part of the published package.
@@ -0,0 +1,26 @@
1
+ /**
2
+ * GENERATED by `scripts/build-codelists.mjs` — do not edit.
3
+ *
4
+ * Read from the `BR-CL-*` assertions of the EN 16931 Schematron for UBL, version 1.3.15,
5
+ * as Peppol BIS Billing 3.0 ships it. `test/codelists.test.ts` compares every
6
+ * list here with that file, code for code.
7
+ */
8
+ /** ISO 4217 currency codes (BT-5). From BR-CL-04: 179 codes. */
9
+ export declare const CURRENCY_CODES: ReadonlySet<string>;
10
+ /** ISO 3166-1 country codes (BT-40, BT-55, BT-80). From BR-CL-14: 251 codes. */
11
+ export declare const COUNTRY_CODES: ReadonlySet<string>;
12
+ /** Prefixes a VAT identifier may start with (BT-31, BT-48): ISO 3166-1, and EL, which is what a Greek number starts with. From BR-CO-09: 252 codes. */
13
+ export declare const VAT_IDENTIFIER_PREFIXES: ReadonlySet<string>;
14
+ /** UNTDID 4461 payment means codes (BT-81). From BR-CL-16: 84 codes. */
15
+ export declare const PAYMENT_MEANS_CODES: ReadonlySet<string>;
16
+ /** UNTDID 5305 duty or tax category codes, the subset of EN 16931 (BT-118, BT-151). From BR-CL-18: 10 codes. */
17
+ export declare const VAT_CATEGORY_CODES: ReadonlySet<string>;
18
+ /** VATEX exemption reason codes (BT-121). From BR-CL-22: 88 codes. */
19
+ export declare const EXEMPTION_REASON_CODES: ReadonlySet<string>;
20
+ /** UN/ECE Recommendation 20 and 21 unit codes (BT-130). From BR-CL-23: 2162 codes. */
21
+ export declare const UNIT_CODES: ReadonlySet<string>;
22
+ /** Electronic address schemes, EAS (BT-34-1, BT-49-1). From BR-CL-25: 101 codes. */
23
+ export declare const ELECTRONIC_ADDRESS_SCHEMES: ReadonlySet<string>;
24
+ /** ISO 6523 ICD identifier schemes (BT-30-1, BT-47-1). From BR-CL-11: 240 codes. */
25
+ export declare const IDENTIFIER_SCHEMES: ReadonlySet<string>;
26
+ //# sourceMappingURL=codelists.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codelists.d.ts","sourceRoot":"","sources":["../src/codelists.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,gEAAgE;AAChE,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAS9C,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAS7C,CAAC;AAEF,uJAAuJ;AACvJ,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CASvD,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,EAAE,WAAW,CAAC,MAAM,CAInD,CAAC;AAEF,gHAAgH;AAChH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAElD,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAiBtD,CAAC;AAEF,sFAAsF;AACtF,eAAO,MAAM,UAAU,EAAE,WAAW,CAAC,MAAM,CAyF1C,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,0BAA0B,EAAE,WAAW,CAAC,MAAM,CAO1D,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAclD,CAAC"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * GENERATED by `scripts/build-codelists.mjs` — do not edit.
3
+ *
4
+ * Read from the `BR-CL-*` assertions of the EN 16931 Schematron for UBL, version 1.3.15,
5
+ * as Peppol BIS Billing 3.0 ships it. `test/codelists.test.ts` compares every
6
+ * list here with that file, code for code.
7
+ */
8
+ const list = (codes) => new Set(codes.split(' '));
9
+ /** ISO 4217 currency codes (BT-5). From BR-CL-04: 179 codes. */
10
+ export const CURRENCY_CODES = list('AED AFN ALL AMD ANG AOA ARS AUD AWG AZN BAM BBD BDT BGN BHD BIF BMD BND BOB BOV BRL BSD BTN BWP ' +
11
+ 'BYN BZD CAD CDF CHE CHF CHW CLF CLP CNH CNY COP COU CRC CUP CVE CZK DJF DKK DOP DZD EGP ERN ETB ' +
12
+ 'EUR FJD FKP GBP GEL GHS GIP GMD GNF GTQ GYD HKD HNL HTG HUF IDR ILS INR IQD IRR ISK JMD JOD JPY ' +
13
+ 'KES KGS KHR KMF KPW KRW KWD KYD KZT LAK LBP LKR LRD LSL LYD MAD MDL MGA MKD MMK MNT MOP MRU MUR ' +
14
+ 'MVR MWK MXN MXV MYR MZN NAD NGN NIO NOK NPR NZD OMR PAB PEN PGK PHP PKR PLN PYG QAR RON RSD RUB ' +
15
+ 'RWF SAR SBD SCR SDG SEK SGD SHP SLE SOS SRD SSP STD SVC SYP SZL THB TJS TMT TND TOP TRY TTD TWD ' +
16
+ 'TZS UAH UGX USD USN UYI UYU UYW UZS VES VED VND VUV WST XAF XAG XAU XBA XBB XBC XBD XCD XDR XOF ' +
17
+ 'XPD XPF XPT XSU XTS XUA XXX YER ZAR ZMW ZWG');
18
+ /** ISO 3166-1 country codes (BT-40, BT-55, BT-80). From BR-CL-14: 251 codes. */
19
+ export const COUNTRY_CODES = list('1A AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR ' +
20
+ 'BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC ' +
21
+ 'EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY HK ' +
22
+ 'HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB ' +
23
+ 'LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ ' +
24
+ 'NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO RS RU ' +
25
+ 'RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM TN ' +
26
+ 'TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS XI YE YT ZA ZM ZW');
27
+ /** Prefixes a VAT identifier may start with (BT-31, BT-48): ISO 3166-1, and EL, which is what a Greek number starts with. From BR-CO-09: 252 codes. */
28
+ export const VAT_IDENTIFIER_PREFIXES = list('1A AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR ' +
29
+ 'BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC ' +
30
+ 'EE EG EH EL ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY ' +
31
+ 'HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA ' +
32
+ 'LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY ' +
33
+ 'MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO RS ' +
34
+ 'RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM ' +
35
+ 'TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS XI YE YT ZA ZM ZW');
36
+ /** UNTDID 4461 payment means codes (BT-81). From BR-CL-16: 84 codes. */
37
+ export const PAYMENT_MEANS_CODES = list('1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 ' +
38
+ '36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 ' +
39
+ '68 69 70 74 75 76 77 78 91 92 93 94 95 96 97 98 ZZZ');
40
+ /** UNTDID 5305 duty or tax category codes, the subset of EN 16931 (BT-118, BT-151). From BR-CL-18: 10 codes. */
41
+ export const VAT_CATEGORY_CODES = list('AE L M E S Z G O K B');
42
+ /** VATEX exemption reason codes (BT-121). From BR-CL-22: 88 codes. */
43
+ export const EXEMPTION_REASON_CODES = list('VATEX-EU-79-C VATEX-EU-132 VATEX-EU-132-1A VATEX-EU-132-1B VATEX-EU-132-1C VATEX-EU-132-1D ' +
44
+ 'VATEX-EU-132-1E VATEX-EU-132-1F VATEX-EU-132-1G VATEX-EU-132-1H VATEX-EU-132-1I VATEX-EU-132-1J ' +
45
+ 'VATEX-EU-132-1K VATEX-EU-132-1L VATEX-EU-132-1M VATEX-EU-132-1N VATEX-EU-132-1O VATEX-EU-132-1P ' +
46
+ 'VATEX-EU-132-1Q VATEX-EU-135-1 VATEX-EU-143 VATEX-EU-143-1A VATEX-EU-143-1B VATEX-EU-143-1C ' +
47
+ 'VATEX-EU-143-1D VATEX-EU-143-1E VATEX-EU-143-1F VATEX-EU-143-1FA VATEX-EU-143-1G VATEX-EU-143-1H ' +
48
+ 'VATEX-EU-143-1I VATEX-EU-143-1J VATEX-EU-143-1K VATEX-EU-143-1L VATEX-EU-144 VATEX-EU-146-1E ' +
49
+ 'VATEX-EU-159 VATEX-EU-309 VATEX-EU-148 VATEX-EU-148-A VATEX-EU-148-B VATEX-EU-148-C ' +
50
+ 'VATEX-EU-148-D VATEX-EU-148-E VATEX-EU-148-F VATEX-EU-148-G VATEX-EU-151 VATEX-EU-151-1A ' +
51
+ 'VATEX-EU-151-1AA VATEX-EU-151-1B VATEX-EU-151-1C VATEX-EU-151-1D VATEX-EU-151-1E VATEX-EU-G ' +
52
+ 'VATEX-EU-O VATEX-EU-IC VATEX-EU-AE VATEX-EU-D VATEX-EU-F VATEX-EU-I VATEX-EU-J ' +
53
+ 'VATEX-FR-FRANCHISE VATEX-FR-CNWVAT VATEX-EU-153 VATEX-FR-CGI261-1 VATEX-FR-CGI261-2 ' +
54
+ 'VATEX-FR-CGI261-3 VATEX-FR-CGI261-4 VATEX-FR-CGI261-5 VATEX-FR-CGI261-7 VATEX-FR-CGI261-8 ' +
55
+ 'VATEX-FR-CGI261A VATEX-FR-CGI261B VATEX-FR-CGI261C-1 VATEX-FR-CGI261C-2 VATEX-FR-CGI261C-3 ' +
56
+ 'VATEX-FR-CGI261D-1 VATEX-FR-CGI261D-1BIS VATEX-FR-CGI261D-2 VATEX-FR-CGI261D-3 ' +
57
+ 'VATEX-FR-CGI261D-4 VATEX-FR-CGI261E-1 VATEX-FR-CGI261E-2 VATEX-FR-CGI277A VATEX-FR-CGI275 ' +
58
+ 'VATEX-FR-298SEXDECIESA VATEX-FR-CGI295 VATEX-FR-AE');
59
+ /** UN/ECE Recommendation 20 and 21 unit codes (BT-130). From BR-CL-23: 2162 codes. */
60
+ export const UNIT_CODES = list('10 11 13 14 15 20 21 22 23 24 25 27 28 33 34 35 37 38 40 41 56 57 58 59 60 61 74 77 80 81 85 87 ' +
61
+ '89 91 1I 2A 2B 2C 2G 2H 2I 2J 2K 2L 2M 2N 2P 2Q 2R 2U 2X 2Y 2Z 3B 3C 4C 4G 4H 4K 4L 4M 4N 4O 4P ' +
62
+ '4Q 4R 4T 4U 4W 4X 5A 5B 5E 5J A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A2 A20 A21 A22 A23 A24 A26 ' +
63
+ 'A27 A28 A29 A3 A30 A31 A32 A33 A34 A35 A36 A37 A38 A39 A4 A40 A41 A42 A43 A44 A45 A47 A48 A49 A5 ' +
64
+ 'A53 A54 A55 A56 A59 A6 A68 A69 A7 A70 A71 A73 A74 A75 A76 A8 A84 A85 A86 A87 A88 A89 A9 A90 A91 ' +
65
+ 'A93 A94 A95 A96 A97 A98 A99 AA AB ACR ACT AD AE AH AI AK AL AMH AMP ANN APZ AQ AS ASM ASU ATM ' +
66
+ 'AWG AY AZ B1 B10 B11 B12 B13 B14 B15 B16 B17 B18 B19 B20 B21 B22 B23 B24 B25 B26 B27 B28 B29 B3 ' +
67
+ 'B30 B31 B32 B33 B34 B35 B4 B41 B42 B43 B44 B45 B46 B47 B48 B49 B50 B52 B53 B54 B55 B56 B57 B58 ' +
68
+ 'B59 B60 B61 B62 B63 B64 B66 B67 B68 B69 B7 B70 B71 B72 B73 B74 B75 B76 B77 B78 B79 B8 B80 B81 ' +
69
+ 'B82 B83 B84 B85 B86 B87 B88 B89 B90 B91 B92 B93 B94 B95 B96 B97 B98 B99 BAR BB BFT BHP BIL BLD ' +
70
+ 'BLL BP BPM BQL BTU BUA BUI C0 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C20 C21 C22 C23 C24 C25 ' +
71
+ 'C26 C27 C28 C29 C3 C30 C31 C32 C33 C34 C35 C36 C37 C38 C39 C40 C41 C42 C43 C44 C45 C46 C47 C48 ' +
72
+ 'C49 C50 C51 C52 C53 C54 C55 C56 C57 C58 C59 C60 C61 C62 C63 C64 C65 C66 C67 C68 C69 C7 C70 C71 ' +
73
+ 'C72 C73 C74 C75 C76 C78 C79 C8 C80 C81 C82 C83 C84 C85 C86 C87 C88 C89 C9 C90 C91 C92 C93 C94 ' +
74
+ 'C95 C96 C97 C99 CCT CDL CEL CEN CG CGM CKG CLF CLT CMK CMQ CMT CNP CNT COU CTG CTM CTN CUR CWA ' +
75
+ 'CWI D03 D04 D1 D10 D11 D12 D13 D15 D16 D17 D18 D19 D2 D20 D21 D22 D23 D24 D25 D26 D27 D29 D30 ' +
76
+ 'D31 D32 D33 D34 D36 D41 D42 D43 D44 D45 D46 D47 D48 D49 D5 D50 D51 D52 D53 D54 D55 D56 D57 D58 ' +
77
+ 'D59 D6 D60 D61 D62 D63 D65 D68 D69 D73 D74 D77 D78 D80 D81 D82 D83 D85 D86 D87 D88 D89 D91 D93 ' +
78
+ 'D94 D95 DAA DAD DAY DB DBM DBW DD DEC DG DJ DLT DMA DMK DMO DMQ DMT DN DPC DPR DPT DRA DRI DRL ' +
79
+ 'DT DTN DWT DZN DZP E01 E07 E08 E09 E10 E12 E14 E15 E16 E17 E18 E19 E20 E21 E22 E23 E25 E27 E28 ' +
80
+ 'E30 E31 E32 E33 E34 E35 E36 E37 E38 E39 E4 E40 E41 E42 E43 E44 E45 E46 E47 E48 E49 E50 E51 E52 ' +
81
+ 'E53 E54 E55 E56 E57 E58 E59 E60 E61 E62 E63 E64 E65 E66 E67 E68 E69 E70 E71 E72 E73 E74 E75 E76 ' +
82
+ 'E77 E78 E79 E80 E81 E82 E83 E84 E85 E86 E87 E88 E89 E90 E91 E92 E93 E94 E95 E96 E97 E98 E99 EA ' +
83
+ 'EB EQ F01 F02 F03 F04 F05 F06 F07 F08 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 ' +
84
+ 'F24 F25 F26 F27 F28 F29 F30 F31 F32 F33 F34 F35 F36 F37 F38 F39 F40 F41 F42 F43 F44 F45 F46 F47 ' +
85
+ 'F48 F49 F50 F51 F52 F53 F54 F55 F56 F57 F58 F59 F60 F61 F62 F63 F64 F65 F66 F67 F68 F69 F70 F71 ' +
86
+ 'F72 F73 F74 F75 F76 F77 F78 F79 F80 F81 F82 F83 F84 F85 F86 F87 F88 F89 F90 F91 F92 F93 F94 F95 ' +
87
+ 'F96 F97 F98 F99 FAH FAR FBM FC FF FH FIT FL FNU FOT FP FR FS FTK FTQ G01 G04 G05 G06 G08 G09 G10 ' +
88
+ 'G11 G12 G13 G14 G15 G16 G17 G18 G19 G2 G20 G21 G23 G24 G25 G26 G27 G28 G29 G3 G30 G31 G32 G33 ' +
89
+ 'G34 G35 G36 G37 G38 G39 G40 G41 G42 G43 G44 G45 G46 G47 G48 G49 G50 G51 G52 G53 G54 G55 G56 G57 ' +
90
+ 'G58 G59 G60 G61 G62 G63 G64 G65 G66 G67 G68 G69 G70 G71 G72 G73 G74 G75 G76 G77 G78 G79 G80 G81 ' +
91
+ 'G82 G83 G84 G85 G86 G87 G88 G89 G90 G91 G92 G93 G94 G95 G96 G97 G98 G99 GB GBQ GDW GE GF GFI GGR ' +
92
+ 'GIA GIC GII GIP GJ GL GLD GLI GLL GM GO GP GQ GRM GRN GRO GV GWH H03 H04 H05 H06 H07 H08 H09 H10 ' +
93
+ 'H11 H12 H13 H14 H15 H16 H18 H19 H20 H21 H22 H23 H24 H25 H26 H27 H28 H29 H30 H31 H32 H33 H34 H35 ' +
94
+ 'H36 H37 H38 H39 H40 H41 H42 H43 H44 H45 H46 H47 H48 H49 H50 H51 H52 H53 H54 H55 H56 H57 H58 H59 ' +
95
+ 'H60 H61 H62 H63 H64 H65 H66 H67 H68 H69 H70 H71 H72 H73 H74 H75 H76 H77 H79 H80 H81 H82 H83 H84 ' +
96
+ 'H85 H87 H88 H89 H90 H91 H92 H93 H94 H95 H96 H98 H99 HA HAD HBA HBX HC HDW HEA HGM HH HIU HKM HLT ' +
97
+ 'HM HMO HMQ HMT HPA HTZ HUR HWE IA IE INH INK INQ ISD IU IUG IV J10 J12 J13 J14 J15 J16 J17 J18 ' +
98
+ 'J19 J2 J20 J21 J22 J23 J24 J25 J26 J27 J28 J29 J30 J31 J32 J33 J34 J35 J36 J38 J39 J40 J41 J42 ' +
99
+ 'J43 J44 J45 J46 J47 J48 J49 J50 J51 J52 J53 J54 J55 J56 J57 J58 J59 J60 J61 J62 J63 J64 J65 J66 ' +
100
+ 'J67 J68 J69 J70 J71 J72 J73 J74 J75 J76 J78 J79 J81 J82 J83 J84 J85 J87 J90 J91 J92 J93 J95 J96 ' +
101
+ 'J97 J98 J99 JE JK JM JNT JOU JPS JWL K1 K10 K11 K12 K13 K14 K15 K16 K17 K18 K19 K2 K20 K21 K22 ' +
102
+ 'K23 K26 K27 K28 K3 K30 K31 K32 K33 K34 K35 K36 K37 K38 K39 K40 K41 K42 K43 K45 K46 K47 K48 K49 ' +
103
+ 'K50 K51 K52 K53 K54 K55 K58 K59 K6 K60 K61 K62 K63 K64 K65 K66 K67 K68 K69 K70 K71 K73 K74 K75 ' +
104
+ 'K76 K77 K78 K79 K80 K81 K82 K83 K84 K85 K86 K87 K88 K89 K90 K91 K92 K93 K94 K95 K96 K97 K98 K99 ' +
105
+ 'KA KAT KB KBA KCC KDW KEL KGM KGS KHY KHZ KI KIC KIP KJ KJO KL KLK KLX KMA KMH KMK KMQ KMT KNI ' +
106
+ 'KNM KNS KNT KO KPA KPH KPO KPP KR KSD KSH KT KTN KUR KVA KVR KVT KW KWH KWN KWO KWS KWT KWY KX ' +
107
+ 'L10 L11 L12 L13 L14 L15 L16 L17 L18 L19 L2 L20 L21 L23 L24 L25 L26 L27 L28 L29 L30 L31 L32 L33 ' +
108
+ 'L34 L35 L36 L37 L38 L39 L40 L41 L42 L43 L44 L45 L46 L47 L48 L49 L50 L51 L52 L53 L54 L55 L56 L57 ' +
109
+ 'L58 L59 L60 L63 L64 L65 L66 L67 L68 L69 L70 L71 L72 L73 L74 L75 L76 L77 L78 L79 L80 L81 L82 L83 ' +
110
+ 'L84 L85 L86 L87 L88 L89 L90 L91 L92 L93 L94 L95 L96 L98 L99 LA LAC LBR LBT LD LEF LF LH LK LM LN ' +
111
+ 'LO LP LPA LR LS LTN LTR LUB LUM LUX LY M1 M10 M11 M12 M13 M14 M15 M16 M17 M18 M19 M20 M21 M22 ' +
112
+ 'M23 M24 M25 M26 M27 M29 M30 M31 M32 M33 M34 M35 M36 M37 M38 M39 M4 M40 M41 M42 M43 M44 M45 M46 ' +
113
+ 'M47 M48 M49 M5 M50 M51 M52 M53 M55 M56 M57 M58 M59 M60 M61 M62 M63 M64 M65 M66 M67 M68 M69 M7 ' +
114
+ 'M70 M71 M72 M73 M74 M75 M76 M77 M78 M79 M80 M81 M82 M83 M84 M85 M86 M87 M88 M89 M9 M90 M91 M92 ' +
115
+ 'M93 M94 M95 M96 M97 M98 M99 MAH MAL MAM MAR MAW MBE MBF MBR MC MCU MD MGM MHZ MIK MIL MIN MIO ' +
116
+ 'MIU MKD MKM MKW MLD MLT MMK MMQ MMT MND MNJ MON MPA MQD MQH MQM MQS MQW MRD MRM MRW MSK MTK MTQ ' +
117
+ 'MTR MTS MTZ MVA MWH N1 N10 N11 N12 N13 N14 N15 N16 N17 N18 N19 N20 N21 N22 N23 N24 N25 N26 N27 ' +
118
+ 'N28 N29 N3 N30 N31 N32 N33 N34 N35 N36 N37 N38 N39 N40 N41 N42 N43 N44 N45 N46 N47 N48 N49 N50 ' +
119
+ 'N51 N52 N53 N54 N55 N56 N57 N58 N59 N60 N61 N62 N63 N64 N65 N66 N67 N68 N69 N70 N71 N72 N73 N74 ' +
120
+ 'N75 N76 N77 N78 N79 N80 N81 N82 N83 N84 N85 N86 N87 N88 N89 N90 N91 N92 N93 N94 N95 N96 N97 N98 ' +
121
+ 'N99 NA NAR NCL NEW NF NIL NIU NL NM3 NMI NMP NPT NT NTU NU NX OA ODE ODG ODK ODM OHM ON ONZ OPM ' +
122
+ 'OT OZA OZI P1 P10 P11 P12 P13 P14 P15 P16 P17 P18 P19 P2 P20 P21 P22 P23 P24 P25 P26 P27 P28 P29 ' +
123
+ 'P30 P31 P32 P33 P34 P35 P36 P37 P38 P39 P40 P41 P42 P43 P44 P45 P46 P47 P48 P49 P5 P50 P51 P52 ' +
124
+ 'P53 P54 P55 P56 P57 P58 P59 P60 P61 P62 P63 P64 P65 P66 P67 P68 P69 P70 P71 P72 P73 P74 P75 P76 ' +
125
+ 'P77 P78 P79 P80 P81 P82 P83 P84 P85 P86 P87 P88 P89 P90 P91 P92 P93 P94 P95 P96 P97 P98 P99 PAL ' +
126
+ 'PD PFL PGL PI PLA PO PQ PR PS PTD PTI PTL PTN Q10 Q11 Q12 Q13 Q14 Q15 Q16 Q17 Q18 Q19 Q20 Q21 ' +
127
+ 'Q22 Q23 Q24 Q25 Q26 Q27 Q28 Q29 Q3 Q30 Q31 Q32 Q33 Q34 Q35 Q36 Q37 Q38 Q39 Q40 Q41 Q42 QA QAN QB ' +
128
+ 'QR QTD QTI QTL QTR R1 R9 RH RM ROM RP RPM RPS RT S3 S4 SAN SCO SCR SEC SET SG SIE SM3 SMI SQ SQR ' +
129
+ 'SR STC STI STK STL STN STW SW SX SYR T0 T3 TAH TAN TI TIC TIP TKM TMS TNE TP TPI TPR TQD TRL TST ' +
130
+ 'TTS U1 U2 UB UC VA VLT VP W2 WA WB WCD WE WEB WEE WG WHR WM WSD WTT X1 YDK YDQ YRD Z11 Z9 ZP ZZ ' +
131
+ 'X1A X1B X1D X1F X1G X1W X2C X3A X3H X43 X44 X4A X4B X4C X4D X4F X4G X4H X5H X5L X5M X6H X6P X7A ' +
132
+ 'X7B X8A X8B X8C XAA XAB XAC XAD XAE XAF XAG XAH XAI XAJ XAL XAM XAP XAT XAV XB4 XBA XBB XBC XBD ' +
133
+ 'XBE XBF XBG XBH XBI XBJ XBK XBL XBM XBN XBO XBP XBQ XBR XBS XBT XBU XBV XBW XBX XBY XBZ XCA XCB ' +
134
+ 'XCC XCD XCE XCF XCG XCH XCI XCJ XCK XCL XCM XCN XCO XCP XCQ XCR XCS XCT XCU XCV XCW XCX XCY XCZ ' +
135
+ 'XDA XDB XDC XDG XDH XDI XDJ XDK XDL XDM XDN XDP XDR XDS XDT XDU XDV XDW XDX XDY XEC XED XEE XEF ' +
136
+ 'XEG XEH XEI XEN XFB XFC XFD XFE XFI XFL XFO XFP XFR XFT XFW XFX XGB XGI XGL XGR XGU XGY XGZ XHA ' +
137
+ 'XHB XHC XHG XHN XHR XIA XIB XIC XID XIE XIF XIG XIH XIK XIL XIN XIZ XJB XJC XJG XJR XJT XJY XKG ' +
138
+ 'XKI XLE XLG XLT XLU XLV XLZ XMA XMB XMC XME XMR XMS XMT XMW XMX XNA XNE XNF XNG XNS XNT XNU XNV ' +
139
+ 'XO1 XO2 XO3 XO4 XO5 XO6 XO7 XO8 XO9 XOA XOB XOC XOD XOE XOF XOG XOH XOI XOJ XOK XOL XOM XON XOP ' +
140
+ 'XOQ XOR XOS XOT XOU XOV XOW XOX XOY XOZ XP1 XP2 XP3 XP4 XPA XPB XPC XPD XPE XPF XPG XPH XPI XPJ ' +
141
+ 'XPK XPL XPN XPO XPP XPR XPT XPU XPV XPX XPY XPZ XQA XQB XQC XQD XQF XQG XQH XQJ XQK XQL XQM XQN ' +
142
+ 'XQP XQQ XQR XQS XRD XRG XRJ XRK XRL XRO XRT XRZ XSA XSB XSC XSD XSE XSH XSI XSK XSL XSM XSO XSP ' +
143
+ 'XSS XST XSU XSV XSW XSX XSY XSZ XT1 XTB XTC XTD XTE XTG XTI XTK XTL XTN XTO XTR XTS XTT XTU XTV ' +
144
+ 'XTW XTY XTZ XUC XUN XVA XVG XVI XVK XVL XVN XVO XVP XVQ XVR XVS XVY XWA XWB XWC XWD XWF XWG XWH ' +
145
+ 'XWJ XWK XWL XWM XWN XWP XWQ XWR XWS XWT XWU XWV XWW XWX XWY XWZ XXA XXB XXC XXD XXF XXG XXH XXJ ' +
146
+ 'XXK XYA XYB XYC XYD XYF XYG XYH XYJ XYK XYL XYM XYN XYP XYQ XYR XYS XYT XYV XYW XYX XYY XYZ XZA ' +
147
+ 'XZB XZC XZD XZF XZG XZH XZJ XZK XZL XZM XZN XZP XZQ XZR XZS XZT XZU XZV XZW XZX XZY XZZ');
148
+ /** Electronic address schemes, EAS (BT-34-1, BT-49-1). From BR-CL-25: 101 codes. */
149
+ export const ELECTRONIC_ADDRESS_SCHEMES = list('0002 0007 0009 0037 0060 0088 0096 0097 0106 0130 0135 0142 0147 0151 0154 0158 0170 0177 0183 ' +
150
+ '0184 0188 0190 0191 0192 0193 0194 0195 0196 0198 0199 0200 0201 0202 0203 0204 0205 0208 0209 ' +
151
+ '0210 0211 0212 0213 0215 0216 0217 0218 0219 0220 0221 0225 0230 0235 0240 0244 0245 9910 9913 ' +
152
+ '9914 9915 9918 9919 9920 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 ' +
153
+ '9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9957 ' +
154
+ '9959 AN AQ AS AU EM');
155
+ /** ISO 6523 ICD identifier schemes (BT-30-1, BT-47-1). From BR-CL-11: 240 codes. */
156
+ export const IDENTIFIER_SCHEMES = list('0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 0020 ' +
157
+ '0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 ' +
158
+ '0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056 0057 0058 ' +
159
+ '0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 0070 0071 0072 0073 0074 0075 0076 0077 ' +
160
+ '0078 0079 0080 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0093 0094 0095 0096 0097 ' +
161
+ '0098 0099 0100 0101 0102 0104 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116 0117 ' +
162
+ '0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128 0129 0130 0131 0132 0133 0134 0135 0136 ' +
163
+ '0137 0138 0139 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 0154 0155 ' +
164
+ '0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 0168 0169 0170 0171 0172 0173 0174 ' +
165
+ '0175 0176 0177 0178 0179 0180 0183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 ' +
166
+ '0196 0197 0198 0199 0200 0201 0202 0203 0204 0205 0206 0207 0208 0209 0210 0211 0212 0213 0214 ' +
167
+ '0215 0216 0217 0218 0219 0220 0221 0222 0223 0224 0225 0226 0227 0228 0229 0230 0231 0232 0233 ' +
168
+ '0234 0235 0236 0237 0238 0239 0240 0241 0242 0243 0244 0245');
169
+ //# sourceMappingURL=codelists.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codelists.js","sourceRoot":"","sources":["../src/codelists.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Exact decimals, on the text they arrive as.
3
+ *
4
+ * Every figure of an invoice reaches this package as Postgres wrote it — a
5
+ * `numeric` read as text — and leaves it the same way. The rules of EN 16931
6
+ * compare those figures with `=`, not with a tolerance: a sum that a binary
7
+ * float gets wrong by one part in 2^52 is a rule reported broken on an invoice
8
+ * that is right. So nothing here is a `number`. A decimal is an integer and a
9
+ * scale, the integer is a `bigint`, and the four operations the rules need are
10
+ * exact.
11
+ */
12
+ export interface Decimal {
13
+ /** The digits, as an integer: 12.30 is `1230n` at scale 2. */
14
+ readonly units: bigint;
15
+ /** How many of those digits are after the point. */
16
+ readonly scale: number;
17
+ }
18
+ /**
19
+ * Reads a decimal, or returns null for anything that is not one. An exponent,
20
+ * a thousands separator and a comma are not decimals: `xs:decimal` refuses the
21
+ * three, and what is refused there is refused here.
22
+ */
23
+ export declare function parseDecimal(value: string | number | null | undefined): Decimal | null;
24
+ export declare function add(a: Decimal, b: Decimal): Decimal;
25
+ export declare function subtract(a: Decimal, b: Decimal): Decimal;
26
+ export declare function multiply(a: Decimal, b: Decimal): Decimal;
27
+ export declare function compare(a: Decimal, b: Decimal): -1 | 0 | 1;
28
+ export declare const equal: (a: Decimal, b: Decimal) => boolean;
29
+ export declare const ZERO: Decimal;
30
+ export declare const isZero: (a: Decimal) => boolean;
31
+ export declare function abs(a: Decimal): Decimal;
32
+ export declare function sum(values: readonly Decimal[]): Decimal;
33
+ /**
34
+ * Rounds to `places` decimals the way XPath's `round()` does: half towards
35
+ * positive infinity, so 2.5 becomes 3 and -2.5 becomes -2. It is the rounding
36
+ * the published rules are written with, and it is used here for nothing but
37
+ * re-reading them — this package rounds no figure it writes.
38
+ */
39
+ export declare function roundXPath(a: Decimal, places: number): Decimal;
40
+ /** How many digits follow the point once the zeros that say nothing are gone. */
41
+ export declare function significantScale(a: Decimal): number;
42
+ /**
43
+ * The text of a decimal: a point, no exponent, no sign on zero, and at least
44
+ * `minScale` digits after the point. Trailing zeros beyond that are dropped,
45
+ * which changes no value and keeps `21.0000` — a rate as `numeric(7,4)` stores
46
+ * it — from travelling as four digits of nothing.
47
+ */
48
+ export declare function formatDecimal(a: Decimal, minScale?: number): string;
49
+ //# sourceMappingURL=decimal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decimal.d.ts","sourceRoot":"","sources":["../src/decimal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,OAAO;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAID;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,GAAG,IAAI,CAkBtF;AAOD,wBAAgB,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAGnD;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAGxD;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAExD;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAG1D;AAED,eAAO,MAAM,KAAK,GAAI,GAAG,OAAO,EAAE,GAAG,OAAO,KAAG,OAA8B,CAAC;AAE9E,eAAO,MAAM,IAAI,EAAE,OAAiC,CAAC;AAErD,eAAO,MAAM,MAAM,GAAI,GAAG,OAAO,KAAG,OAAyB,CAAC;AAE9D,wBAAgB,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAEvC;AAED,wBAAgB,GAAG,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAEvD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAS9D;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAOnD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,SAAI,GAAG,MAAM,CAe9D"}