@sythos/js_barcode_universal 1.5.8 → 1.5.9
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/LICENSE +5 -4
- package/NOTICE.md +2 -2
- package/README.md +17 -13
- package/bundle/sythos-barcode.esm.js +11658 -11244
- package/bundle/sythos-barcode.js +11658 -11244
- package/package.json +10 -3
- package/src/index.d.ts +1 -1
- package/src/index.js +508 -516
- package/src/js/aztec/decoder.js +208 -199
- package/src/js/aztec/detector.js +153 -126
- package/src/js/aztec/encoder.js +172 -153
- package/src/js/aztec/high-level.js +106 -101
- package/src/js/aztec/index.js +1 -12
- package/src/js/aztec/tables.js +106 -120
- package/src/js/aztecrune/decoder.js +76 -85
- package/src/js/aztecrune/detector.js +107 -93
- package/src/js/aztecrune/encoder.js +50 -68
- package/src/js/aztecrune/index.js +1 -16
- package/src/js/aztecrune/tables.js +59 -54
- package/src/js/compactpdf417/decoder.js +69 -74
- package/src/js/compactpdf417/detector.js +74 -75
- package/src/js/compactpdf417/encoder.js +68 -81
- package/src/js/compactpdf417/index.js +1 -13
- package/src/js/compactpdf417/tables.js +71 -80
- package/src/js/core/bit-buffer.js +106 -122
- package/src/js/core/bit-matrix.js +196 -194
- package/src/js/core/errors.js +13 -15
- package/src/js/core/galois-field.js +119 -133
- package/src/js/core/index.js +2 -19
- package/src/js/core/reed-solomon.js +195 -204
- package/src/js/databar/codec.js +93 -108
- package/src/js/databar/decoder.js +149 -140
- package/src/js/databar/encoder.js +47 -55
- package/src/js/databar/gs1.js +122 -123
- package/src/js/databar/index.js +4 -36
- package/src/js/databar/patterns.js +81 -85
- package/src/js/databar/tables.js +51 -52
- package/src/js/datamatrix/decoder.js +216 -182
- package/src/js/datamatrix/detector.js +161 -132
- package/src/js/datamatrix/encoder.js +192 -133
- package/src/js/datamatrix/index.js +1 -9
- package/src/js/datamatrix/tables.js +68 -69
- package/src/js/frameqr/decoder.js +102 -125
- package/src/js/frameqr/detector.js +101 -94
- package/src/js/frameqr/encoder.js +67 -80
- package/src/js/frameqr/index.js +1 -10
- package/src/js/frameqr/tables.js +145 -163
- package/src/js/image/binarizer.js +146 -162
- package/src/js/image/grid-sampler.js +63 -79
- package/src/js/image/index.js +0 -2
- package/src/js/image/luminance.js +129 -140
- package/src/js/image/perspective.js +112 -149
- package/src/js/micropdf417/compaction.js +64 -65
- package/src/js/micropdf417/decoder.js +106 -109
- package/src/js/micropdf417/detector.js +73 -70
- package/src/js/micropdf417/encoder.js +129 -154
- package/src/js/micropdf417/error-correction.js +6 -11
- package/src/js/micropdf417/index.js +2 -16
- package/src/js/micropdf417/tables.js +112 -99
- package/src/js/microqr/decoder.js +177 -182
- package/src/js/microqr/detector.js +240 -256
- package/src/js/microqr/encoder.js +239 -194
- package/src/js/microqr/index.js +0 -2
- package/src/js/microqr/tables.js +208 -200
- package/src/js/oned/addons.js +167 -191
- package/src/js/oned/index.js +27 -58
- package/src/js/oned/patterns.js +194 -213
- package/src/js/oned/reader.js +1003 -984
- package/src/js/oned/writers.js +411 -466
- package/src/js/pdf417/compaction.js +315 -222
- package/src/js/pdf417/decoder.js +71 -36
- package/src/js/pdf417/detector.js +377 -361
- package/src/js/pdf417/encoder.js +57 -46
- package/src/js/pdf417/error-correction.js +5 -8
- package/src/js/pdf417/tables.js +248 -250
- package/src/js/qr/decoder.js +311 -347
- package/src/js/qr/detector.js +378 -395
- package/src/js/qr/encoder.js +514 -599
- package/src/js/qr/index.js +0 -2
- package/src/js/qr/tables.js +375 -422
- package/src/js/render/image-data.js +57 -62
- package/src/js/render/index.js +21 -23
- package/src/js/render/options.js +82 -90
- package/src/js/render/png.js +144 -169
- package/src/js/render/svg.js +41 -44
- package/src/js/render/webgl.js +103 -109
- package/src/js/render/webgpu.js +205 -217
- package/src/js/rmqr/decoder.js +161 -53
- package/src/js/rmqr/detector.js +73 -41
- package/src/js/rmqr/encoder.js +253 -104
- package/src/js/rmqr/index.js +1 -5
- package/src/js/rmqr/tables.js +108 -85
- package/src/ts/aztec/decoder.ts +317 -0
- package/src/ts/aztec/detector.ts +224 -0
- package/src/ts/aztec/encoder.ts +257 -0
- package/src/ts/aztec/high-level.ts +211 -0
- package/src/ts/aztec/index.ts +45 -0
- package/src/ts/aztec/tables.ts +210 -0
- package/src/ts/aztecrune/decoder.ts +155 -0
- package/src/ts/aztecrune/detector.ts +166 -0
- package/src/ts/aztecrune/encoder.ts +121 -0
- package/src/ts/aztecrune/index.ts +49 -0
- package/src/ts/aztecrune/tables.ts +137 -0
- package/src/ts/compactpdf417/decoder.ts +128 -0
- package/src/ts/compactpdf417/detector.ts +139 -0
- package/src/ts/compactpdf417/encoder.ts +140 -0
- package/src/ts/compactpdf417/index.ts +17 -0
- package/src/ts/compactpdf417/tables.ts +173 -0
- package/src/ts/core/bit-buffer.ts +174 -0
- package/src/ts/core/bit-matrix.ts +241 -0
- package/src/ts/core/errors.ts +61 -0
- package/src/ts/core/galois-field.ts +207 -0
- package/src/ts/core/index.ts +56 -0
- package/src/ts/core/reed-solomon.ts +327 -0
- package/src/ts/databar/codec.ts +181 -0
- package/src/ts/databar/decoder.ts +215 -0
- package/src/ts/databar/encoder.ts +96 -0
- package/src/ts/databar/gs1.ts +177 -0
- package/src/ts/databar/index.ts +68 -0
- package/src/ts/databar/patterns.ts +143 -0
- package/src/ts/databar/tables.ts +124 -0
- package/src/ts/datamatrix/decoder.ts +262 -0
- package/src/ts/datamatrix/detector.ts +225 -0
- package/src/ts/datamatrix/encoder.ts +191 -0
- package/src/ts/datamatrix/index.ts +42 -0
- package/src/ts/datamatrix/tables.ts +123 -0
- package/src/ts/frameqr/decoder.ts +239 -0
- package/src/ts/frameqr/detector.ts +192 -0
- package/src/ts/frameqr/encoder.ts +156 -0
- package/src/ts/frameqr/index.ts +42 -0
- package/src/ts/frameqr/tables.ts +270 -0
- package/src/ts/image/binarizer.ts +270 -0
- package/src/ts/image/grid-sampler.ts +164 -0
- package/src/ts/image/index.ts +40 -0
- package/src/ts/image/luminance.ts +196 -0
- package/src/ts/image/perspective.ts +195 -0
- package/src/ts/index.d.ts +1 -1
- package/src/ts/index.ts +790 -0
- package/src/ts/micropdf417/compaction.ts +116 -0
- package/src/ts/micropdf417/decoder.ts +183 -0
- package/src/ts/micropdf417/detector.ts +149 -0
- package/src/ts/micropdf417/encoder.ts +209 -0
- package/src/ts/micropdf417/error-correction.ts +55 -0
- package/src/ts/micropdf417/index.ts +49 -0
- package/src/ts/micropdf417/tables.ts +184 -0
- package/src/ts/microqr/decoder.ts +245 -0
- package/src/ts/microqr/detector.ts +355 -0
- package/src/ts/microqr/encoder.ts +269 -0
- package/src/ts/microqr/index.ts +36 -0
- package/src/ts/microqr/tables.ts +316 -0
- package/src/ts/oned/addons.ts +420 -0
- package/src/ts/oned/index.ts +106 -0
- package/src/ts/oned/patterns.ts +384 -0
- package/src/ts/oned/reader.ts +1364 -0
- package/src/ts/oned/writers.ts +746 -0
- package/src/ts/pdf417/compaction.ts +298 -0
- package/src/ts/pdf417/decoder.ts +75 -0
- package/src/ts/pdf417/detector.ts +468 -0
- package/src/ts/pdf417/encoder.ts +91 -0
- package/src/ts/pdf417/error-correction.ts +47 -0
- package/src/ts/pdf417/index.ts +6 -0
- package/src/ts/pdf417/tables.ts +317 -0
- package/src/ts/qr/decoder.ts +575 -0
- package/src/ts/qr/detector.ts +630 -0
- package/src/ts/qr/encoder.ts +958 -0
- package/src/ts/qr/index.ts +44 -0
- package/src/ts/qr/tables.ts +737 -0
- package/src/ts/render/image-data.ts +125 -0
- package/src/ts/render/index.ts +130 -0
- package/src/ts/render/options.ts +160 -0
- package/src/ts/render/png.ts +295 -0
- package/src/ts/render/svg.ts +120 -0
- package/src/ts/render/webgl.ts +206 -0
- package/src/ts/render/webgpu.ts +369 -0
- package/src/ts/rmqr/decoder.ts +101 -0
- package/src/ts/rmqr/detector.ts +90 -0
- package/src/ts/rmqr/encoder.ts +172 -0
- package/src/ts/rmqr/index.ts +37 -0
- package/src/ts/rmqr/tables.ts +154 -0
package/src/js/oned/writers.js
CHANGED
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
*
|
|
28
28
|
* Original work. No code from any other barcode implementation.
|
|
29
29
|
*/
|
|
30
|
-
|
|
31
30
|
/**
|
|
32
31
|
* Linear barcode writers.
|
|
33
32
|
*
|
|
@@ -38,24 +37,12 @@
|
|
|
38
37
|
*
|
|
39
38
|
* @module oned/writers
|
|
40
39
|
*/
|
|
41
|
-
|
|
42
40
|
import { BitMatrix } from '../core/bit-matrix.js';
|
|
43
41
|
import { EncodeError } from '../core/errors.js';
|
|
44
|
-
import {
|
|
45
|
-
EAN_L, EAN_G, EAN_R, EAN13_PARITY, UPCE_PARITY,
|
|
46
|
-
EAN_START_END, EAN_MIDDLE, UPCE_END,
|
|
47
|
-
CODE39, CODE39_CHECK_SET, CODE39_EXTENDED,
|
|
48
|
-
CODE93, CODE93_VALUES, CODE93_START_STOP,
|
|
49
|
-
CODE128, CODE128_START_B, CODE128_START_C,
|
|
50
|
-
CODE128_STOP, CODE128_FNC1, CODE128_CODE_A, CODE128_CODE_B, CODE128_CODE_C,
|
|
51
|
-
ITF, CODABAR, CODABAR_START_STOP, CODE11, CODE11_START_STOP,
|
|
52
|
-
MSI_BIT, MSI_START, MSI_STOP,
|
|
53
|
-
} from './patterns.js';
|
|
54
|
-
|
|
42
|
+
import { EAN_L, EAN_G, EAN_R, EAN13_PARITY, UPCE_PARITY, EAN_START_END, EAN_MIDDLE, UPCE_END, CODE39, CODE39_CHECK_SET, CODE39_EXTENDED, CODE93, CODE93_VALUES, CODE93_START_STOP, CODE128, CODE128_START_B, CODE128_START_C, CODE128_STOP, CODE128_FNC1, CODE128_CODE_A, CODE128_CODE_B, CODE128_CODE_C, ITF, CODABAR, CODABAR_START_STOP, CODE11, CODE11_START_STOP, MSI_BIT, MSI_START, MSI_STOP, } from './patterns.js';
|
|
55
43
|
/* ------------------------------------------------------------------ *
|
|
56
44
|
* Shared helpers
|
|
57
45
|
* ------------------------------------------------------------------ */
|
|
58
|
-
|
|
59
46
|
/**
|
|
60
47
|
* Expand an n/w width pattern into a module string, starting with a bar.
|
|
61
48
|
*
|
|
@@ -64,14 +51,13 @@ import {
|
|
|
64
51
|
* @returns {string} Module string, '1' = dark.
|
|
65
52
|
*/
|
|
66
53
|
function expandNarrowWide(pattern, wide = 3) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
54
|
+
let out = '';
|
|
55
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
56
|
+
const width = pattern[i] === 'w' ? wide : 1;
|
|
57
|
+
out += (i % 2 === 0 ? '1' : '0').repeat(width);
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
73
60
|
}
|
|
74
|
-
|
|
75
61
|
/**
|
|
76
62
|
* Expand a digit-width pattern into a module string, starting with a bar.
|
|
77
63
|
*
|
|
@@ -79,35 +65,33 @@ function expandNarrowWide(pattern, wide = 3) {
|
|
|
79
65
|
* @returns {string}
|
|
80
66
|
*/
|
|
81
67
|
function expandWidths(pattern) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
68
|
+
let out = '';
|
|
69
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
70
|
+
out += (i % 2 === 0 ? '1' : '0').repeat(Number(pattern[i]));
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
87
73
|
}
|
|
88
|
-
|
|
89
74
|
/**
|
|
90
75
|
* @param {string} modules
|
|
91
76
|
* @returns {BitMatrix} One row tall.
|
|
92
77
|
*/
|
|
93
78
|
function toMatrix(modules) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
79
|
+
const m = new BitMatrix(modules.length, 1);
|
|
80
|
+
for (let x = 0; x < modules.length; x++) {
|
|
81
|
+
if (modules[x] === '1')
|
|
82
|
+
m.set(x, 0);
|
|
83
|
+
}
|
|
84
|
+
return m;
|
|
99
85
|
}
|
|
100
|
-
|
|
101
86
|
/**
|
|
102
87
|
* @param {string} value
|
|
103
88
|
* @param {string} format
|
|
104
89
|
*/
|
|
105
90
|
function requireDigits(value, format) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
91
|
+
if (!/^[0-9]+$/.test(value)) {
|
|
92
|
+
throw new EncodeError(`${format}: payload must be digits only, got "${value}"`);
|
|
93
|
+
}
|
|
109
94
|
}
|
|
110
|
-
|
|
111
95
|
/**
|
|
112
96
|
* Modulo-10 check digit for the EAN/UPC family.
|
|
113
97
|
*
|
|
@@ -120,18 +104,16 @@ function requireDigits(value, format) {
|
|
|
120
104
|
* @returns {number}
|
|
121
105
|
*/
|
|
122
106
|
export function ean13CheckDigit(payload) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
107
|
+
let sum = 0;
|
|
108
|
+
for (let i = 0; i < payload.length; i++) {
|
|
109
|
+
const fromRight = payload.length - 1 - i;
|
|
110
|
+
sum += Number(payload[i]) * (fromRight % 2 === 0 ? 3 : 1);
|
|
111
|
+
}
|
|
112
|
+
return (10 - (sum % 10)) % 10;
|
|
129
113
|
}
|
|
130
|
-
|
|
131
114
|
/* ------------------------------------------------------------------ *
|
|
132
115
|
* EAN / UPC
|
|
133
116
|
* ------------------------------------------------------------------ */
|
|
134
|
-
|
|
135
117
|
/**
|
|
136
118
|
* EAN-13. Accepts 12 digits (check digit appended) or 13 (verified).
|
|
137
119
|
*
|
|
@@ -139,32 +121,32 @@ export function ean13CheckDigit(payload) {
|
|
|
139
121
|
* @returns {BitMatrix}
|
|
140
122
|
*/
|
|
141
123
|
export function encodeEAN13(value) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
124
|
+
requireDigits(value, 'EAN-13');
|
|
125
|
+
let digits = value;
|
|
126
|
+
if (digits.length === 12) {
|
|
127
|
+
digits += String(ean13CheckDigit(digits));
|
|
128
|
+
}
|
|
129
|
+
else if (digits.length === 13) {
|
|
130
|
+
const expected = ean13CheckDigit(digits.slice(0, 12));
|
|
131
|
+
if (Number(digits[12]) !== expected) {
|
|
132
|
+
throw new EncodeError(`EAN-13: check digit is ${digits[12]}, expected ${expected}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
throw new EncodeError(`EAN-13: needs 12 or 13 digits, got ${digits.length}`);
|
|
137
|
+
}
|
|
138
|
+
const parity = EAN13_PARITY[Number(digits[0])];
|
|
139
|
+
let modules = EAN_START_END;
|
|
140
|
+
for (let i = 0; i < 6; i++) {
|
|
141
|
+
const d = Number(digits[i + 1]);
|
|
142
|
+
modules += parity[i] === 'L' ? EAN_L[d] : EAN_G[d];
|
|
143
|
+
}
|
|
144
|
+
modules += EAN_MIDDLE;
|
|
145
|
+
for (let i = 7; i < 13; i++)
|
|
146
|
+
modules += EAN_R[Number(digits[i])];
|
|
147
|
+
modules += EAN_START_END;
|
|
148
|
+
return toMatrix(modules);
|
|
166
149
|
}
|
|
167
|
-
|
|
168
150
|
/**
|
|
169
151
|
* EAN-8. Accepts 7 digits (check digit appended) or 8 (verified).
|
|
170
152
|
*
|
|
@@ -172,28 +154,29 @@ export function encodeEAN13(value) {
|
|
|
172
154
|
* @returns {BitMatrix}
|
|
173
155
|
*/
|
|
174
156
|
export function encodeEAN8(value) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
157
|
+
requireDigits(value, 'EAN-8');
|
|
158
|
+
let digits = value;
|
|
159
|
+
if (digits.length === 7) {
|
|
160
|
+
digits += String(ean13CheckDigit(digits));
|
|
161
|
+
}
|
|
162
|
+
else if (digits.length === 8) {
|
|
163
|
+
const expected = ean13CheckDigit(digits.slice(0, 7));
|
|
164
|
+
if (Number(digits[7]) !== expected) {
|
|
165
|
+
throw new EncodeError(`EAN-8: check digit is ${digits[7]}, expected ${expected}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
throw new EncodeError(`EAN-8: needs 7 or 8 digits, got ${digits.length}`);
|
|
170
|
+
}
|
|
171
|
+
let modules = EAN_START_END;
|
|
172
|
+
for (let i = 0; i < 4; i++)
|
|
173
|
+
modules += EAN_L[Number(digits[i])];
|
|
174
|
+
modules += EAN_MIDDLE;
|
|
175
|
+
for (let i = 4; i < 8; i++)
|
|
176
|
+
modules += EAN_R[Number(digits[i])];
|
|
177
|
+
modules += EAN_START_END;
|
|
178
|
+
return toMatrix(modules);
|
|
195
179
|
}
|
|
196
|
-
|
|
197
180
|
/**
|
|
198
181
|
* ISBN, as its printed EAN-13 ("Bookland") symbol.
|
|
199
182
|
*
|
|
@@ -211,34 +194,29 @@ export function encodeEAN8(value) {
|
|
|
211
194
|
* @returns {BitMatrix}
|
|
212
195
|
*/
|
|
213
196
|
export function encodeISBN(value) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
throw new EncodeError(
|
|
238
|
-
`ISBN: expected 10 or 13 digits, hyphens optional — got "${value}"`
|
|
239
|
-
);
|
|
197
|
+
const cleaned = String(value).replace(/[\s-]/g, '').toUpperCase();
|
|
198
|
+
if (/^[0-9]{9}[0-9X]$/.test(cleaned)) {
|
|
199
|
+
// ISBN-10: verify its modulo-11 check, then convert to the 978 form.
|
|
200
|
+
let sum = 0;
|
|
201
|
+
for (let i = 0; i < 9; i++)
|
|
202
|
+
sum += Number(cleaned[i]) * (10 - i);
|
|
203
|
+
sum += cleaned[9] === 'X' ? 10 : Number(cleaned[9]);
|
|
204
|
+
if (sum % 11 !== 0) {
|
|
205
|
+
throw new EncodeError(`ISBN-10: check digit "${cleaned[9]}" fails the modulo-11 test`);
|
|
206
|
+
}
|
|
207
|
+
// The check digit does not carry over — encodeEAN13 computes the new one.
|
|
208
|
+
return encodeEAN13('978' + cleaned.slice(0, 9));
|
|
209
|
+
}
|
|
210
|
+
if (/^[0-9]{12,13}$/.test(cleaned)) {
|
|
211
|
+
const prefix = cleaned.slice(0, 3);
|
|
212
|
+
if (prefix !== '978' && prefix !== '979') {
|
|
213
|
+
throw new EncodeError(`ISBN-13 must begin with 978 or 979, got ${prefix}`);
|
|
214
|
+
}
|
|
215
|
+
// encodeEAN13 appends the check digit at 12, or verifies it at 13.
|
|
216
|
+
return encodeEAN13(cleaned);
|
|
217
|
+
}
|
|
218
|
+
throw new EncodeError(`ISBN: expected 10 or 13 digits, hyphens optional — got "${value}"`);
|
|
240
219
|
}
|
|
241
|
-
|
|
242
220
|
/**
|
|
243
221
|
* UPC-A. Structurally an EAN-13 whose first digit is zero.
|
|
244
222
|
*
|
|
@@ -246,13 +224,12 @@ export function encodeISBN(value) {
|
|
|
246
224
|
* @returns {BitMatrix}
|
|
247
225
|
*/
|
|
248
226
|
export function encodeUPCA(value) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
227
|
+
requireDigits(value, 'UPC-A');
|
|
228
|
+
if (value.length !== 11 && value.length !== 12) {
|
|
229
|
+
throw new EncodeError(`UPC-A: needs 11 or 12 digits, got ${value.length}`);
|
|
230
|
+
}
|
|
231
|
+
return encodeEAN13('0' + value);
|
|
254
232
|
}
|
|
255
|
-
|
|
256
233
|
/**
|
|
257
234
|
* Expand a UPC-E body to the 11 digits preceding the check digit.
|
|
258
235
|
*
|
|
@@ -261,21 +238,23 @@ export function encodeUPCA(value) {
|
|
|
261
238
|
* @returns {string} 11 digits.
|
|
262
239
|
*/
|
|
263
240
|
export function upceToUpcaBody(system, body) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
241
|
+
const d = body;
|
|
242
|
+
const last = Number(d[5]);
|
|
243
|
+
let middle;
|
|
244
|
+
if (last <= 2) {
|
|
245
|
+
middle = d.slice(0, 2) + String(last) + '0000' + d.slice(2, 5);
|
|
246
|
+
}
|
|
247
|
+
else if (last === 3) {
|
|
248
|
+
middle = d.slice(0, 3) + '00000' + d.slice(3, 5);
|
|
249
|
+
}
|
|
250
|
+
else if (last === 4) {
|
|
251
|
+
middle = d.slice(0, 4) + '00000' + d[4];
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
middle = d.slice(0, 5) + '0000' + String(last);
|
|
255
|
+
}
|
|
256
|
+
return String(system) + middle;
|
|
277
257
|
}
|
|
278
|
-
|
|
279
258
|
/**
|
|
280
259
|
* UPC-E, the zero-suppressed form of UPC-A.
|
|
281
260
|
*
|
|
@@ -283,46 +262,43 @@ export function upceToUpcaBody(system, body) {
|
|
|
283
262
|
* @returns {BitMatrix}
|
|
284
263
|
*/
|
|
285
264
|
export function encodeUPCE(value) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return toMatrix(modules);
|
|
265
|
+
requireDigits(value, 'UPC-E');
|
|
266
|
+
let system, body, check;
|
|
267
|
+
if (value.length === 6) {
|
|
268
|
+
system = 0;
|
|
269
|
+
body = value;
|
|
270
|
+
check = ean13CheckDigit(upceToUpcaBody(0, body));
|
|
271
|
+
}
|
|
272
|
+
else if (value.length === 7) {
|
|
273
|
+
system = Number(value[0]);
|
|
274
|
+
body = value.slice(1);
|
|
275
|
+
check = ean13CheckDigit(upceToUpcaBody(system, body));
|
|
276
|
+
}
|
|
277
|
+
else if (value.length === 8) {
|
|
278
|
+
system = Number(value[0]);
|
|
279
|
+
body = value.slice(1, 7);
|
|
280
|
+
check = Number(value[7]);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
throw new EncodeError(`UPC-E: needs 6, 7 or 8 digits, got ${value.length}`);
|
|
284
|
+
}
|
|
285
|
+
if (system !== 0 && system !== 1) {
|
|
286
|
+
throw new EncodeError(`UPC-E: number system must be 0 or 1, got ${system}`);
|
|
287
|
+
}
|
|
288
|
+
const parity = UPCE_PARITY[check];
|
|
289
|
+
let modules = EAN_START_END;
|
|
290
|
+
for (let i = 0; i < 6; i++) {
|
|
291
|
+
const d = Number(body[i]);
|
|
292
|
+
// Number system 1 inverts the entire parity pattern relative to system 0.
|
|
293
|
+
const even = system === 0 ? parity[i] === 'E' : parity[i] === 'O';
|
|
294
|
+
modules += even ? EAN_G[d] : EAN_L[d];
|
|
295
|
+
}
|
|
296
|
+
modules += UPCE_END;
|
|
297
|
+
return toMatrix(modules);
|
|
320
298
|
}
|
|
321
|
-
|
|
322
299
|
/* ------------------------------------------------------------------ *
|
|
323
300
|
* Code 39
|
|
324
301
|
* ------------------------------------------------------------------ */
|
|
325
|
-
|
|
326
302
|
/**
|
|
327
303
|
* Code 39.
|
|
328
304
|
*
|
|
@@ -334,49 +310,43 @@ export function encodeUPCE(value) {
|
|
|
334
310
|
* @returns {BitMatrix}
|
|
335
311
|
*/
|
|
336
312
|
export function encodeCode39(value, options = {}) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
// Characters are separated by a narrow inter-character gap.
|
|
372
|
-
const parts = ['*', ...payload, '*'].map((ch) => expandNarrowWide(CODE39[ch], wideRatio));
|
|
373
|
-
return toMatrix(parts.join('0'));
|
|
313
|
+
const { checkDigit = false, fullAscii = false, wideRatio = 3 } = options;
|
|
314
|
+
if (wideRatio < 2 || wideRatio > 3) {
|
|
315
|
+
throw new EncodeError(`Code 39: wide ratio must be 2 or 3, got ${wideRatio}`);
|
|
316
|
+
}
|
|
317
|
+
let text = value;
|
|
318
|
+
if (fullAscii) {
|
|
319
|
+
text = '';
|
|
320
|
+
for (const ch of value) {
|
|
321
|
+
const code = ch.charCodeAt(0);
|
|
322
|
+
if (code > 127)
|
|
323
|
+
throw new EncodeError(`Code 39: '${ch}' is outside ASCII`);
|
|
324
|
+
text += CODE39_EXTENDED[code];
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
for (const ch of text) {
|
|
328
|
+
if (ch === '*') {
|
|
329
|
+
throw new EncodeError("Code 39: '*' is reserved as the start/stop character");
|
|
330
|
+
}
|
|
331
|
+
if (!CODE39[ch]) {
|
|
332
|
+
throw new EncodeError(`Code 39: character '${ch}' is not encodable` +
|
|
333
|
+
(fullAscii ? '' : ' — try the fullAscii option'));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
let payload = text;
|
|
337
|
+
if (checkDigit) {
|
|
338
|
+
let sum = 0;
|
|
339
|
+
for (const ch of text)
|
|
340
|
+
sum += CODE39_CHECK_SET.indexOf(ch);
|
|
341
|
+
payload += CODE39_CHECK_SET[sum % 43];
|
|
342
|
+
}
|
|
343
|
+
// Characters are separated by a narrow inter-character gap.
|
|
344
|
+
const parts = ['*', ...payload, '*'].map((ch) => expandNarrowWide(CODE39[ch], wideRatio));
|
|
345
|
+
return toMatrix(parts.join('0'));
|
|
374
346
|
}
|
|
375
|
-
|
|
376
347
|
/* ------------------------------------------------------------------ *
|
|
377
348
|
* Code 93
|
|
378
349
|
* ------------------------------------------------------------------ */
|
|
379
|
-
|
|
380
350
|
/**
|
|
381
351
|
* Code 93, always with its two mandatory check characters.
|
|
382
352
|
*
|
|
@@ -384,42 +354,37 @@ export function encodeCode39(value, options = {}) {
|
|
|
384
354
|
* @returns {BitMatrix}
|
|
385
355
|
*/
|
|
386
356
|
export function encodeCode93(value) {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
return toMatrix(modules);
|
|
357
|
+
const values = [];
|
|
358
|
+
for (const ch of value) {
|
|
359
|
+
const idx = CODE93_VALUES.indexOf(ch);
|
|
360
|
+
if (idx < 0)
|
|
361
|
+
throw new EncodeError(`Code 93: character '${ch}' is not encodable`);
|
|
362
|
+
values.push(idx);
|
|
363
|
+
}
|
|
364
|
+
// Check character C weights the payload 1..20 from the right; K then repeats
|
|
365
|
+
// the exercise over the payload plus C, weighted 1..15.
|
|
366
|
+
const weighted = (data, maxWeight) => {
|
|
367
|
+
let sum = 0;
|
|
368
|
+
for (let i = 0; i < data.length; i++) {
|
|
369
|
+
const weight = ((data.length - 1 - i) % maxWeight) + 1;
|
|
370
|
+
sum += weight * data[i];
|
|
371
|
+
}
|
|
372
|
+
return sum % 47;
|
|
373
|
+
};
|
|
374
|
+
values.push(weighted(values, 20));
|
|
375
|
+
values.push(weighted(values, 15));
|
|
376
|
+
let modules = expandWidths(CODE93_START_STOP);
|
|
377
|
+
for (const v of values)
|
|
378
|
+
modules += expandWidths(CODE93[CODE93_VALUES[v]]);
|
|
379
|
+
modules += expandWidths(CODE93_START_STOP);
|
|
380
|
+
modules += '1'; // termination bar
|
|
381
|
+
return toMatrix(modules);
|
|
414
382
|
}
|
|
415
|
-
|
|
416
383
|
/* ------------------------------------------------------------------ *
|
|
417
384
|
* Code 128
|
|
418
385
|
* ------------------------------------------------------------------ */
|
|
419
|
-
|
|
420
386
|
/** Set B maps printable ASCII starting at space to symbol value 0. */
|
|
421
387
|
const CODE128_B_OFFSET = 32;
|
|
422
|
-
|
|
423
388
|
/**
|
|
424
389
|
* Code 128, with automatic code-set selection.
|
|
425
390
|
*
|
|
@@ -434,97 +399,91 @@ const CODE128_B_OFFSET = 32;
|
|
|
434
399
|
* @returns {BitMatrix}
|
|
435
400
|
*/
|
|
436
401
|
export function encodeCode128(value, options = {}) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
codes.push(CODE128_START_B);
|
|
461
|
-
mode = 'B';
|
|
462
|
-
}
|
|
463
|
-
if (gs1) codes.push(CODE128_FNC1);
|
|
464
|
-
|
|
465
|
-
while (i < value.length) {
|
|
466
|
-
if (gs1 && value[i] === '\x1d') {
|
|
467
|
-
codes.push(CODE128_FNC1);
|
|
468
|
-
i++;
|
|
469
|
-
continue;
|
|
470
|
-
}
|
|
471
|
-
const run = digitRun(i);
|
|
472
|
-
const atEnd = i + run === value.length;
|
|
473
|
-
const worthC = run >= 6 || (i === 0 && run >= 4) || (atEnd && run >= 4);
|
|
474
|
-
|
|
475
|
-
if (mode !== 'C' && worthC && run >= 2) {
|
|
476
|
-
codes.push(CODE128_CODE_C);
|
|
477
|
-
mode = 'C';
|
|
478
|
-
continue;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
if (mode === 'C') {
|
|
482
|
-
if (run >= 2) {
|
|
483
|
-
codes.push(Number(value.substr(i, 2)));
|
|
484
|
-
i += 2;
|
|
485
|
-
continue;
|
|
486
|
-
}
|
|
487
|
-
codes.push(CODE128_CODE_B);
|
|
488
|
-
mode = 'B';
|
|
489
|
-
continue;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
const code = value.charCodeAt(i);
|
|
493
|
-
if (code < 32) {
|
|
494
|
-
// Control characters live in set A only.
|
|
495
|
-
if (mode !== 'A') {
|
|
496
|
-
codes.push(CODE128_CODE_A);
|
|
497
|
-
mode = 'A';
|
|
498
|
-
continue;
|
|
499
|
-
}
|
|
500
|
-
codes.push(code + 64);
|
|
501
|
-
} else {
|
|
502
|
-
if (mode === 'A' && code >= 96) {
|
|
503
|
-
codes.push(CODE128_CODE_B);
|
|
402
|
+
const { gs1 = false } = options;
|
|
403
|
+
for (const ch of value) {
|
|
404
|
+
if (ch.charCodeAt(0) > 127) {
|
|
405
|
+
throw new EncodeError(`Code 128: '${ch}' is outside ASCII`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
/** Length of the digit run starting at i. */
|
|
409
|
+
const digitRun = (i) => {
|
|
410
|
+
let n = 0;
|
|
411
|
+
while (i + n < value.length && value[i + n] >= '0' && value[i + n] <= '9')
|
|
412
|
+
n++;
|
|
413
|
+
return n;
|
|
414
|
+
};
|
|
415
|
+
const codes = [];
|
|
416
|
+
let mode;
|
|
417
|
+
let i = 0;
|
|
418
|
+
const startRun = digitRun(0);
|
|
419
|
+
if (startRun >= 4 && startRun % 2 === 0) {
|
|
420
|
+
codes.push(CODE128_START_C);
|
|
421
|
+
mode = 'C';
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
codes.push(CODE128_START_B);
|
|
504
425
|
mode = 'B';
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
426
|
+
}
|
|
427
|
+
if (gs1)
|
|
428
|
+
codes.push(CODE128_FNC1);
|
|
429
|
+
while (i < value.length) {
|
|
430
|
+
if (gs1 && value[i] === '\x1d') {
|
|
431
|
+
codes.push(CODE128_FNC1);
|
|
432
|
+
i++;
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
const run = digitRun(i);
|
|
436
|
+
const atEnd = i + run === value.length;
|
|
437
|
+
const worthC = run >= 6 || (i === 0 && run >= 4) || (atEnd && run >= 4);
|
|
438
|
+
if (mode !== 'C' && worthC && run >= 2) {
|
|
439
|
+
codes.push(CODE128_CODE_C);
|
|
440
|
+
mode = 'C';
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
if (mode === 'C') {
|
|
444
|
+
if (run >= 2) {
|
|
445
|
+
codes.push(Number(value.substr(i, 2)));
|
|
446
|
+
i += 2;
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
codes.push(CODE128_CODE_B);
|
|
450
|
+
mode = 'B';
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
const code = value.charCodeAt(i);
|
|
454
|
+
if (code < 32) {
|
|
455
|
+
// Control characters live in set A only.
|
|
456
|
+
if (mode !== 'A') {
|
|
457
|
+
codes.push(CODE128_CODE_A);
|
|
458
|
+
mode = 'A';
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
codes.push(code + 64);
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
if (mode === 'A' && code >= 96) {
|
|
465
|
+
codes.push(CODE128_CODE_B);
|
|
466
|
+
mode = 'B';
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
codes.push(code - CODE128_B_OFFSET);
|
|
470
|
+
}
|
|
471
|
+
i++;
|
|
472
|
+
}
|
|
473
|
+
// Checksum: the start value plus each symbol weighted by its position.
|
|
474
|
+
let sum = codes[0];
|
|
475
|
+
for (let k = 1; k < codes.length; k++)
|
|
476
|
+
sum += codes[k] * k;
|
|
477
|
+
codes.push(sum % 103);
|
|
478
|
+
codes.push(CODE128_STOP);
|
|
479
|
+
let modules = '';
|
|
480
|
+
for (const c of codes)
|
|
481
|
+
modules += expandWidths(CODE128[c]);
|
|
482
|
+
return toMatrix(modules);
|
|
522
483
|
}
|
|
523
|
-
|
|
524
484
|
/* ------------------------------------------------------------------ *
|
|
525
485
|
* Interleaved 2 of 5
|
|
526
486
|
* ------------------------------------------------------------------ */
|
|
527
|
-
|
|
528
487
|
/**
|
|
529
488
|
* Interleaved 2 of 5.
|
|
530
489
|
*
|
|
@@ -539,30 +498,27 @@ export function encodeCode128(value, options = {}) {
|
|
|
539
498
|
* @returns {BitMatrix}
|
|
540
499
|
*/
|
|
541
500
|
export function encodeITF(value, options = {}) {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
modules += '1'.repeat(wideRatio) + '0' + '1';
|
|
563
|
-
return toMatrix(modules);
|
|
501
|
+
const { checkDigit = false, wideRatio = 3 } = options;
|
|
502
|
+
requireDigits(value, 'ITF');
|
|
503
|
+
let digits = value;
|
|
504
|
+
if (checkDigit)
|
|
505
|
+
digits += String(ean13CheckDigit(digits));
|
|
506
|
+
// A leading zero pads to an even length without changing the value.
|
|
507
|
+
if (digits.length % 2 !== 0)
|
|
508
|
+
digits = '0' + digits;
|
|
509
|
+
let modules = '1010'; // start: four narrow elements
|
|
510
|
+
for (let i = 0; i < digits.length; i += 2) {
|
|
511
|
+
const bars = ITF[Number(digits[i])];
|
|
512
|
+
const spaces = ITF[Number(digits[i + 1])];
|
|
513
|
+
for (let k = 0; k < 5; k++) {
|
|
514
|
+
modules += '1'.repeat(bars[k] === 'w' ? wideRatio : 1);
|
|
515
|
+
modules += '0'.repeat(spaces[k] === 'w' ? wideRatio : 1);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
// Stop: wide bar, narrow space, narrow bar.
|
|
519
|
+
modules += '1'.repeat(wideRatio) + '0' + '1';
|
|
520
|
+
return toMatrix(modules);
|
|
564
521
|
}
|
|
565
|
-
|
|
566
522
|
/**
|
|
567
523
|
* ITF-14, the shipping-container form: exactly 14 digits.
|
|
568
524
|
*
|
|
@@ -570,20 +526,19 @@ export function encodeITF(value, options = {}) {
|
|
|
570
526
|
* @returns {BitMatrix}
|
|
571
527
|
*/
|
|
572
528
|
export function encodeITF14(value) {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
529
|
+
requireDigits(value, 'ITF-14');
|
|
530
|
+
let digits = value;
|
|
531
|
+
if (digits.length === 13) {
|
|
532
|
+
digits += String(ean13CheckDigit(digits));
|
|
533
|
+
}
|
|
534
|
+
else if (digits.length !== 14) {
|
|
535
|
+
throw new EncodeError(`ITF-14: needs 13 or 14 digits, got ${digits.length}`);
|
|
536
|
+
}
|
|
537
|
+
return encodeITF(digits);
|
|
581
538
|
}
|
|
582
|
-
|
|
583
539
|
/* ------------------------------------------------------------------ *
|
|
584
540
|
* Codabar
|
|
585
541
|
* ------------------------------------------------------------------ */
|
|
586
|
-
|
|
587
542
|
/**
|
|
588
543
|
* Codabar.
|
|
589
544
|
*
|
|
@@ -595,42 +550,38 @@ export function encodeITF14(value) {
|
|
|
595
550
|
* @returns {BitMatrix}
|
|
596
551
|
*/
|
|
597
552
|
export function encodeCodabar(value, options = {}) {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
return toMatrix(parts.join('0'));
|
|
553
|
+
const { wideRatio = 3 } = options;
|
|
554
|
+
let text = value.toUpperCase();
|
|
555
|
+
let start = (options.start || '').toUpperCase();
|
|
556
|
+
let stop = (options.stop || '').toUpperCase();
|
|
557
|
+
// Accept the common convention of embedding the guards in the payload.
|
|
558
|
+
if (!start && text.length >= 2 &&
|
|
559
|
+
CODABAR_START_STOP.includes(text[0]) &&
|
|
560
|
+
CODABAR_START_STOP.includes(text[text.length - 1])) {
|
|
561
|
+
start = text[0];
|
|
562
|
+
stop = text[text.length - 1];
|
|
563
|
+
text = text.slice(1, -1);
|
|
564
|
+
}
|
|
565
|
+
if (!start)
|
|
566
|
+
start = 'A';
|
|
567
|
+
if (!stop)
|
|
568
|
+
stop = 'A';
|
|
569
|
+
if (!CODABAR_START_STOP.includes(start) || !CODABAR_START_STOP.includes(stop)) {
|
|
570
|
+
throw new EncodeError('Codabar: start and stop characters must be A, B, C or D');
|
|
571
|
+
}
|
|
572
|
+
for (const ch of text) {
|
|
573
|
+
if (!CODABAR[ch] || CODABAR_START_STOP.includes(ch)) {
|
|
574
|
+
throw new EncodeError(`Codabar: character '${ch}' is not encodable in the payload`);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
const parts = [start, ...text, stop].map((ch) => expandNarrowWide(CODABAR[ch], wideRatio));
|
|
578
|
+
return toMatrix(parts.join('0'));
|
|
625
579
|
}
|
|
626
|
-
|
|
627
580
|
/* ------------------------------------------------------------------ *
|
|
628
581
|
* Code 11
|
|
629
582
|
* ------------------------------------------------------------------ */
|
|
630
|
-
|
|
631
583
|
/** Code 11 character values, in order. */
|
|
632
584
|
const CODE11_CHARSET = '0123456789-';
|
|
633
|
-
|
|
634
585
|
/**
|
|
635
586
|
* Code 11, digits and hyphen.
|
|
636
587
|
*
|
|
@@ -641,41 +592,37 @@ const CODE11_CHARSET = '0123456789-';
|
|
|
641
592
|
* @returns {BitMatrix}
|
|
642
593
|
*/
|
|
643
594
|
export function encodeCode11(value, options = {}) {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
];
|
|
672
|
-
return toMatrix(parts.join('0'));
|
|
595
|
+
const { checkDigit = true, wideRatio = 3 } = options;
|
|
596
|
+
for (const ch of value) {
|
|
597
|
+
if (!CODE11_CHARSET.includes(ch)) {
|
|
598
|
+
throw new EncodeError(`Code 11: character '${ch}' is not encodable`);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
let payload = value;
|
|
602
|
+
if (checkDigit) {
|
|
603
|
+
const weighted = (text, maxWeight) => {
|
|
604
|
+
let sum = 0;
|
|
605
|
+
for (let i = 0; i < text.length; i++) {
|
|
606
|
+
const weight = ((text.length - 1 - i) % maxWeight) + 1;
|
|
607
|
+
sum += weight * CODE11_CHARSET.indexOf(text[i]);
|
|
608
|
+
}
|
|
609
|
+
return sum;
|
|
610
|
+
};
|
|
611
|
+
payload += CODE11_CHARSET[weighted(payload, 10) % 11];
|
|
612
|
+
// The second check character is conventionally added only to longer payloads.
|
|
613
|
+
if (value.length >= 10)
|
|
614
|
+
payload += CODE11_CHARSET[weighted(payload, 9) % 11];
|
|
615
|
+
}
|
|
616
|
+
const parts = [
|
|
617
|
+
expandNarrowWide(CODE11_START_STOP, wideRatio),
|
|
618
|
+
...[...payload].map((ch) => expandNarrowWide(CODE11[ch], wideRatio)),
|
|
619
|
+
expandNarrowWide(CODE11_START_STOP, wideRatio),
|
|
620
|
+
];
|
|
621
|
+
return toMatrix(parts.join('0'));
|
|
673
622
|
}
|
|
674
|
-
|
|
675
623
|
/* ------------------------------------------------------------------ *
|
|
676
624
|
* MSI / Plessey
|
|
677
625
|
* ------------------------------------------------------------------ */
|
|
678
|
-
|
|
679
626
|
/**
|
|
680
627
|
* MSI Plessey.
|
|
681
628
|
*
|
|
@@ -685,35 +632,34 @@ export function encodeCode11(value, options = {}) {
|
|
|
685
632
|
* @returns {BitMatrix}
|
|
686
633
|
*/
|
|
687
634
|
export function encodeMSI(value, options = {}) {
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
const
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
635
|
+
const { checkDigit = false } = options;
|
|
636
|
+
requireDigits(value, 'MSI');
|
|
637
|
+
let digits = value;
|
|
638
|
+
if (checkDigit) {
|
|
639
|
+
// Luhn: the odd-positioned digits, read as one number, are doubled.
|
|
640
|
+
let odd = '';
|
|
641
|
+
for (let i = digits.length - 1; i >= 0; i -= 2)
|
|
642
|
+
odd = digits[i] + odd;
|
|
643
|
+
const doubled = String(Number(odd) * 2);
|
|
644
|
+
let sum = 0;
|
|
645
|
+
for (const ch of doubled)
|
|
646
|
+
sum += Number(ch);
|
|
647
|
+
for (let i = digits.length - 2; i >= 0; i -= 2)
|
|
648
|
+
sum += Number(digits[i]);
|
|
649
|
+
digits += String((10 - (sum % 10)) % 10);
|
|
650
|
+
}
|
|
651
|
+
let modules = MSI_START;
|
|
652
|
+
for (const ch of digits) {
|
|
653
|
+
const bits = Number(ch).toString(2).padStart(4, '0');
|
|
654
|
+
for (const b of bits)
|
|
655
|
+
modules += MSI_BIT[b];
|
|
656
|
+
}
|
|
657
|
+
modules += MSI_STOP;
|
|
658
|
+
return toMatrix(modules);
|
|
711
659
|
}
|
|
712
|
-
|
|
713
660
|
/* ------------------------------------------------------------------ *
|
|
714
661
|
* Pharmacode
|
|
715
662
|
* ------------------------------------------------------------------ */
|
|
716
|
-
|
|
717
663
|
/**
|
|
718
664
|
* Pharmacode, one-track.
|
|
719
665
|
*
|
|
@@ -725,22 +671,21 @@ export function encodeMSI(value, options = {}) {
|
|
|
725
671
|
* @returns {BitMatrix}
|
|
726
672
|
*/
|
|
727
673
|
export function encodePharmacode(value) {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
return toMatrix(bars.join('0'));
|
|
674
|
+
let n = typeof value === 'string' ? Number(value) : value;
|
|
675
|
+
if (!Number.isInteger(n) || n < 3 || n > 131070) {
|
|
676
|
+
throw new EncodeError(`Pharmacode: value must be an integer in 3..131070, got ${value}`);
|
|
677
|
+
}
|
|
678
|
+
const bars = [];
|
|
679
|
+
while (n > 0) {
|
|
680
|
+
if (n % 2 === 0) {
|
|
681
|
+
bars.push('111'); // wide
|
|
682
|
+
n = n / 2 - 1;
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
bars.push('1'); // narrow
|
|
686
|
+
n = (n - 1) / 2;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
bars.reverse();
|
|
690
|
+
return toMatrix(bars.join('0'));
|
|
746
691
|
}
|