@thermal-print/escpos 0.1.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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +193 -0
  3. package/dist/command-adapters/escbematech-adapter.d.ts +30 -0
  4. package/dist/command-adapters/escbematech-adapter.d.ts.map +1 -0
  5. package/dist/command-adapters/escbematech-adapter.js +175 -0
  6. package/dist/command-adapters/escpos-adapter.d.ts +25 -0
  7. package/dist/command-adapters/escpos-adapter.d.ts.map +1 -0
  8. package/dist/command-adapters/escpos-adapter.js +144 -0
  9. package/dist/command-adapters/index.d.ts +11 -0
  10. package/dist/command-adapters/index.d.ts.map +1 -0
  11. package/dist/command-adapters/index.js +14 -0
  12. package/dist/command-adapters/types.d.ts +78 -0
  13. package/dist/command-adapters/types.d.ts.map +1 -0
  14. package/dist/command-adapters/types.js +8 -0
  15. package/dist/commands/escbematech.d.ts +867 -0
  16. package/dist/commands/escbematech.d.ts.map +1 -0
  17. package/dist/commands/escbematech.js +1387 -0
  18. package/dist/commands/escpos.d.ts +582 -0
  19. package/dist/commands/escpos.d.ts.map +1 -0
  20. package/dist/commands/escpos.js +1048 -0
  21. package/dist/converter.d.ts +47 -0
  22. package/dist/converter.d.ts.map +1 -0
  23. package/dist/converter.js +92 -0
  24. package/dist/encodings/cp860.d.ts +25 -0
  25. package/dist/encodings/cp860.d.ts.map +1 -0
  26. package/dist/encodings/cp860.js +187 -0
  27. package/dist/generator.d.ts +118 -0
  28. package/dist/generator.d.ts.map +1 -0
  29. package/dist/generator.js +383 -0
  30. package/dist/index.d.ts +17 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +55 -0
  33. package/dist/styles.d.ts +72 -0
  34. package/dist/styles.d.ts.map +1 -0
  35. package/dist/styles.js +210 -0
  36. package/dist/traverser.d.ts +60 -0
  37. package/dist/traverser.d.ts.map +1 -0
  38. package/dist/traverser.js +285 -0
  39. package/dist/types.d.ts +21 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +5 -0
  42. package/package.json +31 -0
@@ -0,0 +1,1048 @@
1
+ "use strict";
2
+ /**
3
+ * ESC/POS Command Set
4
+ *
5
+ * Comprehensive ESC/POS thermal printer command bytes for MP-4200 TH.
6
+ * Reference: ESC/POS Command Manual
7
+ *
8
+ * This file contains all documented ESC/POS commands organized by category.
9
+ * Commands are compatible with standard ESC/POS thermal printers.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.UNDERLINE_2DOT = exports.UNDERLINE_1DOT = exports.UPSIDE_DOWN_OFF = exports.UPSIDE_DOWN_ON = exports.ROTATE_90_OFF = exports.ROTATE_90_ON = exports.SELECT_FONT_D = exports.selectFont = exports.CharacterFont = exports.DOUBLE_STRIKE_OFF = exports.DOUBLE_STRIKE_ON = exports.CLEAR_TABS = exports.setTabPositions = exports.setCharacterSpacing = exports.setRelativePosition = exports.setAbsolutePosition = exports.realtimePulse = exports.realtimeRequest = exports.transmitRealtimeStatus = exports.encodeText = exports.generateRasterImage = exports.generateQRCode = exports.CODEPAGE_WPC1252 = exports.CODEPAGE_CP860 = exports.CODEPAGE_CP437 = exports.cutWithFeed = exports.CUT_PARTIAL = exports.CUT_FULL = exports.feedLines = exports.LINE_FEED = exports.LINE_SPACING_DEFAULT = exports.setLineSpacing = exports.calculateCharacterSize = exports.UNDERLINE_OFF = exports.UNDERLINE_ON = exports.BOLD_OFF = exports.BOLD_ON = exports.ALIGN_RIGHT = exports.ALIGN_CENTER = exports.ALIGN_LEFT = exports.INIT = exports.GS = exports.FS = exports.ESC = exports.CAN = exports.DLE = exports.CR = exports.FF = exports.LF = exports.HT = void 0;
13
+ exports.selectCharacterSize = exports.generatePDF417 = exports.printPDF417 = exports.storePDF417Data = exports.setPDF417ErrorCorrection = exports.setPDF417RowHeight = exports.setPDF417Width = exports.setPDF417Rows = exports.setPDF417Columns = exports.printBarcodeCODE128 = exports.printBarcodeCODE93 = exports.printBarcodeCODABAR = exports.printBarcodeITF = exports.printBarcodeCODE39 = exports.printBarcodeEAN8 = exports.printBarcodeEAN13 = exports.printBarcodeUPCE = exports.printBarcodeUPCA = exports.printBarcodeWithLength = exports.printBarcode = exports.BarcodeType = exports.setBarcodeWidth = exports.setBarcodeHeight = exports.setBarcodeFont = exports.setBarcodeHRI = exports.BarcodeHRIPosition = exports.defineNVBitImage = exports.printNVBitImage = exports.printDownloadedBitImage = exports.DownloadedImageMode = exports.defineDownloadedBitImage = exports.printBitImage = exports.BitImageMode = exports.setCodePage = exports.CodePage = exports.selectInternationalCharset = exports.InternationalCharset = exports.disablePanelButtons = exports.enablePanelButtons = exports.selectPaperSensorStop = exports.selectPaperSensorOutput = exports.generatePulse = exports.selectPeripheral = exports.cutAndFeedPartial = exports.cutAndFeedFull = exports.CUT_PARTIAL_ESC = exports.CUT_FULL_ESC = exports.printAndReverseFeed = exports.printAndFeed = exports.LINE_SPACING_DEFAULT_ALT = void 0;
14
+ exports.executeTestPrint = exports.CANCEL = exports.UNIDIRECTIONAL_OFF = exports.UNIDIRECTIONAL_ON = exports.executeMacro = exports.END_MACRO = exports.START_MACRO = exports.setPrintingAreaWidth = exports.setLeftMargin = exports.requestStatus = exports.StatusType = exports.requestPrinterID = exports.PrinterIDType = exports.disableASB = exports.enableASB = exports.setCharacterSmoothing = exports.setCharacterColor = exports.REVERSE_PRINT_OFF = exports.REVERSE_PRINT_ON = void 0;
15
+ const cp860_1 = require("../encodings/cp860");
16
+ // ============================================================================
17
+ // CONTROL CHARACTERS
18
+ // ============================================================================
19
+ exports.HT = 0x09; // Horizontal Tab
20
+ exports.LF = 0x0a; // Line Feed
21
+ exports.FF = 0x0c; // Form Feed
22
+ exports.CR = 0x0d; // Carriage Return
23
+ exports.DLE = 0x10; // Data Link Escape
24
+ exports.CAN = 0x18; // Cancel
25
+ exports.ESC = 0x1b; // Escape
26
+ exports.FS = 0x1c; // File Separator
27
+ exports.GS = 0x1d; // Group Separator
28
+ // Initialize printer
29
+ // ESC @ - Reset printer to default state
30
+ exports.INIT = [exports.ESC, 0x40];
31
+ // Text alignment
32
+ // ESC a n - Set text alignment (n: 0=left, 1=center, 2=right)
33
+ exports.ALIGN_LEFT = [exports.ESC, 0x61, 0x00];
34
+ exports.ALIGN_CENTER = [exports.ESC, 0x61, 0x01];
35
+ exports.ALIGN_RIGHT = [exports.ESC, 0x61, 0x02];
36
+ // Text emphasis
37
+ // ESC E n - Turn bold on/off (n: 0=off, 1=on)
38
+ exports.BOLD_ON = [exports.ESC, 0x45, 0x01];
39
+ exports.BOLD_OFF = [exports.ESC, 0x45, 0x00];
40
+ // ESC - n - Turn underline on/off (n: 0=off, 1=on, 2=double)
41
+ exports.UNDERLINE_ON = [exports.ESC, 0x2d, 0x01];
42
+ exports.UNDERLINE_OFF = [exports.ESC, 0x2d, 0x00];
43
+ /**
44
+ * Calculate character size using ESC ! command (compatible with more printers)
45
+ * ESC ! only supports up to 2x2 character size
46
+ * @param width - Width multiplier (1 or 2)
47
+ * @param height - Height multiplier (1 or 2)
48
+ * @param bold - Whether text should be bold (optional, default: false)
49
+ * @returns ESC/POS ESC ! n command bytes
50
+ */
51
+ const calculateCharacterSize = (width, height, bold = false) => {
52
+ // ESC ! command format:
53
+ // Bit 0: Character font (0=Font A, 1=Font B)
54
+ // Bit 3: Emphasis (bold)
55
+ // Bit 4: Double-height
56
+ // Bit 5: Double-width
57
+ // Bit 7: Underline
58
+ // Use Font B as base (9×17 dots)
59
+ // Note: Font D (16×24 dots) is selected separately via ESC U command
60
+ // and will override this font selection
61
+ let n = 0x01; // Font B
62
+ // Set double-height bit (bit 4 = 0x10)
63
+ if (height >= 2) {
64
+ n |= 0x10;
65
+ }
66
+ // Set double-width bit (bit 5 = 0x20)
67
+ if (width >= 2) {
68
+ n |= 0x20;
69
+ }
70
+ // Set bold/emphasis bit (bit 3 = 0x08)
71
+ if (bold) {
72
+ n |= 0x08;
73
+ }
74
+ return [exports.ESC, 0x21, n];
75
+ };
76
+ exports.calculateCharacterSize = calculateCharacterSize;
77
+ // Line spacing
78
+ // ESC 3 n - Set line spacing to n dots
79
+ // Note: Using minimum of 18 dots for consistency with ESC/Bematech protocol
80
+ const setLineSpacing = (dots) => {
81
+ const value = Math.max(18, Math.min(255, dots));
82
+ return [exports.ESC, 0x33, value];
83
+ };
84
+ exports.setLineSpacing = setLineSpacing;
85
+ // Default line spacing (30 dots = ~3.75mm)
86
+ exports.LINE_SPACING_DEFAULT = [exports.ESC, 0x33, 30];
87
+ // Paper control
88
+ // LF - Line feed (move paper up one line)
89
+ exports.LINE_FEED = [exports.LF];
90
+ // ESC d n - Print and feed n lines
91
+ const feedLines = (lines) => [exports.ESC, 0x64, lines];
92
+ exports.feedLines = feedLines;
93
+ // GS V m - Paper cut
94
+ // m: 0=full cut, 1=partial cut
95
+ exports.CUT_FULL = [exports.GS, 0x56, 0x00];
96
+ exports.CUT_PARTIAL = [exports.GS, 0x56, 0x01];
97
+ // Alternative: GS V m n - Cut with feed
98
+ const cutWithFeed = (lines) => [exports.GS, 0x56, 0x41, lines];
99
+ exports.cutWithFeed = cutWithFeed;
100
+ // Character code table
101
+ // ESC t n - Select character code table
102
+ // Common tables: 0=CP437, 3=CP860 (Portuguese), 16=WPC1252
103
+ exports.CODEPAGE_CP437 = [exports.ESC, 0x74, 0x00]; // USA
104
+ exports.CODEPAGE_CP860 = [exports.ESC, 0x74, 0x03]; // Portuguese
105
+ exports.CODEPAGE_WPC1252 = [exports.ESC, 0x74, 0x10]; // Windows Latin-1
106
+ // Barcode and QR Code
107
+ // QR Code: GS ( k pL pH cn fn n1 n2 [data]
108
+ // This is a complex command, implemented as a function
109
+ /**
110
+ * Generate QR Code command
111
+ * @param data - QR code data (URL or text)
112
+ * @param size - QR code module size (1-16, default 6)
113
+ * @returns ESC/POS command bytes
114
+ */
115
+ const generateQRCode = (data, size = 6) => {
116
+ const commands = [];
117
+ // QR Code model (function 165, cn=49, fn=65, n=48/49/50)
118
+ // Model 2 (most common)
119
+ commands.push(exports.GS, 0x28, 0x6b, 0x04, 0x00, 0x31, 0x41, 0x32, 0x00);
120
+ // QR Code size (function 167, cn=49, fn=67, n=size)
121
+ commands.push(exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x43, size);
122
+ // QR Code error correction (function 169, cn=49, fn=69, n=48-51)
123
+ // 48=L(7%), 49=M(15%), 50=Q(25%), 51=H(30%)
124
+ commands.push(exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x45, 0x31);
125
+ // Store QR code data (function 180, cn=49, fn=80)
126
+ const dataBytes = new TextEncoder().encode(data);
127
+ const pL = (dataBytes.length + 3) % 256;
128
+ const pH = Math.floor((dataBytes.length + 3) / 256);
129
+ commands.push(exports.GS, 0x28, 0x6b, pL, pH, 0x31, 0x50, 0x30);
130
+ commands.push(...Array.from(dataBytes));
131
+ // Print QR code (function 181, cn=49, fn=81)
132
+ commands.push(exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x31, 0x51, 0x30);
133
+ return commands;
134
+ };
135
+ exports.generateQRCode = generateQRCode;
136
+ /**
137
+ * Generate raster image command (GS v 0)
138
+ * @param imageData - Monochrome bitmap data (1 bit per pixel, 1=black, 0=white)
139
+ * @param width - Image width in pixels
140
+ * @param height - Image height in pixels
141
+ * @returns ESC/POS command bytes
142
+ */
143
+ const generateRasterImage = (imageData, width, height) => {
144
+ const commands = [];
145
+ // Calculate bytes per line (width in bytes, rounded up to nearest byte)
146
+ const bytesPerLine = Math.ceil(width / 8);
147
+ // GS v 0 m xL xH yL yH d1...dk
148
+ // m = 0 (normal), 1 (double width), 2 (double height), 3 (quadruple)
149
+ // xL xH = width in bytes (little endian)
150
+ // yL yH = height in dots (little endian)
151
+ // d1...dk = raster image data
152
+ commands.push(exports.GS, 0x76, 0x30, 0x00); // GS v 0 m (m=0: normal)
153
+ // Width in bytes (little endian)
154
+ commands.push(bytesPerLine & 0xff);
155
+ commands.push((bytesPerLine >> 8) & 0xff);
156
+ // Height in dots (little endian)
157
+ commands.push(height & 0xff);
158
+ commands.push((height >> 8) & 0xff);
159
+ // Add image data
160
+ commands.push(...imageData);
161
+ return commands;
162
+ };
163
+ exports.generateRasterImage = generateRasterImage;
164
+ /**
165
+ * Text encoding helper
166
+ * Converts string to CP860 byte array for Brazilian Portuguese thermal printers
167
+ */
168
+ const encodeText = (text) => {
169
+ // CP860 is the standard codepage for Portuguese thermal printers
170
+ // Supports: ç Ç á é í ó ú à ã õ â ê ô and other Portuguese characters
171
+ return (0, cp860_1.encodeCP860)(text);
172
+ };
173
+ exports.encodeText = encodeText;
174
+ // ============================================================================
175
+ // REAL-TIME COMMANDS
176
+ // ============================================================================
177
+ /**
178
+ * DLE EOT n - Transmit real-time status
179
+ * n = 1: Transmit printer status
180
+ * n = 2: Transmit offline status
181
+ * n = 3: Transmit error status
182
+ * n = 4: Transmit paper roll sensor status
183
+ */
184
+ const transmitRealtimeStatus = (n) => [
185
+ exports.DLE,
186
+ 0x04,
187
+ n,
188
+ ];
189
+ exports.transmitRealtimeStatus = transmitRealtimeStatus;
190
+ /**
191
+ * DLE ENQ n - Real-time request to printer
192
+ * n = 1: Recover from error and restart printing
193
+ * n = 2: Clear buffer
194
+ */
195
+ const realtimeRequest = (n) => [exports.DLE, 0x05, n];
196
+ exports.realtimeRequest = realtimeRequest;
197
+ /**
198
+ * DLE DC4 fn a b - Generate pulse in real-time
199
+ * fn = 1: Generate pulse
200
+ * a = drawer (0 or 1)
201
+ * b = pulse time
202
+ */
203
+ const realtimePulse = (drawer, pulseTime) => [
204
+ exports.DLE,
205
+ 0x14,
206
+ 0x01,
207
+ drawer,
208
+ pulseTime,
209
+ ];
210
+ exports.realtimePulse = realtimePulse;
211
+ // ============================================================================
212
+ // TEXT POSITION & LAYOUT
213
+ // ============================================================================
214
+ /**
215
+ * ESC $ nL nH - Set absolute print position
216
+ * Position = ((nH × 256) + nL) × (horizontal motion unit)
217
+ */
218
+ const setAbsolutePosition = (position) => {
219
+ const nL = position & 0xff;
220
+ const nH = (position >> 8) & 0xff;
221
+ return [exports.ESC, 0x24, nL, nH];
222
+ };
223
+ exports.setAbsolutePosition = setAbsolutePosition;
224
+ /**
225
+ * ESC \ nL nH - Set relative print position
226
+ * Relative position = ((nH × 256) + nL) × (horizontal motion unit)
227
+ * Supports negative values (two's complement)
228
+ */
229
+ const setRelativePosition = (position) => {
230
+ const nL = position & 0xff;
231
+ const nH = (position >> 8) & 0xff;
232
+ return [exports.ESC, 0x5c, nL, nH];
233
+ };
234
+ exports.setRelativePosition = setRelativePosition;
235
+ /**
236
+ * ESC SP n - Set right-side character spacing
237
+ * Range: 0 ≤ n ≤ 255
238
+ * Spacing = n × (horizontal motion unit)
239
+ */
240
+ const setCharacterSpacing = (dots) => [
241
+ exports.ESC,
242
+ 0x20,
243
+ Math.max(0, Math.min(255, dots)),
244
+ ];
245
+ exports.setCharacterSpacing = setCharacterSpacing;
246
+ /**
247
+ * ESC D n1...nk NUL - Set horizontal tab positions
248
+ * n1-nk: Tab positions (1-255), up to 32 positions
249
+ * Must be in ascending order, terminated with NUL
250
+ */
251
+ const setTabPositions = (positions) => {
252
+ const validPositions = positions
253
+ .filter((p) => p >= 1 && p <= 255)
254
+ .slice(0, 32)
255
+ .sort((a, b) => a - b);
256
+ return [exports.ESC, 0x44, ...validPositions, 0x00];
257
+ };
258
+ exports.setTabPositions = setTabPositions;
259
+ /**
260
+ * ESC D NUL - Cancel all horizontal tab positions
261
+ */
262
+ exports.CLEAR_TABS = [exports.ESC, 0x44, 0x00];
263
+ // ============================================================================
264
+ // TEXT EMPHASIS & STYLES
265
+ // ============================================================================
266
+ /**
267
+ * ESC G n - Turn double-strike mode on/off
268
+ * n = 0 or 48: Turn off double-strike mode
269
+ * n = 1 or 49: Turn on double-strike mode
270
+ */
271
+ exports.DOUBLE_STRIKE_ON = [exports.ESC, 0x47, 0x01];
272
+ exports.DOUBLE_STRIKE_OFF = [exports.ESC, 0x47, 0x00];
273
+ /**
274
+ * Character font selection
275
+ */
276
+ var CharacterFont;
277
+ (function (CharacterFont) {
278
+ CharacterFont[CharacterFont["FONT_A"] = 0] = "FONT_A";
279
+ CharacterFont[CharacterFont["FONT_B"] = 1] = "FONT_B";
280
+ CharacterFont[CharacterFont["FONT_C"] = 2] = "FONT_C";
281
+ })(CharacterFont || (exports.CharacterFont = CharacterFont = {}));
282
+ /**
283
+ * ESC M n - Select character font
284
+ * n = 0 or 48: Font A (12×24)
285
+ * n = 1 or 49: Font B (9×17)
286
+ * n = 2 or 50: Font C (printer dependent)
287
+ */
288
+ const selectFont = (font) => [exports.ESC, 0x4d, font];
289
+ exports.selectFont = selectFont;
290
+ /**
291
+ * ESC U - Select Font D (Phoenix printers only)
292
+ * Font D: 16×24 dots
293
+ * Warning: This is a Phoenix-specific feature and may not work on all printers
294
+ */
295
+ exports.SELECT_FONT_D = [exports.ESC, 0x51];
296
+ /**
297
+ * ESC V n - Turn 90° clockwise rotation mode on/off
298
+ * n = 0 or 48: Turn off 90° clockwise rotation mode
299
+ * n = 1 or 49: Turn on 90° clockwise rotation mode
300
+ */
301
+ exports.ROTATE_90_ON = [exports.ESC, 0x56, 0x01];
302
+ exports.ROTATE_90_OFF = [exports.ESC, 0x56, 0x00];
303
+ /**
304
+ * ESC { n - Turn upside-down printing mode on/off
305
+ * n = 0 or 48: Turn off upside-down printing mode
306
+ * n = 1 or 49: Turn on upside-down printing mode
307
+ */
308
+ exports.UPSIDE_DOWN_ON = [exports.ESC, 0x7b, 0x01];
309
+ exports.UPSIDE_DOWN_OFF = [exports.ESC, 0x7b, 0x00];
310
+ /**
311
+ * ESC - n - Turn underline mode on/off with thickness selection
312
+ * n = 0 or 48: Turn off underline mode
313
+ * n = 1 or 49: Turn on underline mode (1-dot thick)
314
+ * n = 2 or 50: Turn on underline mode (2-dots thick)
315
+ */
316
+ exports.UNDERLINE_1DOT = [exports.ESC, 0x2d, 0x01];
317
+ exports.UNDERLINE_2DOT = [exports.ESC, 0x2d, 0x02];
318
+ // ============================================================================
319
+ // LINE SPACING & PAPER CONTROL (ADDITIONAL)
320
+ // ============================================================================
321
+ /**
322
+ * ESC 2 - Select default line spacing
323
+ * Sets line spacing to approximately 4.23mm (1/6 inch)
324
+ */
325
+ exports.LINE_SPACING_DEFAULT_ALT = [exports.ESC, 0x32, 0x5];
326
+ /**
327
+ * ESC J n - Print and feed paper
328
+ * Range: 0 ≤ n ≤ 255
329
+ * Feed amount = n × (vertical motion unit)
330
+ */
331
+ const printAndFeed = (dots) => [
332
+ exports.ESC,
333
+ 0x4a,
334
+ Math.max(0, Math.min(255, dots)),
335
+ ];
336
+ exports.printAndFeed = printAndFeed;
337
+ /**
338
+ * ESC K n - Print and reverse feed
339
+ * Range: 0 ≤ n ≤ 255
340
+ * Reverse feed amount = n × (vertical motion unit)
341
+ */
342
+ const printAndReverseFeed = (dots) => [
343
+ exports.ESC,
344
+ 0x4b,
345
+ Math.max(0, Math.min(255, dots)),
346
+ ];
347
+ exports.printAndReverseFeed = printAndReverseFeed;
348
+ // ============================================================================
349
+ // PAPER CUTTING (ADDITIONAL)
350
+ // ============================================================================
351
+ /**
352
+ * ESC i - Full cut
353
+ * Executes a full cut (cuts paper completely)
354
+ */
355
+ exports.CUT_FULL_ESC = [exports.ESC, 0x69];
356
+ /**
357
+ * ESC m - Partial cut
358
+ * Executes a partial cut (leaves connection point)
359
+ */
360
+ exports.CUT_PARTIAL_ESC = [exports.ESC, 0x6d];
361
+ /**
362
+ * GS V m n - Cut paper and feed
363
+ * m = 65 (0x41): Feed then full cut
364
+ * m = 66 (0x42): Feed then partial cut
365
+ * n = feed amount before cut
366
+ */
367
+ const cutAndFeedFull = (dots) => [
368
+ exports.GS,
369
+ 0x56,
370
+ 0x41,
371
+ Math.max(0, Math.min(255, dots)),
372
+ ];
373
+ exports.cutAndFeedFull = cutAndFeedFull;
374
+ const cutAndFeedPartial = (dots) => [
375
+ exports.GS,
376
+ 0x56,
377
+ 0x42,
378
+ Math.max(0, Math.min(255, dots)),
379
+ ];
380
+ exports.cutAndFeedPartial = cutAndFeedPartial;
381
+ // ============================================================================
382
+ // PERIPHERAL DEVICE CONTROL
383
+ // ============================================================================
384
+ /**
385
+ * ESC = n - Select peripheral device
386
+ * n = 0: Disabled
387
+ * n = 1: Enabled
388
+ */
389
+ const selectPeripheral = (enabled) => [
390
+ exports.ESC,
391
+ 0x3d,
392
+ enabled ? 0x01 : 0x00,
393
+ ];
394
+ exports.selectPeripheral = selectPeripheral;
395
+ /**
396
+ * ESC p m t1 t2 - Generate pulse
397
+ * m = 0 or 48: Drawer kick-out connector pin 2
398
+ * m = 1 or 49: Drawer kick-out connector pin 5
399
+ * t1 = ON time (0-255, units of 100ms)
400
+ * t2 = OFF time (0-255, units of 100ms)
401
+ */
402
+ const generatePulse = (connector, onTime, offTime) => [
403
+ exports.ESC,
404
+ 0x70,
405
+ connector,
406
+ Math.max(0, Math.min(255, onTime)),
407
+ Math.max(0, Math.min(255, offTime)),
408
+ ];
409
+ exports.generatePulse = generatePulse;
410
+ /**
411
+ * ESC c 3 n - Select paper sensor(s) to output paper-end signals
412
+ * n is a bitmask for sensor selection
413
+ */
414
+ const selectPaperSensorOutput = (sensorMask) => [
415
+ exports.ESC,
416
+ 0x63,
417
+ 0x33,
418
+ sensorMask,
419
+ ];
420
+ exports.selectPaperSensorOutput = selectPaperSensorOutput;
421
+ /**
422
+ * ESC c 4 n - Select paper sensor(s) to stop printing
423
+ * n is a bitmask for sensor selection
424
+ */
425
+ const selectPaperSensorStop = (sensorMask) => [
426
+ exports.ESC,
427
+ 0x63,
428
+ 0x34,
429
+ sensorMask,
430
+ ];
431
+ exports.selectPaperSensorStop = selectPaperSensorStop;
432
+ /**
433
+ * ESC c 5 n - Enable/disable panel buttons
434
+ * n = 0: Enable panel buttons
435
+ * n = 1: Disable panel buttons
436
+ */
437
+ const enablePanelButtons = () => [exports.ESC, 0x63, 0x35, 0x00];
438
+ exports.enablePanelButtons = enablePanelButtons;
439
+ const disablePanelButtons = () => [exports.ESC, 0x63, 0x35, 0x01];
440
+ exports.disablePanelButtons = disablePanelButtons;
441
+ // ============================================================================
442
+ // CHARACTER CODE TABLES
443
+ // ============================================================================
444
+ /**
445
+ * International character set selection
446
+ */
447
+ var InternationalCharset;
448
+ (function (InternationalCharset) {
449
+ InternationalCharset[InternationalCharset["USA"] = 0] = "USA";
450
+ InternationalCharset[InternationalCharset["FRANCE"] = 1] = "FRANCE";
451
+ InternationalCharset[InternationalCharset["GERMANY"] = 2] = "GERMANY";
452
+ InternationalCharset[InternationalCharset["UK"] = 3] = "UK";
453
+ InternationalCharset[InternationalCharset["DENMARK_I"] = 4] = "DENMARK_I";
454
+ InternationalCharset[InternationalCharset["SWEDEN"] = 5] = "SWEDEN";
455
+ InternationalCharset[InternationalCharset["ITALY"] = 6] = "ITALY";
456
+ InternationalCharset[InternationalCharset["SPAIN_I"] = 7] = "SPAIN_I";
457
+ InternationalCharset[InternationalCharset["JAPAN"] = 8] = "JAPAN";
458
+ InternationalCharset[InternationalCharset["NORWAY"] = 9] = "NORWAY";
459
+ InternationalCharset[InternationalCharset["DENMARK_II"] = 10] = "DENMARK_II";
460
+ InternationalCharset[InternationalCharset["SPAIN_II"] = 11] = "SPAIN_II";
461
+ InternationalCharset[InternationalCharset["LATIN_AMERICA"] = 12] = "LATIN_AMERICA";
462
+ InternationalCharset[InternationalCharset["KOREA"] = 13] = "KOREA";
463
+ })(InternationalCharset || (exports.InternationalCharset = InternationalCharset = {}));
464
+ /**
465
+ * ESC R n - Select international character set
466
+ */
467
+ const selectInternationalCharset = (charset) => [exports.ESC, 0x52, charset];
468
+ exports.selectInternationalCharset = selectInternationalCharset;
469
+ /**
470
+ * Extended code page enumeration
471
+ */
472
+ var CodePage;
473
+ (function (CodePage) {
474
+ CodePage[CodePage["CP437"] = 0] = "CP437";
475
+ CodePage[CodePage["CP850"] = 2] = "CP850";
476
+ CodePage[CodePage["CP860"] = 3] = "CP860";
477
+ CodePage[CodePage["CP863"] = 4] = "CP863";
478
+ CodePage[CodePage["CP865"] = 5] = "CP865";
479
+ CodePage[CodePage["CP851"] = 11] = "CP851";
480
+ CodePage[CodePage["CP853"] = 12] = "CP853";
481
+ CodePage[CodePage["CP857"] = 13] = "CP857";
482
+ CodePage[CodePage["CP737"] = 14] = "CP737";
483
+ CodePage[CodePage["CP928"] = 16] = "CP928";
484
+ CodePage[CodePage["CP866"] = 17] = "CP866";
485
+ CodePage[CodePage["CP852"] = 18] = "CP852";
486
+ CodePage[CodePage["CP858"] = 19] = "CP858";
487
+ CodePage[CodePage["WPC1252"] = 16] = "WPC1252";
488
+ })(CodePage || (exports.CodePage = CodePage = {}));
489
+ /**
490
+ * ESC t n - Select character code table
491
+ */
492
+ const setCodePage = (page) => [exports.ESC, 0x74, page];
493
+ exports.setCodePage = setCodePage;
494
+ // ============================================================================
495
+ // GRAPHICS - BIT IMAGE
496
+ // ============================================================================
497
+ /**
498
+ * Bit image modes for ESC *
499
+ */
500
+ var BitImageMode;
501
+ (function (BitImageMode) {
502
+ BitImageMode[BitImageMode["MODE_8_SINGLE"] = 0] = "MODE_8_SINGLE";
503
+ BitImageMode[BitImageMode["MODE_8_DOUBLE"] = 1] = "MODE_8_DOUBLE";
504
+ BitImageMode[BitImageMode["MODE_24_SINGLE"] = 32] = "MODE_24_SINGLE";
505
+ BitImageMode[BitImageMode["MODE_24_DOUBLE"] = 33] = "MODE_24_DOUBLE";
506
+ })(BitImageMode || (exports.BitImageMode = BitImageMode = {}));
507
+ /**
508
+ * ESC * m nL nH d1...dk - Print bit image
509
+ * m: Bit image mode
510
+ * nL, nH: Number of data columns (nL + nH × 256)
511
+ * d1...dk: Bit image data
512
+ */
513
+ const printBitImage = (mode, width, data) => {
514
+ const nL = width & 0xff;
515
+ const nH = (width >> 8) & 0xff;
516
+ return [exports.ESC, 0x2a, mode, nL, nH, ...data];
517
+ };
518
+ exports.printBitImage = printBitImage;
519
+ // ============================================================================
520
+ // GRAPHICS - DOWNLOADED BIT IMAGE
521
+ // ============================================================================
522
+ /**
523
+ * GS * x y d1...dk - Define downloaded bit image
524
+ * x: Number of bytes in horizontal direction (1 ≤ x ≤ 255)
525
+ * y: Number of bytes in vertical direction (1 ≤ y ≤ 48)
526
+ * Horizontal dots = x × 8
527
+ * Vertical dots = y × 8
528
+ */
529
+ const defineDownloadedBitImage = (x, y, data) => {
530
+ const xVal = Math.max(1, Math.min(255, x));
531
+ const yVal = Math.max(1, Math.min(48, y));
532
+ return [exports.GS, 0x2a, xVal, yVal, ...data];
533
+ };
534
+ exports.defineDownloadedBitImage = defineDownloadedBitImage;
535
+ /**
536
+ * Downloaded image print modes
537
+ */
538
+ var DownloadedImageMode;
539
+ (function (DownloadedImageMode) {
540
+ DownloadedImageMode[DownloadedImageMode["NORMAL"] = 0] = "NORMAL";
541
+ DownloadedImageMode[DownloadedImageMode["DOUBLE_WIDTH"] = 1] = "DOUBLE_WIDTH";
542
+ DownloadedImageMode[DownloadedImageMode["DOUBLE_HEIGHT"] = 2] = "DOUBLE_HEIGHT";
543
+ DownloadedImageMode[DownloadedImageMode["QUADRUPLE"] = 3] = "QUADRUPLE";
544
+ })(DownloadedImageMode || (exports.DownloadedImageMode = DownloadedImageMode = {}));
545
+ /**
546
+ * GS / m - Print downloaded bit image
547
+ * m: Print mode (0-3)
548
+ */
549
+ const printDownloadedBitImage = (mode) => [exports.GS, 0x2f, mode];
550
+ exports.printDownloadedBitImage = printDownloadedBitImage;
551
+ // ============================================================================
552
+ // GRAPHICS - NV BIT IMAGE
553
+ // ============================================================================
554
+ /**
555
+ * FS p n m - Print NV bit image
556
+ * n: NV bit image number (1-255)
557
+ * m: Print mode (0-3, same as DownloadedImageMode)
558
+ */
559
+ const printNVBitImage = (imageNumber, mode) => [exports.FS, 0x70, Math.max(1, Math.min(255, imageNumber)), mode];
560
+ exports.printNVBitImage = printNVBitImage;
561
+ /**
562
+ * FS q n [xL xH yL yH d1...dk]1...n - Define NV bit image
563
+ * n: Number of NV bit images to define (1-255)
564
+ * For each image:
565
+ * xL, xH: Width in bytes ((xH × 256 + xL) × 8 dots)
566
+ * yL, yH: Height in bytes ((yH × 256 + yL) × 8 dots)
567
+ * d1...dk: Bit image data
568
+ */
569
+ const defineNVBitImage = (images) => {
570
+ const result = [exports.FS, 0x71, Math.min(images.length, 255)];
571
+ for (const img of images.slice(0, 255)) {
572
+ const xL = img.width & 0xff;
573
+ const xH = (img.width >> 8) & 0xff;
574
+ const yL = img.height & 0xff;
575
+ const yH = (img.height >> 8) & 0xff;
576
+ result.push(xL, xH, yL, yH, ...img.data);
577
+ }
578
+ return result;
579
+ };
580
+ exports.defineNVBitImage = defineNVBitImage;
581
+ // ============================================================================
582
+ // BARCODE CONFIGURATION
583
+ // ============================================================================
584
+ /**
585
+ * Barcode HRI (Human Readable Interpretation) position
586
+ */
587
+ var BarcodeHRIPosition;
588
+ (function (BarcodeHRIPosition) {
589
+ BarcodeHRIPosition[BarcodeHRIPosition["NOT_PRINTED"] = 0] = "NOT_PRINTED";
590
+ BarcodeHRIPosition[BarcodeHRIPosition["ABOVE"] = 1] = "ABOVE";
591
+ BarcodeHRIPosition[BarcodeHRIPosition["BELOW"] = 2] = "BELOW";
592
+ BarcodeHRIPosition[BarcodeHRIPosition["BOTH"] = 3] = "BOTH";
593
+ })(BarcodeHRIPosition || (exports.BarcodeHRIPosition = BarcodeHRIPosition = {}));
594
+ /**
595
+ * GS H n - Select HRI character print position
596
+ */
597
+ const setBarcodeHRI = (position) => [
598
+ exports.GS,
599
+ 0x48,
600
+ position,
601
+ ];
602
+ exports.setBarcodeHRI = setBarcodeHRI;
603
+ /**
604
+ * GS f n - Select font for HRI characters
605
+ * n = 0 or 48: Font A
606
+ * n = 1 or 49: Font B
607
+ */
608
+ const setBarcodeFont = (fontB) => [
609
+ exports.GS,
610
+ 0x66,
611
+ fontB ? 0x01 : 0x00,
612
+ ];
613
+ exports.setBarcodeFont = setBarcodeFont;
614
+ /**
615
+ * GS h n - Set barcode height
616
+ * Range: 1 ≤ n ≤ 255 (in dots)
617
+ * Default: 162
618
+ */
619
+ const setBarcodeHeight = (height) => [
620
+ exports.GS,
621
+ 0x68,
622
+ Math.max(1, Math.min(255, height)),
623
+ ];
624
+ exports.setBarcodeHeight = setBarcodeHeight;
625
+ /**
626
+ * GS w n - Set barcode width
627
+ * Range: 2 ≤ n ≤ 6 (module width in dots)
628
+ * Default: 3
629
+ */
630
+ const setBarcodeWidth = (width) => [
631
+ exports.GS,
632
+ 0x77,
633
+ Math.max(2, Math.min(6, width)),
634
+ ];
635
+ exports.setBarcodeWidth = setBarcodeWidth;
636
+ // ============================================================================
637
+ // BARCODE PRINTING
638
+ // ============================================================================
639
+ /**
640
+ * Barcode symbologies
641
+ */
642
+ var BarcodeType;
643
+ (function (BarcodeType) {
644
+ BarcodeType[BarcodeType["UPC_A"] = 0] = "UPC_A";
645
+ BarcodeType[BarcodeType["UPC_E"] = 1] = "UPC_E";
646
+ BarcodeType[BarcodeType["EAN13"] = 2] = "EAN13";
647
+ BarcodeType[BarcodeType["EAN8"] = 3] = "EAN8";
648
+ BarcodeType[BarcodeType["CODE39"] = 4] = "CODE39";
649
+ BarcodeType[BarcodeType["ITF"] = 5] = "ITF";
650
+ BarcodeType[BarcodeType["CODABAR"] = 6] = "CODABAR";
651
+ BarcodeType[BarcodeType["CODE93"] = 72] = "CODE93";
652
+ BarcodeType[BarcodeType["CODE128"] = 73] = "CODE128";
653
+ })(BarcodeType || (exports.BarcodeType = BarcodeType = {}));
654
+ /**
655
+ * GS k m d1...dk NUL - Print barcode (NUL-terminated)
656
+ * For barcode types 0-6 (UPC-A, UPC-E, EAN-13, EAN-8, CODE39, ITF, CODABAR)
657
+ */
658
+ const printBarcode = (type, data) => {
659
+ const bytes = data.split("").map((c) => c.charCodeAt(0));
660
+ return [exports.GS, 0x6b, type, ...bytes, 0x00];
661
+ };
662
+ exports.printBarcode = printBarcode;
663
+ /**
664
+ * GS k m n d1...dn - Print barcode (length-specified)
665
+ * For barcode types 65-73 (with length prefix)
666
+ */
667
+ const printBarcodeWithLength = (type, data) => {
668
+ const bytes = data.split("").map((c) => c.charCodeAt(0));
669
+ return [exports.GS, 0x6b, type, bytes.length, ...bytes];
670
+ };
671
+ exports.printBarcodeWithLength = printBarcodeWithLength;
672
+ /**
673
+ * Print UPC-A barcode
674
+ * Requires 11-12 digits
675
+ */
676
+ const printBarcodeUPCA = (data) => {
677
+ if (!/^\d{11,12}$/.test(data)) {
678
+ throw new Error("UPC-A requires 11-12 digits");
679
+ }
680
+ return (0, exports.printBarcode)(BarcodeType.UPC_A, data.slice(0, 12));
681
+ };
682
+ exports.printBarcodeUPCA = printBarcodeUPCA;
683
+ /**
684
+ * Print UPC-E barcode
685
+ * Requires 6-8 digits
686
+ */
687
+ const printBarcodeUPCE = (data) => {
688
+ if (!/^\d{6,8}$/.test(data)) {
689
+ throw new Error("UPC-E requires 6-8 digits");
690
+ }
691
+ return (0, exports.printBarcode)(BarcodeType.UPC_E, data);
692
+ };
693
+ exports.printBarcodeUPCE = printBarcodeUPCE;
694
+ /**
695
+ * Print EAN-13 barcode
696
+ * Requires 12-13 digits
697
+ */
698
+ const printBarcodeEAN13 = (data) => {
699
+ if (!/^\d{12,13}$/.test(data)) {
700
+ throw new Error("EAN-13 requires 12-13 digits");
701
+ }
702
+ return (0, exports.printBarcode)(BarcodeType.EAN13, data.slice(0, 13));
703
+ };
704
+ exports.printBarcodeEAN13 = printBarcodeEAN13;
705
+ /**
706
+ * Print EAN-8 barcode
707
+ * Requires 7-8 digits
708
+ */
709
+ const printBarcodeEAN8 = (data) => {
710
+ if (!/^\d{7,8}$/.test(data)) {
711
+ throw new Error("EAN-8 requires 7-8 digits");
712
+ }
713
+ return (0, exports.printBarcode)(BarcodeType.EAN8, data);
714
+ };
715
+ exports.printBarcodeEAN8 = printBarcodeEAN8;
716
+ /**
717
+ * Print CODE39 barcode
718
+ * Supports: 0-9, A-Z, space, and symbols ($ % + - . /)
719
+ */
720
+ const printBarcodeCODE39 = (data) => {
721
+ if (!/^[0-9A-Z $%+\-.\/]+$/.test(data)) {
722
+ throw new Error("CODE39 supports: 0-9, A-Z, space, $%+-./ only");
723
+ }
724
+ return (0, exports.printBarcode)(BarcodeType.CODE39, data);
725
+ };
726
+ exports.printBarcodeCODE39 = printBarcodeCODE39;
727
+ /**
728
+ * Print ITF barcode (Interleaved 2 of 5)
729
+ * Requires even number of digits
730
+ */
731
+ const printBarcodeITF = (data) => {
732
+ if (!/^\d+$/.test(data) || data.length % 2 !== 0) {
733
+ throw new Error("ITF requires even number of digits");
734
+ }
735
+ return (0, exports.printBarcode)(BarcodeType.ITF, data);
736
+ };
737
+ exports.printBarcodeITF = printBarcodeITF;
738
+ /**
739
+ * Print CODABAR barcode
740
+ * Supports: 0-9, A-D, and symbols ($ + - . / :)
741
+ */
742
+ const printBarcodeCODABAR = (data) => {
743
+ if (!/^[A-D][0-9A-D $+\-.\/:]*[A-D]$/.test(data)) {
744
+ throw new Error("CODABAR must start and end with A-D, and contain 0-9, A-D, $+-./:");
745
+ }
746
+ return (0, exports.printBarcode)(BarcodeType.CODABAR, data);
747
+ };
748
+ exports.printBarcodeCODABAR = printBarcodeCODABAR;
749
+ /**
750
+ * Print CODE93 barcode
751
+ * Supports all ASCII characters (0-127)
752
+ */
753
+ const printBarcodeCODE93 = (data) => {
754
+ return (0, exports.printBarcodeWithLength)(BarcodeType.CODE93, data);
755
+ };
756
+ exports.printBarcodeCODE93 = printBarcodeCODE93;
757
+ /**
758
+ * Print CODE128 barcode
759
+ * Supports all ASCII characters (0-127)
760
+ */
761
+ const printBarcodeCODE128 = (data) => {
762
+ return (0, exports.printBarcodeWithLength)(BarcodeType.CODE128, data);
763
+ };
764
+ exports.printBarcodeCODE128 = printBarcodeCODE128;
765
+ // ============================================================================
766
+ // 2D CODES - PDF417
767
+ // ============================================================================
768
+ /**
769
+ * GS ( k pL pH cn fn [parameters] - PDF417 commands
770
+ * cn = 0x30 (function code 48 for PDF417)
771
+ */
772
+ /**
773
+ * Set PDF417 number of columns
774
+ * fn = 0x41, n = number of columns (0 or 1-30)
775
+ */
776
+ const setPDF417Columns = (columns) => {
777
+ const col = Math.max(0, Math.min(30, columns));
778
+ return [exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x30, 0x41, col];
779
+ };
780
+ exports.setPDF417Columns = setPDF417Columns;
781
+ /**
782
+ * Set PDF417 number of rows
783
+ * fn = 0x42, n = number of rows (0 or 3-90)
784
+ */
785
+ const setPDF417Rows = (rows) => {
786
+ const row = rows === 0 ? 0 : Math.max(3, Math.min(90, rows));
787
+ return [exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x30, 0x42, row];
788
+ };
789
+ exports.setPDF417Rows = setPDF417Rows;
790
+ /**
791
+ * Set PDF417 module width
792
+ * fn = 0x43, n = module width (2-8 dots)
793
+ */
794
+ const setPDF417Width = (width) => {
795
+ const w = Math.max(2, Math.min(8, width));
796
+ return [exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x30, 0x43, w];
797
+ };
798
+ exports.setPDF417Width = setPDF417Width;
799
+ /**
800
+ * Set PDF417 row height
801
+ * fn = 0x44, n = row height (2-8 dots)
802
+ */
803
+ const setPDF417RowHeight = (height) => {
804
+ const h = Math.max(2, Math.min(8, height));
805
+ return [exports.GS, 0x28, 0x6b, 0x03, 0x00, 0x30, 0x44, h];
806
+ };
807
+ exports.setPDF417RowHeight = setPDF417RowHeight;
808
+ /**
809
+ * Set PDF417 error correction level
810
+ * fn = 0x45, m = 48 (standard mode), n = level (0-8)
811
+ */
812
+ const setPDF417ErrorCorrection = (level) => {
813
+ const lvl = Math.max(0, Math.min(8, level));
814
+ return [exports.GS, 0x28, 0x6b, 0x04, 0x00, 0x30, 0x45, 0x30, lvl];
815
+ };
816
+ exports.setPDF417ErrorCorrection = setPDF417ErrorCorrection;
817
+ /**
818
+ * Store PDF417 data
819
+ * fn = 0x50, m = 48 (standard mode), followed by data
820
+ */
821
+ const storePDF417Data = (data) => {
822
+ const bytes = new TextEncoder().encode(data);
823
+ const pL = (bytes.length + 3) & 0xff;
824
+ const pH = ((bytes.length + 3) >> 8) & 0xff;
825
+ return [exports.GS, 0x28, 0x6b, pL, pH, 0x30, 0x50, 0x30, ...Array.from(bytes)];
826
+ };
827
+ exports.storePDF417Data = storePDF417Data;
828
+ /**
829
+ * Print PDF417 symbol
830
+ * fn = 0x51, m = 48 (standard mode)
831
+ */
832
+ const printPDF417 = () => [
833
+ exports.GS,
834
+ 0x28,
835
+ 0x6b,
836
+ 0x03,
837
+ 0x00,
838
+ 0x30,
839
+ 0x51,
840
+ 0x30,
841
+ ];
842
+ exports.printPDF417 = printPDF417;
843
+ /**
844
+ * Generate complete PDF417 barcode
845
+ * Convenience function that combines all PDF417 commands
846
+ */
847
+ const generatePDF417 = (data, options) => {
848
+ const commands = [];
849
+ if (options?.columns !== undefined) {
850
+ commands.push(...(0, exports.setPDF417Columns)(options.columns));
851
+ }
852
+ if (options?.rows !== undefined) {
853
+ commands.push(...(0, exports.setPDF417Rows)(options.rows));
854
+ }
855
+ if (options?.width !== undefined) {
856
+ commands.push(...(0, exports.setPDF417Width)(options.width));
857
+ }
858
+ if (options?.rowHeight !== undefined) {
859
+ commands.push(...(0, exports.setPDF417RowHeight)(options.rowHeight));
860
+ }
861
+ if (options?.errorCorrection !== undefined) {
862
+ commands.push(...(0, exports.setPDF417ErrorCorrection)(options.errorCorrection));
863
+ }
864
+ commands.push(...(0, exports.storePDF417Data)(data));
865
+ commands.push(...(0, exports.printPDF417)());
866
+ return commands;
867
+ };
868
+ exports.generatePDF417 = generatePDF417;
869
+ // ============================================================================
870
+ // CHARACTER EFFECTS (ADVANCED)
871
+ // ============================================================================
872
+ /**
873
+ * GS ! n - Select character size
874
+ * Supports 1-8x width and height multipliers
875
+ * Bits 0-2: Width (0-7 for 1x-8x)
876
+ * Bits 4-6: Height (0-7 for 1x-8x)
877
+ */
878
+ const selectCharacterSize = (widthMultiplier, heightMultiplier) => {
879
+ const w = Math.max(0, Math.min(7, widthMultiplier - 1));
880
+ const h = Math.max(0, Math.min(7, heightMultiplier - 1));
881
+ const n = (w & 0x07) | ((h & 0x07) << 4);
882
+ return [exports.GS, 0x21, n];
883
+ };
884
+ exports.selectCharacterSize = selectCharacterSize;
885
+ /**
886
+ * GS B n - Turn white/black reverse printing mode on/off
887
+ * n = 0 or 48: Turn off white/black reverse mode
888
+ * n = 1 or 49: Turn on white/black reverse mode
889
+ */
890
+ exports.REVERSE_PRINT_ON = [exports.GS, 0x42, 0x01];
891
+ exports.REVERSE_PRINT_OFF = [exports.GS, 0x42, 0x00];
892
+ /**
893
+ * GS ( N pL pH fn n - Select character effects
894
+ * fn = 48: Set character color
895
+ * fn = 49: Set character smoothing
896
+ */
897
+ const setCharacterColor = (color) => [
898
+ exports.GS,
899
+ 0x28,
900
+ 0x4e,
901
+ 0x02,
902
+ 0x00,
903
+ 0x30,
904
+ color,
905
+ ];
906
+ exports.setCharacterColor = setCharacterColor;
907
+ const setCharacterSmoothing = (enabled) => [
908
+ exports.GS,
909
+ 0x28,
910
+ 0x4e,
911
+ 0x02,
912
+ 0x00,
913
+ 0x31,
914
+ enabled ? 0x01 : 0x00,
915
+ ];
916
+ exports.setCharacterSmoothing = setCharacterSmoothing;
917
+ // ============================================================================
918
+ // STATUS COMMANDS
919
+ // ============================================================================
920
+ /**
921
+ * GS a n - Enable/disable Automatic Status Back (ASB)
922
+ * n is a bitmask for status types to enable
923
+ */
924
+ const enableASB = (statusBits) => [
925
+ exports.GS,
926
+ 0x61,
927
+ statusBits,
928
+ ];
929
+ exports.enableASB = enableASB;
930
+ const disableASB = () => [exports.GS, 0x61, 0x00];
931
+ exports.disableASB = disableASB;
932
+ /**
933
+ * Printer ID types for GS I command
934
+ */
935
+ var PrinterIDType;
936
+ (function (PrinterIDType) {
937
+ PrinterIDType[PrinterIDType["PRINTER_MODEL"] = 1] = "PRINTER_MODEL";
938
+ PrinterIDType[PrinterIDType["TYPE_ID"] = 2] = "TYPE_ID";
939
+ PrinterIDType[PrinterIDType["ROM_VERSION"] = 65] = "ROM_VERSION";
940
+ PrinterIDType[PrinterIDType["FONT_TYPE"] = 66] = "FONT_TYPE";
941
+ PrinterIDType[PrinterIDType["MANUFACTURER"] = 67] = "MANUFACTURER";
942
+ })(PrinterIDType || (exports.PrinterIDType = PrinterIDType = {}));
943
+ /**
944
+ * GS I n - Transmit printer ID
945
+ */
946
+ const requestPrinterID = (type) => [
947
+ exports.GS,
948
+ 0x49,
949
+ type,
950
+ ];
951
+ exports.requestPrinterID = requestPrinterID;
952
+ /**
953
+ * Status types for GS r command
954
+ */
955
+ var StatusType;
956
+ (function (StatusType) {
957
+ StatusType[StatusType["PAPER_SENSOR"] = 1] = "PAPER_SENSOR";
958
+ StatusType[StatusType["DRAWER_SENSOR"] = 2] = "DRAWER_SENSOR";
959
+ StatusType[StatusType["INK_SENSOR"] = 4] = "INK_SENSOR";
960
+ StatusType[StatusType["PAPER_ROLL_SENSOR"] = 18] = "PAPER_ROLL_SENSOR";
961
+ })(StatusType || (exports.StatusType = StatusType = {}));
962
+ /**
963
+ * GS r n - Transmit status
964
+ */
965
+ const requestStatus = (type) => [exports.GS, 0x72, type];
966
+ exports.requestStatus = requestStatus;
967
+ // ============================================================================
968
+ // MARGINS & PRINT AREA
969
+ // ============================================================================
970
+ /**
971
+ * GS L nL nH - Set left margin
972
+ * Left margin = ((nH × 256) + nL) × (horizontal motion unit)
973
+ */
974
+ const setLeftMargin = (dots) => {
975
+ const nL = dots & 0xff;
976
+ const nH = (dots >> 8) & 0xff;
977
+ return [exports.GS, 0x4c, nL, nH];
978
+ };
979
+ exports.setLeftMargin = setLeftMargin;
980
+ /**
981
+ * GS W nL nH - Set printing area width
982
+ * Width = ((nH × 256) + nL) × (horizontal motion unit)
983
+ */
984
+ const setPrintingAreaWidth = (dots) => {
985
+ const nL = dots & 0xff;
986
+ const nH = (dots >> 8) & 0xff;
987
+ return [exports.GS, 0x57, nL, nH];
988
+ };
989
+ exports.setPrintingAreaWidth = setPrintingAreaWidth;
990
+ // ============================================================================
991
+ // MACRO FUNCTIONS
992
+ // ============================================================================
993
+ /**
994
+ * GS : - Start/end macro definition
995
+ * First call starts macro definition
996
+ * Second call ends macro definition
997
+ */
998
+ exports.START_MACRO = [exports.GS, 0x3a];
999
+ exports.END_MACRO = [exports.GS, 0x3a];
1000
+ /**
1001
+ * GS ^ r t m - Execute macro
1002
+ * r: Number of times to execute macro (0-255)
1003
+ * t: Waiting time between executions (0-255, units of 100ms)
1004
+ * m: Macro execution mode (0 or 1)
1005
+ */
1006
+ const executeMacro = (repeatCount, waitTime, mode) => [
1007
+ exports.GS,
1008
+ 0x5e,
1009
+ Math.max(0, Math.min(255, repeatCount)),
1010
+ Math.max(0, Math.min(255, waitTime)),
1011
+ mode,
1012
+ ];
1013
+ exports.executeMacro = executeMacro;
1014
+ // ============================================================================
1015
+ // MISCELLANEOUS
1016
+ // ============================================================================
1017
+ /**
1018
+ * ESC U n - Turn unidirectional printing mode on/off
1019
+ * n = 0 or 48: Turn off unidirectional printing
1020
+ * n = 1 or 49: Turn on unidirectional printing
1021
+ */
1022
+ exports.UNIDIRECTIONAL_ON = [exports.ESC, 0x55, 0x01];
1023
+ exports.UNIDIRECTIONAL_OFF = [exports.ESC, 0x55, 0x00];
1024
+ /**
1025
+ * CAN - Cancel print data in page mode
1026
+ * Deletes all print data in the current printable area
1027
+ */
1028
+ exports.CANCEL = [exports.CAN];
1029
+ /**
1030
+ * ESC ( A pL pH n m r t - Execute test print
1031
+ * pL pH = 2 (fixed)
1032
+ * n = paper pattern (1-3)
1033
+ * m = mode (0-2)
1034
+ * r = number of times to repeat
1035
+ * t = interval time
1036
+ */
1037
+ const executeTestPrint = (pattern, mode, repeat) => [
1038
+ exports.ESC,
1039
+ 0x28,
1040
+ 0x41,
1041
+ 0x02,
1042
+ 0x00,
1043
+ Math.max(1, Math.min(3, pattern)),
1044
+ Math.max(0, Math.min(2, mode)),
1045
+ repeat,
1046
+ 0x00,
1047
+ ];
1048
+ exports.executeTestPrint = executeTestPrint;