@thermal-label/brother-ql-core 0.0.1 → 0.3.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/dist/__tests__/devices.test.js +16 -2
- package/dist/__tests__/devices.test.js.map +1 -1
- package/dist/__tests__/media.test.js +37 -6
- package/dist/__tests__/media.test.js.map +1 -1
- package/dist/__tests__/pack-bits.test.d.ts +2 -0
- package/dist/__tests__/pack-bits.test.d.ts.map +1 -0
- package/dist/__tests__/pack-bits.test.js +90 -0
- package/dist/__tests__/pack-bits.test.js.map +1 -0
- package/dist/__tests__/preview.test.d.ts +2 -0
- package/dist/__tests__/preview.test.d.ts.map +1 -0
- package/dist/__tests__/preview.test.js +41 -0
- package/dist/__tests__/preview.test.js.map +1 -0
- package/dist/__tests__/protocol.test.js +46 -1
- package/dist/__tests__/protocol.test.js.map +1 -1
- package/dist/__tests__/status.test.js +28 -22
- package/dist/__tests__/status.test.js.map +1 -1
- package/dist/devices.d.ts +40 -21
- package/dist/devices.d.ts.map +1 -1
- package/dist/devices.js +38 -20
- package/dist/devices.js.map +1 -1
- package/dist/index.d.ts +8 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/media.d.ts +43 -4
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +92 -24
- package/dist/media.js.map +1 -1
- package/dist/orientation.d.ts +11 -0
- package/dist/orientation.d.ts.map +1 -0
- package/dist/orientation.js +10 -0
- package/dist/orientation.js.map +1 -0
- package/dist/pack-bits.d.ts +20 -0
- package/dist/pack-bits.d.ts.map +1 -0
- package/dist/pack-bits.js +61 -0
- package/dist/pack-bits.js.map +1 -0
- package/dist/preview.d.ts +13 -0
- package/dist/preview.d.ts.map +1 -0
- package/dist/preview.js +31 -0
- package/dist/preview.js.map +1 -0
- package/dist/protocol.d.ts +2 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +14 -8
- package/dist/protocol.js.map +1 -1
- package/dist/status.d.ts +20 -2
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +59 -45
- package/dist/status.js.map +1 -1
- package/dist/types.d.ts +46 -30
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +3 -2
- package/src/__tests__/devices.test.ts +18 -2
- package/src/__tests__/media.test.ts +39 -6
- package/src/__tests__/pack-bits.test.ts +92 -0
- package/src/__tests__/preview.test.ts +52 -0
- package/src/__tests__/protocol.test.ts +47 -1
- package/src/__tests__/status.test.ts +31 -22
- package/src/devices.ts +41 -22
- package/src/index.ts +45 -11
- package/src/media.ts +105 -27
- package/src/orientation.ts +11 -0
- package/src/pack-bits.ts +64 -0
- package/src/preview.ts +35 -0
- package/src/protocol.ts +16 -9
- package/src/status.ts +62 -47
- package/src/types.ts +52 -32
package/dist/media.d.ts
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type { BrotherQLMedia, MediaType } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Registry of supported Brother QL consumables.
|
|
4
|
+
*
|
|
5
|
+
* Entries are keyed by the firmware media id — the same number the
|
|
6
|
+
* printer reports in the 32-byte status response. `heightMm` is omitted
|
|
7
|
+
* for continuous media (variable length) and set for die-cut labels
|
|
8
|
+
* (fixed length).
|
|
9
|
+
*
|
|
10
|
+
* `palette` is set on multi-ink media (DK-22251, today's only entry) —
|
|
11
|
+
* the driver routes those through `renderMultiPlaneImage` and emits the
|
|
12
|
+
* second plane in the raster job. Single-ink rolls leave it undefined
|
|
13
|
+
* and route through `renderImage` (dithered single-plane).
|
|
14
|
+
*
|
|
15
|
+
* Rectangular die-cut entries declare `defaultOrientation: 'horizontal'`
|
|
16
|
+
* so landscape input auto-rotates to read along the tape feed direction.
|
|
17
|
+
* Continuous wide tape leaves the hint undefined — users may go either
|
|
18
|
+
* way.
|
|
19
|
+
*
|
|
20
|
+
* `cornerRadiusMm` is informational; previews use it to render the
|
|
21
|
+
* actual paper outline. Round die-cut labels set the radius to
|
|
22
|
+
* `widthMm / 2` so the rounded rectangle degenerates to a circle.
|
|
23
|
+
*/
|
|
24
|
+
export declare const MEDIA: Record<number, BrotherQLMedia>;
|
|
25
|
+
/**
|
|
26
|
+
* Default media when `createPreview()` is called without media and
|
|
27
|
+
* without a detected roll. 62mm continuous (DK-22205) is the common
|
|
28
|
+
* single-colour shipping roll.
|
|
29
|
+
*/
|
|
30
|
+
export declare const DEFAULT_MEDIA: BrotherQLMedia;
|
|
31
|
+
export declare function findMedia(id: number): BrotherQLMedia | undefined;
|
|
32
|
+
export declare function findMediaByWidth(widthMm: number, type: MediaType): BrotherQLMedia[];
|
|
33
|
+
/**
|
|
34
|
+
* Match status-response dimensions to a media registry entry.
|
|
35
|
+
*
|
|
36
|
+
* @param widthMm media width in mm (status byte 10)
|
|
37
|
+
* @param heightMm media length in mm (status byte 17) — 0 = continuous
|
|
38
|
+
* @param twoColorMode true when the status response indicates the
|
|
39
|
+
* printer is configured for two-colour media. When
|
|
40
|
+
* both DK-22205 (259) and DK-22251 (251) match the
|
|
41
|
+
* dimensions, the flag picks the right one.
|
|
42
|
+
*/
|
|
43
|
+
export declare function findMediaByDimensions(widthMm: number, heightMm: number, twoColorMode?: boolean): BrotherQLMedia | undefined;
|
|
5
44
|
//# sourceMappingURL=media.d.ts.map
|
package/dist/media.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5D;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAmQhD,CAAC;AAEF;;;;GAIG;AAEH,eAAO,MAAM,aAAa,EAAE,cAA4B,CAAC;AAEzD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEhE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,cAAc,EAAE,CAEnF;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,YAAY,UAAQ,GACnB,cAAc,GAAG,SAAS,CAY5B"}
|
package/dist/media.js
CHANGED
|
@@ -1,4 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Registry of supported Brother QL consumables.
|
|
3
|
+
*
|
|
4
|
+
* Entries are keyed by the firmware media id — the same number the
|
|
5
|
+
* printer reports in the 32-byte status response. `heightMm` is omitted
|
|
6
|
+
* for continuous media (variable length) and set for die-cut labels
|
|
7
|
+
* (fixed length).
|
|
8
|
+
*
|
|
9
|
+
* `palette` is set on multi-ink media (DK-22251, today's only entry) —
|
|
10
|
+
* the driver routes those through `renderMultiPlaneImage` and emits the
|
|
11
|
+
* second plane in the raster job. Single-ink rolls leave it undefined
|
|
12
|
+
* and route through `renderImage` (dithered single-plane).
|
|
13
|
+
*
|
|
14
|
+
* Rectangular die-cut entries declare `defaultOrientation: 'horizontal'`
|
|
15
|
+
* so landscape input auto-rotates to read along the tape feed direction.
|
|
16
|
+
* Continuous wide tape leaves the hint undefined — users may go either
|
|
17
|
+
* way.
|
|
18
|
+
*
|
|
19
|
+
* `cornerRadiusMm` is informational; previews use it to render the
|
|
20
|
+
* actual paper outline. Round die-cut labels set the radius to
|
|
21
|
+
* `widthMm / 2` so the rounded rectangle degenerates to a circle.
|
|
22
|
+
*/
|
|
2
23
|
export const MEDIA = {
|
|
3
24
|
// Continuous length tape
|
|
4
25
|
257: {
|
|
@@ -6,7 +27,6 @@ export const MEDIA = {
|
|
|
6
27
|
name: '12mm continuous',
|
|
7
28
|
type: 'continuous',
|
|
8
29
|
widthMm: 12,
|
|
9
|
-
lengthMm: 0,
|
|
10
30
|
printAreaDots: 106,
|
|
11
31
|
leftMarginPins: 585,
|
|
12
32
|
rightMarginPins: 29,
|
|
@@ -16,7 +36,6 @@ export const MEDIA = {
|
|
|
16
36
|
name: '29mm continuous (DK-22210)',
|
|
17
37
|
type: 'continuous',
|
|
18
38
|
widthMm: 29,
|
|
19
|
-
lengthMm: 0,
|
|
20
39
|
printAreaDots: 306,
|
|
21
40
|
leftMarginPins: 408,
|
|
22
41
|
rightMarginPins: 6,
|
|
@@ -26,7 +45,6 @@ export const MEDIA = {
|
|
|
26
45
|
name: '38mm continuous (DK-22225)',
|
|
27
46
|
type: 'continuous',
|
|
28
47
|
widthMm: 38,
|
|
29
|
-
lengthMm: 0,
|
|
30
48
|
printAreaDots: 413,
|
|
31
49
|
leftMarginPins: 295,
|
|
32
50
|
rightMarginPins: 12,
|
|
@@ -36,7 +54,6 @@ export const MEDIA = {
|
|
|
36
54
|
name: '50mm continuous (DK-22246)',
|
|
37
55
|
type: 'continuous',
|
|
38
56
|
widthMm: 50,
|
|
39
|
-
lengthMm: 0,
|
|
40
57
|
printAreaDots: 554,
|
|
41
58
|
leftMarginPins: 154,
|
|
42
59
|
rightMarginPins: 12,
|
|
@@ -46,7 +63,6 @@ export const MEDIA = {
|
|
|
46
63
|
name: '54mm continuous (DK-22214)',
|
|
47
64
|
type: 'continuous',
|
|
48
65
|
widthMm: 54,
|
|
49
|
-
lengthMm: 0,
|
|
50
66
|
printAreaDots: 590,
|
|
51
67
|
leftMarginPins: 130,
|
|
52
68
|
rightMarginPins: 0,
|
|
@@ -56,7 +72,6 @@ export const MEDIA = {
|
|
|
56
72
|
name: '62mm continuous (DK-22205)',
|
|
57
73
|
type: 'continuous',
|
|
58
74
|
widthMm: 62,
|
|
59
|
-
lengthMm: 0,
|
|
60
75
|
printAreaDots: 696,
|
|
61
76
|
leftMarginPins: 12,
|
|
62
77
|
rightMarginPins: 12,
|
|
@@ -66,18 +81,19 @@ export const MEDIA = {
|
|
|
66
81
|
name: '62mm continuous two-color (DK-22251)',
|
|
67
82
|
type: 'continuous',
|
|
68
83
|
widthMm: 62,
|
|
69
|
-
|
|
84
|
+
palette: [
|
|
85
|
+
{ name: 'black', rgb: [0, 0, 0] },
|
|
86
|
+
{ name: 'red', rgb: [255, 0, 0] },
|
|
87
|
+
],
|
|
70
88
|
printAreaDots: 696,
|
|
71
89
|
leftMarginPins: 12,
|
|
72
90
|
rightMarginPins: 12,
|
|
73
|
-
twoColorTape: true,
|
|
74
91
|
},
|
|
75
92
|
260: {
|
|
76
93
|
id: 260,
|
|
77
94
|
name: '102mm continuous (DK-22243)',
|
|
78
95
|
type: 'continuous',
|
|
79
96
|
widthMm: 102,
|
|
80
|
-
lengthMm: 0,
|
|
81
97
|
printAreaDots: 1164,
|
|
82
98
|
leftMarginPins: 76,
|
|
83
99
|
rightMarginPins: 56,
|
|
@@ -88,7 +104,9 @@ export const MEDIA = {
|
|
|
88
104
|
name: '17×54mm die-cut (DK-11204)',
|
|
89
105
|
type: 'die-cut',
|
|
90
106
|
widthMm: 17,
|
|
91
|
-
|
|
107
|
+
heightMm: 54,
|
|
108
|
+
defaultOrientation: 'horizontal',
|
|
109
|
+
cornerRadiusMm: 3,
|
|
92
110
|
printAreaDots: 165,
|
|
93
111
|
leftMarginPins: 0,
|
|
94
112
|
rightMarginPins: 0,
|
|
@@ -99,7 +117,9 @@ export const MEDIA = {
|
|
|
99
117
|
name: '17×87mm die-cut (DK-11203)',
|
|
100
118
|
type: 'die-cut',
|
|
101
119
|
widthMm: 17,
|
|
102
|
-
|
|
120
|
+
heightMm: 87,
|
|
121
|
+
defaultOrientation: 'horizontal',
|
|
122
|
+
cornerRadiusMm: 3,
|
|
103
123
|
printAreaDots: 165,
|
|
104
124
|
leftMarginPins: 0,
|
|
105
125
|
rightMarginPins: 0,
|
|
@@ -110,7 +130,9 @@ export const MEDIA = {
|
|
|
110
130
|
name: '23×23mm die-cut',
|
|
111
131
|
type: 'die-cut',
|
|
112
132
|
widthMm: 23,
|
|
113
|
-
|
|
133
|
+
heightMm: 23,
|
|
134
|
+
defaultOrientation: 'horizontal',
|
|
135
|
+
cornerRadiusMm: 3,
|
|
114
136
|
printAreaDots: 236,
|
|
115
137
|
leftMarginPins: 0,
|
|
116
138
|
rightMarginPins: 0,
|
|
@@ -121,7 +143,9 @@ export const MEDIA = {
|
|
|
121
143
|
name: '29×90mm die-cut (DK-11201)',
|
|
122
144
|
type: 'die-cut',
|
|
123
145
|
widthMm: 29,
|
|
124
|
-
|
|
146
|
+
heightMm: 90,
|
|
147
|
+
defaultOrientation: 'horizontal',
|
|
148
|
+
cornerRadiusMm: 3,
|
|
125
149
|
printAreaDots: 306,
|
|
126
150
|
leftMarginPins: 0,
|
|
127
151
|
rightMarginPins: 0,
|
|
@@ -132,7 +156,9 @@ export const MEDIA = {
|
|
|
132
156
|
name: '38×90mm die-cut (DK-11218)',
|
|
133
157
|
type: 'die-cut',
|
|
134
158
|
widthMm: 38,
|
|
135
|
-
|
|
159
|
+
heightMm: 90,
|
|
160
|
+
defaultOrientation: 'horizontal',
|
|
161
|
+
cornerRadiusMm: 3,
|
|
136
162
|
printAreaDots: 413,
|
|
137
163
|
leftMarginPins: 0,
|
|
138
164
|
rightMarginPins: 0,
|
|
@@ -143,7 +169,9 @@ export const MEDIA = {
|
|
|
143
169
|
name: '39×48mm die-cut (DK-11219)',
|
|
144
170
|
type: 'die-cut',
|
|
145
171
|
widthMm: 39,
|
|
146
|
-
|
|
172
|
+
heightMm: 48,
|
|
173
|
+
defaultOrientation: 'horizontal',
|
|
174
|
+
cornerRadiusMm: 3,
|
|
147
175
|
printAreaDots: 425,
|
|
148
176
|
leftMarginPins: 0,
|
|
149
177
|
rightMarginPins: 0,
|
|
@@ -154,7 +182,9 @@ export const MEDIA = {
|
|
|
154
182
|
name: '52×29mm die-cut',
|
|
155
183
|
type: 'die-cut',
|
|
156
184
|
widthMm: 52,
|
|
157
|
-
|
|
185
|
+
heightMm: 29,
|
|
186
|
+
defaultOrientation: 'horizontal',
|
|
187
|
+
cornerRadiusMm: 3,
|
|
158
188
|
printAreaDots: 578,
|
|
159
189
|
leftMarginPins: 0,
|
|
160
190
|
rightMarginPins: 0,
|
|
@@ -165,7 +195,9 @@ export const MEDIA = {
|
|
|
165
195
|
name: '62×29mm die-cut (DK-11209)',
|
|
166
196
|
type: 'die-cut',
|
|
167
197
|
widthMm: 62,
|
|
168
|
-
|
|
198
|
+
heightMm: 29,
|
|
199
|
+
defaultOrientation: 'horizontal',
|
|
200
|
+
cornerRadiusMm: 3,
|
|
169
201
|
printAreaDots: 696,
|
|
170
202
|
leftMarginPins: 0,
|
|
171
203
|
rightMarginPins: 0,
|
|
@@ -176,7 +208,9 @@ export const MEDIA = {
|
|
|
176
208
|
name: '62×100mm die-cut (DK-11202)',
|
|
177
209
|
type: 'die-cut',
|
|
178
210
|
widthMm: 62,
|
|
179
|
-
|
|
211
|
+
heightMm: 100,
|
|
212
|
+
defaultOrientation: 'horizontal',
|
|
213
|
+
cornerRadiusMm: 3,
|
|
180
214
|
printAreaDots: 696,
|
|
181
215
|
leftMarginPins: 0,
|
|
182
216
|
rightMarginPins: 0,
|
|
@@ -187,7 +221,9 @@ export const MEDIA = {
|
|
|
187
221
|
name: '102×51mm die-cut (DK-11240)',
|
|
188
222
|
type: 'die-cut',
|
|
189
223
|
widthMm: 102,
|
|
190
|
-
|
|
224
|
+
heightMm: 51,
|
|
225
|
+
defaultOrientation: 'horizontal',
|
|
226
|
+
cornerRadiusMm: 3,
|
|
191
227
|
printAreaDots: 1164,
|
|
192
228
|
leftMarginPins: 0,
|
|
193
229
|
rightMarginPins: 0,
|
|
@@ -198,7 +234,9 @@ export const MEDIA = {
|
|
|
198
234
|
name: '102×152mm die-cut (DK-11241)',
|
|
199
235
|
type: 'die-cut',
|
|
200
236
|
widthMm: 102,
|
|
201
|
-
|
|
237
|
+
heightMm: 152,
|
|
238
|
+
defaultOrientation: 'horizontal',
|
|
239
|
+
cornerRadiusMm: 3,
|
|
202
240
|
printAreaDots: 1164,
|
|
203
241
|
leftMarginPins: 0,
|
|
204
242
|
rightMarginPins: 0,
|
|
@@ -209,7 +247,8 @@ export const MEDIA = {
|
|
|
209
247
|
name: '12mm Ø die-cut',
|
|
210
248
|
type: 'die-cut',
|
|
211
249
|
widthMm: 12,
|
|
212
|
-
|
|
250
|
+
heightMm: 12,
|
|
251
|
+
cornerRadiusMm: 6,
|
|
213
252
|
printAreaDots: 94,
|
|
214
253
|
leftMarginPins: 0,
|
|
215
254
|
rightMarginPins: 0,
|
|
@@ -220,7 +259,8 @@ export const MEDIA = {
|
|
|
220
259
|
name: '24mm Ø die-cut (DK-11221)',
|
|
221
260
|
type: 'die-cut',
|
|
222
261
|
widthMm: 24,
|
|
223
|
-
|
|
262
|
+
heightMm: 24,
|
|
263
|
+
cornerRadiusMm: 12,
|
|
224
264
|
printAreaDots: 236,
|
|
225
265
|
leftMarginPins: 0,
|
|
226
266
|
rightMarginPins: 0,
|
|
@@ -231,17 +271,45 @@ export const MEDIA = {
|
|
|
231
271
|
name: '58mm Ø die-cut (DK-11207)',
|
|
232
272
|
type: 'die-cut',
|
|
233
273
|
widthMm: 58,
|
|
234
|
-
|
|
274
|
+
heightMm: 58,
|
|
275
|
+
cornerRadiusMm: 29,
|
|
235
276
|
printAreaDots: 618,
|
|
236
277
|
leftMarginPins: 0,
|
|
237
278
|
rightMarginPins: 0,
|
|
238
279
|
dieCutMaskedAreaDots: 618,
|
|
239
280
|
},
|
|
240
281
|
};
|
|
282
|
+
/**
|
|
283
|
+
* Default media when `createPreview()` is called without media and
|
|
284
|
+
* without a detected roll. 62mm continuous (DK-22205) is the common
|
|
285
|
+
* single-colour shipping roll.
|
|
286
|
+
*/
|
|
287
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- DK-22205 is a hard-coded registry key
|
|
288
|
+
export const DEFAULT_MEDIA = MEDIA[259];
|
|
241
289
|
export function findMedia(id) {
|
|
242
290
|
return MEDIA[id];
|
|
243
291
|
}
|
|
244
292
|
export function findMediaByWidth(widthMm, type) {
|
|
245
293
|
return Object.values(MEDIA).filter(m => m.widthMm === widthMm && m.type === type);
|
|
246
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Match status-response dimensions to a media registry entry.
|
|
297
|
+
*
|
|
298
|
+
* @param widthMm media width in mm (status byte 10)
|
|
299
|
+
* @param heightMm media length in mm (status byte 17) — 0 = continuous
|
|
300
|
+
* @param twoColorMode true when the status response indicates the
|
|
301
|
+
* printer is configured for two-colour media. When
|
|
302
|
+
* both DK-22205 (259) and DK-22251 (251) match the
|
|
303
|
+
* dimensions, the flag picks the right one.
|
|
304
|
+
*/
|
|
305
|
+
export function findMediaByDimensions(widthMm, heightMm, twoColorMode = false) {
|
|
306
|
+
if (heightMm === 0) {
|
|
307
|
+
const continuousMatches = Object.values(MEDIA).filter(m => m.type === 'continuous' && m.widthMm === widthMm);
|
|
308
|
+
if (continuousMatches.length === 0)
|
|
309
|
+
return undefined;
|
|
310
|
+
const preferred = continuousMatches.find(m => (m.palette !== undefined) === twoColorMode);
|
|
311
|
+
return preferred ?? continuousMatches[0];
|
|
312
|
+
}
|
|
313
|
+
return Object.values(MEDIA).find(m => m.type === 'die-cut' && m.widthMm === widthMm && m.heightMm === heightMm);
|
|
314
|
+
}
|
|
247
315
|
//# sourceMappingURL=media.js.map
|
package/dist/media.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.js","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../src/media.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { RotateDirection } from '@thermal-label/contracts';
|
|
2
|
+
/**
|
|
3
|
+
* Direction the Brother QL print head rotates landscape input.
|
|
4
|
+
*
|
|
5
|
+
* `90` = clockwise. Verified once on hardware with a die-cut "F"
|
|
6
|
+
* landscape print (see plan §6 step 1). Identical across every QL
|
|
7
|
+
* model — this is a print-head/leading-edge mechanical fact, not a
|
|
8
|
+
* per-media setting.
|
|
9
|
+
*/
|
|
10
|
+
export declare const ROTATE_DIRECTION: RotateDirection;
|
|
11
|
+
//# sourceMappingURL=orientation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orientation.d.ts","sourceRoot":"","sources":["../src/orientation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,eAAoB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Direction the Brother QL print head rotates landscape input.
|
|
3
|
+
*
|
|
4
|
+
* `90` = clockwise. Verified once on hardware with a die-cut "F"
|
|
5
|
+
* landscape print (see plan §6 step 1). Identical across every QL
|
|
6
|
+
* model — this is a print-head/leading-edge mechanical fact, not a
|
|
7
|
+
* per-media setting.
|
|
8
|
+
*/
|
|
9
|
+
export const ROTATE_DIRECTION = 90;
|
|
10
|
+
//# sourceMappingURL=orientation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orientation.js","sourceRoot":"","sources":["../src/orientation.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TIFF-style PackBits row encoder used by Brother QL when compression
|
|
3
|
+
* mode (`M 02`, emitted by `buildCompression(true)`) is enabled for a job.
|
|
4
|
+
*
|
|
5
|
+
* Header byte `n` (interpreted as a signed int8):
|
|
6
|
+
* n in [0, 127]: literal run — the next `n + 1` bytes follow verbatim.
|
|
7
|
+
* n in [-127, -1]: repeat run — the next byte is repeated `1 - n` times.
|
|
8
|
+
* n = -128: no-op. Unused by this encoder.
|
|
9
|
+
*
|
|
10
|
+
* The encoder switches to repeat mode for runs of two or more identical
|
|
11
|
+
* bytes (a 2-byte repeat costs 2 wire bytes; the equivalent 2-byte literal
|
|
12
|
+
* would cost 3). Both run kinds are capped at 128 bytes to fit the header.
|
|
13
|
+
*
|
|
14
|
+
* For a typical Brother QL raster row (90 bytes, mostly zeros in margins
|
|
15
|
+
* and long runs of `0x00` / `0xff` in print area), this compresses to 5–15
|
|
16
|
+
* bytes — a 6–18× reduction. Worst-case for highly random input is one
|
|
17
|
+
* extra byte per 128 (the literal-mode header), i.e. < 1 % expansion.
|
|
18
|
+
*/
|
|
19
|
+
export declare function packBits(input: Uint8Array): Uint8Array;
|
|
20
|
+
//# sourceMappingURL=pack-bits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack-bits.d.ts","sourceRoot":"","sources":["../src/pack-bits.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAsCtD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion --
|
|
2
|
+
* `noUncheckedIndexedAccess` types Uint8Array reads as `number | undefined`
|
|
3
|
+
* but every index in this file is bounded by `i < input.length` or
|
|
4
|
+
* `runEnd < input.length` checks. The `!` assertions collapse the
|
|
5
|
+
* unreachable `undefined` branches so branch coverage doesn't count them.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* TIFF-style PackBits row encoder used by Brother QL when compression
|
|
9
|
+
* mode (`M 02`, emitted by `buildCompression(true)`) is enabled for a job.
|
|
10
|
+
*
|
|
11
|
+
* Header byte `n` (interpreted as a signed int8):
|
|
12
|
+
* n in [0, 127]: literal run — the next `n + 1` bytes follow verbatim.
|
|
13
|
+
* n in [-127, -1]: repeat run — the next byte is repeated `1 - n` times.
|
|
14
|
+
* n = -128: no-op. Unused by this encoder.
|
|
15
|
+
*
|
|
16
|
+
* The encoder switches to repeat mode for runs of two or more identical
|
|
17
|
+
* bytes (a 2-byte repeat costs 2 wire bytes; the equivalent 2-byte literal
|
|
18
|
+
* would cost 3). Both run kinds are capped at 128 bytes to fit the header.
|
|
19
|
+
*
|
|
20
|
+
* For a typical Brother QL raster row (90 bytes, mostly zeros in margins
|
|
21
|
+
* and long runs of `0x00` / `0xff` in print area), this compresses to 5–15
|
|
22
|
+
* bytes — a 6–18× reduction. Worst-case for highly random input is one
|
|
23
|
+
* extra byte per 128 (the literal-mode header), i.e. < 1 % expansion.
|
|
24
|
+
*/
|
|
25
|
+
export function packBits(input) {
|
|
26
|
+
if (input.length === 0)
|
|
27
|
+
return new Uint8Array(0);
|
|
28
|
+
const out = [];
|
|
29
|
+
let i = 0;
|
|
30
|
+
while (i < input.length) {
|
|
31
|
+
// How many identical bytes start at position i (cap at 128).
|
|
32
|
+
let runEnd = i + 1;
|
|
33
|
+
while (runEnd < input.length && runEnd - i < 128 && input[runEnd] === input[i]) {
|
|
34
|
+
runEnd++;
|
|
35
|
+
}
|
|
36
|
+
const runLen = runEnd - i;
|
|
37
|
+
if (runLen >= 2) {
|
|
38
|
+
// Repeat run: header is signed -(runLen - 1).
|
|
39
|
+
out.push((1 - runLen) & 0xff);
|
|
40
|
+
out.push(input[i]);
|
|
41
|
+
i = runEnd;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
// Otherwise emit a literal run. Stop at 128 bytes, or right before a
|
|
45
|
+
// 2+ repeat run starts (cheaper to encode that separately).
|
|
46
|
+
let litEnd = i + 1;
|
|
47
|
+
while (litEnd < input.length && litEnd - i < 128) {
|
|
48
|
+
if (litEnd + 1 < input.length && input[litEnd] === input[litEnd + 1]) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
litEnd++;
|
|
52
|
+
}
|
|
53
|
+
const litLen = litEnd - i;
|
|
54
|
+
out.push(litLen - 1);
|
|
55
|
+
for (let x = i; x < litEnd; x++)
|
|
56
|
+
out.push(input[x]);
|
|
57
|
+
i = litEnd;
|
|
58
|
+
}
|
|
59
|
+
return new Uint8Array(out);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=pack-bits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack-bits.js","sourceRoot":"","sources":["../src/pack-bits.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAiB;IACxC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAEjD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,CAAC,GAAG,CAAC,CAAC;IAEV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACxB,6DAA6D;QAC7D,IAAI,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/E,MAAM,EAAE,CAAC;QACX,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC;QAE1B,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAChB,8CAA8C;YAC9C,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;YACpB,CAAC,GAAG,MAAM,CAAC;YACX,SAAS;QACX,CAAC;QAED,qEAAqE;QACrE,4DAA4D;QAC5D,IAAI,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;QACnB,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,MAAM,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;YACjD,IAAI,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;gBACrE,MAAM;YACR,CAAC;YACD,MAAM,EAAE,CAAC;QACX,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC;QAC1B,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;QACrD,CAAC,GAAG,MAAM,CAAC;IACb,CAAC;IAED,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RawImageData } from '@mbtech-nl/bitmap';
|
|
2
|
+
import type { PreviewResult } from '@thermal-label/contracts';
|
|
3
|
+
import type { BrotherQLMedia } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Offline preview without a live printer connection.
|
|
6
|
+
*
|
|
7
|
+
* Multi-ink aware: when `media.palette` is defined (DK-22251 today),
|
|
8
|
+
* the image is split per-plane via `renderMultiPlaneImage()` — the
|
|
9
|
+
* same code path `print()` takes for that media. Single-ink media
|
|
10
|
+
* returns one black plane via dithered `renderImage`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function createPreviewOffline(image: RawImageData, media: BrotherQLMedia): PreviewResult;
|
|
13
|
+
//# sourceMappingURL=preview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../src/preview.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,cAAc,GAAG,aAAa,CAqB9F"}
|
package/dist/preview.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { renderImage, renderMultiPlaneImage } from '@mbtech-nl/bitmap';
|
|
2
|
+
/**
|
|
3
|
+
* Offline preview without a live printer connection.
|
|
4
|
+
*
|
|
5
|
+
* Multi-ink aware: when `media.palette` is defined (DK-22251 today),
|
|
6
|
+
* the image is split per-plane via `renderMultiPlaneImage()` — the
|
|
7
|
+
* same code path `print()` takes for that media. Single-ink media
|
|
8
|
+
* returns one black plane via dithered `renderImage`.
|
|
9
|
+
*/
|
|
10
|
+
export function createPreviewOffline(image, media) {
|
|
11
|
+
if (media.palette) {
|
|
12
|
+
const planes = renderMultiPlaneImage(image, {
|
|
13
|
+
palette: media.palette,
|
|
14
|
+
});
|
|
15
|
+
return {
|
|
16
|
+
planes: [
|
|
17
|
+
{ name: 'black', bitmap: planes.black, displayColor: '#000000' },
|
|
18
|
+
{ name: 'red', bitmap: planes.red, displayColor: '#ff0000' },
|
|
19
|
+
],
|
|
20
|
+
media,
|
|
21
|
+
assumed: false,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const bitmap = renderImage(image, { dither: true });
|
|
25
|
+
return {
|
|
26
|
+
planes: [{ name: 'black', bitmap, displayColor: '#000000' }],
|
|
27
|
+
media,
|
|
28
|
+
assumed: false,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../src/preview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAKvE;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAmB,EAAE,KAAqB;IAC7E,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,EAAE;YAC1C,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB,CAAyC,CAAC;QAC3C,OAAO;YACL,MAAM,EAAE;gBACN,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE;gBAChE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE;aAC7D;YACD,KAAK;YACL,OAAO,EAAE,KAAK;SACf,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,OAAO;QACL,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;QAC5D,KAAK;QACL,OAAO,EAAE,KAAK;KACf,CAAC;AACJ,CAAC"}
|
package/dist/protocol.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { BrotherQLMedia, PageData, JobOptions } from './types.js';
|
|
2
2
|
export declare function buildInvalidate(): Uint8Array;
|
|
3
3
|
export declare function buildStatusRequest(): Uint8Array;
|
|
4
4
|
export declare function buildInitialize(): Uint8Array;
|
|
5
5
|
export declare function buildRasterMode(): Uint8Array;
|
|
6
6
|
export declare function buildStatusNotification(enabled: boolean): Uint8Array;
|
|
7
|
-
export declare function buildPrintInfo(media:
|
|
7
|
+
export declare function buildPrintInfo(media: BrotherQLMedia, rowCount: number, pageIndex: number): Uint8Array;
|
|
8
8
|
export declare function buildVariousMode(autoCut: boolean): Uint8Array;
|
|
9
9
|
export declare function buildExpandedMode(cutAtEnd: boolean, highRes: boolean, twoColor?: boolean): Uint8Array;
|
|
10
10
|
export declare function buildCutEach(n: number): Uint8Array;
|
package/dist/protocol.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAEpF,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAED,wBAAgB,kBAAkB,IAAI,UAAU,CAE/C;AAED,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAED,wBAAgB,eAAe,IAAI,UAAU,CAE5C;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAEpE;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,UAAU,CAsBZ;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAE7D;AAED,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO,EAChB,QAAQ,UAAQ,GACf,UAAU,CAMZ;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,UAAU,CAElD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CAE7D;AAKD,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,OAAO,GAAG,KAAK,EACtB,QAAQ,UAAQ,GACf,UAAU,CAYZ;AAED,wBAAgB,YAAY,IAAI,UAAU,CAEzC;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,OAAO,GAAG,UAAU,CAEjE;AA8BD,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,OAAO,GAAE,UAAe,GAAG,UAAU,CAkFjF"}
|
package/dist/protocol.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getRow, createBitmap } from '@mbtech-nl/bitmap';
|
|
2
|
-
import {} from './
|
|
2
|
+
import { packBits } from './pack-bits.js';
|
|
3
3
|
export function buildInvalidate() {
|
|
4
4
|
return new Uint8Array(200);
|
|
5
5
|
}
|
|
@@ -28,7 +28,7 @@ export function buildPrintInfo(media, rowCount, pageIndex) {
|
|
|
28
28
|
buf[3] = validFlags;
|
|
29
29
|
buf[4] = mediaType;
|
|
30
30
|
buf[5] = media.widthMm;
|
|
31
|
-
buf[6] = media.
|
|
31
|
+
buf[6] = media.heightMm ?? 0;
|
|
32
32
|
// rowCount little-endian at bytes 7-8 (offsets 4-5 in param block)
|
|
33
33
|
buf[7] = rowCount & 0xff;
|
|
34
34
|
buf[8] = (rowCount >> 8) & 0xff;
|
|
@@ -128,11 +128,11 @@ export function encodeJob(pages, options = {}) {
|
|
|
128
128
|
const marginDots = opts.marginDots ?? 35;
|
|
129
129
|
const compress = opts.compress ?? false;
|
|
130
130
|
const { bitmap, media } = page;
|
|
131
|
-
//
|
|
131
|
+
// Multi-ink media (e.g. DK-22251) requires two-color mode even for black-only jobs.
|
|
132
132
|
// Auto-create an empty red plane when the tape demands it but caller didn't supply one.
|
|
133
|
-
const
|
|
134
|
-
const
|
|
135
|
-
|
|
133
|
+
const multiInk = media.palette !== undefined;
|
|
134
|
+
const twoColor = page.redBitmap !== undefined || multiInk;
|
|
135
|
+
const redBitmap = page.redBitmap ?? (multiInk ? createBitmap(bitmap.widthPx, bitmap.heightPx) : undefined);
|
|
136
136
|
if (twoColor && redBitmap !== undefined) {
|
|
137
137
|
if (bitmap.widthPx !== redBitmap.widthPx || bitmap.heightPx !== redBitmap.heightPx) {
|
|
138
138
|
throw new Error('Two-color bitmaps must have identical dimensions');
|
|
@@ -154,16 +154,22 @@ export function encodeJob(pages, options = {}) {
|
|
|
154
154
|
const rowByteLen = Math.ceil(totalPins / 8);
|
|
155
155
|
// Rows interleaved per raster line (matches Python brother_ql behaviour).
|
|
156
156
|
// Two-color: black row then red row for each line. Single-color: black only.
|
|
157
|
+
// When `compress` is on, each row's bytes are PackBits-encoded and the
|
|
158
|
+
// raster-row LEN byte carries the compressed length. The printer was
|
|
159
|
+
// already switched into compression mode by `buildCompression(true)`
|
|
160
|
+
// above, so it expects every subsequent row to be PackBits.
|
|
157
161
|
for (let r = 0; r < rowCount; r++) {
|
|
158
162
|
const blackSrc = getRow(bitmap, r);
|
|
159
163
|
const blackBytes = new Uint8Array(rowByteLen);
|
|
160
164
|
placeBits(blackSrc, bitmap.widthPx, blackBytes, media.leftMarginPins);
|
|
161
|
-
|
|
165
|
+
const blackPayload = compress ? packBits(blackBytes) : blackBytes;
|
|
166
|
+
chunks.push(buildRasterRow(blackPayload, 'black', twoColor));
|
|
162
167
|
if (twoColor && redBitmap !== undefined) {
|
|
163
168
|
const redSrc = getRow(redBitmap, r);
|
|
164
169
|
const redBytes = new Uint8Array(rowByteLen);
|
|
165
170
|
placeBits(redSrc, redBitmap.widthPx, redBytes, media.leftMarginPins);
|
|
166
|
-
|
|
171
|
+
const redPayload = compress ? packBits(redBytes) : redBytes;
|
|
172
|
+
chunks.push(buildRasterRow(redPayload, 'red', twoColor));
|
|
167
173
|
}
|
|
168
174
|
}
|
|
169
175
|
chunks.push(buildPrintCommand(isLastPage));
|